From 243c862a032b9047e959f1edb3cd6fa036c93f35 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Tue, 26 Aug 2014 14:37:36 +0000 Subject: [PATCH] Made all cookie spec implementations thread safe git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1620612 13f79535-47bb-0310-9956-ffa450edef68 --- .../cookie/CommonCookieAttributeHandler.java | 40 ++++++++++ .../http/impl/cookie/AbstractCookieSpec.java | 44 ++++++++--- .../http/impl/cookie/BasicCommentHandler.java | 9 ++- .../http/impl/cookie/BasicDomainHandler.java | 10 ++- .../http/impl/cookie/BasicExpiresHandler.java | 9 ++- .../http/impl/cookie/BasicMaxAgeHandler.java | 9 ++- .../http/impl/cookie/BasicPathHandler.java | 10 ++- .../http/impl/cookie/BasicSecureHandler.java | 9 ++- .../http/impl/cookie/BestMatchSpec.java | 74 +++++++------------ .../http/impl/cookie/BrowserCompatSpec.java | 50 ++++--------- .../BrowserCompatVersionAttributeHandler.java | 9 ++- .../http/impl/cookie/CookieSpecBase.java | 25 ++++++- .../apache/http/impl/cookie/IgnoreSpec.java | 4 +- .../http/impl/cookie/NetscapeDraftSpec.java | 36 ++++----- .../impl/cookie/NetscapeDraftSpecFactory.java | 4 + .../impl/cookie/RFC2109DomainHandler.java | 10 ++- .../apache/http/impl/cookie/RFC2109Spec.java | 36 ++++----- .../impl/cookie/RFC2109VersionHandler.java | 9 ++- .../RFC2965CommentUrlAttributeHandler.java | 12 ++- .../RFC2965DiscardAttributeHandler.java | 12 ++- .../cookie/RFC2965DomainAttributeHandler.java | 9 ++- .../cookie/RFC2965PortAttributeHandler.java | 9 ++- .../apache/http/impl/cookie/RFC2965Spec.java | 22 ++++-- .../RFC2965VersionAttributeHandler.java | 9 ++- 24 files changed, 303 insertions(+), 167 deletions(-) create mode 100644 httpclient/src/main/java/org/apache/http/cookie/CommonCookieAttributeHandler.java diff --git a/httpclient/src/main/java/org/apache/http/cookie/CommonCookieAttributeHandler.java b/httpclient/src/main/java/org/apache/http/cookie/CommonCookieAttributeHandler.java new file mode 100644 index 000000000..d82f7afc4 --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/cookie/CommonCookieAttributeHandler.java @@ -0,0 +1,40 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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; + +/** + * Extension of {@link org.apache.http.cookie.CookieAttributeHandler} intended + * to handle one specific common attribute whose name is returned with + * {@link #getAttributeName()} method. + * + * @since 4.4 + */ +public interface CommonCookieAttributeHandler extends CookieAttributeHandler { + + String getAttributeName(); + +} diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.java b/httpclient/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.java index dd8be9c81..054ee90d1 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.java @@ -30,11 +30,14 @@ package org.apache.http.impl.cookie; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; -import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieSpec; import org.apache.http.util.Args; +import org.apache.http.util.Asserts; /** * Abstract cookie specification which can delegate the job of parsing, @@ -44,7 +47,7 @@ import org.apache.http.util.Args; * * @since 4.0 */ -@NotThreadSafe // HashMap is not thread-safe +@ThreadSafe public abstract class AbstractCookieSpec implements CookieSpec { /** @@ -57,9 +60,35 @@ public abstract class AbstractCookieSpec implements CookieSpec { * */ public AbstractCookieSpec() { super(); - this.attribHandlerMap = new HashMap(10); + this.attribHandlerMap = new ConcurrentHashMap(10); } + /** + * @since 4.4 + */ + protected AbstractCookieSpec(final HashMap map) { + super(); + Asserts.notNull(map, "Attribute handler map"); + this.attribHandlerMap = new ConcurrentHashMap(map); + } + + /** + * @since 4.4 + */ + protected AbstractCookieSpec(final CommonCookieAttributeHandler... handlers) { + super(); + this.attribHandlerMap = new ConcurrentHashMap(handlers.length); + for (CommonCookieAttributeHandler handler: handlers) { + this.attribHandlerMap.put(handler.getAttributeName(), handler); + } + } + + /** + * @deprecated (4.4) use {@link #AbstractCookieSpec(java.util.HashMap)} or + * {@link #AbstractCookieSpec(org.apache.http.cookie.CommonCookieAttributeHandler...)} + * constructors instead. + */ + @Deprecated public void registerAttribHandler( final String name, final CookieAttributeHandler handler) { Args.notNull(name, "Attribute name"); @@ -89,12 +118,9 @@ public abstract class AbstractCookieSpec implements CookieSpec { */ protected CookieAttributeHandler getAttribHandler(final String name) { final CookieAttributeHandler handler = findAttribHandler(name); - if (handler == null) { - throw new IllegalStateException("Handler not registered for " + - name + " attribute."); - } else { - return handler; - } + Asserts.check(handler != null, "Handler not registered for " + + name + " attribute"); + return handler; } protected Collection getAttribHandlers() { diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicCommentHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicCommentHandler.java index 8ee660829..14c9cfe59 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicCommentHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicCommentHandler.java @@ -27,6 +27,8 @@ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; @@ -36,7 +38,7 @@ import org.apache.http.util.Args; * @since 4.0 */ @Immutable -public class BasicCommentHandler extends AbstractCookieAttributeHandler { +public class BasicCommentHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler { public BasicCommentHandler() { super(); @@ -49,4 +51,9 @@ public class BasicCommentHandler extends AbstractCookieAttributeHandler { cookie.setComment(value); } + @Override + public String getAttributeName() { + return ClientCookie.COMMENT_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicDomainHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicDomainHandler.java index 74444364f..6f77006bf 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicDomainHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicDomainHandler.java @@ -27,8 +27,9 @@ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; @@ -40,7 +41,7 @@ import org.apache.http.util.Args; * @since 4.0 */ @Immutable -public class BasicDomainHandler implements CookieAttributeHandler { +public class BasicDomainHandler implements CommonCookieAttributeHandler { public BasicDomainHandler() { super(); @@ -116,4 +117,9 @@ public class BasicDomainHandler implements CookieAttributeHandler { return host.endsWith(domain) || host.equals(domain.substring(1)); } + @Override + public String getAttributeName() { + return ClientCookie.DOMAIN_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicExpiresHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicExpiresHandler.java index 618fadb3a..42450d593 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicExpiresHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicExpiresHandler.java @@ -30,6 +30,8 @@ import java.util.Date; import org.apache.http.annotation.Immutable; import org.apache.http.client.utils.DateUtils; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; @@ -39,7 +41,7 @@ import org.apache.http.util.Args; * @since 4.0 */ @Immutable -public class BasicExpiresHandler extends AbstractCookieAttributeHandler { +public class BasicExpiresHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler { /** Valid date patterns */ private final String[] datepatterns; @@ -64,4 +66,9 @@ public class BasicExpiresHandler extends AbstractCookieAttributeHandler { cookie.setExpiryDate(expiry); } + @Override + public String getAttributeName() { + return ClientCookie.EXPIRES_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.java index 22a12b11b..db28aa88d 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.java @@ -29,6 +29,8 @@ package org.apache.http.impl.cookie; import java.util.Date; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; @@ -38,7 +40,7 @@ import org.apache.http.util.Args; * @since 4.0 */ @Immutable -public class BasicMaxAgeHandler extends AbstractCookieAttributeHandler { +public class BasicMaxAgeHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler { public BasicMaxAgeHandler() { super(); @@ -65,4 +67,9 @@ public class BasicMaxAgeHandler extends AbstractCookieAttributeHandler { cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L)); } + @Override + public String getAttributeName() { + return ClientCookie.MAX_AGE_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicPathHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicPathHandler.java index 093837ae5..4f10e47c0 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicPathHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicPathHandler.java @@ -27,8 +27,9 @@ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; @@ -41,7 +42,7 @@ import org.apache.http.util.TextUtils; * @since 4.0 */ @Immutable -public class BasicPathHandler implements CookieAttributeHandler { +public class BasicPathHandler implements CommonCookieAttributeHandler { public BasicPathHandler() { super(); @@ -87,4 +88,9 @@ public class BasicPathHandler implements CookieAttributeHandler { return match; } + @Override + public String getAttributeName() { + return ClientCookie.PATH_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicSecureHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicSecureHandler.java index 678c22fb1..5b8f55cc8 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/BasicSecureHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/BasicSecureHandler.java @@ -27,6 +27,8 @@ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; @@ -38,7 +40,7 @@ import org.apache.http.util.Args; * @since 4.0 */ @Immutable -public class BasicSecureHandler extends AbstractCookieAttributeHandler { +public class BasicSecureHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler { public BasicSecureHandler() { super(); @@ -58,4 +60,9 @@ public class BasicSecureHandler extends AbstractCookieAttributeHandler { return !cookie.isSecure() || origin.isSecure(); } + @Override + public String getAttributeName() { + return ClientCookie.SECURE_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/BestMatchSpec.java b/httpclient/src/main/java/org/apache/http/impl/cookie/BestMatchSpec.java index bb8a9b171..d2284ffda 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/BestMatchSpec.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/BestMatchSpec.java @@ -32,7 +32,7 @@ import java.util.List; import org.apache.http.FormattedHeader; import org.apache.http.Header; import org.apache.http.HeaderElement; -import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.annotation.ThreadSafe; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; @@ -49,48 +49,30 @@ import org.apache.http.util.CharArrayBuffer; * * @since 4.0 */ -@NotThreadSafe // CookieSpec fields are @NotThreadSafe +@ThreadSafe public class BestMatchSpec implements CookieSpec { - private final String[] datepatterns; - private final boolean oneHeader; - - // Cached values of CookieSpec instances - private RFC2965Spec strict; // @NotThreadSafe - private RFC2109Spec obsoleteStrict; // @NotThreadSafe - private NetscapeDraftSpec netscape; // @NotThreadSafe + private final RFC2965Spec strict; + private final RFC2109Spec obsoleteStrict; + private final NetscapeDraftSpec netscapeDraft; public BestMatchSpec(final String[] datepatterns, final boolean oneHeader) { super(); - this.datepatterns = datepatterns == null ? null : datepatterns.clone(); - this.oneHeader = oneHeader; + this.strict = new RFC2965Spec(datepatterns, oneHeader); + this.obsoleteStrict = new RFC2109Spec(datepatterns, oneHeader); + this.netscapeDraft = new NetscapeDraftSpec( + new BasicDomainHandler(), + new BasicPathHandler(), + new BasicSecureHandler(), + new BasicCommentHandler(), + new BasicExpiresHandler( + datepatterns != null ? datepatterns.clone() : new String[]{NetscapeDraftSpec.EXPIRES_PATTERN})); } public BestMatchSpec() { this(null, false); } - private RFC2965Spec getStrict() { - if (this.strict == null) { - this.strict = new RFC2965Spec(this.datepatterns, this.oneHeader); - } - return strict; - } - - private RFC2109Spec getObsoleteStrict() { - if (this.obsoleteStrict == null) { - this.obsoleteStrict = new RFC2109Spec(this.datepatterns, this.oneHeader); - } - return obsoleteStrict; - } - - private NetscapeDraftSpec getNetscapeCompat() { - if (this.netscape == null) { - this.netscape = new NetscapeDraftSpec(false, this.datepatterns); - } - return netscape; - } - @Override public List parse( final Header header, @@ -129,12 +111,12 @@ public class BestMatchSpec implements CookieSpec { cursor = new ParserCursor(0, buffer.length()); } helems = new HeaderElement[] { parser.parseHeader(buffer, cursor) }; - return getNetscapeCompat().parse(helems, origin); + return netscapeDraft.parse(helems, origin); } else { if (SM.SET_COOKIE2.equals(header.getName())) { - return getStrict().parse(helems, origin); + return strict.parse(helems, origin); } else { - return getObsoleteStrict().parse(helems, origin); + return obsoleteStrict.parse(helems, origin); } } } @@ -147,12 +129,12 @@ public class BestMatchSpec implements CookieSpec { Args.notNull(origin, "Cookie origin"); if (cookie.getVersion() > 0) { if (cookie instanceof SetCookie2) { - getStrict().validate(cookie, origin); + strict.validate(cookie, origin); } else { - getObsoleteStrict().validate(cookie, origin); + obsoleteStrict.validate(cookie, origin); } } else { - getNetscapeCompat().validate(cookie, origin); + netscapeDraft.validate(cookie, origin); } } @@ -162,12 +144,12 @@ public class BestMatchSpec implements CookieSpec { Args.notNull(origin, "Cookie origin"); if (cookie.getVersion() > 0) { if (cookie instanceof SetCookie2) { - return getStrict().match(cookie, origin); + return strict.match(cookie, origin); } else { - return getObsoleteStrict().match(cookie, origin); + return obsoleteStrict.match(cookie, origin); } } else { - return getNetscapeCompat().match(cookie, origin); + return netscapeDraft.match(cookie, origin); } } @@ -186,23 +168,23 @@ public class BestMatchSpec implements CookieSpec { } if (version > 0) { if (isSetCookie2) { - return getStrict().formatCookies(cookies); + return strict.formatCookies(cookies); } else { - return getObsoleteStrict().formatCookies(cookies); + return obsoleteStrict.formatCookies(cookies); } } else { - return getNetscapeCompat().formatCookies(cookies); + return netscapeDraft.formatCookies(cookies); } } @Override public int getVersion() { - return getStrict().getVersion(); + return strict.getVersion(); } @Override public Header getVersionHeader() { - return getStrict().getVersionHeader(); + return strict.getVersionHeader(); } @Override diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpec.java b/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpec.java index 018d5b982..96573fe60 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpec.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpec.java @@ -36,9 +36,8 @@ import org.apache.http.FormattedHeader; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.NameValuePair; -import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.utils.DateUtils; -import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; @@ -60,7 +59,7 @@ import org.apache.http.util.CharArrayBuffer; * * @since 4.0 */ -@NotThreadSafe // superclass is @NotThreadSafe +@ThreadSafe public class BrowserCompatSpec extends CookieSpecBase { @@ -81,40 +80,21 @@ public class BrowserCompatSpec extends CookieSpecBase { "EEE, dd-MM-yyyy HH:mm:ss z", }; - private final String[] datepatterns; - /** Default constructor */ public BrowserCompatSpec(final String[] datepatterns, final BrowserCompatSpecFactory.SecurityLevel securityLevel) { - super(); - if (datepatterns != null) { - this.datepatterns = datepatterns.clone(); - } else { - this.datepatterns = DEFAULT_DATE_PATTERNS; - } - switch (securityLevel) { - case SECURITYLEVEL_DEFAULT: - registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); - break; - case SECURITYLEVEL_IE_MEDIUM: - registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler() { - @Override - public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { - // No validation - } - } - ); - break; - default: - throw new RuntimeException("Unknown security level"); - } - - registerAttribHandler(ClientCookie.DOMAIN_ATTR, new BasicDomainHandler()); - registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); - registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); - registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); - registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( - this.datepatterns)); - registerAttribHandler(ClientCookie.VERSION_ATTR, new BrowserCompatVersionAttributeHandler()); + super(new BrowserCompatVersionAttributeHandler(), + new BasicDomainHandler(), + securityLevel == BrowserCompatSpecFactory.SecurityLevel.SECURITYLEVEL_IE_MEDIUM ? + new BasicPathHandler() { + @Override + public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { + // No validation + } + } : new BasicPathHandler(), + new BasicMaxAgeHandler(), + new BasicSecureHandler(), + new BasicCommentHandler(), + new BasicExpiresHandler(datepatterns != null ? datepatterns.clone() : DEFAULT_DATE_PATTERNS)); } /** Default constructor */ diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatVersionAttributeHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatVersionAttributeHandler.java index dbf9a42b6..02ab8a887 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatVersionAttributeHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatVersionAttributeHandler.java @@ -28,6 +28,8 @@ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; @@ -39,7 +41,7 @@ import org.apache.http.util.Args; */ @Immutable public class BrowserCompatVersionAttributeHandler extends - AbstractCookieAttributeHandler { + AbstractCookieAttributeHandler implements CommonCookieAttributeHandler { public BrowserCompatVersionAttributeHandler() { super(); @@ -64,4 +66,9 @@ public class BrowserCompatVersionAttributeHandler extends cookie.setVersion(version); } + @Override + public String getAttributeName() { + return ClientCookie.VERSION_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/CookieSpecBase.java b/httpclient/src/main/java/org/apache/http/impl/cookie/CookieSpecBase.java index c0329e0ae..32730d25b 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/CookieSpecBase.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/CookieSpecBase.java @@ -28,12 +28,14 @@ package org.apache.http.impl.cookie; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Locale; import org.apache.http.HeaderElement; import org.apache.http.NameValuePair; -import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; @@ -43,12 +45,29 @@ import org.apache.http.util.Args; /** * Cookie management functions shared by all specification. * - * * @since 4.0 */ -@NotThreadSafe // AbstractCookieSpec is not thread-safe +@ThreadSafe public abstract class CookieSpecBase extends AbstractCookieSpec { + public CookieSpecBase() { + super(); + } + + /** + * @since 4.4 + */ + protected CookieSpecBase(final HashMap map) { + super(map); + } + + /** + * @since 4.4 + */ + protected CookieSpecBase(final CommonCookieAttributeHandler... handlers) { + super(handlers); + } + protected static String getDefaultPath(final CookieOrigin origin) { String defaultPath = origin.getPath(); int lastSlashIndex = defaultPath.lastIndexOf('/'); diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/IgnoreSpec.java b/httpclient/src/main/java/org/apache/http/impl/cookie/IgnoreSpec.java index 7954cb33e..a6cd4f2e5 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/IgnoreSpec.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/IgnoreSpec.java @@ -31,7 +31,7 @@ import java.util.Collections; import java.util.List; import org.apache.http.Header; -import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.annotation.ThreadSafe; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; @@ -41,7 +41,7 @@ import org.apache.http.cookie.MalformedCookieException; * * @since 4.1 */ -@NotThreadSafe // superclass is @NotThreadSafe +@ThreadSafe public class IgnoreSpec extends CookieSpecBase { @Override diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpec.java b/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpec.java index b5b6275b7..cebf17456 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpec.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpec.java @@ -33,8 +33,8 @@ import java.util.List; import org.apache.http.FormattedHeader; import org.apache.http.Header; import org.apache.http.HeaderElement; -import org.apache.http.annotation.NotThreadSafe; -import org.apache.http.cookie.ClientCookie; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; @@ -52,35 +52,27 @@ import org.apache.http.util.CharArrayBuffer; * * @since 4.0 */ -@NotThreadSafe // superclass is @NotThreadSafe +@ThreadSafe public class NetscapeDraftSpec extends CookieSpecBase { protected static final String EXPIRES_PATTERN = "EEE, dd-MMM-yy HH:mm:ss z"; - private final String[] datepatterns; - - NetscapeDraftSpec(final boolean strictDomainValidation, final String[] datepatterns) { - super(); - if (datepatterns != null) { - this.datepatterns = datepatterns.clone(); - } else { - this.datepatterns = new String[] { EXPIRES_PATTERN }; - } - registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); - registerAttribHandler(ClientCookie.DOMAIN_ATTR, - strictDomainValidation ? new NetscapeDomainHandler() : new BasicDomainHandler()); - registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); - registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); - registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( - this.datepatterns)); + /** Default constructor */ + public NetscapeDraftSpec(final String[] datepatterns) { + super(new BasicPathHandler(), + new NetscapeDomainHandler(), + new BasicSecureHandler(), + new BasicCommentHandler(), + new BasicExpiresHandler( + datepatterns != null ? datepatterns.clone() : new String[]{EXPIRES_PATTERN})); } - public NetscapeDraftSpec(final String[] datepatterns) { - this(true, datepatterns); + NetscapeDraftSpec(final CommonCookieAttributeHandler... handlers) { + super(handlers); } public NetscapeDraftSpec() { - this(null); + this((String[]) null); } /** diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpecFactory.java b/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpecFactory.java index c94074239..4b516c594 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpecFactory.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpecFactory.java @@ -77,6 +77,10 @@ public class NetscapeDraftSpecFactory implements CookieSpecFactory, CookieSpecPr @Override public CookieSpec create(final HttpContext context) { + + + + return new NetscapeDraftSpec(this.datepatterns); } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109DomainHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109DomainHandler.java index f4988b247..fdbeb1532 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109DomainHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109DomainHandler.java @@ -29,8 +29,9 @@ package org.apache.http.impl.cookie; import java.util.Locale; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; @@ -42,7 +43,7 @@ import org.apache.http.util.Args; * @since 4.0 */ @Immutable -public class RFC2109DomainHandler implements CookieAttributeHandler { +public class RFC2109DomainHandler implements CommonCookieAttributeHandler { public RFC2109DomainHandler() { super(); @@ -120,4 +121,9 @@ public class RFC2109DomainHandler implements CookieAttributeHandler { return host.equals(domain) || (domain.startsWith(".") && host.endsWith(domain)); } + @Override + public String getAttributeName() { + return ClientCookie.DOMAIN_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java index 4b8b082bd..581db54ca 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java @@ -33,9 +33,10 @@ import java.util.List; import org.apache.http.Header; import org.apache.http.HeaderElement; -import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.utils.DateUtils; import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookiePathComparator; @@ -55,37 +56,30 @@ import org.apache.http.util.CharArrayBuffer; * * @since 4.0 */ -@NotThreadSafe // superclass is @NotThreadSafe +@ThreadSafe public class RFC2109Spec extends CookieSpecBase { private final static CookiePathComparator PATH_COMPARATOR = new CookiePathComparator(); - private final static String[] DATE_PATTERNS = { + final static String[] DATE_PATTERNS = { DateUtils.PATTERN_RFC1123, DateUtils.PATTERN_RFC1036, DateUtils.PATTERN_ASCTIME }; - private final String[] datepatterns; private final boolean oneHeader; /** Default constructor */ public RFC2109Spec(final String[] datepatterns, final boolean oneHeader) { - super(); - if (datepatterns != null) { - this.datepatterns = datepatterns.clone(); - } else { - this.datepatterns = DATE_PATTERNS; - } + super(new RFC2109VersionHandler(), + new BasicPathHandler(), + new RFC2109DomainHandler(), + new BasicMaxAgeHandler(), + new BasicSecureHandler(), + new BasicCommentHandler(), + new BasicExpiresHandler( + datepatterns != null ? datepatterns.clone() : DATE_PATTERNS)); this.oneHeader = oneHeader; - registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2109VersionHandler()); - registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); - registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2109DomainHandler()); - registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); - registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); - registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); - registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( - this.datepatterns)); } /** Default constructor */ @@ -93,6 +87,12 @@ public class RFC2109Spec extends CookieSpecBase { this(null, false); } + protected RFC2109Spec(final boolean oneHeader, + final CommonCookieAttributeHandler... handlers) { + super(handlers); + this.oneHeader = oneHeader; + } + @Override public List parse(final Header header, final CookieOrigin origin) throws MalformedCookieException { diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109VersionHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109VersionHandler.java index 2abcd0e60..a342e851a 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109VersionHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109VersionHandler.java @@ -27,6 +27,8 @@ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; @@ -39,7 +41,7 @@ import org.apache.http.util.Args; * @since 4.0 */ @Immutable -public class RFC2109VersionHandler extends AbstractCookieAttributeHandler { +public class RFC2109VersionHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler { public RFC2109VersionHandler() { super(); @@ -72,4 +74,9 @@ public class RFC2109VersionHandler extends AbstractCookieAttributeHandler { } } + @Override + public String getAttributeName() { + return ClientCookie.VERSION_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965CommentUrlAttributeHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965CommentUrlAttributeHandler.java index fca2a5d9e..dd739bce5 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965CommentUrlAttributeHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965CommentUrlAttributeHandler.java @@ -28,8 +28,9 @@ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; @@ -41,7 +42,7 @@ import org.apache.http.cookie.SetCookie2; * @since 4.0 */ @Immutable -public class RFC2965CommentUrlAttributeHandler implements CookieAttributeHandler { +public class RFC2965CommentUrlAttributeHandler implements CommonCookieAttributeHandler { public RFC2965CommentUrlAttributeHandler() { super(); @@ -66,4 +67,9 @@ public class RFC2965CommentUrlAttributeHandler implements CookieAttributeHandler return true; } - } + @Override + public String getAttributeName() { + return ClientCookie.COMMENTURL_ATTR; + } + +} diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DiscardAttributeHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DiscardAttributeHandler.java index c3c631f0f..62d1f453e 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DiscardAttributeHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DiscardAttributeHandler.java @@ -28,8 +28,9 @@ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; @@ -41,7 +42,7 @@ import org.apache.http.cookie.SetCookie2; * @since 4.0 */ @Immutable -public class RFC2965DiscardAttributeHandler implements CookieAttributeHandler { +public class RFC2965DiscardAttributeHandler implements CommonCookieAttributeHandler { public RFC2965DiscardAttributeHandler() { super(); @@ -66,4 +67,9 @@ public class RFC2965DiscardAttributeHandler implements CookieAttributeHandler { return true; } - } + @Override + public String getAttributeName() { + return ClientCookie.DISCARD_ATTR; + } + +} diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DomainAttributeHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DomainAttributeHandler.java index 04893acd9..42e790e56 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DomainAttributeHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DomainAttributeHandler.java @@ -31,8 +31,8 @@ import java.util.Locale; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; @@ -46,7 +46,7 @@ import org.apache.http.util.Args; * @since 3.1 */ @Immutable -public class RFC2965DomainAttributeHandler implements CookieAttributeHandler { +public class RFC2965DomainAttributeHandler implements CommonCookieAttributeHandler { public RFC2965DomainAttributeHandler() { super(); @@ -186,4 +186,9 @@ public class RFC2965DomainAttributeHandler implements CookieAttributeHandler { return effectiveHostWithoutDomain.indexOf('.') == -1; } + @Override + public String getAttributeName() { + return ClientCookie.DOMAIN_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java index cc82ffeea..004f25473 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java @@ -31,8 +31,8 @@ import java.util.StringTokenizer; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; @@ -46,7 +46,7 @@ import org.apache.http.util.Args; * @since 4.0 */ @Immutable -public class RFC2965PortAttributeHandler implements CookieAttributeHandler { +public class RFC2965PortAttributeHandler implements CommonCookieAttributeHandler { public RFC2965PortAttributeHandler() { super(); @@ -160,4 +160,9 @@ public class RFC2965PortAttributeHandler implements CookieAttributeHandler { return true; } + @Override + public String getAttributeName() { + return ClientCookie.PORT_ATTR; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java index 98862b30d..7d2f33124 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java @@ -35,7 +35,7 @@ import java.util.Map; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.NameValuePair; -import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.annotation.ThreadSafe; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; @@ -51,7 +51,7 @@ import org.apache.http.util.CharArrayBuffer; * * @since 4.0 */ -@NotThreadSafe // superclass is @NotThreadSafe +@ThreadSafe public class RFC2965Spec extends RFC2109Spec { /** @@ -63,12 +63,18 @@ public class RFC2965Spec extends RFC2109Spec { } public RFC2965Spec(final String[] datepatterns, final boolean oneHeader) { - super(datepatterns, oneHeader); - registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2965DomainAttributeHandler()); - registerAttribHandler(ClientCookie.PORT_ATTR, new RFC2965PortAttributeHandler()); - registerAttribHandler(ClientCookie.COMMENTURL_ATTR, new RFC2965CommentUrlAttributeHandler()); - registerAttribHandler(ClientCookie.DISCARD_ATTR, new RFC2965DiscardAttributeHandler()); - registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2965VersionAttributeHandler()); + super(oneHeader, + new RFC2965VersionAttributeHandler(), + new BasicPathHandler(), + new RFC2965DomainAttributeHandler(), + new RFC2965PortAttributeHandler(), + new BasicMaxAgeHandler(), + new BasicSecureHandler(), + new BasicCommentHandler(), + new BasicExpiresHandler( + datepatterns != null ? datepatterns.clone() : DATE_PATTERNS), + new RFC2965CommentUrlAttributeHandler(), + new RFC2965DiscardAttributeHandler()); } @Override diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java index 8def12e02..ac682d8cb 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java @@ -29,8 +29,8 @@ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.CommonCookieAttributeHandler; import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; @@ -44,7 +44,7 @@ import org.apache.http.util.Args; * @since 4.0 */ @Immutable -public class RFC2965VersionAttributeHandler implements CookieAttributeHandler { +public class RFC2965VersionAttributeHandler implements CommonCookieAttributeHandler { public RFC2965VersionAttributeHandler() { super(); @@ -94,4 +94,9 @@ public class RFC2965VersionAttributeHandler implements CookieAttributeHandler { return true; } + @Override + public String getAttributeName() { + return ClientCookie.VERSION_ATTR; + } + }