From d6760df3e5df705f5a321fac8ebec220d6cafcb7 Mon Sep 17 00:00:00 2001 From: reger Date: Sun, 3 Nov 2013 02:26:00 +0100 Subject: [PATCH] fix servlet class exist check to use default path only (in Jetty8YaCyDefaultServlet) - del redundant doget code in yacydefaultservlet - small declaration code opts - del obsolete libt/proxyservlet.java --- libt/ProxyServlet.java | 418 ------------------ .../yacy/http/Jetty8YaCyDefaultServlet.java | 2 +- source/net/yacy/http/YaCyDefaultServlet.java | 147 +----- 3 files changed, 8 insertions(+), 559 deletions(-) delete mode 100644 libt/ProxyServlet.java diff --git a/libt/ProxyServlet.java b/libt/ProxyServlet.java deleted file mode 100644 index 19b156ac0..000000000 --- a/libt/ProxyServlet.java +++ /dev/null @@ -1,418 +0,0 @@ -// package de.spieleck.servlets; -// ProxyServlet - serving pages from foreign servers.... -// - -import java.io.*; -import java.net.*; -import java.lang.Integer; -import java.util.StringTokenizer; - -import javax.servlet.*; -import javax.servlet.http.*; - -/** - * Serves pages which are fetched from another HTTP-Server - * useful for going thru firewalls and other trickery... - *

- * The communication is somewhat this way: - *

- *

