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
This commit is contained in:
Oleg Kalnichevski 2014-08-26 14:37:36 +00:00
parent 6b2b1a6e93
commit 243c862a03
24 changed files with 303 additions and 167 deletions

View File

@ -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
* <http://www.apache.org/>.
*
*/
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();
}

View File

@ -30,11 +30,14 @@ package org.apache.http.impl.cookie;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; 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.CookieAttributeHandler;
import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpec;
import org.apache.http.util.Args; import org.apache.http.util.Args;
import org.apache.http.util.Asserts;
/** /**
* Abstract cookie specification which can delegate the job of parsing, * Abstract cookie specification which can delegate the job of parsing,
@ -44,7 +47,7 @@ import org.apache.http.util.Args;
* *
* @since 4.0 * @since 4.0
*/ */
@NotThreadSafe // HashMap is not thread-safe @ThreadSafe
public abstract class AbstractCookieSpec implements CookieSpec { public abstract class AbstractCookieSpec implements CookieSpec {
/** /**
@ -57,9 +60,35 @@ public abstract class AbstractCookieSpec implements CookieSpec {
* */ * */
public AbstractCookieSpec() { public AbstractCookieSpec() {
super(); super();
this.attribHandlerMap = new HashMap<String, CookieAttributeHandler>(10); this.attribHandlerMap = new ConcurrentHashMap<String, CookieAttributeHandler>(10);
} }
/**
* @since 4.4
*/
protected AbstractCookieSpec(final HashMap<String, CookieAttributeHandler> map) {
super();
Asserts.notNull(map, "Attribute handler map");
this.attribHandlerMap = new ConcurrentHashMap<String, CookieAttributeHandler>(map);
}
/**
* @since 4.4
*/
protected AbstractCookieSpec(final CommonCookieAttributeHandler... handlers) {
super();
this.attribHandlerMap = new ConcurrentHashMap<String, CookieAttributeHandler>(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( public void registerAttribHandler(
final String name, final CookieAttributeHandler handler) { final String name, final CookieAttributeHandler handler) {
Args.notNull(name, "Attribute name"); Args.notNull(name, "Attribute name");
@ -89,12 +118,9 @@ public abstract class AbstractCookieSpec implements CookieSpec {
*/ */
protected CookieAttributeHandler getAttribHandler(final String name) { protected CookieAttributeHandler getAttribHandler(final String name) {
final CookieAttributeHandler handler = findAttribHandler(name); final CookieAttributeHandler handler = findAttribHandler(name);
if (handler == null) { Asserts.check(handler != null, "Handler not registered for " +
throw new IllegalStateException("Handler not registered for " + name + " attribute");
name + " attribute."); return handler;
} else {
return handler;
}
} }
protected Collection<CookieAttributeHandler> getAttribHandlers() { protected Collection<CookieAttributeHandler> getAttribHandlers() {

View File

@ -27,6 +27,8 @@
package org.apache.http.impl.cookie; package org.apache.http.impl.cookie;
import org.apache.http.annotation.Immutable; 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.MalformedCookieException;
import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie;
import org.apache.http.util.Args; import org.apache.http.util.Args;
@ -36,7 +38,7 @@ import org.apache.http.util.Args;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class BasicCommentHandler extends AbstractCookieAttributeHandler { public class BasicCommentHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
public BasicCommentHandler() { public BasicCommentHandler() {
super(); super();
@ -49,4 +51,9 @@ public class BasicCommentHandler extends AbstractCookieAttributeHandler {
cookie.setComment(value); cookie.setComment(value);
} }
@Override
public String getAttributeName() {
return ClientCookie.COMMENT_ATTR;
}
} }

View File

@ -27,8 +27,9 @@
package org.apache.http.impl.cookie; package org.apache.http.impl.cookie;
import org.apache.http.annotation.Immutable; 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.Cookie;
import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.CookieRestrictionViolationException;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
@ -40,7 +41,7 @@ import org.apache.http.util.Args;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class BasicDomainHandler implements CookieAttributeHandler { public class BasicDomainHandler implements CommonCookieAttributeHandler {
public BasicDomainHandler() { public BasicDomainHandler() {
super(); super();
@ -116,4 +117,9 @@ public class BasicDomainHandler implements CookieAttributeHandler {
return host.endsWith(domain) || host.equals(domain.substring(1)); return host.endsWith(domain) || host.equals(domain.substring(1));
} }
@Override
public String getAttributeName() {
return ClientCookie.DOMAIN_ATTR;
}
} }

View File

@ -30,6 +30,8 @@ import java.util.Date;
import org.apache.http.annotation.Immutable; import org.apache.http.annotation.Immutable;
import org.apache.http.client.utils.DateUtils; 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.MalformedCookieException;
import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie;
import org.apache.http.util.Args; import org.apache.http.util.Args;
@ -39,7 +41,7 @@ import org.apache.http.util.Args;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class BasicExpiresHandler extends AbstractCookieAttributeHandler { public class BasicExpiresHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
/** Valid date patterns */ /** Valid date patterns */
private final String[] datepatterns; private final String[] datepatterns;
@ -64,4 +66,9 @@ public class BasicExpiresHandler extends AbstractCookieAttributeHandler {
cookie.setExpiryDate(expiry); cookie.setExpiryDate(expiry);
} }
@Override
public String getAttributeName() {
return ClientCookie.EXPIRES_ATTR;
}
} }

View File

@ -29,6 +29,8 @@ package org.apache.http.impl.cookie;
import java.util.Date; import java.util.Date;
import org.apache.http.annotation.Immutable; 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.MalformedCookieException;
import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie;
import org.apache.http.util.Args; import org.apache.http.util.Args;
@ -38,7 +40,7 @@ import org.apache.http.util.Args;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class BasicMaxAgeHandler extends AbstractCookieAttributeHandler { public class BasicMaxAgeHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
public BasicMaxAgeHandler() { public BasicMaxAgeHandler() {
super(); super();
@ -65,4 +67,9 @@ public class BasicMaxAgeHandler extends AbstractCookieAttributeHandler {
cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L)); cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L));
} }
@Override
public String getAttributeName() {
return ClientCookie.MAX_AGE_ATTR;
}
} }

View File

@ -27,8 +27,9 @@
package org.apache.http.impl.cookie; package org.apache.http.impl.cookie;
import org.apache.http.annotation.Immutable; 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.Cookie;
import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.CookieRestrictionViolationException;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
@ -41,7 +42,7 @@ import org.apache.http.util.TextUtils;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class BasicPathHandler implements CookieAttributeHandler { public class BasicPathHandler implements CommonCookieAttributeHandler {
public BasicPathHandler() { public BasicPathHandler() {
super(); super();
@ -87,4 +88,9 @@ public class BasicPathHandler implements CookieAttributeHandler {
return match; return match;
} }
@Override
public String getAttributeName() {
return ClientCookie.PATH_ATTR;
}
} }

View File

@ -27,6 +27,8 @@
package org.apache.http.impl.cookie; package org.apache.http.impl.cookie;
import org.apache.http.annotation.Immutable; 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.Cookie;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
@ -38,7 +40,7 @@ import org.apache.http.util.Args;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class BasicSecureHandler extends AbstractCookieAttributeHandler { public class BasicSecureHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
public BasicSecureHandler() { public BasicSecureHandler() {
super(); super();
@ -58,4 +60,9 @@ public class BasicSecureHandler extends AbstractCookieAttributeHandler {
return !cookie.isSecure() || origin.isSecure(); return !cookie.isSecure() || origin.isSecure();
} }
@Override
public String getAttributeName() {
return ClientCookie.SECURE_ATTR;
}
} }

View File

@ -32,7 +32,7 @@ import java.util.List;
import org.apache.http.FormattedHeader; import org.apache.http.FormattedHeader;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HeaderElement; 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.Cookie;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpec;
@ -49,48 +49,30 @@ import org.apache.http.util.CharArrayBuffer;
* *
* @since 4.0 * @since 4.0
*/ */
@NotThreadSafe // CookieSpec fields are @NotThreadSafe @ThreadSafe
public class BestMatchSpec implements CookieSpec { public class BestMatchSpec implements CookieSpec {
private final String[] datepatterns; private final RFC2965Spec strict;
private final boolean oneHeader; private final RFC2109Spec obsoleteStrict;
private final NetscapeDraftSpec netscapeDraft;
// Cached values of CookieSpec instances
private RFC2965Spec strict; // @NotThreadSafe
private RFC2109Spec obsoleteStrict; // @NotThreadSafe
private NetscapeDraftSpec netscape; // @NotThreadSafe
public BestMatchSpec(final String[] datepatterns, final boolean oneHeader) { public BestMatchSpec(final String[] datepatterns, final boolean oneHeader) {
super(); super();
this.datepatterns = datepatterns == null ? null : datepatterns.clone(); this.strict = new RFC2965Spec(datepatterns, oneHeader);
this.oneHeader = 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() { public BestMatchSpec() {
this(null, false); 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 @Override
public List<Cookie> parse( public List<Cookie> parse(
final Header header, final Header header,
@ -129,12 +111,12 @@ public class BestMatchSpec implements CookieSpec {
cursor = new ParserCursor(0, buffer.length()); cursor = new ParserCursor(0, buffer.length());
} }
helems = new HeaderElement[] { parser.parseHeader(buffer, cursor) }; helems = new HeaderElement[] { parser.parseHeader(buffer, cursor) };
return getNetscapeCompat().parse(helems, origin); return netscapeDraft.parse(helems, origin);
} else { } else {
if (SM.SET_COOKIE2.equals(header.getName())) { if (SM.SET_COOKIE2.equals(header.getName())) {
return getStrict().parse(helems, origin); return strict.parse(helems, origin);
} else { } 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"); Args.notNull(origin, "Cookie origin");
if (cookie.getVersion() > 0) { if (cookie.getVersion() > 0) {
if (cookie instanceof SetCookie2) { if (cookie instanceof SetCookie2) {
getStrict().validate(cookie, origin); strict.validate(cookie, origin);
} else { } else {
getObsoleteStrict().validate(cookie, origin); obsoleteStrict.validate(cookie, origin);
} }
} else { } else {
getNetscapeCompat().validate(cookie, origin); netscapeDraft.validate(cookie, origin);
} }
} }
@ -162,12 +144,12 @@ public class BestMatchSpec implements CookieSpec {
Args.notNull(origin, "Cookie origin"); Args.notNull(origin, "Cookie origin");
if (cookie.getVersion() > 0) { if (cookie.getVersion() > 0) {
if (cookie instanceof SetCookie2) { if (cookie instanceof SetCookie2) {
return getStrict().match(cookie, origin); return strict.match(cookie, origin);
} else { } else {
return getObsoleteStrict().match(cookie, origin); return obsoleteStrict.match(cookie, origin);
} }
} else { } else {
return getNetscapeCompat().match(cookie, origin); return netscapeDraft.match(cookie, origin);
} }
} }
@ -186,23 +168,23 @@ public class BestMatchSpec implements CookieSpec {
} }
if (version > 0) { if (version > 0) {
if (isSetCookie2) { if (isSetCookie2) {
return getStrict().formatCookies(cookies); return strict.formatCookies(cookies);
} else { } else {
return getObsoleteStrict().formatCookies(cookies); return obsoleteStrict.formatCookies(cookies);
} }
} else { } else {
return getNetscapeCompat().formatCookies(cookies); return netscapeDraft.formatCookies(cookies);
} }
} }
@Override @Override
public int getVersion() { public int getVersion() {
return getStrict().getVersion(); return strict.getVersion();
} }
@Override @Override
public Header getVersionHeader() { public Header getVersionHeader() {
return getStrict().getVersionHeader(); return strict.getVersionHeader();
} }
@Override @Override

View File

@ -36,9 +36,8 @@ import org.apache.http.FormattedHeader;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HeaderElement; import org.apache.http.HeaderElement;
import org.apache.http.NameValuePair; 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.client.utils.DateUtils;
import org.apache.http.cookie.ClientCookie;
import org.apache.http.cookie.Cookie; import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
@ -60,7 +59,7 @@ import org.apache.http.util.CharArrayBuffer;
* *
* @since 4.0 * @since 4.0
*/ */
@NotThreadSafe // superclass is @NotThreadSafe @ThreadSafe
public class BrowserCompatSpec extends CookieSpecBase { public class BrowserCompatSpec extends CookieSpecBase {
@ -81,40 +80,21 @@ public class BrowserCompatSpec extends CookieSpecBase {
"EEE, dd-MM-yyyy HH:mm:ss z", "EEE, dd-MM-yyyy HH:mm:ss z",
}; };
private final String[] datepatterns;
/** Default constructor */ /** Default constructor */
public BrowserCompatSpec(final String[] datepatterns, final BrowserCompatSpecFactory.SecurityLevel securityLevel) { public BrowserCompatSpec(final String[] datepatterns, final BrowserCompatSpecFactory.SecurityLevel securityLevel) {
super(); super(new BrowserCompatVersionAttributeHandler(),
if (datepatterns != null) { new BasicDomainHandler(),
this.datepatterns = datepatterns.clone(); securityLevel == BrowserCompatSpecFactory.SecurityLevel.SECURITYLEVEL_IE_MEDIUM ?
} else { new BasicPathHandler() {
this.datepatterns = DEFAULT_DATE_PATTERNS; @Override
} public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException {
switch (securityLevel) { // No validation
case SECURITYLEVEL_DEFAULT: }
registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); } : new BasicPathHandler(),
break; new BasicMaxAgeHandler(),
case SECURITYLEVEL_IE_MEDIUM: new BasicSecureHandler(),
registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler() { new BasicCommentHandler(),
@Override new BasicExpiresHandler(datepatterns != null ? datepatterns.clone() : DEFAULT_DATE_PATTERNS));
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());
} }
/** Default constructor */ /** Default constructor */

View File

@ -28,6 +28,8 @@
package org.apache.http.impl.cookie; package org.apache.http.impl.cookie;
import org.apache.http.annotation.Immutable; 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.MalformedCookieException;
import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie;
import org.apache.http.util.Args; import org.apache.http.util.Args;
@ -39,7 +41,7 @@ import org.apache.http.util.Args;
*/ */
@Immutable @Immutable
public class BrowserCompatVersionAttributeHandler extends public class BrowserCompatVersionAttributeHandler extends
AbstractCookieAttributeHandler { AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
public BrowserCompatVersionAttributeHandler() { public BrowserCompatVersionAttributeHandler() {
super(); super();
@ -64,4 +66,9 @@ public class BrowserCompatVersionAttributeHandler extends
cookie.setVersion(version); cookie.setVersion(version);
} }
@Override
public String getAttributeName() {
return ClientCookie.VERSION_ATTR;
}
} }

View File

@ -28,12 +28,14 @@
package org.apache.http.impl.cookie; package org.apache.http.impl.cookie;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import org.apache.http.HeaderElement; import org.apache.http.HeaderElement;
import org.apache.http.NameValuePair; 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.Cookie;
import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
@ -43,12 +45,29 @@ import org.apache.http.util.Args;
/** /**
* Cookie management functions shared by all specification. * Cookie management functions shared by all specification.
* *
*
* @since 4.0 * @since 4.0
*/ */
@NotThreadSafe // AbstractCookieSpec is not thread-safe @ThreadSafe
public abstract class CookieSpecBase extends AbstractCookieSpec { public abstract class CookieSpecBase extends AbstractCookieSpec {
public CookieSpecBase() {
super();
}
/**
* @since 4.4
*/
protected CookieSpecBase(final HashMap<String, CookieAttributeHandler> map) {
super(map);
}
/**
* @since 4.4
*/
protected CookieSpecBase(final CommonCookieAttributeHandler... handlers) {
super(handlers);
}
protected static String getDefaultPath(final CookieOrigin origin) { protected static String getDefaultPath(final CookieOrigin origin) {
String defaultPath = origin.getPath(); String defaultPath = origin.getPath();
int lastSlashIndex = defaultPath.lastIndexOf('/'); int lastSlashIndex = defaultPath.lastIndexOf('/');

View File

@ -31,7 +31,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.http.Header; 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.Cookie;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
@ -41,7 +41,7 @@ import org.apache.http.cookie.MalformedCookieException;
* *
* @since 4.1 * @since 4.1
*/ */
@NotThreadSafe // superclass is @NotThreadSafe @ThreadSafe
public class IgnoreSpec extends CookieSpecBase { public class IgnoreSpec extends CookieSpecBase {
@Override @Override

View File

@ -33,8 +33,8 @@ import java.util.List;
import org.apache.http.FormattedHeader; import org.apache.http.FormattedHeader;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HeaderElement; import org.apache.http.HeaderElement;
import org.apache.http.annotation.NotThreadSafe; import org.apache.http.annotation.ThreadSafe;
import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.CommonCookieAttributeHandler;
import org.apache.http.cookie.Cookie; import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
@ -52,35 +52,27 @@ import org.apache.http.util.CharArrayBuffer;
* *
* @since 4.0 * @since 4.0
*/ */
@NotThreadSafe // superclass is @NotThreadSafe @ThreadSafe
public class NetscapeDraftSpec extends CookieSpecBase { public class NetscapeDraftSpec extends CookieSpecBase {
protected static final String EXPIRES_PATTERN = "EEE, dd-MMM-yy HH:mm:ss z"; protected static final String EXPIRES_PATTERN = "EEE, dd-MMM-yy HH:mm:ss z";
private final String[] datepatterns; /** Default constructor */
public NetscapeDraftSpec(final String[] datepatterns) {
NetscapeDraftSpec(final boolean strictDomainValidation, final String[] datepatterns) { super(new BasicPathHandler(),
super(); new NetscapeDomainHandler(),
if (datepatterns != null) { new BasicSecureHandler(),
this.datepatterns = datepatterns.clone(); new BasicCommentHandler(),
} else { new BasicExpiresHandler(
this.datepatterns = new String[] { EXPIRES_PATTERN }; datepatterns != null ? datepatterns.clone() : 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));
} }
public NetscapeDraftSpec(final String[] datepatterns) { NetscapeDraftSpec(final CommonCookieAttributeHandler... handlers) {
this(true, datepatterns); super(handlers);
} }
public NetscapeDraftSpec() { public NetscapeDraftSpec() {
this(null); this((String[]) null);
} }
/** /**

View File

@ -77,6 +77,10 @@ public class NetscapeDraftSpecFactory implements CookieSpecFactory, CookieSpecPr
@Override @Override
public CookieSpec create(final HttpContext context) { public CookieSpec create(final HttpContext context) {
return new NetscapeDraftSpec(this.datepatterns); return new NetscapeDraftSpec(this.datepatterns);
} }

View File

@ -29,8 +29,9 @@ package org.apache.http.impl.cookie;
import java.util.Locale; import java.util.Locale;
import org.apache.http.annotation.Immutable; 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.Cookie;
import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.CookieRestrictionViolationException;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
@ -42,7 +43,7 @@ import org.apache.http.util.Args;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class RFC2109DomainHandler implements CookieAttributeHandler { public class RFC2109DomainHandler implements CommonCookieAttributeHandler {
public RFC2109DomainHandler() { public RFC2109DomainHandler() {
super(); super();
@ -120,4 +121,9 @@ public class RFC2109DomainHandler implements CookieAttributeHandler {
return host.equals(domain) || (domain.startsWith(".") && host.endsWith(domain)); return host.equals(domain) || (domain.startsWith(".") && host.endsWith(domain));
} }
@Override
public String getAttributeName() {
return ClientCookie.DOMAIN_ATTR;
}
} }

View File

@ -33,9 +33,10 @@ import java.util.List;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HeaderElement; 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.client.utils.DateUtils;
import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.ClientCookie;
import org.apache.http.cookie.CommonCookieAttributeHandler;
import org.apache.http.cookie.Cookie; import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookiePathComparator; import org.apache.http.cookie.CookiePathComparator;
@ -55,37 +56,30 @@ import org.apache.http.util.CharArrayBuffer;
* *
* @since 4.0 * @since 4.0
*/ */
@NotThreadSafe // superclass is @NotThreadSafe @ThreadSafe
public class RFC2109Spec extends CookieSpecBase { public class RFC2109Spec extends CookieSpecBase {
private final static CookiePathComparator PATH_COMPARATOR = new CookiePathComparator(); private final static CookiePathComparator PATH_COMPARATOR = new CookiePathComparator();
private final static String[] DATE_PATTERNS = { final static String[] DATE_PATTERNS = {
DateUtils.PATTERN_RFC1123, DateUtils.PATTERN_RFC1123,
DateUtils.PATTERN_RFC1036, DateUtils.PATTERN_RFC1036,
DateUtils.PATTERN_ASCTIME DateUtils.PATTERN_ASCTIME
}; };
private final String[] datepatterns;
private final boolean oneHeader; private final boolean oneHeader;
/** Default constructor */ /** Default constructor */
public RFC2109Spec(final String[] datepatterns, final boolean oneHeader) { public RFC2109Spec(final String[] datepatterns, final boolean oneHeader) {
super(); super(new RFC2109VersionHandler(),
if (datepatterns != null) { new BasicPathHandler(),
this.datepatterns = datepatterns.clone(); new RFC2109DomainHandler(),
} else { new BasicMaxAgeHandler(),
this.datepatterns = DATE_PATTERNS; new BasicSecureHandler(),
} new BasicCommentHandler(),
new BasicExpiresHandler(
datepatterns != null ? datepatterns.clone() : DATE_PATTERNS));
this.oneHeader = oneHeader; 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 */ /** Default constructor */
@ -93,6 +87,12 @@ public class RFC2109Spec extends CookieSpecBase {
this(null, false); this(null, false);
} }
protected RFC2109Spec(final boolean oneHeader,
final CommonCookieAttributeHandler... handlers) {
super(handlers);
this.oneHeader = oneHeader;
}
@Override @Override
public List<Cookie> parse(final Header header, final CookieOrigin origin) public List<Cookie> parse(final Header header, final CookieOrigin origin)
throws MalformedCookieException { throws MalformedCookieException {

View File

@ -27,6 +27,8 @@
package org.apache.http.impl.cookie; package org.apache.http.impl.cookie;
import org.apache.http.annotation.Immutable; 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.Cookie;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.CookieRestrictionViolationException;
@ -39,7 +41,7 @@ import org.apache.http.util.Args;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class RFC2109VersionHandler extends AbstractCookieAttributeHandler { public class RFC2109VersionHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
public RFC2109VersionHandler() { public RFC2109VersionHandler() {
super(); super();
@ -72,4 +74,9 @@ public class RFC2109VersionHandler extends AbstractCookieAttributeHandler {
} }
} }
@Override
public String getAttributeName() {
return ClientCookie.VERSION_ATTR;
}
} }

View File

@ -28,8 +28,9 @@
package org.apache.http.impl.cookie; package org.apache.http.impl.cookie;
import org.apache.http.annotation.Immutable; 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.Cookie;
import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie;
@ -41,7 +42,7 @@ import org.apache.http.cookie.SetCookie2;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class RFC2965CommentUrlAttributeHandler implements CookieAttributeHandler { public class RFC2965CommentUrlAttributeHandler implements CommonCookieAttributeHandler {
public RFC2965CommentUrlAttributeHandler() { public RFC2965CommentUrlAttributeHandler() {
super(); super();
@ -66,4 +67,9 @@ public class RFC2965CommentUrlAttributeHandler implements CookieAttributeHandler
return true; return true;
} }
} @Override
public String getAttributeName() {
return ClientCookie.COMMENTURL_ATTR;
}
}

View File

@ -28,8 +28,9 @@
package org.apache.http.impl.cookie; package org.apache.http.impl.cookie;
import org.apache.http.annotation.Immutable; 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.Cookie;
import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie;
@ -41,7 +42,7 @@ import org.apache.http.cookie.SetCookie2;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class RFC2965DiscardAttributeHandler implements CookieAttributeHandler { public class RFC2965DiscardAttributeHandler implements CommonCookieAttributeHandler {
public RFC2965DiscardAttributeHandler() { public RFC2965DiscardAttributeHandler() {
super(); super();
@ -66,4 +67,9 @@ public class RFC2965DiscardAttributeHandler implements CookieAttributeHandler {
return true; return true;
} }
} @Override
public String getAttributeName() {
return ClientCookie.DISCARD_ATTR;
}
}

View File

@ -31,8 +31,8 @@ import java.util.Locale;
import org.apache.http.annotation.Immutable; import org.apache.http.annotation.Immutable;
import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.ClientCookie;
import org.apache.http.cookie.CommonCookieAttributeHandler;
import org.apache.http.cookie.Cookie; import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.CookieRestrictionViolationException;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
@ -46,7 +46,7 @@ import org.apache.http.util.Args;
* @since 3.1 * @since 3.1
*/ */
@Immutable @Immutable
public class RFC2965DomainAttributeHandler implements CookieAttributeHandler { public class RFC2965DomainAttributeHandler implements CommonCookieAttributeHandler {
public RFC2965DomainAttributeHandler() { public RFC2965DomainAttributeHandler() {
super(); super();
@ -186,4 +186,9 @@ public class RFC2965DomainAttributeHandler implements CookieAttributeHandler {
return effectiveHostWithoutDomain.indexOf('.') == -1; return effectiveHostWithoutDomain.indexOf('.') == -1;
} }
@Override
public String getAttributeName() {
return ClientCookie.DOMAIN_ATTR;
}
} }

View File

@ -31,8 +31,8 @@ import java.util.StringTokenizer;
import org.apache.http.annotation.Immutable; import org.apache.http.annotation.Immutable;
import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.ClientCookie;
import org.apache.http.cookie.CommonCookieAttributeHandler;
import org.apache.http.cookie.Cookie; import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.CookieRestrictionViolationException;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
@ -46,7 +46,7 @@ import org.apache.http.util.Args;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class RFC2965PortAttributeHandler implements CookieAttributeHandler { public class RFC2965PortAttributeHandler implements CommonCookieAttributeHandler {
public RFC2965PortAttributeHandler() { public RFC2965PortAttributeHandler() {
super(); super();
@ -160,4 +160,9 @@ public class RFC2965PortAttributeHandler implements CookieAttributeHandler {
return true; return true;
} }
@Override
public String getAttributeName() {
return ClientCookie.PORT_ATTR;
}
} }

View File

@ -35,7 +35,7 @@ import java.util.Map;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HeaderElement; import org.apache.http.HeaderElement;
import org.apache.http.NameValuePair; 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.ClientCookie;
import org.apache.http.cookie.Cookie; import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieAttributeHandler;
@ -51,7 +51,7 @@ import org.apache.http.util.CharArrayBuffer;
* *
* @since 4.0 * @since 4.0
*/ */
@NotThreadSafe // superclass is @NotThreadSafe @ThreadSafe
public class RFC2965Spec extends RFC2109Spec { public class RFC2965Spec extends RFC2109Spec {
/** /**
@ -63,12 +63,18 @@ public class RFC2965Spec extends RFC2109Spec {
} }
public RFC2965Spec(final String[] datepatterns, final boolean oneHeader) { public RFC2965Spec(final String[] datepatterns, final boolean oneHeader) {
super(datepatterns, oneHeader); super(oneHeader,
registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2965DomainAttributeHandler()); new RFC2965VersionAttributeHandler(),
registerAttribHandler(ClientCookie.PORT_ATTR, new RFC2965PortAttributeHandler()); new BasicPathHandler(),
registerAttribHandler(ClientCookie.COMMENTURL_ATTR, new RFC2965CommentUrlAttributeHandler()); new RFC2965DomainAttributeHandler(),
registerAttribHandler(ClientCookie.DISCARD_ATTR, new RFC2965DiscardAttributeHandler()); new RFC2965PortAttributeHandler(),
registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2965VersionAttributeHandler()); new BasicMaxAgeHandler(),
new BasicSecureHandler(),
new BasicCommentHandler(),
new BasicExpiresHandler(
datepatterns != null ? datepatterns.clone() : DATE_PATTERNS),
new RFC2965CommentUrlAttributeHandler(),
new RFC2965DiscardAttributeHandler());
} }
@Override @Override

View File

@ -29,8 +29,8 @@ package org.apache.http.impl.cookie;
import org.apache.http.annotation.Immutable; import org.apache.http.annotation.Immutable;
import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.ClientCookie;
import org.apache.http.cookie.CommonCookieAttributeHandler;
import org.apache.http.cookie.Cookie; import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.CookieRestrictionViolationException;
import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.MalformedCookieException;
@ -44,7 +44,7 @@ import org.apache.http.util.Args;
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
public class RFC2965VersionAttributeHandler implements CookieAttributeHandler { public class RFC2965VersionAttributeHandler implements CommonCookieAttributeHandler {
public RFC2965VersionAttributeHandler() { public RFC2965VersionAttributeHandler() {
super(); super();
@ -94,4 +94,9 @@ public class RFC2965VersionAttributeHandler implements CookieAttributeHandler {
return true; return true;
} }
@Override
public String getAttributeName() {
return ClientCookie.VERSION_ATTR;
}
} }