Merge remote-tracking branch 'origin/jetty-8'
Conflicts: jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java jetty-server/src/main/java/org/eclipse/jetty/server/Request.java jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java
This commit is contained in:
commit
2b1e6bf0de
|
@ -435,12 +435,21 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
|
||||||
LOG.ignore(e);
|
LOG.ignore(e);
|
||||||
path = _uri.getDecodedPath(StringUtil.__ISO_8859_1);
|
path = _uri.getDecodedPath(StringUtil.__ISO_8859_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
String info = URIUtil.canonicalPath(path);
|
String info = URIUtil.canonicalPath(path);
|
||||||
|
|
||||||
if (info == null)
|
if (info == null)
|
||||||
{
|
{
|
||||||
info = "/";
|
if( path==null && _uri.getScheme()!=null &&_uri.getHost()!=null)
|
||||||
_request.setRequestURI("");
|
{
|
||||||
|
info = "/";
|
||||||
|
_request.setRequestURI("");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
badMessage(400,null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_request.setPathInfo(info);
|
_request.setPathInfo(info);
|
||||||
_version = version == null ? HttpVersion.HTTP_0_9 : version;
|
_version = version == null ? HttpVersion.HTTP_0_9 : version;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.eclipse.jetty.server;
|
package org.eclipse.jetty.server;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -72,6 +73,7 @@ import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||||
import org.eclipse.jetty.server.session.AbstractSession;
|
import org.eclipse.jetty.server.session.AbstractSession;
|
||||||
import org.eclipse.jetty.util.Attributes;
|
import org.eclipse.jetty.util.Attributes;
|
||||||
import org.eclipse.jetty.util.AttributesMap;
|
import org.eclipse.jetty.util.AttributesMap;
|
||||||
|
import org.eclipse.jetty.util.IO;
|
||||||
import org.eclipse.jetty.util.MultiException;
|
import org.eclipse.jetty.util.MultiException;
|
||||||
import org.eclipse.jetty.util.MultiMap;
|
import org.eclipse.jetty.util.MultiMap;
|
||||||
import org.eclipse.jetty.util.MultiPartInputStreamParser;
|
import org.eclipse.jetty.util.MultiPartInputStreamParser;
|
||||||
|
@ -349,6 +351,7 @@ public class Request implements HttpServletRequest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_parameters == null)
|
if (_parameters == null)
|
||||||
|
@ -358,6 +361,28 @@ public class Request implements HttpServletRequest
|
||||||
// Merge parameters (needed if parameters extracted after a forward).
|
// Merge parameters (needed if parameters extracted after a forward).
|
||||||
_parameters.addAllValues(_baseParameters);
|
_parameters.addAllValues(_baseParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (content_type != null && content_type.length()>0 && content_type.startsWith("multipart/form-data") && getAttribute(__MULTIPART_CONFIG_ELEMENT)!=null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
getParts();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.warn(e);
|
||||||
|
else
|
||||||
|
LOG.warn(e.toString());
|
||||||
|
}
|
||||||
|
catch (ServletException e)
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.warn(e);
|
||||||
|
else
|
||||||
|
LOG.warn(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -2036,38 +2061,8 @@ public class Request implements HttpServletRequest
|
||||||
@Override
|
@Override
|
||||||
public Part getPart(String name) throws IOException, ServletException
|
public Part getPart(String name) throws IOException, ServletException
|
||||||
{
|
{
|
||||||
if (getContentType() == null || !getContentType().startsWith("multipart/form-data"))
|
getParts();
|
||||||
throw new ServletException("Content-Type != multipart/form-data");
|
|
||||||
|
|
||||||
if (_multiPartInputStream == null)
|
|
||||||
{
|
|
||||||
MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT);
|
|
||||||
|
|
||||||
if (config == null)
|
|
||||||
throw new IllegalStateException("No multipart config for servlet");
|
|
||||||
|
|
||||||
_multiPartInputStream = new MultiPartInputStreamParser(getInputStream(),
|
|
||||||
getContentType(),config,
|
|
||||||
(_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null));
|
|
||||||
setAttribute(__MULTIPART_INPUT_STREAM, _multiPartInputStream);
|
|
||||||
setAttribute(__MULTIPART_CONTEXT, _context);
|
|
||||||
Collection<Part> parts = _multiPartInputStream.getParts(); //causes parsing
|
|
||||||
for (Part p:parts)
|
|
||||||
{
|
|
||||||
MultiPartInputStreamParser.MultiPart mp = (MultiPartInputStreamParser.MultiPart)p;
|
|
||||||
if (mp.getContentDispositionFilename() == null && mp.getFile() == null)
|
|
||||||
{
|
|
||||||
//Servlet Spec 3.0 pg 23, parts without filenames must be put into init params
|
|
||||||
String charset = null;
|
|
||||||
if (mp.getContentType() != null)
|
|
||||||
charset = MimeTypes.getCharsetFromContentType(mp.getContentType());
|
|
||||||
|
|
||||||
String content=new String(mp.getBytes(),charset==null?StringUtil.__UTF8:charset);
|
|
||||||
getParameter(""); //cause params to be evaluated
|
|
||||||
getParameters().add(mp.getName(), content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _multiPartInputStream.getPart(name);
|
return _multiPartInputStream.getPart(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2078,6 +2073,9 @@ public class Request implements HttpServletRequest
|
||||||
if (getContentType() == null || !getContentType().startsWith("multipart/form-data"))
|
if (getContentType() == null || !getContentType().startsWith("multipart/form-data"))
|
||||||
throw new ServletException("Content-Type != multipart/form-data");
|
throw new ServletException("Content-Type != multipart/form-data");
|
||||||
|
|
||||||
|
if (_multiPartInputStream == null)
|
||||||
|
_multiPartInputStream = (MultiPartInputStreamParser)getAttribute(__MULTIPART_INPUT_STREAM);
|
||||||
|
|
||||||
if (_multiPartInputStream == null)
|
if (_multiPartInputStream == null)
|
||||||
{
|
{
|
||||||
MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT);
|
MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT);
|
||||||
|
@ -2095,19 +2093,32 @@ public class Request implements HttpServletRequest
|
||||||
for (Part p:parts)
|
for (Part p:parts)
|
||||||
{
|
{
|
||||||
MultiPartInputStreamParser.MultiPart mp = (MultiPartInputStreamParser.MultiPart)p;
|
MultiPartInputStreamParser.MultiPart mp = (MultiPartInputStreamParser.MultiPart)p;
|
||||||
if (mp.getContentDispositionFilename() == null && mp.getFile() == null)
|
if (mp.getContentDispositionFilename() == null)
|
||||||
{
|
{
|
||||||
//Servlet Spec 3.0 pg 23, parts without filenames must be put into init params
|
//Servlet Spec 3.0 pg 23, parts without filenames must be put into init params
|
||||||
String charset = null;
|
String charset = null;
|
||||||
if (mp.getContentType() != null)
|
if (mp.getContentType() != null)
|
||||||
charset = MimeTypes.getCharsetFromContentType(mp.getContentType());
|
charset = MimeTypes.getCharsetFromContentType(mp.getContentType());
|
||||||
|
|
||||||
String content=new String(mp.getBytes(),charset==null?StringUtil.__UTF8:charset);
|
ByteArrayOutputStream os = null;
|
||||||
getParameter(""); //cause params to be evaluated
|
InputStream is = mp.getInputStream(); //get the bytes regardless of being in memory or in temp file
|
||||||
getParameters().add(mp.getName(), content);
|
try
|
||||||
|
{
|
||||||
|
os = new ByteArrayOutputStream();
|
||||||
|
IO.copy(is, os);
|
||||||
|
String content=new String(os.toByteArray(),charset==null?StringUtil.__UTF8:charset);
|
||||||
|
getParameter(""); //cause params to be evaluated
|
||||||
|
getParameters().add(mp.getName(), content);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IO.close(os);
|
||||||
|
IO.close(is);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _multiPartInputStream.getParts();
|
return _multiPartInputStream.getParts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1825,9 +1825,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
||||||
// uriInContext = uriInContext.substring(0,q);
|
// uriInContext = uriInContext.substring(0,q);
|
||||||
|
|
||||||
String pathInContext = URIUtil.canonicalPath(URIUtil.decodePath(uriInContext));
|
String pathInContext = URIUtil.canonicalPath(URIUtil.decodePath(uriInContext));
|
||||||
String uri = URIUtil.addPaths(getContextPath(),uriInContext);
|
if (pathInContext!=null)
|
||||||
ContextHandler context = ContextHandler.this;
|
{
|
||||||
return new Dispatcher(context,uri,pathInContext,query);
|
String uri = URIUtil.addPaths(getContextPath(),uriInContext);
|
||||||
|
ContextHandler context = ContextHandler.this;
|
||||||
|
return new Dispatcher(context,uri,pathInContext,query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -138,6 +138,66 @@ public class HttpConnectionTest
|
||||||
checkContains(response,offset,"pathInfo=/");
|
checkContains(response,offset,"pathInfo=/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBadNoPath() throws Exception
|
||||||
|
{
|
||||||
|
String response=connector.getResponses("GET http://localhost:80/../cheat HTTP/1.1\n"+
|
||||||
|
"Host: localhost:80\n"+
|
||||||
|
"\n");
|
||||||
|
int offset=0;
|
||||||
|
offset = checkContains(response,offset,"HTTP/1.1 400");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOKPathDotDotPath() throws Exception
|
||||||
|
{
|
||||||
|
String response=connector.getResponses("GET /ooops/../path HTTP/1.0\nHost: localhost:80\n\n");
|
||||||
|
checkContains(response,0,"HTTP/1.1 200 OK");
|
||||||
|
checkContains(response,0,"pathInfo=/path");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBadPathDotDotPath() throws Exception
|
||||||
|
{
|
||||||
|
String response=connector.getResponses("GET /ooops/../../path HTTP/1.0\nHost: localhost:80\n\n");
|
||||||
|
checkContains(response,0,"HTTP/1.1 400 Bad Request");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOKPathEncodedDotDotPath() throws Exception
|
||||||
|
{
|
||||||
|
String response=connector.getResponses("GET /ooops/%2e%2e/path HTTP/1.0\nHost: localhost:80\n\n");
|
||||||
|
checkContains(response,0,"HTTP/1.1 200 OK");
|
||||||
|
checkContains(response,0,"pathInfo=/path");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBadPathEncodedDotDotPath() throws Exception
|
||||||
|
{
|
||||||
|
String response=connector.getResponses("GET /ooops/%2e%2e/%2e%2e/path HTTP/1.0\nHost: localhost:80\n\n");
|
||||||
|
checkContains(response,0,"HTTP/1.1 400 Bad Request");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBadDotDotPath() throws Exception
|
||||||
|
{
|
||||||
|
String response=connector.getResponses("GET ../path HTTP/1.0\nHost: localhost:80\n\n");
|
||||||
|
checkContains(response,0,"HTTP/1.1 400 Bad Request");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBadSlashDotDotPath() throws Exception
|
||||||
|
{
|
||||||
|
String response=connector.getResponses("GET /../path HTTP/1.0\nHost: localhost:80\n\n");
|
||||||
|
checkContains(response,0,"HTTP/1.1 400 Bad Request");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodedBadDotDotPath() throws Exception
|
||||||
|
{
|
||||||
|
String response=connector.getResponses("GET %2e%2e/path HTTP/1.0\nHost: localhost:80\n\n");
|
||||||
|
checkContains(response,0,"HTTP/1.1 400 Bad Request");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmpty() throws Exception
|
public void testEmpty() throws Exception
|
||||||
|
|
|
@ -1094,10 +1094,12 @@ public class RequestTest
|
||||||
MultipartConfigElement mpce = new MultipartConfigElement(tmpDir.getAbsolutePath(),-1, -1, 2);
|
MultipartConfigElement mpce = new MultipartConfigElement(tmpDir.getAbsolutePath(),-1, -1, 2);
|
||||||
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
|
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
|
||||||
|
|
||||||
|
String field1 = request.getParameter("field1");
|
||||||
|
assertNotNull(field1);
|
||||||
|
|
||||||
Part foo = request.getPart("stuff");
|
Part foo = request.getPart("stuff");
|
||||||
assertNotNull(foo);
|
assertNotNull(foo);
|
||||||
assertTrue(foo.getSize() > 0);
|
assertTrue(foo.getSize() > 0);
|
||||||
|
|
||||||
response.setStatus(200);
|
response.setStatus(200);
|
||||||
}
|
}
|
||||||
catch (IllegalStateException e)
|
catch (IllegalStateException e)
|
||||||
|
|
|
@ -220,6 +220,19 @@ public class DispatcherTest
|
||||||
assertEquals(expected, responses);
|
assertEquals(expected, responses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testServletForwardDotDot() throws Exception
|
||||||
|
{
|
||||||
|
_contextHandler.addServlet(DispatchServletServlet.class, "/dispatch/*");
|
||||||
|
_contextHandler.addServlet(RogerThatServlet.class, "/roger/that");
|
||||||
|
|
||||||
|
String requests="GET /context/dispatch/test?forward=%2e%2e/roger/that HTTP/1.0\n" + "Host: localhost\n\n";
|
||||||
|
|
||||||
|
String responses = _connector.getResponses(requests);
|
||||||
|
|
||||||
|
assertThat(responses,startsWith("HTTP/1.1 404 "));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testServletInclude() throws Exception
|
public void testServletInclude() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -412,7 +425,10 @@ public class DispatcherTest
|
||||||
else if(request.getParameter("forward")!=null)
|
else if(request.getParameter("forward")!=null)
|
||||||
{
|
{
|
||||||
dispatcher = getServletContext().getRequestDispatcher(request.getParameter("forward"));
|
dispatcher = getServletContext().getRequestDispatcher(request.getParameter("forward"));
|
||||||
dispatcher.forward(new ServletRequestWrapper(request), new ServletResponseWrapper(response));
|
if (dispatcher!=null)
|
||||||
|
dispatcher.forward(new ServletRequestWrapper(request), new ServletResponseWrapper(response));
|
||||||
|
else
|
||||||
|
response.sendError(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue