diff --git a/src/java/org/apache/http/cookie/impl/NetscapeDraftSpec.java b/src/java/org/apache/http/cookie/impl/NetscapeDraftSpec.java
index 0bf646d0f..847e2cf9f 100644
--- a/src/java/org/apache/http/cookie/impl/NetscapeDraftSpec.java
+++ b/src/java/org/apache/http/cookie/impl/NetscapeDraftSpec.java
@@ -5,7 +5,7 @@
*
* ====================================================================
*
- * Copyright 2002-2004 The Apache Software Foundation
+ * Copyright 2002-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ import org.apache.http.cookie.MalformedCookieException;
import org.apache.http.io.CharArrayBuffer;
/**
- * Netscape cookie draft specific cookie management functions
+ * Netscape cookie draft compliant cookie policy
*
* @author B.C. Holmes
* @author Park, Sung-Gu
diff --git a/src/java/org/apache/http/cookie/impl/RFC2109DomainHandler.java b/src/java/org/apache/http/cookie/impl/RFC2109DomainHandler.java
new file mode 100644
index 000000000..6c5931db1
--- /dev/null
+++ b/src/java/org/apache/http/cookie/impl/RFC2109DomainHandler.java
@@ -0,0 +1,122 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+package org.apache.http.cookie.impl;
+
+import org.apache.http.cookie.Cookie;
+import org.apache.http.cookie.CookieAttributeHandler;
+import org.apache.http.cookie.CookieOrigin;
+import org.apache.http.cookie.MalformedCookieException;
+
+public class RFC2109DomainHandler implements CookieAttributeHandler {
+
+ public RFC2109DomainHandler() {
+ super();
+ }
+
+ public void parse(final Cookie cookie, final String value)
+ throws MalformedCookieException {
+ if (cookie == null) {
+ throw new IllegalArgumentException("Cookie may not be null");
+ }
+ if (value == null) {
+ throw new MalformedCookieException("Missing value for domain attribute");
+ }
+ if (value.trim().equals("")) {
+ throw new MalformedCookieException("Blank value for domain attribute");
+ }
+ cookie.setDomain(value);
+ cookie.setDomainAttributeSpecified(true);
+ }
+
+ public void validate(final Cookie cookie, final CookieOrigin origin)
+ throws MalformedCookieException {
+ if (cookie == null) {
+ throw new IllegalArgumentException("Cookie may not be null");
+ }
+ if (origin == null) {
+ throw new IllegalArgumentException("Cookie origin may not be null");
+ }
+ String host = origin.getHost();
+ String domain = cookie.getDomain();
+ if (domain == null) {
+ throw new MalformedCookieException("Cookie domain may not be null");
+ }
+ if (!domain.equals(host)) {
+ int dotIndex = domain.indexOf('.');
+ if (dotIndex == -1) {
+ throw new MalformedCookieException("Domain attribute \""
+ + domain
+ + "\" does not match the host \""
+ + host + "\"");
+ }
+ // domain must start with dot
+ if (!domain.startsWith(".")) {
+ throw new MalformedCookieException("Domain attribute \""
+ + domain
+ + "\" violates RFC 2109: domain must start with a dot");
+ }
+ // domain must have at least one embedded dot
+ dotIndex = domain.indexOf('.', 1);
+ if (dotIndex < 0 || dotIndex == domain.length() - 1) {
+ throw new MalformedCookieException("Domain attribute \""
+ + domain
+ + "\" violates RFC 2109: domain must contain an embedded dot");
+ }
+ host = host.toLowerCase();
+ if (!host.endsWith(domain)) {
+ throw new MalformedCookieException(
+ "Illegal domain attribute \"" + domain
+ + "\". Domain of origin: \"" + host + "\"");
+ }
+ // host minus domain may not contain any dots
+ String hostWithoutDomain = host.substring(0, host.length() - domain.length());
+ if (hostWithoutDomain.indexOf('.') != -1) {
+ throw new MalformedCookieException("Domain attribute \""
+ + domain
+ + "\" violates RFC 2109: host minus domain may not contain any dots");
+ }
+ }
+ }
+
+ public boolean match(final Cookie cookie, final CookieOrigin origin) {
+ if (cookie == null) {
+ throw new IllegalArgumentException("Cookie may not be null");
+ }
+ if (origin == null) {
+ throw new IllegalArgumentException("Cookie origin may not be null");
+ }
+ String host = origin.getHost();
+ String domain = cookie.getDomain();
+ if (domain == null) {
+ return false;
+ }
+ return host.equals(domain) || (domain.startsWith(".") && host.endsWith(domain));
+ }
+
+}
\ No newline at end of file
diff --git a/src/java/org/apache/http/cookie/impl/RFC2109VersionHandler.java b/src/java/org/apache/http/cookie/impl/RFC2109VersionHandler.java
new file mode 100644
index 000000000..3d80068fe
--- /dev/null
+++ b/src/java/org/apache/http/cookie/impl/RFC2109VersionHandler.java
@@ -0,0 +1,70 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+package org.apache.http.cookie.impl;
+
+import org.apache.http.cookie.Cookie;
+import org.apache.http.cookie.CookieOrigin;
+import org.apache.http.cookie.MalformedCookieException;
+
+public class RFC2109VersionHandler extends AbstractCookieAttributeHandler {
+
+ public RFC2109VersionHandler() {
+ super();
+ }
+
+ public void parse(final Cookie cookie, final String value)
+ throws MalformedCookieException {
+ if (cookie == null) {
+ throw new IllegalArgumentException("Cookie may not be null");
+ }
+ if (value == null) {
+ throw new MalformedCookieException("Missing value for version attribute");
+ }
+ if (value.trim().equals("")) {
+ throw new MalformedCookieException("Blank value for version attribute");
+ }
+ try {
+ cookie.setVersion(Integer.parseInt(value));
+ } catch (NumberFormatException e) {
+ throw new MalformedCookieException("Invalid version: "
+ + e.getMessage());
+ }
+ }
+
+ public void validate(final Cookie cookie, final CookieOrigin origin)
+ throws MalformedCookieException {
+ if (cookie == null) {
+ throw new IllegalArgumentException("Cookie may not be null");
+ }
+ if (cookie.getVersion() < 0) {
+ throw new MalformedCookieException("Cookie version may not be negative");
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/org/apache/http/cookie/impl/TestAllCookieImpl.java b/src/test/org/apache/http/cookie/impl/TestAllCookieImpl.java
index b87f9e4a7..4881d12f4 100644
--- a/src/test/org/apache/http/cookie/impl/TestAllCookieImpl.java
+++ b/src/test/org/apache/http/cookie/impl/TestAllCookieImpl.java
@@ -41,6 +41,7 @@ public class TestAllCookieImpl extends TestCase {
suite.addTest(TestAbstractCookieSpec.suite());
suite.addTest(TestBasicCookieAttribHandlers.suite());
suite.addTest(TestNetscapeCookieAttribHandlers.suite());
+ suite.addTest(TestRFC2109CookieAttribHandlers.suite());
suite.addTest(TestBrowserCompatSpec.suite());
suite.addTest(TestCookieNetscapeDraft.suite());
return suite;
diff --git a/src/test/org/apache/http/cookie/impl/TestNetscapeCookieAttribHandlers.java b/src/test/org/apache/http/cookie/impl/TestNetscapeCookieAttribHandlers.java
index 2f5f17b24..f1f43405d 100644
--- a/src/test/org/apache/http/cookie/impl/TestNetscapeCookieAttribHandlers.java
+++ b/src/test/org/apache/http/cookie/impl/TestNetscapeCookieAttribHandlers.java
@@ -4,7 +4,7 @@
* $Date$
* ====================================================================
*
- * Copyright 2002-2004 The Apache Software Foundation
+ * Copyright 2002-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -149,7 +149,7 @@ public class TestNetscapeCookieAttribHandlers extends TestCase {
assertTrue(h.match(cookie, origin));
}
- public void testBrowserCompatDomainInvalidInput() throws Exception {
+ public void testNetscapeDomainInvalidInput() throws Exception {
CookieAttributeHandler h = new NetscapeDomainHandler();
try {
h.match(null, null);
diff --git a/src/test/org/apache/http/cookie/impl/TestRFC2109CookieAttribHandlers.java b/src/test/org/apache/http/cookie/impl/TestRFC2109CookieAttribHandlers.java
new file mode 100644
index 000000000..5e5b75e9a
--- /dev/null
+++ b/src/test/org/apache/http/cookie/impl/TestRFC2109CookieAttribHandlers.java
@@ -0,0 +1,302 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ * ====================================================================
+ *
+ * Copyright 2002-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.http.cookie.impl;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.http.cookie.Cookie;
+import org.apache.http.cookie.CookieAttributeHandler;
+import org.apache.http.cookie.CookieOrigin;
+import org.apache.http.cookie.MalformedCookieException;
+
+public class TestRFC2109CookieAttribHandlers extends TestCase {
+
+ public TestRFC2109CookieAttribHandlers(String testName) {
+ super(testName);
+ }
+
+ public static Test suite() {
+ return new TestSuite(TestRFC2109CookieAttribHandlers.class);
+ }
+
+ // ------------------------------------------------------------------- Main
+ public static void main(String args[]) {
+ String[] testCaseName = { TestRFC2109CookieAttribHandlers.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ public void testRFC2109DomainParse() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+
+ h.parse(cookie, "somehost");
+ assertEquals("somehost", cookie.getDomain());
+
+ try {
+ h.parse(cookie, null);
+ fail("MalformedCookieException should have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ try {
+ h.parse(cookie, " ");
+ fail("MalformedCookieException should have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ }
+
+ public void testRFC2109DomainValidate1() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieOrigin origin = new CookieOrigin("somehost", 80, "/", false);
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+
+ cookie.setDomain("somehost");
+ h.validate(cookie, origin);
+
+ cookie.setDomain("otherhost");
+ try {
+ h.validate(cookie, origin);
+ fail("MalformedCookieException should have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ cookie.setDomain(null);
+ try {
+ h.validate(cookie, origin);
+ fail("MalformedCookieException should have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ }
+
+ public void testRFC2109DomainValidate2() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false);
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+
+ cookie.setDomain(".somedomain.com");
+ h.validate(cookie, origin);
+
+ cookie.setDomain(".otherdomain.com");
+ try {
+ h.validate(cookie, origin);
+ fail("MalformedCookieException should have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ cookie.setDomain("www.otherdomain.com");
+ try {
+ h.validate(cookie, origin);
+ fail("MalformedCookieException should have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ }
+
+ public void testRFC2109DomainValidate3() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieOrigin origin = new CookieOrigin("www.a.com", 80, "/", false);
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+
+ cookie.setDomain(".a.com");
+ h.validate(cookie, origin);
+
+ cookie.setDomain(".com");
+ try {
+ h.validate(cookie, origin);
+ fail("MalformedCookieException should have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ }
+
+ public void testRFC2109DomainValidate4() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieOrigin origin = new CookieOrigin("www.a.b.c", 80, "/", false);
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+
+ cookie.setDomain(".a.b.c");
+ h.validate(cookie, origin);
+
+ cookie.setDomain(".b.c");
+ try {
+ h.validate(cookie, origin);
+ fail("MalformedCookieException should have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ cookie.setDomain(".a.a.b.c");
+ try {
+ h.validate(cookie, origin);
+ fail("MalformedCookieException should have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ }
+
+ public void testRFC2109DomainMatch1() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false);
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+
+ cookie.setDomain(null);
+ assertFalse(h.match(cookie, origin));
+
+ cookie.setDomain(".somedomain.com");
+ assertTrue(h.match(cookie, origin));
+ }
+
+ public void testRFC2109DomainMatch2() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieOrigin origin = new CookieOrigin("www.whatever.somedomain.com", 80, "/", false);
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+
+ cookie.setDomain(".somedomain.com");
+ assertTrue(h.match(cookie, origin));
+ }
+
+ public void testRFC2109DomainMatch3() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false);
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+
+ cookie.setDomain("somedomain.com");
+ assertTrue(h.match(cookie, origin));
+ }
+
+ public void testRFC2109DomainMatch4() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false);
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+
+ cookie.setDomain("somedomain.com");
+ assertFalse(h.match(cookie, origin));
+ }
+
+ public void testRFC2109DomainInvalidInput() throws Exception {
+ CookieAttributeHandler h = new RFC2109DomainHandler();
+ try {
+ h.parse(null, null);
+ fail("IllegalArgumentException must have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ h.validate(null, null);
+ fail("IllegalArgumentException must have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ h.validate(new Cookie("name", "value"), null);
+ fail("IllegalArgumentException must have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ h.match(null, null);
+ fail("IllegalArgumentException must have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ h.match(new Cookie("name", "value"), null);
+ fail("IllegalArgumentException must have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+
+ public void testRFC2109VersionParse() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieAttributeHandler h = new RFC2109VersionHandler();
+ h.parse(cookie, "12");
+ assertEquals(12, cookie.getVersion());
+ }
+
+ public void testRFC2109VersionParseInvalid() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieAttributeHandler h = new RFC2109VersionHandler();
+ try {
+ h.parse(cookie, "garbage");
+ fail("MalformedCookieException must have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ try {
+ h.parse(cookie, null);
+ fail("MalformedCookieException must have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ try {
+ h.parse(cookie, " ");
+ fail("MalformedCookieException must have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ }
+
+ public void testRFC2109VersionValidate() throws Exception {
+ Cookie cookie = new Cookie("name", "value");
+ CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false);
+ CookieAttributeHandler h = new RFC2109VersionHandler();
+
+ cookie.setVersion(12);
+ h.validate(cookie, origin);
+
+ cookie.setVersion(-12);
+ try {
+ h.validate(cookie, origin);
+ fail("MalformedCookieException must have been thrown");
+ } catch (MalformedCookieException ex) {
+ // expected
+ }
+ }
+
+ public void testRFC2109VersionInvalidInput() throws Exception {
+ CookieAttributeHandler h = new RFC2109VersionHandler();
+ try {
+ h.parse(null, null);
+ fail("IllegalArgumentException must have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ h.validate(null, null);
+ fail("IllegalArgumentException must have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+
+}
\ No newline at end of file