Skip to content

Commit cab9945

Browse files
authored
Issue #7748 - allow override of path mapping behavior in ServletContextHandler (#7614)
Added protected method to ServletHandler to allow other servlet mappings (eg regex) in embedded/extended usage Signed-off-by: Greg Wilkins <[email protected]> Signed-off-by: Joakim Erdfelt <[email protected]>
1 parent 29011e9 commit cab9945

File tree

3 files changed

+163
-9
lines changed

3 files changed

+163
-9
lines changed

jetty-server/src/main/java/org/eclipse/jetty/server/ServletPathMapping.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,13 @@ public ServletPathMapping(PathSpec pathSpec, String servletName, String pathInCo
8686
break;
8787

8888
case MIDDLE_GLOB:
89-
_mappingMatch = null;
90-
_matchValue = "";
91-
_servletPath = pathInContext;
92-
_pathInfo = null;
93-
break;
94-
9589
default:
9690
throw new IllegalStateException();
9791
}
9892
}
9993
else
10094
{
95+
// TODO can we do better for RegexPathSpec
10196
_mappingMatch = null;
10297
_matchValue = "";
10398
_servletPath = pathInContext;

jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,12 @@ protected void updateNameMappings()
12461246
}
12471247
}
12481248

1249+
protected PathSpec asPathSpec(String pathSpec)
1250+
{
1251+
// By default only allow servlet path specs
1252+
return new ServletPathSpec(pathSpec);
1253+
}
1254+
12491255
protected void updateMappings()
12501256
{
12511257
try (AutoLock ignored = lock())
@@ -1354,9 +1360,9 @@ else if (isAllowDuplicateMappings())
13541360
finalMapping.getServletName(),
13551361
getServlet(finalMapping.getServletName()).getSource());
13561362

1357-
ServletPathSpec servletPathSpec = new ServletPathSpec(pathSpec);
1358-
MappedServlet mappedServlet = new MappedServlet(servletPathSpec, getServlet(finalMapping.getServletName()));
1359-
pm.put(servletPathSpec, mappedServlet);
1363+
PathSpec ps = asPathSpec(pathSpec);
1364+
MappedServlet mappedServlet = new MappedServlet(ps, getServlet(finalMapping.getServletName()));
1365+
pm.put(ps, mappedServlet);
13601366
}
13611367

