diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/DefaultServlet.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/DefaultServlet.java index 2c350c2f4772..7b1a0969bfff 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/DefaultServlet.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/DefaultServlet.java @@ -56,6 +56,7 @@ import org.eclipse.jetty.util.Blocker; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.ExceptionUtil; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.Resources; @@ -555,7 +556,16 @@ protected String getEncodedPathInContext(HttpServletRequest req, String included if (includedServletPath != null) return encodePath(getIncludedPathInContext(req, includedServletPath, !isDefaultMapping(req))); else if (!isDefaultMapping(req)) - return encodePath(req.getPathInfo()); + { + //a match via an extension mapping will more than likely + //have no path info + String path = req.getPathInfo(); + if (StringUtil.isEmpty(path) && + MappingMatch.EXTENSION.equals(req.getHttpServletMapping().getMappingMatch())) + path = req.getServletPath(); + + return encodePath(path); + } else if (req instanceof ServletApiRequest apiRequest) return Context.getPathInContext(req.getContextPath(), apiRequest.getRequest().getHttpURI().getCanonicalPath()); else diff --git a/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DefaultServletTest.java b/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DefaultServletTest.java index 554bce24f1dd..c8b3e4c889c6 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DefaultServletTest.java +++ b/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DefaultServletTest.java @@ -3487,6 +3487,26 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws assertThat(response.getContent(), containsString("testPathInfoOnly-OK")); } + @Test + public void testSuffixMappings() throws Exception + { + server.stop(); + + Path suffixroot = MavenTestingUtils.getTestResourcePath("suffixroot"); + ResourceFactory resourceFactory = ResourceFactory.of(context); + context.setBaseResource(resourceFactory.newResource(suffixroot.toUri())); + + ServletHolder holderAlt = new ServletHolder("static-js", DefaultServlet.class); + context.addServlet(holderAlt, "*.js"); + ServletHolder holderDef = new ServletHolder("default", DefaultServlet.class); + holderDef.setInitParameter("dirAllowed", "true"); + context.addServlet(holderDef, "/"); + + server.start(); + String rawResponse = connector.getResponse("GET /context/test.js HTTP/1.0\r\n\r\n"); + assertThat(rawResponse, containsString("Hello")); + } + @Test public void testMemoryResourceRange() throws Exception { diff --git a/jetty-ee10/jetty-ee10-servlet/src/test/resources/suffixroot/test.js b/jetty-ee10/jetty-ee10-servlet/src/test/resources/suffixroot/test.js new file mode 100644 index 000000000000..08268dffc00a --- /dev/null +++ b/jetty-ee10/jetty-ee10-servlet/src/test/resources/suffixroot/test.js @@ -0,0 +1 @@ +document.write("Hello");