diff options
author | Greg Wilkins | 2016-02-04 06:00:13 +0000 |
---|---|---|
committer | Greg Wilkins | 2016-02-04 06:00:13 +0000 |
commit | df79ad689a38592472d3696e15bf0252e617b8e7 (patch) | |
tree | c2fedd48685d4f06c044821f01b3a7c12a455b71 /jetty-servlet/src | |
parent | 459ba4ae5aa7f9a29d18b4e08848ff6e1cec0e4a (diff) | |
parent | 009fde2400a746b1ce24ba04bd4fcd001378516b (diff) | |
download | org.eclipse.jetty.project-df79ad689a38592472d3696e15bf0252e617b8e7.tar.gz org.eclipse.jetty.project-df79ad689a38592472d3696e15bf0252e617b8e7.tar.xz org.eclipse.jetty.project-df79ad689a38592472d3696e15bf0252e617b8e7.zip |
Merge remote-tracking branch 'origin/jetty-9.3.x'
Diffstat (limited to 'jetty-servlet/src')
5 files changed, 247 insertions, 45 deletions
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java index 4ef91fa921..3dffd4c3c1 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java @@ -30,6 +30,8 @@ import javax.servlet.http.HttpServletRequest; import org.eclipse.jetty.server.Dispatcher; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ErrorHandler; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; /** * An ErrorHandler that maps exceptions and status codes to URIs for dispatch using @@ -38,6 +40,8 @@ import org.eclipse.jetty.server.handler.ErrorHandler; public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler.ErrorPageMapper { public final static String GLOBAL_ERROR_PAGE = "org.eclipse.jetty.server.error_page.global"; + private static final Logger LOG = Log.getLogger(ErrorPageErrorHandler.class); + enum PageLookupTechnique{ THROWABLE, STATUS_CODE, GLOBAL } protected ServletContext _servletContext; private final Map<String,String> _errorPages= new HashMap<>(); // code or exception to URL @@ -48,11 +52,15 @@ public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler. { String error_page= null; + PageLookupTechnique pageSource = null; + Throwable th = (Throwable)request.getAttribute(Dispatcher.ERROR_EXCEPTION); // Walk the cause hierarchy while (error_page == null && th != null ) { + pageSource = PageLookupTechnique.THROWABLE; + Class<?> exClass=th.getClass(); error_page = _errorPages.get(exClass.getName()); @@ -68,13 +76,17 @@ public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler. th=(th instanceof ServletException)?((ServletException)th).getRootCause():null; } + Integer errorStatusCode = null; + if (error_page == null) { + pageSource = PageLookupTechnique.STATUS_CODE; + // look for an exact code match - Integer code=(Integer)request.getAttribute(Dispatcher.ERROR_STATUS_CODE); - if (code!=null) + errorStatusCode = (Integer)request.getAttribute(Dispatcher.ERROR_STATUS_CODE); + if (errorStatusCode!=null) { - error_page=_errorPages.get(Integer.toString(code)); + error_page= (String)_errorPages.get(Integer.toString(errorStatusCode)); // if still not found if ((error_page == null) && (_errorPageList != null)) @@ -83,7 +95,7 @@ public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler. for (int i = 0; i < _errorPageList.size(); i++) { ErrorCodeRange errCode = _errorPageList.get(i); - if (errCode.isInRange(code)) + if (errCode.isInRange(errorStatusCode)) { error_page = errCode.getUri(); break; @@ -95,7 +107,38 @@ public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler. // Try servlet 3.x global error page. if (error_page == null) + { + pageSource = PageLookupTechnique.GLOBAL; error_page = _errorPages.get(GLOBAL_ERROR_PAGE); + } + + if (LOG.isDebugEnabled()) + { + StringBuilder dbg = new StringBuilder(); + dbg.append("getErrorPage("); + dbg.append(request.getMethod()).append(' '); + dbg.append(request.getRequestURI()); + dbg.append(") => error_page=").append(error_page); + switch (pageSource) + { + case THROWABLE: + dbg.append(" (from Throwable "); + dbg.append(th.getClass().getName()); + dbg.append(')'); + LOG.debug(dbg.toString(),th); + break; + case STATUS_CODE: + dbg.append(" (from status code "); + dbg.append(errorStatusCode); + dbg.append(')'); + LOG.debug(dbg.toString()); + break; + case GLOBAL: + dbg.append(" (from global default)"); + LOG.debug(dbg.toString()); + break; + } + } return error_page; } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java index e1680a57ca..4d7a4139b0 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java @@ -66,6 +66,8 @@ import org.eclipse.jetty.util.DeprecationWarning; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; /** * Servlet Context. @@ -83,6 +85,8 @@ import org.eclipse.jetty.util.component.LifeCycle; @ManagedObject("Servlet Context Handler") public class ServletContextHandler extends ContextHandler { + private static final Logger LOG = Log.getLogger(ServletContextHandler.class); + public final static int SESSIONS=1; public final static int SECURITY=2; public final static int GZIP=4; @@ -169,7 +173,21 @@ public class ServletContextHandler extends ContextHandler if (errorHandler!=null) setErrorHandler(errorHandler); + } + + @Override + public void setHandler(Handler handler) + { + LOG.warn("ServletContextHandler.setHandler should not be called directly. Use insertHandler or setSessionHandler etc."); + super.setHandler(handler); + } + private void doSetHandler(HandlerWrapper wrapper, Handler handler) + { + if (wrapper==this) + super.setHandler(handler); + else + wrapper.setHandler(handler); } /* ------------------------------------------------------------ */ @@ -189,12 +207,7 @@ public class ServletContextHandler extends ContextHandler handler=(HandlerWrapper)handler.getHandler(); if (handler.getHandler()!=_sessionHandler) - { - if (handler== this) - super.setHandler(_sessionHandler); - else - handler.setHandler(_sessionHandler); - } + doSetHandler(handler,_sessionHandler); handler=_sessionHandler; } @@ -208,12 +221,7 @@ public class ServletContextHandler extends ContextHandler handler=(HandlerWrapper)handler.getHandler(); if (handler.getHandler()!=_securityHandler) - { - if (handler== this) - super.setHandler(_securityHandler); - else - handler.setHandler(_securityHandler); - } + doSetHandler(handler,_securityHandler); handler=_securityHandler; } @@ -226,12 +234,7 @@ public class ServletContextHandler extends ContextHandler handler=(HandlerWrapper)handler.getHandler(); if (handler.getHandler()!=_gzipHandler) - { - if (handler== this) - super.setHandler(_gzipHandler); - else - handler.setHandler(_gzipHandler); - } + doSetHandler(handler,_gzipHandler); handler=_gzipHandler; } @@ -244,12 +247,7 @@ public class ServletContextHandler extends ContextHandler handler=(HandlerWrapper)handler.getHandler(); if (handler.getHandler()!=_servletHandler) - { - if (handler== this) - super.setHandler(_servletHandler); - else - handler.setHandler(_servletHandler); - } + doSetHandler(handler,_servletHandler); handler=_servletHandler; } @@ -554,7 +552,7 @@ public class ServletContextHandler extends ContextHandler { if (wrapper.getHandler()==handler) { - wrapper.setHandler(replace); + doSetHandler(wrapper,replace); return true; } @@ -664,20 +662,38 @@ public class ServletContextHandler extends ContextHandler */ public void insertHandler(HandlerWrapper handler) { - HandlerWrapper h=this; - - // Skip any injected handlers - while (h.getHandler() instanceof HandlerWrapper) - { - HandlerWrapper wrapper = (HandlerWrapper)h.getHandler(); - if (wrapper instanceof SessionHandler || - wrapper instanceof SecurityHandler || - wrapper instanceof ServletHandler) - break; - h=wrapper; + if (handler instanceof SessionHandler) + setSessionHandler((SessionHandler)handler); + else if (handler instanceof SecurityHandler) + setSecurityHandler((SecurityHandler)handler); + else if (handler instanceof GzipHandler) + setGzipHandler((GzipHandler)handler); + else if (handler instanceof ServletHandler) + setServletHandler((ServletHandler)handler); + else + { + HandlerWrapper tail = handler; + while(tail.getHandler() instanceof HandlerWrapper) + tail=(HandlerWrapper)tail.getHandler(); + if (tail.getHandler()!=null) + throw new IllegalArgumentException("bad tail of inserted wrapper chain"); + + // Skip any injected handlers + HandlerWrapper h=this; + while (h.getHandler() instanceof HandlerWrapper) + { + HandlerWrapper wrapper = (HandlerWrapper)h.getHandler(); + if (wrapper instanceof SessionHandler || + wrapper instanceof SecurityHandler || + wrapper instanceof ServletHandler) + break; + h=wrapper; + } + + Handler next=h.getHandler(); + doSetHandler(h,handler); + doSetHandler(tail,next); } - - h.setHandler(handler); relinkHandlers(); } diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java index 4be7ff073c..99ca52f754 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java @@ -81,7 +81,6 @@ public class GzipHandlerTest _server.setHandler(gzipHandler); gzipHandler.setHandler(context); - context.setHandler(servlets); servlets.addServletWithMapping(TestServlet.class,"/content"); servlets.addServletWithMapping(ForwardServlet.class,"/forward"); servlets.addServletWithMapping(IncludeServlet.class,"/include"); @@ -91,7 +90,6 @@ public class GzipHandlerTest public static class TestServlet extends HttpServlet { - @Override protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException { diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/RequestGetPartsTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/RequestGetPartsTest.java new file mode 100644 index 0000000000..9cc62c6094 --- /dev/null +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/RequestGetPartsTest.java @@ -0,0 +1,145 @@ +// +// ======================================================================== +// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// +package org.eclipse.jetty.servlet; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Path; + +import javax.servlet.MultipartConfigElement; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.Part; + +import org.eclipse.jetty.http.HttpTester; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.toolchain.test.FS; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class RequestGetPartsTest +{ + @SuppressWarnings("serial") + public static class DumpPartInfoServlet extends HttpServlet + { + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + resp.setContentType("text/plain"); + PrintWriter out = resp.getWriter(); + + for(Part part: req.getParts()) + { + out.printf("Got part: name=%s, size=%,d, filename=%s%n",part.getName(), part.getSize(), part.getSubmittedFileName()); + } + } + } + + private static Server server; + private static LocalConnector connector; + private static File locationDir; + + @BeforeClass + public static void startServer() throws Exception + { + Path tmpDir = MavenTestingUtils.getTargetTestingPath("testrequest_getparts"); + FS.ensureEmpty(tmpDir); + + locationDir = tmpDir.toFile(); + + server = new Server(); + connector = new LocalConnector(server); + server.addConnector(connector); + + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + server.setHandler(context); + + ServletHolder holder = context.addServlet(DumpPartInfoServlet.class,"/dump/*"); + String location = locationDir.getAbsolutePath(); + long maxFileSize = 1024*1024*5; + long maxRequestSize = 1024*1024*10; + int fileSizeThreshold = 1; + MultipartConfigElement multipartConfig = new MultipartConfigElement(location,maxFileSize,maxRequestSize,fileSizeThreshold); + ((ServletHolder.Registration) holder.getRegistration()).setMultipartConfig(multipartConfig); + + server.start(); + } + + @AfterClass + public static void stopServer() throws Exception + { + server.stop(); + } + + @Test + public void testMultiFileUpload_SameName() throws Exception + { + // generated and parsed test + HttpTester.Request request = HttpTester.newRequest(); + HttpTester.Response response; + + // test GET + request.setMethod("POST"); + request.setURI("/dump/"); + request.setVersion("HTTP/1.1"); + request.setHeader("Host","tester"); + request.setHeader("Connection","close"); + + String boundary="XyXyXy"; + request.setHeader("Content-Type","multipart/form-data; boundary=" + boundary); + + String crocMsg = "See ya later, aligator."; + String aligMsg = "In a while, crocodile."; + + StringBuilder content = new StringBuilder(); + content.append("--").append(boundary).append("\r\n"); + content.append("Content-Disposition: form-data; name=\"same\"; filename=\"crocodile.dat\"\r\n"); + content.append("Content-Type: application/octet-stream\r\n"); + content.append("\r\n"); + content.append(crocMsg).append("\r\n"); + content.append("--").append(boundary).append("\r\n"); + content.append("Content-Disposition: form-data; name=\"same\"; filename=\"aligator.dat\"\r\n"); + content.append("Content-Type: application/octet-stream\r\n"); + content.append("\r\n"); + content.append(aligMsg).append("\r\n"); + content.append("--").append(boundary).append("--\r\n"); + content.append("\r\n"); + + request.setContent(content.toString()); + + response = HttpTester.parseResponse(connector.getResponses(request.generate())); + assertThat("Response status", response.getStatus(), is(HttpServletResponse.SC_OK)); + assertEquals(HttpServletResponse.SC_OK,response.getStatus()); + + String responseContents = response.getContent(); + assertThat("response.contents", responseContents, containsString(String.format("Got part: name=same, size=%d, filename=crocodile.dat",crocMsg.length()))); + assertThat("response.contents", responseContents, containsString(String.format("Got part: name=same, size=%d, filename=aligator.dat",aligMsg.length()))); + } +} diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHandlerTest.java index f088ffd3fc..2b2c671f96 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHandlerTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHandlerTest.java @@ -26,6 +26,7 @@ import java.util.EnumSet; import javax.servlet.DispatcherType; +import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.servlet.BaseHolder.Source; import org.junit.Before; import org.junit.Test; @@ -428,5 +429,4 @@ public class ServletHandlerTest } - } |