Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
HttpServletRequest.getContextPath() should return the undecoded context path used by the user agent.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1593621 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
markt-asf committed May 9, 2014
1 parent 30bcf27 commit 898c64a
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 1 deletion.
12 changes: 11 additions & 1 deletion java/org/apache/catalina/connector/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -1894,7 +1894,17 @@ public String getAuthType() {
*/
@Override
public String getContextPath() {
return mappingData.contextPath.toString();
String uri = getRequestURI();
int lastSlash = mappingData.contextSlashCount;
int pos = 0;
while (lastSlash > 0) {
pos = uri.indexOf('/', pos + 1);
if (pos == -1) {
return uri;
}
lastSlash--;
}
return uri.substring(0, pos);
}


Expand Down
3 changes: 3 additions & 0 deletions java/org/apache/catalina/mapper/Mapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ public void addContextVersion(String hostName, Host host, String path,
new ContextVersion[contextVersions.length + 1];
ContextVersion newContextVersion = new ContextVersion();
newContextVersion.path = path;
newContextVersion.slashCount = slashCount;
newContextVersion.name = version;
newContextVersion.object = context;
newContextVersion.welcomeResources = welcomeResources;
Expand Down Expand Up @@ -799,6 +800,7 @@ private final void internalMap(CharChunk host, CharChunk uri,
}
}
mappingData.context = contextVersion.object;
mappingData.contextSlashCount = contextVersion.slashCount;
}

// Wrapper mapping
Expand Down Expand Up @@ -1480,6 +1482,7 @@ protected static final class MappedContext extends MapElement<Context> {

protected static final class ContextVersion extends MapElement<Context> {
public String path = null;
public int slashCount;
public String[] welcomeResources = new String[0];
public WebResourceRoot resources = null;
public MappedWrapper defaultWrapper = null;
Expand Down
2 changes: 2 additions & 0 deletions java/org/apache/catalina/mapper/MappingData.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class MappingData {

public Host host = null;
public Context context = null;
public int contextSlashCount = 0;
public Context[] contexts = null;
public Wrapper wrapper = null;
public boolean jspWildCard = false;
Expand All @@ -45,6 +46,7 @@ public class MappingData {
public void recycle() {
host = null;
context = null;
contextSlashCount = 0;
contexts = null;
wrapper = null;
jspWildCard = false;
Expand Down
110 changes: 110 additions & 0 deletions test/org/apache/catalina/connector/TestRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -685,4 +685,114 @@ private void checkResponseBug54984(HttpURLConnection conn)
fail("OK status was expected: " + status);
}
}

@Test
public void testBug56501a() throws Exception {
doBug56501("/path", "/path", "/path");
}

@Test
public void testBug56501b() throws Exception {
doBug56501("/path", "/path/", "/path");
}

@Test
public void testBug56501c() throws Exception {
doBug56501("/path", "/path/xxx", "/path");
}

@Test
public void testBug56501d() throws Exception {
doBug56501("", "", "");
}

@Test
public void testBug56501e() throws Exception {
doBug56501("", "/", "");
}

@Test
public void testBug56501f() throws Exception {
doBug56501("", "/xxx", "");
}

@Test
public void testBug56501g() throws Exception {
doBug56501("/path/abc", "/path/abc", "/path/abc");
}

@Test
public void testBug56501h() throws Exception {
doBug56501("/path/abc", "/path/abc/", "/path/abc");
}

@Test
public void testBug56501i() throws Exception {
doBug56501("/path/abc", "/path/abc/xxx", "/path/abc");
}

@Test
public void testBug56501j() throws Exception {
doBug56501("/pa_th/abc", "/pa%5Fth/abc", "/pa%5Fth/abc");
}

@Test
public void testBug56501k() throws Exception {
doBug56501("/pa_th/abc", "/pa%5Fth/abc/", "/pa%5Fth/abc");
}

@Test
public void testBug56501l() throws Exception {
doBug56501("/pa_th/abc", "/pa%5Fth/abc/xxx", "/pa%5Fth/abc");
}

@Test
public void testBug56501m() throws Exception {
doBug56501("/pa_th/abc", "/pa_th/abc", "/pa_th/abc");
}

@Test
public void testBug56501n() throws Exception {
doBug56501("/pa_th/abc", "/pa_th/abc/", "/pa_th/abc");
}

@Test
public void testBug56501o() throws Exception {
doBug56501("/pa_th/abc", "/pa_th/abc/xxx", "/pa_th/abc");
}

private void doBug56501(String deployPath, String requestPath, String expected)
throws Exception {

// Setup Tomcat instance
Tomcat tomcat = getTomcatInstance();

// Must have a real docBase - just use temp
Context ctx = tomcat.addContext(deployPath,
System.getProperty("java.io.tmpdir"));

Tomcat.addServlet(ctx, "servlet", new Bug56501Servelet());
ctx.addServletMapping("/*", "servlet");

tomcat.start();

ByteChunk res = getUrl("http://localhost:" + getPort() + requestPath);
String resultPath = res.toString();
if (resultPath == null) {
resultPath = "";
}
assertEquals(expected, resultPath);
}

private class Bug56501Servelet extends HttpServlet {

private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
resp.getWriter().print(req.getContextPath());
}
}
}
4 changes: 4 additions & 0 deletions webapps/docs/changelog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@
Make the naming context tokens for containers more robust by using a
separate object. (markt/kkolinko)
</fix>
<fix>
<bug>56501</bug>: <code>HttpServletRequest.getContextPath()</code>
should return the undecoded context path used by the user agent. (markt)
</fix>
</changelog>
</subsection>
<subsection name="Coyote">
Expand Down

0 comments on commit 898c64a

Please sign in to comment.