Author: violetagg Date: Fri Jun 28 12:01:42 2013 New Revision: 1497741 URL: http://svn.apache.org/r1497741 Log: Merged revision 1497474 from tomcat/trunk: When calculating the path in AsyncContext.dispatch(), methods ServletRequest.getRequestURI and ServletRequest.getContextPath cannot be used. That's because the first one returns a string that is not decoded and not normalized, but the second one returns decoded string. Instead of this methods ServletRequest.getServletPath and ServletRequest.getPathInfo will be used as requestURI = contextPath + servletPath + pathInfo.
Modified: tomcat/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1497474 Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java?rev=1497741&r1=1497740&r2=1497741&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java Fri Jun 28 12:01:42 2013 @@ -169,17 +169,19 @@ public class AsyncContextImpl implements public void dispatch() { check(); String path; - String cpath; + String pathInfo; ServletRequest servletRequest = getRequest(); if (servletRequest instanceof HttpServletRequest) { HttpServletRequest sr = (HttpServletRequest) servletRequest; - path = sr.getRequestURI(); - cpath = sr.getContextPath(); + path = sr.getServletPath(); + pathInfo = sr.getPathInfo(); } else { - path = request.getRequestURI(); - cpath = request.getContextPath(); + path = request.getServletPath(); + pathInfo = request.getPathInfo(); + } + if (pathInfo != null) { + path += pathInfo; } - if (cpath.length()>1) path = path.substring(cpath.length()); dispatch(path); } Modified: tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java?rev=1497741&r1=1497740&r2=1497741&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java (original) +++ tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java Fri Jun 28 12:01:42 2013 @@ -1809,42 +1809,18 @@ public class TestAsyncContextImpl extend @Test public void testDispatchWithCustomRequestResponse() throws Exception { - // Setup Tomcat instance - Tomcat tomcat = getTomcatInstance(); - - // Must have a real docBase - just use temp - File docBase = new File(System.getProperty("java.io.tmpdir")); - - Context ctx = tomcat.addContext("", docBase.getAbsolutePath()); - - DispatchingGenericServlet dispatch = new DispatchingGenericServlet(); - Wrapper wrapper = Tomcat.addServlet(ctx, "dispatch", dispatch); - wrapper.setAsyncSupported(true); - ctx.addServletMapping("/dispatch", "dispatch"); - - CustomGenericServlet customGeneric = new CustomGenericServlet(); - Wrapper wrapper2 = Tomcat.addServlet(ctx, "customGeneric", - customGeneric); - wrapper2.setAsyncSupported(true); - ctx.addServletMapping("/target", "customGeneric"); - - tomcat.start(); - - ByteChunk res = getUrl("http://localhost:" + getPort() - + "/dispatch?crr=y"); + prepareApplicationWithGenericServlet(""); StringBuilder expected = new StringBuilder(); expected.append("OK"); expected.append("CustomGenericServletGet-"); - assertEquals(expected.toString(), res.toString()); - - res = getUrl("http://localhost:" + getPort() - + "/dispatch?crr=y&empty=y"); + requestApplicationWithGenericServlet("/dispatch?crr=y", expected); expected = new StringBuilder(); expected.append("OK"); expected.append("DispatchingGenericServletGet-"); - assertEquals(expected.toString(), res.toString()); + requestApplicationWithGenericServlet("/dispatch?crr=y&empty=y", + expected); } private static class CustomGenericServlet extends GenericServlet { @@ -1861,4 +1837,75 @@ public class TestAsyncContextImpl extend } } + + @Test + public void testEmptyDispatch() throws Exception { + prepareApplicationWithGenericServlet("/fo o"); + StringBuilder expected = new StringBuilder(); + expected.append("OK"); + expected.append("DispatchingGenericServletGet-"); + requestApplicationWithGenericServlet("/fo%20o/dispatch?empty=y", + expected); + requestApplicationWithGenericServlet("//fo%20o/dispatch?empty=y", + expected); + requestApplicationWithGenericServlet("/./fo%20o/dispatch?empty=y", + expected); + requestApplicationWithGenericServlet("/fo%20o//dispatch?empty=y", + expected); + requestApplicationWithGenericServlet("/fo%20o/./dispatch?empty=y", + expected); + requestApplicationWithGenericServlet("/fo%20o/c/../dispatch?empty=y", + expected); + } + + @Test + public void testEmptyDispatchWithCustomRequestResponse() throws Exception { + prepareApplicationWithGenericServlet("/fo o"); + StringBuilder expected = new StringBuilder(); + expected.append("OK"); + expected.append("DispatchingGenericServletGet-"); + requestApplicationWithGenericServlet("/fo%20o/dispatch?crr=y&empty=y", + expected); + requestApplicationWithGenericServlet("//fo%20o/dispatch?crr=y&empty=y", + expected); + requestApplicationWithGenericServlet( + "/./fo%20o/dispatch?crr=y&empty=y", expected); + requestApplicationWithGenericServlet("/fo%20o//dispatch?crr=y&empty=y", + expected); + requestApplicationWithGenericServlet( + "/fo%20o/./dispatch?crr=y&empty=y", expected); + requestApplicationWithGenericServlet( + "/fo%20o/c/../dispatch?crr=y&empty=y", expected); + } + + private void prepareApplicationWithGenericServlet(String contextPath) + throws Exception { + // Setup Tomcat instance + Tomcat tomcat = getTomcatInstance(); + + // Must have a real docBase - just use temp + File docBase = new File(System.getProperty("java.io.tmpdir")); + + Context ctx = tomcat.addContext(contextPath, docBase.getAbsolutePath()); + + DispatchingGenericServlet dispatch = new DispatchingGenericServlet(); + Wrapper wrapper = Tomcat.addServlet(ctx, "dispatch", dispatch); + wrapper.setAsyncSupported(true); + ctx.addServletMapping("/dispatch", "dispatch"); + + CustomGenericServlet customGeneric = new CustomGenericServlet(); + Wrapper wrapper2 = Tomcat.addServlet(ctx, "customGeneric", + customGeneric); + wrapper2.setAsyncSupported(true); + ctx.addServletMapping("/target", "customGeneric"); + + tomcat.start(); + } + + private void requestApplicationWithGenericServlet(String path, + StringBuilder expectedContent) throws Exception { + ByteChunk res = getUrl("http://localhost:" + getPort() + path); + + assertEquals(expectedContent.toString(), res.toString()); + } } Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1497741&r1=1497740&r2=1497741&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Jun 28 12:01:42 2013 @@ -116,6 +116,10 @@ <code>userPassword</code> was set and passwords were hashed with MD5 or SHA1. (markt/kkolinko) </fix> + <fix> + Correct the mechanism for the path calculation in + <code>AsyncContext.dispatch()</code>. (violetagg) + </fix> </changelog> </subsection> <subsection name="Cluster"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org