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: [email protected]
For additional commands, e-mail: [email protected]