From ac067b523627db09ba9b06e93e0e8859fb4a025e Mon Sep 17 00:00:00 2001 From: reger Date: Sun, 1 Dec 2013 19:36:24 +0100 Subject: [PATCH] clean-up Jetty handler classes --- source/net/yacy/http/ContentModHandler.java | 135 -------- source/net/yacy/http/ProxyHandler.java | 10 +- source/net/yacy/http/TemplateHandler.java | 361 -------------------- 3 files changed, 5 insertions(+), 501 deletions(-) delete mode 100644 source/net/yacy/http/ContentModHandler.java delete mode 100644 source/net/yacy/http/TemplateHandler.java diff --git a/source/net/yacy/http/ContentModHandler.java b/source/net/yacy/http/ContentModHandler.java deleted file mode 100644 index ca903cf73..000000000 --- a/source/net/yacy/http/ContentModHandler.java +++ /dev/null @@ -1,135 +0,0 @@ -// -// ContentModHandler -// Copyright 2011 by Florian Richter -// First released 13.04.2011 at http://yacy.net -// -// $LastChangedDate$ -// $LastChangedRevision$ -// $LastChangedBy$ -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program in the file lgpl21.txt -// If not, see . -// - -package net.yacy.http; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.HandlerContainer; -import org.eclipse.jetty.server.Request; - -import org.eclipse.jetty.server.handler.HandlerWrapper; - -/** - * abstract jetty http handler: - * used to change answer, provided by other handler - */ -public abstract class ContentModHandler extends HandlerWrapper implements Handler, HandlerContainer { - - public ContentModHandler() { - super(); - } - - public ContentModHandler(Handler h) { - super(); - this.setHandler(h); - } - - @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - // wrap response - ContentModResponseWrapper wrapped_response = new ContentModResponseWrapper(response); - super.handle(target, baseRequest, request, wrapped_response); - if(baseRequest.isHandled()) { - //baseRequest.setHandled(false); - this.doContentMod(wrapped_response.getBuffer(), request, response); - //baseRequest.setHandled(true); - } - } - - /** - * method doing editing of answer, overwrite this! - * @param in output of nested handler, to be processed - * @param request original request - * @param response original response object with outputstream to fill - * @throws IOException - * @throws ServletException - */ - protected abstract void doContentMod(byte[] in, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException ; - - /** - * response object, which holds outputstream in bytearray back - */ - private class ContentModResponseWrapper extends HttpServletResponseWrapper { - - private ByteArrayServletOutputStream wrappedOutputStream = new ByteArrayServletOutputStream(); - - public ContentModResponseWrapper(HttpServletResponse response) { - super(response); - } - - @Override - public ServletOutputStream getOutputStream() throws IOException { - return wrappedOutputStream; - } - - /** - * get bytearray hold back from outputstream - * @return - */ - public byte[] getBuffer() { - return wrappedOutputStream.getBuffer(); - } - - public void setContentType(String mime) { - super.setContentType(mime); - } - } - - /** - * ByteArrayOutputStream wrapped into a ServletOutputStream - */ - private class ByteArrayServletOutputStream extends ServletOutputStream { - - private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - public ByteArrayServletOutputStream() { - super(); - } - - @Override - public void write(int b) throws IOException { - buffer.write(b); - } - - public void write(byte[] b) throws IOException { - buffer.write(b); - } - - public byte[] getBuffer() { - return buffer.toByteArray(); - } - - } - -} diff --git a/source/net/yacy/http/ProxyHandler.java b/source/net/yacy/http/ProxyHandler.java index 7d7d208df..ed33dc19f 100644 --- a/source/net/yacy/http/ProxyHandler.java +++ b/source/net/yacy/http/ProxyHandler.java @@ -82,8 +82,8 @@ public class ProxyHandler extends AbstractRemoteHandler implements Handler { } private void cleanResponseHeader(HttpResponse headers) { - headers.removeHeaders("Content-Encoding"); - headers.removeHeaders("Content-Length"); + headers.removeHeaders(HeaderFramework.CONTENT_ENCODING); + headers.removeHeaders(HeaderFramework.CONTENT_LENGTH); } @Override @@ -105,11 +105,11 @@ public class ProxyHandler extends AbstractRemoteHandler implements Handler { try { String queryString = request.getQueryString()!=null ? "?" + request.getQueryString() : ""; String url = request.getRequestURL().toString() + queryString; - if (request.getMethod().equals("GET")) { + if (request.getMethod().equals(HeaderFramework.METHOD_GET)) { client.GET(url); - } else if (request.getMethod().equals("POST")) { + } else if (request.getMethod().equals(HeaderFramework.METHOD_POST)) { client.POST(url, request.getInputStream(), request.getContentLength()); - } else if (request.getMethod().equals("HEAD")) { + } else if (request.getMethod().equals(HeaderFramework.METHOD_HEAD)) { client.HEADResponse(url); } else { throw new ServletException("Unsupported Request Method"); diff --git a/source/net/yacy/http/TemplateHandler.java b/source/net/yacy/http/TemplateHandler.java deleted file mode 100644 index d13e0e00d..000000000 --- a/source/net/yacy/http/TemplateHandler.java +++ /dev/null @@ -1,361 +0,0 @@ -// -// TemplateHandler -// Copyright 2005 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany -// Copyright 2011 by Florian Richter -// First released 13.04.2011 at http://yacy.net -// -// $LastChangedDate$ -// $LastChangedRevision$ -// $LastChangedBy$ -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program in the file lgpl21.txt -// If not, see . -// - -package net.yacy.http; - -import java.awt.Image; -import java.awt.image.BufferedImage; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.ref.SoftReference; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Date; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import net.yacy.cora.date.GenericFormatter; -import net.yacy.cora.document.analysis.Classification; -import net.yacy.cora.protocol.HeaderFramework; -import net.yacy.cora.protocol.RequestHeader; -import net.yacy.cora.util.ByteBuffer; -import net.yacy.cora.util.ConcurrentLog; -import net.yacy.kelondro.util.FileUtils; -import net.yacy.kelondro.util.MemoryControl; -import net.yacy.peers.Seed; -import net.yacy.peers.graphics.EncodedImage; -import net.yacy.peers.operation.yacyBuildProperties; -import net.yacy.search.Switchboard; -import net.yacy.search.SwitchboardConstants; -import net.yacy.server.http.TemplateEngine; -import net.yacy.server.serverClassLoader; -import net.yacy.server.serverCore; -import net.yacy.server.serverObjects; -import net.yacy.server.serverSwitch; -import net.yacy.server.servletProperties; -import net.yacy.visualization.RasterPlotter; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.fileupload.servlet.ServletFileUpload; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.AbstractHandler; - - -/** - * jetty http handler: - * - * Handles classic yacy servlets with templates - */ -public class TemplateHandler extends AbstractHandler implements Handler { - - private final String htLocalePath = "DATA/LOCALE/htroot"; - private final String htDefaultPath = "htroot"; - private String htDocsPath = "DATA/HTDOCS"; - - private static final serverClassLoader provider = new serverClassLoader(/*this.getClass().getClassLoader()*/); - - private ConcurrentHashMap> templateMethodCache = null; - - @Override - protected void doStart() throws Exception { - super.doStart(); - templateMethodCache = new ConcurrentHashMap>(); - htDocsPath = Switchboard.getSwitchboard().htDocsPath.getPath(); - } - - /** Returns a path to the localized or default file according to the parameter localeSelection - * @param path relative from htroot - * @param localeSelection language of localized file; locale.language from switchboard is used if localeSelection.equals("") */ - public File getLocalizedFile(final String path, final String localeSelection){ - if (!(localeSelection.equals("default"))) { - final File localePath = new File(htLocalePath, localeSelection + '/' + path); - if (localePath.exists()) return localePath; // avoid "NoSuchFile" troubles if the "localeSelection" is misspelled - } - - File docsPath = new File(htDocsPath, path); - if (docsPath.exists()) return docsPath; - return new File(htDefaultPath, path); - } - - private final File rewriteClassFile(final File template) { - try { - String f = template.getCanonicalPath(); - final int p = f.lastIndexOf('.'); - if (p < 0) return null; - f = f.substring(0, p) + ".class"; - //System.out.println("constructed class path " + f); - final File cf = new File(f); - if (cf.exists()) return cf; - return null; - } catch (final IOException e) { - return null; - } - } - - private final Method rewriteMethod(final File classFile) throws InvocationTargetException { - Method m = null; - // now make a class out of the stream - try { - final SoftReference ref = templateMethodCache.get(classFile); - if (ref != null) { - m = ref.get(); - if (m == null) { - templateMethodCache.remove(classFile); - } else { - return m; - } - } - - final Class c = provider.loadClass(classFile); - final Class[] params = new Class[] { - RequestHeader.class, - serverObjects.class, - serverSwitch.class }; - m = c.getMethod("respond", params); - - // store the method into the cache - templateMethodCache.put(classFile, new SoftReference(m)); - - } catch (final ClassNotFoundException e) { - ConcurrentLog.severe("HTTPDFileHandler", "class " + classFile + " is missing:" + e.getMessage()); - throw new InvocationTargetException(e, "class " + classFile + " is missing:" + e.getMessage()); - } catch (final NoSuchMethodException e) { - ConcurrentLog.severe("HTTPDFileHandler", "method 'respond' not found in class " + classFile + ": " + e.getMessage()); - throw new InvocationTargetException(e, "method 'respond' not found in class " + classFile + ": " + e.getMessage()); - } - return m; - } - - - private final Object invokeServlet(final File targetClass, final RequestHeader request, final serverObjects args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { - return rewriteMethod(targetClass).invoke(null, new Object[] {request, args, Switchboard.getSwitchboard()}); // add switchboard - } - - private RequestHeader generateLegacyRequestHeader(HttpServletRequest request, String target, String targetExt) { - RequestHeader legacyRequestHeader = new RequestHeader(); - @SuppressWarnings("unchecked") - Enumeration headers = request.getHeaderNames(); - while (headers.hasMoreElements()) { - String headerName = headers.nextElement(); - @SuppressWarnings("unchecked") - Enumeration header = request.getHeaders(headerName); - while(header.hasMoreElements()) - legacyRequestHeader.add(headerName, header.nextElement()); - } - - legacyRequestHeader.put(HeaderFramework.CONNECTION_PROP_CLIENTIP, request.getRemoteAddr()); - legacyRequestHeader.put(HeaderFramework.CONNECTION_PROP_PATH, target); - legacyRequestHeader.put(HeaderFramework.CONNECTION_PROP_EXT, targetExt); - - return legacyRequestHeader; - } - - @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - Switchboard sb = Switchboard.getSwitchboard(); - - String localeSelection = Switchboard.getSwitchboard().getConfig("locale.language","default"); - File targetFile = getLocalizedFile(target, localeSelection); - File targetClass = rewriteClassFile(new File(htDefaultPath, target)); - String targetExt = target.substring(target.lastIndexOf('.') + 1, target.length()); - - if ((targetClass != null)) { - serverObjects args = new serverObjects(); - @SuppressWarnings("unchecked") - Enumeration argNames = request.getParameterNames(); - while (argNames.hasMoreElements()) { - String argName = argNames.nextElement(); - args.put(argName, request.getParameter(argName)); - } - //TODO: for SSI request, local parameters are added as attributes, put them back as parameter for the legacy request - // likely this should be implemented via httpservletrequestwrapper to supply complete parameters - @SuppressWarnings("unchecked") - Enumeration attNames = request.getAttributeNames(); - while (attNames.hasMoreElements()) { - String argName = attNames.nextElement(); - args.put (argName,request.getAttribute(argName).toString()); - } - - // add multipart-form fields to parameter - if (request.getContentType() != null && request.getContentType().startsWith("multipart/form-data")) { - parseMultipart(request, args); - } - // eof modification to read attribute - RequestHeader legacyRequestHeader = generateLegacyRequestHeader(request, target, targetExt); - - Object tmp; - try { - tmp = invokeServlet(targetClass, legacyRequestHeader, args); - } catch (InvocationTargetException e) { - ConcurrentLog.logException(e); - throw new ServletException(); - } catch (IllegalArgumentException e) { - ConcurrentLog.logException(e); - throw new ServletException(); - } catch (IllegalAccessException e) { - ConcurrentLog.logException(e); - throw new ServletException(); - } - - if ( tmp instanceof RasterPlotter || tmp instanceof EncodedImage || tmp instanceof Image) { - - ByteBuffer result = null; - - if (tmp instanceof RasterPlotter) { - final RasterPlotter yp = (RasterPlotter) tmp; - // send an image to client - result = RasterPlotter.exportImage(yp.getImage(), "png"); - } - if (tmp instanceof EncodedImage) { - final EncodedImage yp = (EncodedImage) tmp; - result = yp.getImage(); - } - - if (tmp instanceof Image) { - final Image i = (Image) tmp; - - // generate an byte array from the generated image - int width = i.getWidth(null); if (width < 0) width = 96; // bad hack - int height = i.getHeight(null); if (height < 0) height = 96; // bad hack - final BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); - bi.createGraphics().drawImage(i, 0, 0, width, height, null); - result = RasterPlotter.exportImage(bi, targetExt); - } - - final String mimeType = Classification.ext2mime(targetExt, "text/html"); - response.setContentType(mimeType); - response.setContentLength(result.length()); - response.setStatus(HttpServletResponse.SC_OK); - - result.writeTo(response.getOutputStream()); - - // we handled this request, break out of handler chain - // is null on SSI template - if (baseRequest != null) baseRequest.setHandled(true); - return; - } - - - servletProperties templatePatterns = null; - if (tmp == null) { - // if no args given, then tp will be an empty Hashtable object (not null) - templatePatterns = new servletProperties(); - } else if (tmp instanceof servletProperties) { - templatePatterns = (servletProperties) tmp; - } else { - templatePatterns = new servletProperties((serverObjects) tmp); - } - // add the application version, the uptime and the client name to every rewrite table - templatePatterns.put(servletProperties.PEER_STAT_VERSION, yacyBuildProperties.getVersion()); - templatePatterns.put(servletProperties.PEER_STAT_UPTIME, ((System.currentTimeMillis() - serverCore.startupTime) / 1000) / 60); // uptime in minutes - templatePatterns.putHTML(servletProperties.PEER_STAT_CLIENTNAME, sb.peers.mySeed().getName()); - templatePatterns.putHTML(servletProperties.PEER_STAT_CLIENTID, sb.peers.myID()); - templatePatterns.put(servletProperties.PEER_STAT_MYTIME, GenericFormatter.SHORT_SECOND_FORMATTER.format()); - Seed myPeer = sb.peers.mySeed(); - templatePatterns.put("newpeer", myPeer.getAge() >= 1 ? 0 : 1); - templatePatterns.putHTML("newpeer_peerhash", myPeer.hash); - templatePatterns.put("p2p", sb.getConfigBool(SwitchboardConstants.DHT_ENABLED, true) || !sb.isRobinsonMode() ? 1 : 0); - - if(targetFile.exists() && targetFile.isFile() && targetFile.canRead()) { - String mimeType = Classification.ext2mime(targetExt, "text/html"); - - InputStream fis = null; - long fileSize = targetFile.length(); - - if (fileSize <= Math.min(4 * 1024 * 1204, MemoryControl.available() / 100)) { - // read file completely into ram, avoid that too many files are open at the same time - fis = new ByteArrayInputStream(FileUtils.read(targetFile)); - } else { - fis = new BufferedInputStream(new FileInputStream(targetFile)); - } - - // set response header - response.setContentType(mimeType); - response.setStatus(HttpServletResponse.SC_OK); - - // apply templates - TemplateEngine.writeTemplate(fis, response.getOutputStream(), templatePatterns, "-UNRESOLVED_PATTERN-".getBytes("UTF-8")); - fis.close(); - - // we handled this request, break out of handler chain - // is null on SSI template - if (baseRequest != null) baseRequest.setHandled(true); - } - } - } - - protected final class TemplateCacheEntry { - Date lastModified; - byte[] content; - } - - /** - * TODO: add same functionality & checks as in HTTPDemon.parseMultipart - * - * parse multi-part form data for formfields (only), see also original - * implementation in HTTPDemon.parseMultipart - * - * @param request - * @param args found fields/values are added to the map - */ - public void parseMultipart(HttpServletRequest request, serverObjects args) { - DiskFileItemFactory factory = new DiskFileItemFactory(); - // maximum size that will be stored in memory - factory.setSizeThreshold(4096 * 16); - // Location to save data that is larger than maxMemSize. - // factory.setRepository(new File(".")); - // Create a new file upload handler - ServletFileUpload upload = new ServletFileUpload(factory); - upload.setSizeMax(4096 * 8); - try { - // Parse the request to get form field items - @SuppressWarnings("unchecked") - List fileItems = upload.parseRequest(request); - // Process the uploaded file items - Iterator i = fileItems.iterator(); - while (i.hasNext()) { - FileItem fi = i.next(); - if (fi.isFormField()) { - args.put(fi.getFieldName(), fi.getString()); - } - } - } catch (Exception ex) { - ConcurrentLog.logException(ex); - } - } -}