diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/PublicSuffixDomainFilter.java b/httpclient/src/main/java/org/apache/http/impl/cookie/PublicSuffixDomainFilter.java index 3e44ae89a..2cafcf11c 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/PublicSuffixDomainFilter.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/PublicSuffixDomainFilter.java @@ -26,6 +26,9 @@ */ package org.apache.http.impl.cookie; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import org.apache.http.annotation.Immutable; import org.apache.http.conn.util.PublicSuffixList; import org.apache.http.conn.util.PublicSuffixMatcher; @@ -52,11 +55,23 @@ public class PublicSuffixDomainFilter implements CommonCookieAttributeHandler { private final CommonCookieAttributeHandler handler; private final PublicSuffixMatcher publicSuffixMatcher; + private final Map localDomainMap; + + private static Map createLocalDomainMap() { + final ConcurrentHashMap map = new ConcurrentHashMap(); + map.put(".localhost.", Boolean.TRUE); // RFC 6761 + map.put(".test.", Boolean.TRUE); // RFC 6761 + map.put(".local.", Boolean.TRUE); // RFC 6762 + map.put(".local", Boolean.TRUE); + map.put(".localdomain", Boolean.TRUE); + return map; + } public PublicSuffixDomainFilter( final CommonCookieAttributeHandler handler, final PublicSuffixMatcher publicSuffixMatcher) { this.handler = Args.notNull(handler, "Cookie handler"); this.publicSuffixMatcher = Args.notNull(publicSuffixMatcher, "Public suffix matcher"); + this.localDomainMap = createLocalDomainMap(); } public PublicSuffixDomainFilter( @@ -65,6 +80,7 @@ public class PublicSuffixDomainFilter implements CommonCookieAttributeHandler { Args.notNull(suffixList, "Public suffix list"); this.handler = handler; this.publicSuffixMatcher = new PublicSuffixMatcher(suffixList.getRules(), suffixList.getExceptions()); + this.localDomainMap = createLocalDomainMap(); } /** @@ -72,12 +88,17 @@ public class PublicSuffixDomainFilter implements CommonCookieAttributeHandler { */ @Override public boolean match(final Cookie cookie, final CookieOrigin origin) { - final String domain = cookie.getDomain(); - if (!domain.equalsIgnoreCase("localhost") && publicSuffixMatcher.matches(domain)) { - return false; - } else { - return handler.match(cookie, origin); + final String host = cookie.getDomain(); + final int i = host.indexOf('.'); + if (i >= 0) { + final String domain = host.substring(i); + if (!this.localDomainMap.containsKey(domain)) { + if (this.publicSuffixMatcher.matches(host)) { + return false; + } + } } + return handler.match(cookie, origin); } @Override diff --git a/httpclient/src/test/java/org/apache/http/impl/cookie/TestPublicSuffixListParser.java b/httpclient/src/test/java/org/apache/http/impl/cookie/TestPublicSuffixListParser.java index 86dded928..50816ba2e 100644 --- a/httpclient/src/test/java/org/apache/http/impl/cookie/TestPublicSuffixListParser.java +++ b/httpclient/src/test/java/org/apache/http/impl/cookie/TestPublicSuffixListParser.java @@ -78,6 +78,32 @@ public class TestPublicSuffixListParser { Assert.assertTrue(filter.match(cookie, new CookieOrigin("apache.metro.tokyo.jp", 80, "/stuff", false))); } + @Test + public void testParseLocal() throws Exception { + final BasicClientCookie cookie = new BasicClientCookie("name", "value"); + + cookie.setDomain("localhost"); + Assert.assertTrue(filter.match(cookie, new CookieOrigin("localhost", 80, "/stuff", false))); + + cookie.setDomain("somehost"); + Assert.assertTrue(filter.match(cookie, new CookieOrigin("somehost", 80, "/stuff", false))); + + cookie.setDomain(".localdomain"); + Assert.assertTrue(filter.match(cookie, new CookieOrigin("somehost.localdomain", 80, "/stuff", false))); + + cookie.setDomain(".local."); + Assert.assertTrue(filter.match(cookie, new CookieOrigin("somehost.local.", 80, "/stuff", false))); + + cookie.setDomain(".localhost."); + Assert.assertTrue(filter.match(cookie, new CookieOrigin("somehost.localhost.", 80, "/stuff", false))); + + cookie.setDomain(".local"); + Assert.assertTrue(filter.match(cookie, new CookieOrigin("somehost.local", 80, "/stuff", false))); + + cookie.setDomain(".blah"); + Assert.assertFalse(filter.match(cookie, new CookieOrigin("somehost.blah", 80, "/stuff", false))); + } + @Test public void testUnicode() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value");