Author: markt
Date: Thu Oct  2 11:15:04 2014
New Revision: 1628936

URL: http://svn.apache.org/r1628936
Log:
Add support for the remaining attributes to the RFC 6265 cookie generation

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties
    tomcat/trunk/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java
    
tomcat/trunk/test/org/apache/tomcat/util/http/TestCookieProcessorGeneration.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties?rev=1628936&r1=1628935&r2=1628936&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties Thu 
Oct  2 11:15:04 2014
@@ -30,3 +30,7 @@ cookies.invalidSpecial=Cookies: Unknown 
 cookies.fallToDebug=\n Note: further occurrences of Cookie errors will be 
logged at DEBUG level.
 
 headers.maxCountFail=More than the maximum allowed number of headers ([{0}]) 
were detected.
+
+rfc6265CookieProcessor.invalidCharInValue=An invalid character [{0}] was 
present in the Cookie value
+rfc6265CookieProcessor.invalidDomain=An invalid domain [{0}] was specified for 
this cookie
+rfc6265CookieProcessor.invalidPath=An invalid path [{0}] was specified for 
this cookie
\ No newline at end of file

Modified: 
tomcat/trunk/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java?rev=1628936&r1=1628935&r2=1628936&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java 
Thu Oct  2 11:15:04 2014
@@ -18,17 +18,39 @@ package org.apache.tomcat.util.http;
 
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
+import java.util.BitSet;
 
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.buf.MessageBytes;
 import org.apache.tomcat.util.http.parser.Cookie;
+import org.apache.tomcat.util.res.StringManager;
 
 public class Rfc6265CookieProcessor implements CookieProcessor {
 
     private static final Log log = 
LogFactory.getLog(Rfc6265CookieProcessor.class);
 
+    private static final StringManager sm =
+            
StringManager.getManager(Rfc6265CookieProcessor.class.getPackage().getName());
+
+    private static final BitSet domainValid = new BitSet(128);
+
+    static {
+        for (char c = '0'; c < '9'; c++) {
+            domainValid.set(c);
+        }
+        for (char c = 'a'; c < 'z'; c++) {
+            domainValid.set(c);
+        }
+        for (char c = 'A'; c < 'Z'; c++) {
+            domainValid.set(c);
+        }
+        domainValid.set('.');
+        domainValid.set('-');
+    }
+
+
     @Override
     public Charset getCharset() {
         return StandardCharsets.UTF_8;
@@ -82,7 +104,7 @@ public class Rfc6265CookieProcessor impl
         header.append(cookie.getName());
         header.append('=');
         String value = cookie.getValue();
-        if (value != null) {
+        if (value != null && value.length() > 0) {
             validateCookieValue(value);
             header.append(value);
         }
@@ -95,16 +117,33 @@ public class Rfc6265CookieProcessor impl
             header.append(maxAge);
         }
 
-        // TODO add support for the remaining attributes.
+        String domain = cookie.getDomain();
+        if (domain != null && domain.length() > 0) {
+            validateDomain(domain);
+            header.append(";domain=");
+            header.append(domain);
+        }
+
+        String path = cookie.getPath();
+        if (path != null && path.length() > 0) {
+            validatePath(path);
+            header.append(";path=");
+            header.append(path);
+        }
+
+        if (cookie.getSecure()) {
+            header.append(";Secure");
+        }
+
+        if (cookie.isHttpOnly()) {
+            header.append(";HttpOnly");
+        }
+
         return header.toString();
     }
 
 
     private void validateCookieValue(String value) {
-        if (value == null || value.length() == 0) {
-            return;
-        }
-
         int start = 0;
         int end = value.length();
 
@@ -117,8 +156,53 @@ public class Rfc6265CookieProcessor impl
         for (int i = start; i < end; i++) {
             char c = chars[i];
             if (c < 0x21 || c == 0x22 || c == 0x2c || c == 0x3b || c == 0x5c 
|| c == 0x7f) {
-                // TODO i18n
-                throw new IllegalArgumentException();
+                throw new IllegalArgumentException(sm.getString(
+                        "rfc6265CookieProcessor.invalidCharInValue", 
Integer.toString(c)));
+            }
+        }
+    }
+
+
+    private void validateDomain(String domain) {
+        int i = 0;
+        int prev = -1;
+        int cur = -1;
+        char[] chars = domain.toCharArray();
+        while (i < chars.length) {
+            prev = cur;
+            cur = chars[i];
+            if (!domainValid.get(cur)) {
+                throw new IllegalArgumentException(sm.getString(
+                        "rfc6265CookieProcessor.invalidDomain", domain));
+            }
+            // labels must start with a letter or number
+            if ((prev == '.' || prev == -1) && (cur == '.' || cur == '-')) {
+                throw new IllegalArgumentException(sm.getString(
+                        "rfc6265CookieProcessor.invalidDomain", domain));
+            }
+            // labels must end with a letter or number
+            if (prev == '-' && cur == '.') {
+                throw new IllegalArgumentException(sm.getString(
+                        "rfc6265CookieProcessor.invalidDomain", domain));
+            }
+            i++;
+        }
+        // domain must end with a label
+        if (cur == '.' || cur == '-') {
+            throw new IllegalArgumentException(sm.getString(
+                    "rfc6265CookieProcessor.invalidDomain", domain));
+        }
+    }
+
+
+    private void validatePath(String path) {
+        char[] chars = path.toCharArray();
+
+        for (int i = 0; i < chars.length; i++) {
+            char ch = chars[i];
+            if (ch < 0x20 || ch > 0x7E || ch == ';') {
+                throw new IllegalArgumentException(sm.getString(
+                        "rfc6265CookieProcessor.invalidPath", path));
             }
         }
     }

Modified: 
tomcat/trunk/test/org/apache/tomcat/util/http/TestCookieProcessorGeneration.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/TestCookieProcessorGeneration.java?rev=1628936&r1=1628935&r2=1628936&view=diff
==============================================================================
--- 
tomcat/trunk/test/org/apache/tomcat/util/http/TestCookieProcessorGeneration.java
 (original)
+++ 
tomcat/trunk/test/org/apache/tomcat/util/http/TestCookieProcessorGeneration.java
 Thu Oct  2 11:15:04 2014
@@ -190,6 +190,64 @@ public class TestCookieProcessorGenerati
         doV1TestMaxAge(-100, "foo=bar; Version=1", "foo=bar");
     }
 
