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
This commit is contained in:
reger 2013-11-03 02:26:00 +01:00
parent 9da87c0c7f
commit d6760df3e5
3 changed files with 8 additions and 559 deletions

View File

@ -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...
* <P>
* The communication is somewhat this way:
* <UL>
* <LI>Client requests data from servlet
* <LI>Servlet interprets path and requests data from remote server
* <LI>Servlet obtains answer from remote server and forwards it to client
* <LI>Client obtains answer
* </UL>
* <P>
* 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.
* <br />
* <b>Note:</b> 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 <a href="mailto:frank -at- spieleck.de">Frank Nestel</a>.
*/
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);
}
}

View File

@ -169,7 +169,7 @@ public class Jetty8YaCyDefaultServlet extends YaCyDefaultServlet implements Reso
final int p = pathInContext.lastIndexOf('.'); final int p = pathInContext.lastIndexOf('.');
if (p >= 0) { if (p >= 0) {
String pathofClass = pathInContext.substring(0, p) + ".class"; String pathofClass = pathInContext.substring(0, p) + ".class";
Resource classresource = getResource(pathofClass); Resource classresource = _resourceBase.addPath(pathofClass);
// Does a class resource exist? // Does a class resource exist?
if (classresource != null && classresource.exists() && !classresource.isDirectory()) { if (classresource != null && classresource.exists() && !classresource.isDirectory()) {
hasClass = true; hasClass = true;

View File

@ -232,137 +232,6 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
return r; return r;
} }
/* ------------------------------------------------------------ */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String servletPath = null;
String pathInfo = null;
Enumeration<String> 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<String> reqRanges) { protected boolean hasDefinedRange(Enumeration<String> reqRanges) {
return (reqRanges != null && reqRanges.hasMoreElements()); return (reqRanges != null && reqRanges.hasMoreElements());
@ -396,19 +265,18 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
* Finds a matching welcome file for the supplied path. * Finds a matching welcome file for the supplied path.
* The filename to look is set as servlet context init parameter * The filename to look is set as servlet context init parameter
* default is "index.html" * 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. * @return The path of the matching welcome file in context or null.
*/ */
protected String getWelcomeFile(String pathInContext) { protected String getWelcomeFile(String pathInContext) {
if (_welcomes == null) { if (_welcomes == null) {
return null; return null;
} }
for (String _welcome : _welcomes) {
for (int i = 0; i < _welcomes.length; i++) { String welcome_in_context = URIUtil.addPaths(pathInContext, _welcome);
String welcome_in_context = URIUtil.addPaths(pathInContext, _welcomes[i]);
Resource welcome = getResource(welcome_in_context); Resource welcome = getResource(welcome_in_context);
if (welcome != null && welcome.exists()) { if (welcome != null && welcome.exists()) {
return _welcomes[i]; return _welcome;
} }
} }
return null; return null;
@ -429,8 +297,7 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
response.sendError(HttpServletResponse.SC_FORBIDDEN); response.sendError(HttpServletResponse.SC_FORBIDDEN);
return; return;
} }
byte[] data = null;
String base = URIUtil.addPaths(request.getRequestURI(), URIUtil.SLASH); String base = URIUtil.addPaths(request.getRequestURI(), URIUtil.SLASH);
String dir = resource.getListHTML(base, pathInContext.length() > 1); String dir = resource.getListHTML(base, pathInContext.length() > 1);
@ -440,7 +307,7 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
return; return;
} }
data = dir.getBytes("UTF-8"); byte[] data = dir.getBytes("UTF-8");
response.setContentType("text/html; charset=UTF-8"); response.setContentType("text/html; charset=UTF-8");
response.setContentLength(data.length); response.setContentLength(data.length);
response.getOutputStream().write(data); response.getOutputStream().write(data);
@ -701,7 +568,7 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
if (targetFile.exists() && targetFile.isFile() && targetFile.canRead()) { if (targetFile.exists() && targetFile.isFile() && targetFile.canRead()) {
String mimeType = Classification.ext2mime(targetExt, "text/html"); String mimeType = Classification.ext2mime(targetExt, "text/html");
InputStream fis = null; InputStream fis;
long fileSize = targetFile.length(); long fileSize = targetFile.length();
if (fileSize <= Math.min(4 * 1024 * 1204, MemoryControl.available() / 100)) { if (fileSize <= Math.min(4 * 1024 * 1204, MemoryControl.available() / 100)) {