|
51 | 51 | import jakarta.servlet.http.HttpServletResponseWrapper;
|
52 | 52 | import jakarta.servlet.http.Part;
|
53 | 53 | import org.eclipse.jetty.http.HttpTester;
|
| 54 | +import org.eclipse.jetty.http.UriCompliance; |
54 | 55 | import org.eclipse.jetty.server.HttpConfiguration;
|
| 56 | +import org.eclipse.jetty.server.HttpConnectionFactory; |
55 | 57 | import org.eclipse.jetty.server.LocalConnector;
|
56 | 58 | import org.eclipse.jetty.server.Server;
|
57 | 59 | import org.eclipse.jetty.server.handler.ContextHandler;
|
|
60 | 62 | import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
61 | 63 | import org.eclipse.jetty.util.MultiMap;
|
62 | 64 | import org.eclipse.jetty.util.StringUtil;
|
| 65 | +import org.eclipse.jetty.util.URIUtil; |
63 | 66 | import org.eclipse.jetty.util.UrlEncoded;
|
64 | 67 | import org.eclipse.jetty.util.resource.ResourceFactory;
|
65 | 68 | import org.junit.jupiter.api.AfterEach;
|
@@ -295,6 +298,56 @@ public void testSimpleCrossContextForward() throws Exception
|
295 | 298 | assertThat(content, containsString("REQUEST_URI=/foreign/verify/pinfo"));
|
296 | 299 | }
|
297 | 300 |
|
| 301 | + @Test |
| 302 | + public void testEncodedCrossContextForward() throws Exception |
| 303 | + { |
| 304 | + _server.stop(); |
| 305 | + _targetServletContextHandler.addServlet(VerifyForwardServlet.class, "/verify/*"); |
| 306 | + _targetServletContextHandler.getServletHandler().setDecodeAmbiguousURIs(true); |
| 307 | + _contextHandler.addServlet(CrossContextDispatchServlet.class, "/dispatch/*"); |
| 308 | + _contextHandler.getServletHandler().setDecodeAmbiguousURIs(true); |
| 309 | + _server.getContainedBeans(HttpConnectionFactory.class).forEach(f -> f.getHttpConfiguration().setUriCompliance(UriCompliance.DEFAULT.with("test", UriCompliance.Violation.AMBIGUOUS_PATH_ENCODING))); |
| 310 | + _server.start(); |
| 311 | + |
| 312 | + String rawResponse = _connector.getResponse(""" |
| 313 | + GET /context/dispatch/?forward=/verify/%25%20test HTTP/1.1\r |
| 314 | + Host: localhost\r |
| 315 | + Connection: close\r |
| 316 | + \r |
| 317 | + """); |
| 318 | + |
| 319 | + HttpTester.Response response = HttpTester.parseResponse(rawResponse); |
| 320 | + |
| 321 | + String content = response.getContent(); |
| 322 | + String[] contentLines = content.split("\\n"); |
| 323 | + |
| 324 | + //verify forward attributes |
| 325 | + assertThat(content, containsString("Verified!")); |
| 326 | + assertThat(content, containsString("jakarta.servlet.forward.context_path=/context")); |
| 327 | + assertThat(content, containsString("jakarta.servlet.forward.servlet_path=/dispatch")); |
| 328 | + assertThat(content, containsString("jakarta.servlet.forward.path_info=/")); |
| 329 | + |
| 330 | + String forwardMapping = extractLine(contentLines, "jakarta.servlet.forward.mapping="); |
| 331 | + assertNotNull(forwardMapping); |
| 332 | + assertThat(forwardMapping, containsString("CrossContextDispatchServlet")); |
| 333 | + assertThat(content, containsString("jakarta.servlet.forward.query_string=forward=/verify")); |
| 334 | + assertThat(content, containsString("jakarta.servlet.forward.request_uri=/context/dispatch/")); |
| 335 | + //verify request values |
| 336 | + assertThat(content, containsString("REQUEST_URL=http://localhost/foreign/")); |
| 337 | + assertThat(content, containsString("CONTEXT_PATH=/foreign")); |
| 338 | + assertThat(content, containsString("SERVLET_PATH=/verify")); |
| 339 | + assertThat(content, containsString("PATH_INFO=/% test/pinfo")); |
| 340 | + String mapping = extractLine(contentLines, "MAPPING="); |
| 341 | + assertNotNull(mapping); |
| 342 | + assertThat(mapping, containsString("VerifyForwardServlet")); |
| 343 | + String params = extractLine(contentLines, "PARAMS="); |
| 344 | + assertNotNull(params); |
| 345 | + params = params.substring(params.indexOf("=") + 1); |
| 346 | + params = params.substring(1, params.length() - 1); //dump leading, trailing [ ] |
| 347 | + assertThat(Arrays.asList(StringUtil.csvSplit(params)), containsInAnyOrder("a", "forward")); |
| 348 | + assertThat(content, containsString("REQUEST_URI=/foreign/verify/%25%20test/pinfo")); |
| 349 | + } |
| 350 | + |
298 | 351 | @Test
|
299 | 352 | public void testSimpleCrossContextInclude() throws Exception
|
300 | 353 | {
|
@@ -831,7 +884,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
|
831 | 884 | {
|
832 | 885 | ServletContext foreign = getServletContext().getContext(ctx);
|
833 | 886 | assertNotNull(foreign);
|
834 |
| - dispatcher = foreign.getRequestDispatcher(request.getParameter("forward") + "/pinfo?a=b"); |
| 887 | + dispatcher = foreign.getRequestDispatcher(URIUtil.encodePath(request.getParameter("forward")) + "/pinfo?a=b"); |
835 | 888 |
|
836 | 889 | if (dispatcher == null)
|
837 | 890 | response.sendError(404, "No dispatcher for forward");
|
@@ -994,7 +1047,7 @@ public void service(ServletRequest req, ServletResponse res) throws ServletExcep
|
994 | 1047 | res.getWriter().println("----------- FORWARD ATTRIBUTES");
|
995 | 1048 | res.getWriter().println(RequestDispatcher.FORWARD_CONTEXT_PATH + "=" + req.getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH));
|
996 | 1049 | res.getWriter().println(RequestDispatcher.FORWARD_SERVLET_PATH + "=" + req.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH));
|
997 |
| - res.getWriter().println(RequestDispatcher.FORWARD_PATH_INFO + "=" + req.getAttribute(RequestDispatcher.FORWARD_PATH_INFO)); |
| 1050 | + res.getWriter().println(RequestDispatcher.FORWARD_PATH_INFO + "=" + req.getAttribute(RequestDispatcher.FORWARD_PATH_INFO)); |
998 | 1051 | res.getWriter().println(RequestDispatcher.FORWARD_MAPPING + "=" + req.getAttribute(RequestDispatcher.FORWARD_MAPPING));
|
999 | 1052 | res.getWriter().println(RequestDispatcher.FORWARD_QUERY_STRING + "=" + req.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING));
|
1000 | 1053 | res.getWriter().println(RequestDispatcher.FORWARD_REQUEST_URI + "=" + req.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI));
|
|
0 commit comments