13621368
_servletPathMap = pm;
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
//
2+
// ========================================================================
3+
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
4+
//
5+
// This program and the accompanying materials are made available under the
6+
// terms of the Eclipse Public License v. 2.0 which is available at
7+
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
8+
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
9+
//
10+
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
11+
// ========================================================================
12+
//
13+
14+
package org.eclipse.jetty.servlet;
15+
16+
import java.io.IOException;
17+
import java.io.PrintWriter;
18+
import javax.servlet.ServletException;
19+
import javax.servlet.http.HttpServlet;
20+
import javax.servlet.http.HttpServletRequest;
21+
import javax.servlet.http.HttpServletResponse;
22+
23+
import org.eclipse.jetty.http.pathmap.PathMappings;
24+
import org.eclipse.jetty.http.pathmap.PathSpec;
25+
import org.eclipse.jetty.server.LocalConnector;
26+
import org.eclipse.jetty.server.Server;
27+
import org.junit.jupiter.api.BeforeEach;
28+
import org.junit.jupiter.api.Test;
29+
30+
import static org.hamcrest.MatcherAssert.assertThat;
31+
import static org.hamcrest.Matchers.containsString;
32+
33+
public class RegexServletTest
34+
{
35+
private Server _server;
36+
private LocalConnector _connector;
37+
private ServletContextHandler _servletContextHandler;
38+
39+
@BeforeEach
40+
public void beforeEach()
41+
{
42+
_server = new Server();
43+
_connector = new LocalConnector(_server);
44+
45+
_servletContextHandler = new ServletContextHandler(_server, "/ctx");
46+
_servletContextHandler.setServletHandler(new ServletHandler()
47+
{
48+
@Override
49+
protected PathSpec asPathSpec(String pathSpec)
50+
{
51+
return PathMappings.asPathSpec(pathSpec);
52+
}
53+
});
54+
55+
_server.setHandler(_servletContextHandler);
56+
_server.addConnector(_connector);
57+
}
58+
59+
@Test
60+
public void testHello() throws Exception
61+
{
62+
_servletContextHandler.addServlet(new ServletHolder(new ServletContextHandlerTest.HelloServlet()), "^/[Hh]ello");
63+
_server.start();
64+
65+
assertThat(_connector.getResponse("GET /ctx/hello HTTP/1.0\r\n\r\n"), containsString("Hello World"));
66+
assertThat(_connector.getResponse("GET /ctx/Hello HTTP/1.0\r\n\r\n"), containsString("Hello World"));
67+
assertThat(_connector.getResponse("GET /ctx/HELLO HTTP/1.0\r\n\r\n"), containsString(" 404"));
68+
}
69+
70+
@Test
71+
public void testMapping() throws Exception
72+
{
73+
_servletContextHandler.addServlet(new ServletHolder(new TestServlet()), "^/test/.*$");
74+
_server.start();
75+
76+
String response = _connector.getResponse("GET /ctx/test/info HTTP/1.0\r\n\r\n");
77+
assertThat(response, containsString(" 200 OK"));
78+
assertThat(response, containsString("contextPath='/ctx'"));
79+
assertThat(response, containsString("servletPath='/test/info'"));
80+
assertThat(response, containsString("pathInfo='null'"));
81+
assertThat(response, containsString("mapping.mappingMatch='null'"));
82+
assertThat(response, containsString("mapping.matchValue=''"));
83+
assertThat(response, containsString("mapping.pattern='^/test/.*$'"));
84+
}
85+
86+
@Test
87+
public void testForward() throws Exception
88+
{
89+
_servletContextHandler.addServlet(new ServletHolder(new ForwardServlet()), "^/forward(/.*)?");
90+
_servletContextHandler.addServlet(new ServletHolder(new TestServlet()), "^/[Tt]est(/.*)?");
91+
_server.start();
92+
93+
String response = _connector.getResponse("GET /ctx/forward/ignore HTTP/1.0\r\n\r\n");
94+
assertThat(response, containsString(" 200 OK"));
95+
assertThat(response, containsString("contextPath='/ctx'"));
96+
assertThat(response, containsString("servletPath='/Test/info'"));
97+
assertThat(response, containsString("pathInfo='null'"));
98+
assertThat(response, containsString("mapping.mappingMatch='null'"));
99+
assertThat(response, containsString("mapping.matchValue=''"));
100+
assertThat(response, containsString("mapping.pattern='^/[Tt]est(/.*)?'"));
101+
}
102+
103+
@Test
104+
public void testInclude() throws Exception
105+
{
106+
_servletContextHandler.addServlet(new ServletHolder(new IncludeServlet()), "^/include$");
107+
_servletContextHandler.addServlet(new ServletHolder(new TestServlet()), "^/[Tt]est(/.*)?");
108+
_server.start();
109+
110+
String response = _connector.getResponse("GET /ctx/include HTTP/1.0\r\n\r\n");
111+
assertThat(response, containsString(" 200 OK"));
112+
assertThat(response, containsString("contextPath='/ctx'"));
113+
assertThat(response, containsString("servletPath='/include'"));
114+
assertThat(response, containsString("pathInfo='null'"));
115+
assertThat(response, containsString("mapping.mappingMatch='null'"));
116+
assertThat(response, containsString("mapping.matchValue=''"));
117+
assertThat(response, containsString("mapping.pattern='^/include$'"));
118+
}
119+
120+
static class TestServlet extends HttpServlet
121+
{
122+
@Override
123+
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
124+
{
125+
resp.setStatus(200);
126+
PrintWriter out = resp.getWriter();
127+
out.printf("contextPath='%s'%n", req.getContextPath());
128+
out.printf("servletPath='%s'%n", req.getServletPath());
129+
out.printf("pathInfo='%s'%n", req.getPathInfo());
130+
out.printf("mapping.mappingMatch='%s'%n", req.getHttpServletMapping().getMappingMatch());
131+
out.printf("mapping.matchValue='%s'%n", req.getHttpServletMapping().getMatchValue());
132+
out.printf("mapping.pattern='%s'%n", req.getHttpServletMapping().getPattern());
133+
}
134+
}
135+
136+
static class ForwardServlet extends HttpServlet
137+
{
138+
@Override
139+
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
140+
{
141+
req.getServletContext().getRequestDispatcher("/Test/info").forward(req, resp);
142+
}
143+
}
144+
145+
static class IncludeServlet extends HttpServlet
146+
{
147+
@Override
148+
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
149+
{
150+
req.getServletContext().getRequestDispatcher("/Test/info").include(req, resp);
151+
}
152+
}
153+
}

0 commit comments

Comments
 (0)