diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/Dispatcher.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/Dispatcher.java index 3ecf4a3d6b45..ea213bac5eec 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/Dispatcher.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/Dispatcher.java @@ -380,6 +380,10 @@ public Object getAttribute(String name) public Enumeration getAttributeNames() { ArrayList names = new ArrayList<>(Collections.list(super.getAttributeNames())); + + //only return the multipart attribute name if this servlet mapping has multipart config + if (names.contains(ServletContextRequest.MULTIPART_CONFIG_ELEMENT) && _mappedServlet.getServletHolder().getMultipartConfigElement() == null) + names.remove(ServletContextRequest.MULTIPART_CONFIG_ELEMENT); //Servlet Spec 9.4.2 no forward attributes if a named dispatcher if (_named != null) diff --git a/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DispatcherTest.java b/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DispatcherTest.java index 919f08cdf2e0..77bc3ec6f4c5 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DispatcherTest.java +++ b/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DispatcherTest.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; +import java.util.Enumeration; import java.util.List; import java.util.Map; import java.util.stream.Stream; @@ -30,6 +31,7 @@ import jakarta.servlet.FilterChain; import jakarta.servlet.FilterConfig; import jakarta.servlet.GenericServlet; +import jakarta.servlet.MultipartConfigElement; import jakarta.servlet.RequestDispatcher; import jakarta.servlet.Servlet; import jakarta.servlet.ServletContext; @@ -143,6 +145,33 @@ public void testForward() throws Exception assertEquals(expected, rawResponse); } + + @Test + public void testMultiPartForwardAttribute() throws Exception + { + ServletHolder forwardServlet = new ServletHolder(new ForwardServlet()); + forwardServlet.getRegistration().setMultipartConfig(new MultipartConfigElement("/tmp")); + _contextHandler.addServlet(forwardServlet, "/ForwardServlet/*"); + _contextHandler.addServlet(AssertMultiPartForwardServlet.class, "/AssertMultiPartForwardServlet/*"); + + String rawResponse = _connector.getResponse(""" + GET /context/ForwardServlet?do=assertmultipart&do=more&test=1 HTTP/1.1\r + Host: local\r + Connection: close\r + \r + """); + + String expected = """ + HTTP/1.1 200 OK\r + Content-Type: text/html\r + Content-Length: 42\r + Connection: close\r + \r + org.eclipse.jetty.multipartConfig = null\r + """; + + assertEquals(expected, rawResponse); + } @Test public void testFowardThenForward() throws Exception @@ -993,6 +1022,8 @@ else if (request.getParameter("do").equals("req.echo")) dispatcher = request.getRequestDispatcher(request.getParameter("uri")); else if (request.getParameter("do").equals("always")) dispatcher = request.getRequestDispatcher("/AlwaysForwardServlet"); + else if (request.getParameter("do").equals("assertmultipart")) + dispatcher = getServletContext().getRequestDispatcher("/AssertMultiPartForwardServlet?do=end&do=the"); assert dispatcher != null; dispatcher.forward(request, response); } @@ -1503,6 +1534,17 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t } } + public static class AssertMultiPartForwardServlet extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + response.setContentType("text/html"); + response.setStatus(HttpServletResponse.SC_OK); + response.getOutputStream().println("org.eclipse.jetty.multipartConfig = " + request.getAttribute("org.eclipse.jetty.multipartConfig")); + } + } + public static class AssertNonUTF8ForwardServlet extends HttpServlet implements Servlet { @Override