This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit d16e846c4538ea9d4904cd2d74db41f0a7bcf3a6
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Mar 15 17:18:31 2024 +0000

    Don't use Max-Age=0 in Set-Cookie headers
---
 .../tomcat/util/http/Rfc6265CookieProcessor.java   | 26 +++++++++++-----------
 .../util/http/TestCookieProcessorGeneration.java   | 13 +++++++++--
 webapps/docs/changelog.xml                         |  6 +++++
 3 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java 
b/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java
index acdec29e78..e8227a6d0d 100644
--- a/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java
+++ b/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java
@@ -121,28 +121,28 @@ public class Rfc6265CookieProcessor extends 
CookieProcessorBase {
             header.append(value);
         }
 
-        // RFC 6265 prefers Max-Age to Expires but... (see below)
+        /*
+         *  RFC 6265 prefers Max-Age to Expires but some browsers including 
Microsoft IE and Microsoft Edge don't
+         *  understand Max-Age so send expires as well. Without this, 
persistent cookies fail with those browsers.
+         */
         int maxAge = cookie.getMaxAge();
-        if (maxAge > -1) {
-            // Negative Max-Age is equivalent to no Max-Age
-            header.append("; Max-Age=");
-            header.append(maxAge);
-
-            // Microsoft IE and Microsoft Edge don't understand Max-Age so send
-            // expires as well. Without this, persistent cookies fail with 
those
-            // browsers. See http://tomcat.markmail.org/thread/g6sipbofsjossacn
 
-            // Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format )
+        // Negative Max-Age is equivalent to no Max-Age
+        if (maxAge > -1) {
             header.append("; Expires=");
-            // To expire immediately we need to set the time in past
             if (maxAge == 0) {
+                // To expire immediately we need to set the time in past
                 header.append(ANCIENT_DATE);
             } else {
-                COOKIE_DATE_FORMAT.get().format(new 
Date(System.currentTimeMillis() + maxAge * 1000L), header,
-                        new FieldPosition(0));
+                COOKIE_DATE_FORMAT.get().format(
+                        new Date(System.currentTimeMillis() + maxAge * 1000L), 
header, new FieldPosition(0));
+
+                header.append("; Max-Age=");
+                header.append(maxAge);
             }
         }
 
+
         String domain = cookie.getDomain();
         if (domain != null && domain.length() > 0) {
             validateDomain(domain);
diff --git 
a/test/org/apache/tomcat/util/http/TestCookieProcessorGeneration.java 
b/test/org/apache/tomcat/util/http/TestCookieProcessorGeneration.java
index 3079f423f8..e56a5aa675 100644
--- a/test/org/apache/tomcat/util/http/TestCookieProcessorGeneration.java
+++ b/test/org/apache/tomcat/util/http/TestCookieProcessorGeneration.java
@@ -110,7 +110,7 @@ public class TestCookieProcessorGeneration {
 
     @Test
     public void testMaxAgeZero() {
-        doTestMaxAge(0, "foo=bar; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:10 
GMT");
+        doTestMaxAge(0, "foo=bar; Expires=Thu, 01 Jan 1970 00:00:10 GMT");
     }
 
     @Test
@@ -267,7 +267,16 @@ public class TestCookieProcessorGeneration {
                     cookie.getMaxAge() > 0) {
                 // Expires attribute will depend on time cookie is generated so
                 // use a modified test
-                Assert.assertTrue(cookieProcessor.generateHeader(cookie, 
null).startsWith(expected));
+                String result = cookieProcessor.generateHeader(cookie, null);
+                int posExpiresStart = result.indexOf("Expires");
+                if (posExpiresStart > -1) {
+                    int posExpiresEnd = result.indexOf(';', posExpiresStart);
+                    if (posExpiresEnd > -1) {
+                        // Expires was not at the end of the header - remove it
+                        result = result.substring(0, posExpiresStart -1) + 
result.substring(posExpiresEnd + 1);
+                    }
+                }
+                Assert.assertTrue(result.startsWith(expected));
             } else {
                 Assert.assertEquals(expected, 
cookieProcessor.generateHeader(cookie, null));
             }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index d8b9343f15..981ae76a04 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -141,6 +141,12 @@
         consistency with the recent changes to <code>Set-Cookie</code> header
         generation. (markt)
       </scode>
+      <fix>
+        Do not generate the <code>Max-Age</code> attribute for
+        <code>Set-Cookie</code> headers associated with cookies that have been
+        configured with a <code>Max-Age</code> value of zero as RFC 6265 does
+        not permit a value of zero in this case. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to