+    @Test
+    public void v1TestDomainValid01() {
+        doV1TestDomain("example.com", "foo=bar; Version=1; Domain=example.com",
+                "foo=bar;domain=example.com");
+    }
+
+    @Test
+    public void v1TestDomainValid02() {
+        doV1TestDomain("exa-mple.com", "foo=bar; Version=1; 
Domain=exa-mple.com",
+                "foo=bar;domain=exa-mple.com");
+    }
+
+    @Test
+    public void v1TestDomainInvalid01() {
+        doV1TestDomain("example.com.", "foo=bar; Version=1; 
Domain=example.com.", null);
+    }
+
+    @Test
+    public void v1TestDomainInvalid02() {
+        doV1TestDomain("example.com-", "foo=bar; Version=1; 
Domain=example.com-", null);
+    }
+
+    @Test
+    public void v1TestDomainInvalid03() {
+        doV1TestDomain(".example.com.", "foo=bar; Version=1; 
Domain=.example.com.", null);
+    }
+
+    @Test
+    public void v1TestDomainInvalid04() {
+        doV1TestDomain("-example.com.", "foo=bar; Version=1; 
Domain=-example.com.", null);
+    }
+
+    @Test
+    public void v1TestDomainInvalid05() {
+        doV1TestDomain("example..com.", "foo=bar; Version=1; 
Domain=example..com.", null);
+    }
+
+    @Test
+    public void v1TestDomainInvalid06() {
+        doV1TestDomain("example-.com.", "foo=bar; Version=1; 
Domain=example-.com.", null);
+    }
+
+    @Test
+    public void v1TestDomainInvalid07() {
+        doV1TestDomain("exam$ple.com.", "foo=bar; Version=1; 
Domain=exam$ple.com.", null);
+    }
+
+    @Test
+    public void v1TestPathValid() {
+        doV1TestPath("/example", "foo=bar; Version=1; Path=/example",
+                "foo=bar;path=/example");
+    }
+
+    @Test
+    public void v1TestPathInvalid01() {
+        doV1TestPath("exa\tmple", "foo=bar; Version=1; Path=\"exa\tmple\"", 
null);
+    }
+
 
     private void doTest(Cookie cookie, String expected) {
         doTest(cookie, expected, expected);
@@ -247,4 +305,24 @@ public class TestCookieProcessorGenerati
         cookie.setMaxAge(age);
         doTest(cookie, legacy, expectedLegacy, new Rfc6265CookieProcessor(), 
expectedRfc6265);
     }
+
+
+    private void doV1TestDomain(String domain, String expectedLegacy, String 
expectedRfc6265) {
+        LegacyCookieProcessor legacy = new LegacyCookieProcessor();
+        legacy.setAlwaysAddExpires(false);
+        Cookie cookie = new Cookie("foo", "bar");
+        cookie.setVersion(1);
+        cookie.setDomain(domain);
+        doTest(cookie, legacy, expectedLegacy, new Rfc6265CookieProcessor(), 
expectedRfc6265);
+    }
+
+
+    private void doV1TestPath(String path, String expectedLegacy, String 
expectedRfc6265) {
+        LegacyCookieProcessor legacy = new LegacyCookieProcessor();
+        legacy.setAlwaysAddExpires(false);
+        Cookie cookie = new Cookie("foo", "bar");
+        cookie.setVersion(1);
+        cookie.setPath(path);
+        doTest(cookie, legacy, expectedLegacy, new Rfc6265CookieProcessor(), 
expectedRfc6265);
+    }
 }



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

Reply via email to