diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java index 4b6ea449b09..26051356813 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java @@ -469,7 +469,10 @@ public abstract class AbstractHttpConnection extends AbstractConnection if (info==null && !_request.getMethod().equals(HttpMethods.CONNECT)) { if (_uri.getScheme()!=null && _uri.getHost()!=null) + { info="/"; + _request.setRequestURI(""); + } else throw new HttpException(400); } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java index dfc1d2ae679..c111153a75a 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java @@ -37,7 +37,6 @@ import javax.servlet.AsyncContext; import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterChain; -import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -487,18 +486,11 @@ public class ServletHandler extends ScopedHandler } else if (th instanceof ServletException) { - LOG.debug(th); + LOG.warn(th); Throwable cause=((ServletException)th).getRootCause(); if (cause!=null) th=cause; } - else if (th instanceof RuntimeIOException) - { - LOG.debug(th); - Throwable cause=(IOException)((RuntimeIOException)th).getCause(); - if (cause!=null) - th=cause; - } // handle or log exception if (th instanceof HttpException) diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java index 2628aa8ec54..04efa759483 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java @@ -478,6 +478,76 @@ public class MultipartFilterTest assertEquals(HttpServletResponse.SC_OK,response.getStatus()); } + + @Test + public void testNoBody() + throws Exception + { + String boundary="XyXyXy"; + // generated and parsed test + HttpTester request = new HttpTester(); + HttpTester response = new HttpTester(); + request.setMethod("POST"); + request.setVersion("HTTP/1.0"); + request.setHeader("Host","tester"); + request.setURI("/context/dump"); + request.setHeader("Content-Type","multipart/form-data; boundary="+boundary); + + response.parse(tester.getResponses(request.generate())); + assertTrue(response.getMethod()==null); + assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, response.getStatus()); + assertTrue(response.getReason().startsWith("Missing content")); + } + + @Test + public void testWhitespaceBodyWithCRLF() + throws Exception + { + String whitespace = " \n\n\n\r\n\r\n\r\n\r\n"; + + String boundary="XyXyXy"; + // generated and parsed test + HttpTester request = new HttpTester(); + HttpTester response = new HttpTester(); + request.setMethod("POST"); + request.setVersion("HTTP/1.0"); + request.setHeader("Host","tester"); + request.setURI("/context/dump"); + request.setHeader("Content-Type","multipart/form-data; boundary="+boundary); + request.setContent(whitespace); + + response.parse(tester.getResponses(request.generate())); + assertTrue(response.getMethod()==null); + assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, response.getStatus()); + assertTrue(response.getReason().startsWith("Missing initial")); + } + + + @Test + public void testWhitespaceBody() + throws Exception + { + String whitespace = " "; + + String boundary="XyXyXy"; + // generated and parsed test + HttpTester request = new HttpTester(); + HttpTester response = new HttpTester(); + request.setMethod("POST"); + request.setVersion("HTTP/1.0"); + request.setHeader("Host","tester"); + request.setURI("/context/dump"); + request.setHeader("Content-Type","multipart/form-data; boundary="+boundary); + request.setContent(whitespace); + + response.parse(tester.getResponses(request.generate())); + assertTrue(response.getMethod()==null); + assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, response.getStatus()); + assertTrue(response.getReason().startsWith("Missing initial")); + } + + + /* * see the testParameterMap test diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ReadLineInputStream.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ReadLineInputStream.java index 748d8934d7e..4495f53569d 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ReadLineInputStream.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ReadLineInputStream.java @@ -54,7 +54,7 @@ public class ReadLineInputStream extends BufferedInputStream int m=markpos; markpos=-1; if (pos>m) - return new String(buf,m,pos-m, StringUtil.__UTF8_CHARSET); + return new String(buf,m,pos-m,StringUtil.__UTF8_CHARSET); return null; } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java index 05bd29686a7..b1a47f6c3a3 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java @@ -224,10 +224,7 @@ public class UrlEncoded extends MultiMap implements Cloneable key = null; value=null; if (maxKeys>0 && map.size()>maxKeys) - { - LOG.warn("maxFormKeys limit exceeded keys>{}",maxKeys); - return; - } + throw new IllegalStateException("Form too many keys"); break; case '=': if (key!=null) @@ -396,10 +393,7 @@ public class UrlEncoded extends MultiMap implements Cloneable key = null; value=null; if (maxKeys>0 && map.size()>maxKeys) - { - LOG.warn("maxFormKeys limit exceeded keys>{}",maxKeys); - return; - } + throw new IllegalStateException("Form too many keys"); break; case '=': @@ -483,10 +477,7 @@ public class UrlEncoded extends MultiMap implements Cloneable key = null; value=null; if (maxKeys>0 && map.size()>maxKeys) - { - LOG.warn("maxFormKeys limit exceeded keys>{}",maxKeys); - return; - } + throw new IllegalStateException("Form too many keys"); break; case '=': @@ -611,6 +602,8 @@ public class UrlEncoded extends MultiMap implements Cloneable } key = null; value=null; + if (maxKeys>0 && map.size()>maxKeys) + throw new IllegalStateException("Form too many keys"); break; case '=': if (key!=null) diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java index c6918c2cd87..af27b996a56 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java @@ -35,7 +35,9 @@ import javax.servlet.ServletResponse; import junit.framework.Assert; +import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; @@ -185,6 +187,36 @@ public class WebAppContextTest assertFalse(context.isProtectedTarget("/something-else/web-inf")); } + + @Test + public void testNullPath() throws Exception + { + Server server = new Server(0); + HandlerList handlers = new HandlerList(); + ContextHandlerCollection contexts = new ContextHandlerCollection(); + WebAppContext context = new WebAppContext(); + context.setBaseResource(Resource.newResource("./src/test/webapp")); + context.setContextPath("/"); + server.setHandler(handlers); + handlers.addHandler(contexts); + contexts.addHandler(context); + + LocalConnector connector = new LocalConnector(); + server.addConnector(connector); + + server.start(); + try + { + String response = connector.getResponses("GET http://localhost:8080 HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n"); + Assert.assertTrue(response.indexOf("200 OK")>=0); + } + finally + { + server.stop(); + } + } + + class ServletA extends GenericServlet { @Override diff --git a/test-jetty-webapp/src/main/java/com/acme/CookieDump.java b/test-jetty-webapp/src/main/java/com/acme/CookieDump.java index 5e045227d77..46145898ecc 100644 --- a/test-jetty-webapp/src/main/java/com/acme/CookieDump.java +++ b/test-jetty-webapp/src/main/java/com/acme/CookieDump.java @@ -19,6 +19,7 @@ package com.acme; import java.io.IOException; import java.io.PrintWriter; +import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; import javax.servlet.http.Cookie; @@ -121,4 +122,21 @@ public class CookieDump extends HttpServlet return string; } + @Override + public void destroy() + { + // For testing --stop with STOP.WAIT handling of the jetty-start behavior. + if (Boolean.getBoolean("test.slow.destroy")) + { + try + { + TimeUnit.SECONDS.sleep(10); + } + catch (InterruptedException e) + { + // ignore + } + } + super.destroy(); + } } diff --git a/test-jetty-webapp/src/main/java/com/acme/HelloWorld.java b/test-jetty-webapp/src/main/java/com/acme/HelloWorld.java index abacf87805c..67caa063480 100644 --- a/test-jetty-webapp/src/main/java/com/acme/HelloWorld.java +++ b/test-jetty-webapp/src/main/java/com/acme/HelloWorld.java @@ -67,8 +67,4 @@ public class HelloWorld extends HttpServlet getServletContext().log("exception",e); } } - - - - }