This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push: new e7a0e50d54 Allow Valves to access cookies when no Context has been mapped e7a0e50d54 is described below commit e7a0e50d544a372c71116b1f8f4583f55d0b8adb Author: Mark Thomas <ma...@apache.org> AuthorDate: Tue Jan 17 12:41:00 2023 +0000 Allow Valves to access cookies when no Context has been mapped --- java/org/apache/catalina/connector/Request.java | 23 +++--- .../catalina/valves/rewrite/TestRewriteValve.java | 83 ++++++++++++++++++++++ webapps/docs/changelog.xml | 8 +++ 3 files changed, 106 insertions(+), 8 deletions(-) diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java index 3a38bf8cca..949f4353e1 100644 --- a/java/org/apache/catalina/connector/Request.java +++ b/java/org/apache/catalina/connector/Request.java @@ -104,6 +104,7 @@ import org.apache.tomcat.util.http.CookieProcessor; import org.apache.tomcat.util.http.FastHttpDateFormat; import org.apache.tomcat.util.http.Parameters; import org.apache.tomcat.util.http.Parameters.FailReason; +import org.apache.tomcat.util.http.Rfc6265CookieProcessor; import org.apache.tomcat.util.http.ServerCookie; import org.apache.tomcat.util.http.ServerCookies; import org.apache.tomcat.util.http.fileupload.FileItem; @@ -3150,6 +3151,18 @@ public class Request implements HttpServletRequest { return buf.toString(); } + private CookieProcessor getCookieProcessor() { + Context context = getContext(); + if (context == null) { + // No context. Possible call from Valve before a Host level + // context rewrite when no ROOT content is configured. Use the + // default CookiePreocessor. + return new Rfc6265CookieProcessor(); + } else { + return context.getCookieProcessor(); + } + } + /** * Parse cookies. This only parses the cookies into the memory efficient * ServerCookies structure. It does not populate the Cookie objects. @@ -3163,8 +3176,7 @@ public class Request implements HttpServletRequest { ServerCookies serverCookies = coyoteRequest.getCookies(); serverCookies.setLimit(connector.getMaxCookieCount()); - CookieProcessor cookieProcessor = getContext().getCookieProcessor(); - cookieProcessor.parseCookieHeader(coyoteRequest.getMimeHeaders(), serverCookies); + getCookieProcessor().parseCookieHeader(coyoteRequest.getMimeHeaders(), serverCookies); } /** @@ -3178,14 +3190,9 @@ public class Request implements HttpServletRequest { cookiesConverted = true; - if (getContext() == null) { - return; - } - parseCookies(); ServerCookies serverCookies = coyoteRequest.getCookies(); - CookieProcessor cookieProcessor = getContext().getCookieProcessor(); int count = serverCookies.getCookieCount(); if (count <= 0) { @@ -3202,7 +3209,7 @@ public class Request implements HttpServletRequest { Cookie cookie = new Cookie(scookie.getName().toString(),null); int version = scookie.getVersion(); cookie.setVersion(version); - scookie.getValue().getByteChunk().setCharset(cookieProcessor.getCharset()); + scookie.getValue().getByteChunk().setCharset(getCookieProcessor().getCharset()); cookie.setValue(unescape(scookie.getValue().toString())); cookie.setPath(unescape(scookie.getPath().toString())); String domain = scookie.getDomain().toString(); diff --git a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java index c6e8c26449..0c7c7c10ff 100644 --- a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java +++ b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java @@ -16,20 +16,32 @@ */ package org.apache.catalina.valves.rewrite; +import java.io.IOException; +import java.io.PrintWriter; import java.net.HttpURLConnection; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.junit.Assert; import org.junit.Test; import org.apache.catalina.Context; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; import org.apache.catalina.servlets.DefaultServlet; import org.apache.catalina.startup.TesterServlet; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.catalina.valves.ValveBase; import org.apache.tomcat.util.buf.ByteChunk; /* @@ -722,4 +734,75 @@ public class TestRewriteValve extends TomcatBaseTest { Assert.assertEquals(expectedStatusCode, rc); } } + + + @Test + public void testCookie() throws Exception { + + Tomcat tomcat = getTomcatInstance(); + + // No file system docBase required + Context ctx = tomcat.addContext("redirect", null); + + CookieTestValve cookieTestValve = new CookieTestValve(); + tomcat.getHost().getPipeline().addValve(cookieTestValve); + RewriteValve rewriteValve = new RewriteValve(); + tomcat.getHost().getPipeline().addValve(rewriteValve); + + rewriteValve.setConfiguration("RewriteRule ^/source/(.*) /redirect/$1"); + + Tomcat.addServlet(ctx, "cookieTest", new CookieTestServlet()); + + ctx.addServletMappingDecoded("/", "cookieTest"); + + tomcat.start(); + + Map<String, List<String>> reqHead = new HashMap<>(); + reqHead.put("cookie", Arrays.asList("test=data")); + ByteChunk res = new ByteChunk(); + int rc = methodUrl("http://localhost:" + getPort() + "/source/cookieTest", res, + DEFAULT_CLIENT_TIMEOUT_MS, reqHead, null, "GET", false); + + Assert.assertEquals(HttpServletResponse.SC_OK , rc); + + res.setCharset(StandardCharsets.UTF_8); + Assert.assertEquals("PASS", res.toString()); + } + + + public static class CookieTestValve extends ValveBase { + + @Override + public void invoke(Request request, Response response) throws IOException, ServletException { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if ("test".equals(cookie.getName())) { + request.setAttribute("cookieTest", cookie.getValue()); + break; + } + } + } + getNext().invoke(request, response); + } + } + + + public static class CookieTestServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.setContentType("text/plain"); + resp.setCharacterEncoding("UTF-8"); + + PrintWriter pw = resp.getWriter(); + if (req.getAttribute("cookieTest") != null) { + pw.print("PASS"); + } else { + pw.print("FAIL"); + } + } + } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 6a3de1b3c6..bf5bea503c 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -105,6 +105,14 @@ issues do not "pop up" wrt. others). --> <section name="Tomcat 9.0.72 (remm)" rtext="in development"> + <subsection name="Catalina"> + <changelog> + <fix> + Allow a Valve to access cookies from a request that cannot be mapped to + a Context. (markt) + </fix> + </changelog> + </subsection> <subsection name="Other"> <changelog> <update> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org