You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2023/01/17 13:01:28 UTC

[tomcat] branch 9.0.x updated: Allow Valves to access cookies when no Context has been mapped

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org