- * XXX There is a problem with If-Modified and If-None-Match requests: - * the 304 Not Modified answer does not go thru the servelet in the - * backward direction. It could be that the HttpServletResponse does hava - * some sideeffects which are not helpfull in this special situation. - * This type of request is currently avoided by removing all "If-" requests. - *
- * Note: This servlet is actually buggy. It is buggy since it does - * not solve all problems, it only solves the problems I needed to solve. - * Many thanks to Thorsten Gast the creator of dirjack - * for pointing at least some bugs. - * @author Frank Nestel. - */ - -public class ProxyServlet extends HttpServlet -{ - /** - * "Official" HTTP line end - */ - public final static String CRLF = "\r\n"; - public final static String LF = "\n"; - - /** - * remote path - */ - protected String remotePath; - - /** - * remote server - */ - protected String remoteServer; - - /** - * Port at remote server - */ - protected int remotePort; - - /** - * Debug mode? - */ - protected boolean debugFlag; - - /** Init - */ - public void init(ServletConfig config) - throws ServletException - { - super.init(config); - remotePath = getInitParameter("remotePath"); - remoteServer = getInitParameter("remoteServer"); - String remotePortStr= getInitParameter("remotePort"); - if ( remotePath == null || remoteServer == null ) - throw new ServletException( - "Servlet needs remotePath & remoteServer."); - if ( remotePortStr != null ) - { - try - { - remotePort = Integer.parseInt(remotePortStr); - } - catch ( Exception e ) - { - throw new ServletException("Port must be a number!"); - } - } - else - remotePort = 80; - if ( "".equals(remotePath) ) - remotePath = ""; // XXX ??? "/" - else if ( remotePath.charAt(0) != '/' ) - remotePath = "/"+remotePath; - debugFlag = "true".equals(getInitParameter("debug")); - // - log("remote="+remoteServer+" "+remotePort+" "+remotePath); - } - - /// Returns a string containing information about the author, version, and - // copyright of the servlet. - public String getServletInfo() - { - return "Online redirecting content."; - } - - /// Services a single request from the client. - // @param req the servlet request - // @param req the servlet response - // @exception ServletException when an exception has occurred - public void service( HttpServletRequest req, HttpServletResponse res ) - throws ServletException, IOException - { - // - // Connect to "remote" server: - Socket sock; - OutputStream out; - InputStream in; - // - try - { - sock = new Socket(remoteServer, remotePort); // !!!!!!!! - out = new BufferedOutputStream(sock.getOutputStream()); - in = new BufferedInputStream(sock.getInputStream()); - } - catch (IOException e) - { - res.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "Socket opening: "+remoteServer+" "+remotePort); - return; - } - try - { - // - // Build up a HTTP request from pure strings: - StringBuffer sb = new StringBuffer(200); - sb.append(req.getMethod()); - sb.append(' '); - String pi = req.getPathInfo(); - sb.append(remotePath); - if ( pi != null ) - { - appendCleaned(sb, pi); - } - else - sb.append("/"); - if ( req.getQueryString() != null ) - { - sb.append('?'); - appendCleaned(sb, req.getQueryString()); - } - sb.append(' '); - sb.append("HTTP/1.0"); - sb.append(CRLF); - log(sb.toString()); - out.write(sb.toString().getBytes()); - java.util.Enumeration en = req.getHeaderNames(); - while ( en.hasMoreElements() ) - { - String k = (String) en.nextElement(); - // Filter incoming headers: - if ( "Host".equalsIgnoreCase(k) ) - { - sb.setLength(0); - sb.append(k); - sb.append(": "); - sb.append(remoteServer); - sb.append(":"); - sb.append(remotePort); - sb.append(CRLF); - log("c["+k+"]: "+sb+" "+req.getHeader(k)); - out.write(sb.toString().getBytes()); - } - // - // Throw away persistant connections between servers - // Throw away request potentially causing a 304 response. - else if ( - ! "Connection".equalsIgnoreCase(k) - && ! "If-Modified-Since".equalsIgnoreCase(k) - && ! "If-None-Match".equalsIgnoreCase(k) - ) - { - sb.setLength(0); - sb.append(k); - sb.append(": "); - sb.append(req.getHeader(k)); - sb.append(CRLF); - log("=["+k+"]: "+req.getHeader(k)); - out.write(sb.toString().getBytes()); - } - else - { - log("*["+k+"]: "+req.getHeader(k)); - } - } - // Finish request header by an empty line - out.write(CRLF.getBytes()); - // Copy post data - InputStream inr = req.getInputStream(); - copyStream(inr, out); - out.flush(); - log("Remote request finished. Reading answer."); - - // Now we have finished the outgoing request. - // We'll now see, what is coming back from remote: - - // Get the answer, treat its header and copy the stream data: - if ( treatHeader(in, req, res) ) - { - log("+ copyStream"); - // if ( debugFlag ) res.setContentType("text/plain"); - out = res.getOutputStream(); - copyStream(in, out); - } - else - log("- copyStream"); - } - catch (IOException e) - { - log("out-in.open!"); - // res.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - // "out-in open!"); - return; - } - try - { - // out.close(); - in.close(); - sock.close(); - } - catch (IOException ignore) - { - log("Exception "+ignore); - } - } - - public static void appendCleaned(StringBuffer sb, String str) - { - for(int i = 0; i < str.length(); i++) - { - char ch = str.charAt(i); - if ( ch == ' ' ) - sb.append("%20"); - else - sb.append(ch); - } - } - - - /** - * Forward and filter header from backend Request. - */ - private boolean treatHeader(InputStream in, - HttpServletRequest req, - HttpServletResponse res) - throws ServletException - { - boolean retval = true; - byte[] lineBytes = new byte[4096]; - int len; - String line; - - try - { - // Read the first line of the request. - len = readLine(in, lineBytes ); - if ( len == -1 || len == 0 ) - throw new ServletException( "No Request found in Data." ); -{ - String line2 = new String( lineBytes, 0, len ); - log("head: "+line2+" "+len); -} - - // We mainly skip the header by the foreign server - // assuming, that we can handle protocoll mismatch or so! - res.setHeader("viaJTTP","JTTP"); - - // Some more headers require special care .... - boolean firstline = true; - // Shortcut evaluation skips the read on first time! - while ( firstline || ((len=readLine(in,lineBytes)) > 0) ) - { - line = new String( lineBytes, 0, len ); - int colonPos = line.indexOf( ":" ); - if ( firstline && colonPos == -1 ) - { - // Special first line considerations ... - String headl[] = wordStr(line); -log("head: "+line+" "+headl.length); - try - { - res.setStatus(Integer.parseInt(headl[1])); - } - catch ( NumberFormatException ignore ) - { - log("ID exception: "+headl); - } - catch ( Exception panik ) - { - log("First line invalid!"); - return true; - } - } - else if ( colonPos != -1 ) - { - String head = line.substring(0,colonPos); - // XXX Skip LWS (what is LWS) - int i = colonPos + 1; - while ( isLWS(line.charAt(i)) ) i++; - String value= line.substring(i); -log("<"+head+">=<"+ value+">"); - if ( head.equalsIgnoreCase("Location") ) - { - // res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); - // res.setHeader(head, value ); - log("Location cutted: "+value); - } - else if ( head.equalsIgnoreCase( "Content-type" ) ) - res.setContentType( value ); - else if ( head.equalsIgnoreCase( "Content-length" ) ) - { - try - { - int cLen = Integer.parseInt( value ); - retval = ( cLen > 0 ); - res.setContentLength(cLen); - } - catch ( NumberFormatException ignore ) {} - } - // Generically treat unknown headers - else - { - log("^- generic."); - res.setHeader(head, value ); - } - } - // XXX We do not treat multiline continuation Headers here - // which have not occured anywhere yet. - firstline = false; - } - } - catch ( IOException e ) - { - log("Header skip problem:"); - throw new ServletException("Header skip problem: "+e.getMessage()); - } -log( "--------------" ); - return retval; - } - - /** - * Read a RFC2616 line from an InputStream: - */ - public int readLine(InputStream in, byte[] b ) - throws IOException - { - int off2 = 0; - while ( off2 < b.length ) - { - int r = in.read(); - if ( r == -1 ) - { - if (off2 == 0 ) - return -1; - break; - } - if ( r == 13 ) - continue; - if ( r == 10 ) - break; - b[off2] = (byte) r; - ++off2; - } - return off2; - } - - /** Copy a file from in to out. - * Sub-classes can override this in order to do filtering of some sort. - */ - public void copyStream( InputStream in, OutputStream out ) - throws IOException - { - BufferedInputStream bin = new BufferedInputStream(in); - int b; - while ( ( b = bin.read() ) != -1 ) - out.write(b); - } - - /** - * Split a blank separated string into - */ - public String[] wordStr( String inp ) - { - StringTokenizer tok = new StringTokenizer(inp, " "); - int i, n = tok.countTokens(); - String[] res = new String[n]; - for(i = 0; i < n; i++ ) - res[i] = tok.nextToken(); - return res; - } - - /** - * XXX Should identify RFC2616 LWS - */ - protected boolean isLWS(char c) - { - return c == ' '; - } - - /** - * Capture awaay the standard servlet log .. - */ - public void log(String msg) - { - if ( debugFlag ) - System.err.println("## "+msg); - } -} diff --git a/source/net/yacy/http/Jetty8YaCyDefaultServlet.java b/source/net/yacy/http/Jetty8YaCyDefaultServlet.java index 065bb5ed2..2b3745841 100644 --- a/source/net/yacy/http/Jetty8YaCyDefaultServlet.java +++ b/source/net/yacy/http/Jetty8YaCyDefaultServlet.java @@ -169,7 +169,7 @@ public class Jetty8YaCyDefaultServlet extends YaCyDefaultServlet implements Reso final int p = pathInContext.lastIndexOf('.'); if (p >= 0) { String pathofClass = pathInContext.substring(0, p) + ".class"; - Resource classresource = getResource(pathofClass); + Resource classresource = _resourceBase.addPath(pathofClass); // Does a class resource exist? if (classresource != null && classresource.exists() && !classresource.isDirectory()) { hasClass = true; diff --git a/source/net/yacy/http/YaCyDefaultServlet.java b/source/net/yacy/http/YaCyDefaultServlet.java index 1a745e3df..689c11433 100644 --- a/source/net/yacy/http/YaCyDefaultServlet.java +++ b/source/net/yacy/http/YaCyDefaultServlet.java @@ -232,137 +232,6 @@ public abstract class YaCyDefaultServlet extends HttpServlet { return r; } - /* ------------------------------------------------------------ */ - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String servletPath = null; - String pathInfo = null; - Enumeration reqRanges = null; - Boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null; - if (included != null && included.booleanValue()) { - servletPath = (String) request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH); - pathInfo = (String) request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO); - if (servletPath == null) { - servletPath = request.getServletPath(); - pathInfo = request.getPathInfo(); - } - } else { - included = Boolean.FALSE; - servletPath = _pathInfoOnly ? "/" : request.getServletPath(); - pathInfo = request.getPathInfo(); - - // Is this a Range request? - reqRanges = request.getHeaders(HeaderFramework.RANGE); - if (!hasDefinedRange(reqRanges)) { - reqRanges = null; - } - } - - if (pathInfo.startsWith("/currentyacypeer/")) pathInfo = pathInfo.substring(16); - String pathInContext = URIUtil.addPaths(servletPath, pathInfo); - boolean endsWithSlash = (pathInfo == null ? request.getServletPath() : pathInfo).endsWith(URIUtil.SLASH); - - // Find the resource and content - Resource resource = null; - HttpContent content = null; - try { - String pathofClass = null; - - // Look for a class resource - boolean hasClass = false; - if (reqRanges == null && !endsWithSlash) { - final int p = pathInContext.lastIndexOf('.'); - if (p >= 0) { - pathofClass = pathInContext.substring(0, p) + ".class"; - resource = getResource(pathofClass); - // Does a class resource exist? - if (resource != null && resource.exists() && !resource.isDirectory()) { - hasClass = true; - } - } - } - - // find resource - resource = getResource(pathInContext); - - if (ConcurrentLog.isFine("FILEHANDLER")) { - ConcurrentLog.fine("FILEHANDLER","YaCyDefaultServlet: uri=" + request.getRequestURI() + " resource=" + resource + (content != null ? " content" : "")); - } - - // Handle resource - if (!hasClass && (resource == null || !resource.exists())) { - if (included) { - throw new FileNotFoundException("!" + pathInContext); - } - response.sendError(HttpServletResponse.SC_NOT_FOUND); - } else if (!resource.isDirectory()) { - if (endsWithSlash && pathInContext.length() > 1) { - String q = request.getQueryString(); - pathInContext = pathInContext.substring(0, pathInContext.length() - 1); - if (q != null && q.length() != 0) { - pathInContext += "?" + q; - } - response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(_servletContext.getContextPath(), pathInContext))); - } else { - // ensure we have content - if (content == null) { - content = new HttpContent.ResourceAsHttpContent(resource, _mimeTypes.getMimeByExtension(resource.toString()), response.getBufferSize(), _etags); - } - - if (hasClass) { // this is a YaCy servlet, handle the template - handleTemplate(pathInfo, request, response); - } else { - if (included.booleanValue() || passConditionalHeaders(request, response, resource, content)) { - sendData(request, response, included.booleanValue(), resource, content, reqRanges); - } - } - } - } else { - if (!endsWithSlash || (pathInContext.length() == 1 && request.getAttribute("org.eclipse.jetty.server.nullPathInfo") != null)) { - StringBuffer buf = request.getRequestURL(); - synchronized (buf) { - int param = buf.lastIndexOf(";"); - if (param < 0) { - buf.append('/'); - } else { - buf.insert(param, '/'); - } - String q = request.getQueryString(); - if (q != null && q.length() != 0) { - buf.append('?'); - buf.append(q); - } - response.setContentLength(0); - response.sendRedirect(response.encodeRedirectURL(buf.toString())); - } - } else { // look for a welcome file - String welcomeFileName = getWelcomeFile (pathInContext); - if (welcomeFileName != null) { - RequestDispatcher rd = request.getRequestDispatcher(welcomeFileName); - if (rd != null) rd.forward(request, response); - } else { // send directory listing - content = new HttpContent.ResourceAsHttpContent(resource, _mimeTypes.getMimeByExtension(resource.toString()), _etags); - if (included.booleanValue() || passConditionalHeaders(request, response, resource, content)) { - sendDirectory(request, response, resource, pathInContext); - } - } - } - } - } catch (IllegalArgumentException e) { - ConcurrentLog.logException(e); - if (!response.isCommitted()) { - response.sendError(500, e.getMessage()); - } - } finally { - if (content != null) { - content.release(); - } else if (resource != null) { - resource.release(); - } - } - } - /* ------------------------------------------------------------ */ protected boolean hasDefinedRange(Enumeration reqRanges) { return (reqRanges != null && reqRanges.hasMoreElements()); @@ -396,19 +265,18 @@ public abstract class YaCyDefaultServlet extends HttpServlet { * Finds a matching welcome file for the supplied path. * The filename to look is set as servlet context init parameter * default is "index.html" - * @param path in context + * @param pathInContext path in context * @return The path of the matching welcome file in context or null. */ protected String getWelcomeFile(String pathInContext) { if (_welcomes == null) { return null; } - - for (int i = 0; i < _welcomes.length; i++) { - String welcome_in_context = URIUtil.addPaths(pathInContext, _welcomes[i]); + for (String _welcome : _welcomes) { + String welcome_in_context = URIUtil.addPaths(pathInContext, _welcome); Resource welcome = getResource(welcome_in_context); if (welcome != null && welcome.exists()) { - return _welcomes[i]; + return _welcome; } } return null; @@ -429,8 +297,7 @@ public abstract class YaCyDefaultServlet extends HttpServlet { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } - - byte[] data = null; + String base = URIUtil.addPaths(request.getRequestURI(), URIUtil.SLASH); String dir = resource.getListHTML(base, pathInContext.length() > 1); @@ -440,7 +307,7 @@ public abstract class YaCyDefaultServlet extends HttpServlet { return; } - data = dir.getBytes("UTF-8"); + byte[] data = dir.getBytes("UTF-8"); response.setContentType("text/html; charset=UTF-8"); response.setContentLength(data.length); response.getOutputStream().write(data); @@ -701,7 +568,7 @@ public abstract class YaCyDefaultServlet extends HttpServlet { if (targetFile.exists() && targetFile.isFile() && targetFile.canRead()) { String mimeType = Classification.ext2mime(targetExt, "text/html"); - InputStream fis = null; + InputStream fis; long fileSize = targetFile.length(); if (fileSize <= Math.min(4 * 1024 * 1204, MemoryControl.available() / 100)) {