Author: markt Date: Tue Apr 26 13:22:21 2016 New Revision: 1741018 URL: http://svn.apache.org/viewvc?rev=1741018&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=59317 After a dispatch (async and non-async) ensure that getRequestURI() returns an encoded URI.
Modified: tomcat/tc8.5.x/trunk/ (props changed) tomcat/tc8.5.x/trunk/java/org/apache/catalina/core/ApplicationContext.java tomcat/tc8.5.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc8.5.x/trunk/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Tue Apr 26 13:22:21 2016 @@ -1 +1 @@ -/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740980 +/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740980,1740991,1741015 Modified: tomcat/tc8.5.x/trunk/java/org/apache/catalina/core/ApplicationContext.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/catalina/core/ApplicationContext.java?rev=1741018&r1=1741017&r2=1741018&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/catalina/core/ApplicationContext.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/catalina/core/ApplicationContext.java Tue Apr 26 13:22:21 2016 @@ -65,6 +65,7 @@ import org.apache.catalina.connector.Con import org.apache.catalina.mapper.MappingData; import org.apache.catalina.servlet4preview.http.Mapping; import org.apache.catalina.util.ServerInfo; +import org.apache.catalina.util.URLEncoder; import org.apache.tomcat.util.ExceptionUtils; import org.apache.tomcat.util.buf.CharChunk; import org.apache.tomcat.util.buf.MessageBytes; @@ -465,11 +466,11 @@ public class ApplicationContext mappingData.recycle(); - // Construct a RequestDispatcher to process this request - return new ApplicationDispatcher - (wrapper, uriCC.toString(), wrapperPath, pathInfo, - queryString, mapping, null); + String encodedUri = URLEncoder.DEFAULT.encode(uriCC.toString()); + // Construct a RequestDispatcher to process this request + return new ApplicationDispatcher(wrapper, encodedUri, wrapperPath, pathInfo, + queryString, mapping, null); } Modified: tomcat/tc8.5.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java?rev=1741018&r1=1741017&r2=1741018&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java (original) +++ tomcat/tc8.5.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java Tue Apr 26 13:22:21 2016 @@ -18,6 +18,8 @@ package org.apache.catalina.core; import java.io.IOException; import java.io.PrintWriter; +import java.net.URI; +import java.net.URISyntaxException; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -59,6 +61,7 @@ import org.apache.catalina.startup.Tomca import org.apache.catalina.valves.TesterAccessLogValve; import org.apache.tomcat.unittest.TesterContext; import org.apache.tomcat.util.buf.ByteChunk; +import org.apache.tomcat.util.buf.UDecoder; import org.apache.tomcat.util.descriptor.web.ErrorPage; import org.easymock.EasyMock; @@ -2237,11 +2240,10 @@ public class TestAsyncContextImpl extend tomcat.start(); String uri = "/foo/%24/bar"; - String uriDecoded = "/foo/$/bar"; ByteChunk body = getUrl("http://localhost:" + getPort()+ uri); - Assert.assertEquals(uriDecoded, body.toString()); + Assert.assertEquals(uri, body.toString()); } private static class AsyncRequestUriServlet extends HttpServlet { @@ -2478,4 +2480,115 @@ public class TestAsyncContextImpl extend ac.setErrorState(new Exception(), true); ac.fireOnComplete(); } + + + /* + * https://bz.apache.org/bugzilla/show_bug.cgi?id=59317 + */ + @Test + public void testAsyncDispatchUrlWithSpaces() throws Exception { + doTestDispatchWithSpaces(true); + } + + + @Test + public void testForwardDispatchUrlWithSpaces() throws Exception { + doTestDispatchWithSpaces(false); + } + + + private void doTestDispatchWithSpaces(boolean async) throws Exception { + Tomcat tomcat = getTomcatInstance(); + Context context = tomcat.addContext("", null); + if (async) { + Servlet s = new AsyncDispatchUrlWithSpacesServlet(); + Wrapper w = Tomcat.addServlet(context, "space", s); + w.setAsyncSupported(true); + } else { + Tomcat.addServlet(context, "space", new ForwardDispatchUrlWithSpacesServlet()); + } + context.addServletMapping("/space/*", "space"); + tomcat.start(); + + ByteChunk responseBody = new ByteChunk(); + int rc = getUrl("http://localhost:" + getPort() + "/sp%61ce/foo%20bar", responseBody, null); + + Assert.assertEquals(200, rc); + } + + + private static class AsyncDispatchUrlWithSpacesServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + Integer countObj = (Integer) req.getAttribute("count"); + int count = 0; + if (countObj != null) { + count = countObj.intValue(); + } + count++; + req.setAttribute("count", Integer.valueOf(count)); + + String encodedUri = req.getRequestURI(); + String decodedUri = UDecoder.URLDecode(encodedUri); + + try { + // Just here to trigger the error + @SuppressWarnings("unused") + URI u = new URI(encodedUri); + } catch (URISyntaxException e) { + throw new ServletException(e); + } + + if (count > 3) { + resp.setContentType("text/plain"); + resp.getWriter().print("OK"); + } else { + AsyncContext ac = req.startAsync(); + ac.dispatch(decodedUri); + } + } + } + + + private static class ForwardDispatchUrlWithSpacesServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + Integer countObj = (Integer) req.getAttribute("count"); + int count = 0; + if (countObj != null) { + count = countObj.intValue(); + } + count++; + req.setAttribute("count", Integer.valueOf(count)); + + String encodedUri = req.getRequestURI(); + String decodedUri = UDecoder.URLDecode(encodedUri); + + try { + // Just here to trigger the error + @SuppressWarnings("unused") + URI u = new URI(req.getRequestURI()); + } catch (URISyntaxException e) { + throw new ServletException(e); + } + + if (count > 3) { + resp.setContentType("text/plain"); + resp.getWriter().print("OK"); + } else { + RequestDispatcher rd = req.getRequestDispatcher(decodedUri); + rd.forward(req, resp); + } + } + } } Modified: tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml?rev=1741018&r1=1741017&r2=1741018&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml Tue Apr 26 13:22:21 2016 @@ -155,6 +155,11 @@ consistent with respect to whether or not they end with <code>/</code>. (markt) </fix> + <fix> + <bug>59317</bug>: Ensure that + <code>HttpServletRequest.getRequestURI()</code> returns an encoded URI + rather than a decoded URI after a dispatch. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org