mirror of
https://github.com/apache/httpcomponents-client.git
synced 2025-02-27 21:29:12 +00:00
RFC 6265 compliant cookie spec
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1646864 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
88b56ddb3f
commit
70489c4bb0
@ -156,10 +156,11 @@ public void process(final HttpRequest request, final HttpContext context)
|
||||
}
|
||||
final CookieSpec cookieSpec = provider.create(clientContext);
|
||||
// Get all cookies available in the HTTP state
|
||||
final List<Cookie> cookies = new ArrayList<Cookie>(cookieStore.getCookies());
|
||||
final List<Cookie> cookies = cookieStore.getCookies();
|
||||
// Find cookies matching the given origin
|
||||
final List<Cookie> matchedCookies = new ArrayList<Cookie>();
|
||||
final Date now = new Date();
|
||||
boolean expired = false;
|
||||
for (final Cookie cookie : cookies) {
|
||||
if (!cookie.isExpired(now)) {
|
||||
if (cookieSpec.match(cookie, cookieOrigin)) {
|
||||
@ -172,8 +173,15 @@ public void process(final HttpRequest request, final HttpContext context)
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Cookie " + cookie + " expired");
|
||||
}
|
||||
expired = true;
|
||||
}
|
||||
}
|
||||
// Per RFC 6265, 5.3
|
||||
// The user agent must evict all expired cookies if, at any time, an expired cookie
|
||||
// exists in the cookie store
|
||||
if (expired) {
|
||||
cookieStore.clearExpired(now);
|
||||
}
|
||||
// Generate Cookie request headers
|
||||
if (!matchedCookies.isEmpty()) {
|
||||
final List<Header> headers = cookieSpec.formatCookies(matchedCookies);
|
||||
|
@ -133,5 +133,7 @@ public interface Cookie {
|
||||
*/
|
||||
boolean isExpired(final Date date);
|
||||
|
||||
//TODO: RFC 6265 requires cookies to track their creation time; add #getCreationDate()
|
||||
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.TextUtils;
|
||||
|
||||
/**
|
||||
* CookieOrigin class encapsulates details of an origin server that
|
||||
@ -52,7 +53,7 @@ public CookieOrigin(final String host, final int port, final String path, final
|
||||
Args.notNull(path, "Path");
|
||||
this.host = host.toLowerCase(Locale.ROOT);
|
||||
this.port = port;
|
||||
if (!path.trim().isEmpty()) {
|
||||
if (!TextUtils.isBlank(path)) {
|
||||
this.path = path;
|
||||
} else {
|
||||
this.path = "/";
|
||||
|
@ -50,6 +50,8 @@
|
||||
@Immutable
|
||||
public class CookiePathComparator implements Serializable, Comparator<Cookie> {
|
||||
|
||||
public static final CookiePathComparator INSTANCE = new CookiePathComparator();
|
||||
|
||||
private static final long serialVersionUID = 7523645369616405818L;
|
||||
|
||||
private String normalizePath(final Cookie cookie) {
|
||||
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.impl.cookie.BasicClientCookie;
|
||||
|
||||
/**
|
||||
* This cookie comparator ensures that cookies with longer paths take precedence over
|
||||
* cookies with shorter path. Among cookies with equal path length cookies with ealier
|
||||
* creation time take precedence over cookies with later creation time
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@Immutable
|
||||
public class CookiePriorityComparator implements Comparator<Cookie> {
|
||||
|
||||
public static final CookiePriorityComparator INSTANCE = new CookiePriorityComparator();
|
||||
|
||||
private int getPathLength(final Cookie cookie) {
|
||||
final String path = cookie.getPath();
|
||||
return path != null ? path.length() : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(final Cookie c1, final Cookie c2) {
|
||||
final int l1 = getPathLength(c1);
|
||||
final int l2 = getPathLength(c2);
|
||||
//TODO: update this class once Cookie interface has been expended with #getCreationTime method
|
||||
final int result = l2 - l1;
|
||||
if (result == 0 && c1 instanceof BasicClientCookie && c2 instanceof BasicClientCookie) {
|
||||
final Date d1 = ((BasicClientCookie) c1).getCreationDate();
|
||||
final Date d2 = ((BasicClientCookie) c2).getCreationDate();
|
||||
if (d1 != null && d2 != null) {
|
||||
return (int) (d1.getTime() - d2.getTime());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -304,6 +304,20 @@ public boolean isExpired(final Date date) {
|
||||
&& cookieExpiryDate.getTime() <= date.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public Date getCreationDate() {
|
||||
return creationDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public void setCreationDate(final Date creationDate) {
|
||||
this.creationDate = creationDate;
|
||||
}
|
||||
|
||||
public void setAttribute(final String name, final String value) {
|
||||
this.attribs.put(name, value);
|
||||
}
|
||||
@ -385,5 +399,7 @@ public String toString() {
|
||||
/** The version of the cookie specification I was created from. */
|
||||
private int cookieVersion;
|
||||
|
||||
private Date creationDate;
|
||||
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,10 @@
|
||||
*/
|
||||
package org.apache.http.impl.cookie;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.conn.util.InetAddressUtils;
|
||||
import org.apache.http.cookie.ClientCookie;
|
||||
import org.apache.http.cookie.CommonCookieAttributeHandler;
|
||||
import org.apache.http.cookie.Cookie;
|
||||
@ -35,6 +38,7 @@
|
||||
import org.apache.http.cookie.MalformedCookieException;
|
||||
import org.apache.http.cookie.SetCookie;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.TextUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -51,13 +55,19 @@ public BasicDomainHandler() {
|
||||
public void parse(final SetCookie cookie, final String value)
|
||||
throws MalformedCookieException {
|
||||
Args.notNull(cookie, "Cookie");
|
||||
if (value == null) {
|
||||
throw new MalformedCookieException("Missing value for domain attribute");
|
||||
if (TextUtils.isBlank(value)) {
|
||||
throw new MalformedCookieException("Blank or null value for domain attribute");
|
||||
}
|
||||
if (value.trim().isEmpty()) {
|
||||
throw new MalformedCookieException("Blank value for domain attribute");
|
||||
// Ignore domain attributes ending with '.' per RFC 6265, 4.1.2.3
|
||||
if (value.endsWith(".")) {
|
||||
return;
|
||||
}
|
||||
cookie.setDomain(value);
|
||||
String domain = value;
|
||||
if (domain.startsWith(".")) {
|
||||
domain = domain.substring(1);
|
||||
}
|
||||
domain = domain.toLowerCase(Locale.ROOT);
|
||||
cookie.setDomain(domain);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,32 +81,32 @@ public void validate(final Cookie cookie, final CookieOrigin origin)
|
||||
// request-host and domain must be identical for the cookie to sent
|
||||
// back to the origin-server.
|
||||
final String host = origin.getHost();
|
||||
String domain = cookie.getDomain();
|
||||
final String domain = cookie.getDomain();
|
||||
if (domain == null) {
|
||||
throw new CookieRestrictionViolationException("Cookie domain may not be null");
|
||||
throw new CookieRestrictionViolationException("Cookie 'domain' may not be null");
|
||||
}
|
||||
if (host.contains(".")) {
|
||||
// Not required to have at least two dots. RFC 2965.
|
||||
// A Set-Cookie2 with Domain=ajax.com will be accepted.
|
||||
if (!host.equals(domain) && !domainMatch(domain, host)) {
|
||||
throw new CookieRestrictionViolationException(
|
||||
"Illegal 'domain' attribute \"" + domain + "\". Domain of origin: \"" + host + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
// domain must match host
|
||||
if (!host.endsWith(domain)) {
|
||||
if (domain.startsWith(".")) {
|
||||
domain = domain.substring(1, domain.length());
|
||||
}
|
||||
if (!host.equals(domain)) {
|
||||
throw new CookieRestrictionViolationException(
|
||||
"Illegal domain attribute \"" + domain
|
||||
+ "\". Domain of origin: \"" + host + "\"");
|
||||
}
|
||||
static boolean domainMatch(final String domain, final String host) {
|
||||
if (InetAddressUtils.isIPv4Address(host) || InetAddressUtils.isIPv6Address(host)) {
|
||||
return false;
|
||||
}
|
||||
final String normalizedDomain = domain.startsWith(".") ? domain.substring(1) : domain;
|
||||
if (host.endsWith(normalizedDomain)) {
|
||||
final int prefix = host.length() - normalizedDomain.length();
|
||||
// Either a full match or a prefix endidng with a '.'
|
||||
if (prefix == 0) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!host.equals(domain)) {
|
||||
throw new CookieRestrictionViolationException(
|
||||
"Illegal domain attribute \"" + domain
|
||||
+ "\". Domain of origin: \"" + host + "\"");
|
||||
if (prefix > 1 && host.charAt(prefix - 1) == '.') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -108,13 +118,19 @@ public boolean match(final Cookie cookie, final CookieOrigin origin) {
|
||||
if (domain == null) {
|
||||
return false;
|
||||
}
|
||||
if (domain.startsWith(".")) {
|
||||
domain = domain.substring(1);
|
||||
}
|
||||
domain = domain.toLowerCase(Locale.ROOT);
|
||||
if (host.equals(domain)) {
|
||||
return true;
|
||||
}
|
||||
if (!domain.startsWith(".")) {
|
||||
domain = '.' + domain;
|
||||
if (cookie instanceof ClientCookie) {
|
||||
if (((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) {
|
||||
return domainMatch(domain, host);
|
||||
}
|
||||
}
|
||||
return host.endsWith(domain) || host.equals(domain.substring(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,11 +56,11 @@ public void parse(final SetCookie cookie, final String value)
|
||||
throws MalformedCookieException {
|
||||
Args.notNull(cookie, "Cookie");
|
||||
if (value == null) {
|
||||
throw new MalformedCookieException("Missing value for expires attribute");
|
||||
throw new MalformedCookieException("Missing value for 'expires' attribute");
|
||||
}
|
||||
final Date expiry = DateUtils.parseDate(value, this.datepatterns);
|
||||
if (expiry == null) {
|
||||
throw new MalformedCookieException("Unable to parse expires attribute: "
|
||||
throw new MalformedCookieException("Invalid 'expires' attribute: "
|
||||
+ value);
|
||||
}
|
||||
cookie.setExpiryDate(expiry);
|
||||
|
@ -51,17 +51,17 @@ public void parse(final SetCookie cookie, final String value)
|
||||
throws MalformedCookieException {
|
||||
Args.notNull(cookie, "Cookie");
|
||||
if (value == null) {
|
||||
throw new MalformedCookieException("Missing value for max-age attribute");
|
||||
throw new MalformedCookieException("Missing value for 'max-age' attribute");
|
||||
}
|
||||
final int age;
|
||||
try {
|
||||
age = Integer.parseInt(value);
|
||||
} catch (final NumberFormatException e) {
|
||||
throw new MalformedCookieException ("Invalid max-age attribute: "
|
||||
throw new MalformedCookieException ("Invalid 'max-age' attribute: "
|
||||
+ value);
|
||||
}
|
||||
if (age < 0) {
|
||||
throw new MalformedCookieException ("Negative max-age attribute: "
|
||||
throw new MalformedCookieException ("Negative 'max-age' attribute: "
|
||||
+ value);
|
||||
}
|
||||
cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L));
|
||||
|
@ -60,32 +60,38 @@ public void validate(final Cookie cookie, final CookieOrigin origin)
|
||||
throws MalformedCookieException {
|
||||
if (!match(cookie, origin)) {
|
||||
throw new CookieRestrictionViolationException(
|
||||
"Illegal path attribute \"" + cookie.getPath()
|
||||
"Illegal 'path' attribute \"" + cookie.getPath()
|
||||
+ "\". Path of origin: \"" + origin.getPath() + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean pathMatch(final String uriPath, final String cookiePath) {
|
||||
String normalizedCookiePath = cookiePath;
|
||||
if (normalizedCookiePath == null) {
|
||||
normalizedCookiePath = "/";
|
||||
}
|
||||
if (normalizedCookiePath.length() > 1 && normalizedCookiePath.endsWith("/")) {
|
||||
normalizedCookiePath = normalizedCookiePath.substring(0, normalizedCookiePath.length() - 1);
|
||||
}
|
||||
if (uriPath.startsWith(normalizedCookiePath)) {
|
||||
if (normalizedCookiePath.equals("/")) {
|
||||
return true;
|
||||
}
|
||||
if (uriPath.length() == normalizedCookiePath.length()) {
|
||||
return true;
|
||||
}
|
||||
if (uriPath.charAt(normalizedCookiePath.length()) == '/') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(final Cookie cookie, final CookieOrigin origin) {
|
||||
Args.notNull(cookie, "Cookie");
|
||||
Args.notNull(origin, "Cookie origin");
|
||||
final String targetpath = origin.getPath();
|
||||
String topmostPath = cookie.getPath();
|
||||
if (topmostPath == null) {
|
||||
topmostPath = "/";
|
||||
}
|
||||
if (topmostPath.length() > 1 && topmostPath.endsWith("/")) {
|
||||
topmostPath = topmostPath.substring(0, topmostPath.length() - 1);
|
||||
}
|
||||
boolean match = targetpath.startsWith (topmostPath);
|
||||
// if there is a match and these values are not exactly the same we have
|
||||
// to make sure we're not matcing "/foobar" and "/foo"
|
||||
if (match && targetpath.length() != topmostPath.length()) {
|
||||
if (!topmostPath.endsWith("/")) {
|
||||
match = (targetpath.charAt(topmostPath.length()) == '/');
|
||||
}
|
||||
}
|
||||
return match;
|
||||
return pathMatch(origin.getPath(), cookie.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
/**
|
||||
* {@link org.apache.http.cookie.CookieSpecProvider} implementation that provides an instance of
|
||||
* {@link BestMatchSpec}. The instance returned by this factory can
|
||||
* {@link org.apache.http.impl.cookie.DefaultCookieSpec}. The instance returned by this factory can
|
||||
* be shared by multiple threads.
|
||||
*
|
||||
* @since 4.4
|
||||
|
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.impl.cookie;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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.message.ParserCursor;
|
||||
import org.apache.http.util.Args;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@Immutable
|
||||
public class LaxExpiresHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
|
||||
|
||||
static final TimeZone UTC = TimeZone.getTimeZone("UTC");
|
||||
|
||||
private static final BitSet DELIMS;
|
||||
static {
|
||||
final BitSet bitSet = new BitSet();
|
||||
bitSet.set(0x9);
|
||||
for (int b = 0x20; b <= 0x2f; b++) {
|
||||
bitSet.set(b);
|
||||
}
|
||||
for (int b = 0x3b; b <= 0x40; b++) {
|
||||
bitSet.set(b);
|
||||
}
|
||||
for (int b = 0x5b; b <= 0x60; b++) {
|
||||
bitSet.set(b);
|
||||
}
|
||||
for (int b = 0x7b; b <= 0x7e; b++) {
|
||||
bitSet.set(b);
|
||||
}
|
||||
DELIMS = bitSet;
|
||||
}
|
||||
private static final Map<String, Integer> MONTHS;
|
||||
static {
|
||||
final ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>(12);
|
||||
map.put("jan", Calendar.JANUARY);
|
||||
map.put("feb", Calendar.FEBRUARY);
|
||||
map.put("mar", Calendar.MARCH);
|
||||
map.put("apr", Calendar.APRIL);
|
||||
map.put("may", Calendar.MAY);
|
||||
map.put("jun", Calendar.JUNE);
|
||||
map.put("jul", Calendar.JULY);
|
||||
map.put("aug", Calendar.AUGUST);
|
||||
map.put("sep", Calendar.SEPTEMBER);
|
||||
map.put("oct", Calendar.OCTOBER);
|
||||
map.put("nov", Calendar.NOVEMBER);
|
||||
map.put("dec", Calendar.DECEMBER);
|
||||
MONTHS = map;
|
||||
}
|
||||
|
||||
private final static Pattern TIME_PATTERN = Pattern.compile(
|
||||
"^([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})([^0-9].*)?$");
|
||||
private final static Pattern DAY_OF_MONTH_PATTERN = Pattern.compile(
|
||||
"^([0-9]{1,2})([^0-9].*)?$");
|
||||
private final static Pattern MONTH_PATTERN = Pattern.compile(
|
||||
"^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)(.*)?$", Pattern.CASE_INSENSITIVE);
|
||||
private final static Pattern YEAR_PATTERN = Pattern.compile(
|
||||
"^([0-9]{2,4})([^0-9].*)?$");
|
||||
|
||||
public LaxExpiresHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(final SetCookie cookie, final String value) throws MalformedCookieException {
|
||||
Args.notNull(cookie, "Cookie");
|
||||
final ParserCursor cursor = new ParserCursor(0, value.length());
|
||||
final StringBuilder content = new StringBuilder();
|
||||
|
||||
int second = 0, minute = 0, hour = 0, day = 0, month = 0, year = 0;
|
||||
boolean foundTime = false, foundDayOfMonth = false, foundMonth = false, foundYear = false;
|
||||
try {
|
||||
while (!cursor.atEnd()) {
|
||||
skipDelims(value, cursor);
|
||||
content.setLength(0);
|
||||
copyContent(value, cursor, content);
|
||||
|
||||
if (content.length() == 0) {
|
||||
break;
|
||||
}
|
||||
if (!foundTime) {
|
||||
final Matcher matcher = TIME_PATTERN.matcher(content);
|
||||
if (matcher.matches()) {
|
||||
foundTime = true;
|
||||
hour = Integer.parseInt(matcher.group(1));
|
||||
minute = Integer.parseInt(matcher.group(2));
|
||||
second =Integer.parseInt(matcher.group(3));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!foundDayOfMonth) {
|
||||
final Matcher matcher = DAY_OF_MONTH_PATTERN.matcher(content);
|
||||
if (matcher.matches()) {
|
||||
foundDayOfMonth = true;
|
||||
day = Integer.parseInt(matcher.group(1));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!foundMonth) {
|
||||
final Matcher matcher = MONTH_PATTERN.matcher(content);
|
||||
if (matcher.matches()) {
|
||||
foundMonth = true;
|
||||
month = MONTHS.get(matcher.group(1).toLowerCase(Locale.ROOT));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!foundYear) {
|
||||
final Matcher matcher = YEAR_PATTERN.matcher(content);
|
||||
if (matcher.matches()) {
|
||||
foundYear = true;
|
||||
year = Integer.parseInt(matcher.group(1));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException ignore) {
|
||||
throw new MalformedCookieException("Invalid 'expires' attribute: " + value);
|
||||
}
|
||||
if (!foundTime || !foundDayOfMonth || !foundMonth || !foundYear) {
|
||||
throw new MalformedCookieException("Invalid 'expires' attribute: " + value);
|
||||
}
|
||||
if (year >= 70 && year <= 99) {
|
||||
year = 1900 + year;
|
||||
}
|
||||
if (year >= 0 && year <= 69) {
|
||||
year = 2000 + year;
|
||||
}
|
||||
if (day < 1 || day > 31 || year < 1601 || hour > 23 || minute > 59 || second > 59) {
|
||||
throw new MalformedCookieException("Invalid 'expires' attribute: " + value);
|
||||
}
|
||||
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(UTC);
|
||||
c.setTimeInMillis(0L);
|
||||
c.set(Calendar.SECOND, second);
|
||||
c.set(Calendar.MINUTE, minute);
|
||||
c.set(Calendar.HOUR_OF_DAY, hour);
|
||||
c.set(Calendar.DAY_OF_MONTH, day);
|
||||
c.set(Calendar.MONTH, month);
|
||||
c.set(Calendar.YEAR, year);
|
||||
cookie.setExpiryDate(c.getTime());
|
||||
}
|
||||
|
||||
private void skipDelims(final CharSequence buf, final ParserCursor cursor) {
|
||||
int pos = cursor.getPos();
|
||||
final int indexFrom = cursor.getPos();
|
||||
final int indexTo = cursor.getUpperBound();
|
||||
for (int i = indexFrom; i < indexTo; i++) {
|
||||
final char current = buf.charAt(i);
|
||||
if (DELIMS.get(current)) {
|
||||
pos++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
cursor.updatePos(pos);
|
||||
}
|
||||
|
||||
private void copyContent(final CharSequence buf, final ParserCursor cursor, final StringBuilder dst) {
|
||||
int pos = cursor.getPos();
|
||||
final int indexFrom = cursor.getPos();
|
||||
final int indexTo = cursor.getUpperBound();
|
||||
for (int i = indexFrom; i < indexTo; i++) {
|
||||
final char current = buf.charAt(i);
|
||||
if (DELIMS.get(current)) {
|
||||
break;
|
||||
} else {
|
||||
pos++;
|
||||
dst.append(current);
|
||||
}
|
||||
}
|
||||
cursor.updatePos(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeName() {
|
||||
return ClientCookie.MAX_AGE_ATTR;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.impl.cookie;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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;
|
||||
import org.apache.http.util.TextUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@Immutable
|
||||
public class LaxMaxAgeHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
|
||||
|
||||
private final static Pattern MAX_AGE_PATTERN = Pattern.compile("^\\-?[0-9]+$");
|
||||
|
||||
public LaxMaxAgeHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(final SetCookie cookie, final String value) throws MalformedCookieException {
|
||||
Args.notNull(cookie, "Cookie");
|
||||
if (TextUtils.isBlank(value)) {
|
||||
return;
|
||||
}
|
||||
final Matcher matcher = MAX_AGE_PATTERN.matcher(value);
|
||||
if (matcher.matches()) {
|
||||
final int age;
|
||||
try {
|
||||
age = Integer.parseInt(value);
|
||||
} catch (final NumberFormatException e) {
|
||||
return;
|
||||
}
|
||||
final Date expiryDate = age >= 0 ? new Date(System.currentTimeMillis() + age * 1000L) :
|
||||
new Date(Long.MIN_VALUE);
|
||||
cookie.setExpiryDate(expiryDate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeName() {
|
||||
return ClientCookie.MAX_AGE_ATTR;
|
||||
}
|
||||
|
||||
}
|
@ -30,30 +30,45 @@
|
||||
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.CookieOrigin;
|
||||
import org.apache.http.cookie.CookieRestrictionViolationException;
|
||||
import org.apache.http.cookie.MalformedCookieException;
|
||||
import org.apache.http.cookie.SetCookie;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.TextUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
@Immutable
|
||||
public class NetscapeDomainHandler extends BasicDomainHandler {
|
||||
public class NetscapeDomainHandler implements CommonCookieAttributeHandler {
|
||||
|
||||
public NetscapeDomainHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(final SetCookie cookie, final String value) throws MalformedCookieException {
|
||||
Args.notNull(cookie, "Cookie");
|
||||
if (TextUtils.isBlank(value)) {
|
||||
throw new MalformedCookieException("Blank or null value for domain attribute");
|
||||
}
|
||||
cookie.setDomain(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(final Cookie cookie, final CookieOrigin origin)
|
||||
throws MalformedCookieException {
|
||||
super.validate(cookie, origin);
|
||||
// Perform Netscape Cookie draft specific validation
|
||||
final String host = origin.getHost();
|
||||
final String domain = cookie.getDomain();
|
||||
if (!host.equals(domain) && !BasicDomainHandler.domainMatch(domain, host)) {
|
||||
throw new CookieRestrictionViolationException(
|
||||
"Illegal domain attribute \"" + domain + "\". Domain of origin: \"" + host + "\"");
|
||||
}
|
||||
if (host.contains(".")) {
|
||||
final int domainParts = new StringTokenizer(domain, ".").countTokens();
|
||||
|
||||
@ -103,4 +118,9 @@ public boolean match(final Cookie cookie, final CookieOrigin origin) {
|
||||
return host.endsWith(domain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeName() {
|
||||
return ClientCookie.DOMAIN_ATTR;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -59,8 +59,6 @@
|
||||
@ThreadSafe
|
||||
public class RFC2109Spec extends CookieSpecBase {
|
||||
|
||||
private final static CookiePathComparator PATH_COMPARATOR = new CookiePathComparator();
|
||||
|
||||
final static String[] DATE_PATTERNS = {
|
||||
DateUtils.PATTERN_RFC1123,
|
||||
DateUtils.PATTERN_RFC1036,
|
||||
@ -127,7 +125,7 @@ public List<Header> formatCookies(final List<Cookie> cookies) {
|
||||
if (cookies.size() > 1) {
|
||||
// Create a mutable copy and sort the copy.
|
||||
cookieList = new ArrayList<Cookie>(cookies);
|
||||
Collections.sort(cookieList, PATH_COMPARATOR);
|
||||
Collections.sort(cookieList, CookiePathComparator.INSTANCE);
|
||||
} else {
|
||||
cookieList = cookies;
|
||||
}
|
||||
|
@ -0,0 +1,276 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.impl.cookie;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.http.FormattedHeader;
|
||||
import org.apache.http.Header;
|
||||
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.CookieAttributeHandler;
|
||||
import org.apache.http.cookie.CookieOrigin;
|
||||
import org.apache.http.cookie.CookiePriorityComparator;
|
||||
import org.apache.http.cookie.CookieSpec;
|
||||
import org.apache.http.cookie.MalformedCookieException;
|
||||
import org.apache.http.cookie.SM;
|
||||
import org.apache.http.message.BufferedHeader;
|
||||
import org.apache.http.message.ParserCursor;
|
||||
import org.apache.http.message.TokenParser;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
|
||||
/**
|
||||
* Cookie management functions shared by RFC C6265 compliant specification.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@ThreadSafe
|
||||
class RFC6265CookieSpecBase implements CookieSpec {
|
||||
|
||||
private final static char PARAM_DELIMITER = ';';
|
||||
private final static char COMMA_CHAR = ',';
|
||||
private final static char EQUAL_CHAR = '=';
|
||||
private final static char DQUOTE_CHAR = '"';
|
||||
private final static char ESCAPE_CHAR = '\\';
|
||||
|
||||
// IMPORTANT!
|
||||
// These private static variables must be treated as immutable and never exposed outside this class
|
||||
private static final BitSet TOKEN_DELIMS = TokenParser.INIT_BITSET(EQUAL_CHAR, PARAM_DELIMITER);
|
||||
private static final BitSet VALUE_DELIMS = TokenParser.INIT_BITSET(PARAM_DELIMITER);
|
||||
private static final BitSet SPECIAL_CHARS = TokenParser.INIT_BITSET(' ',
|
||||
DQUOTE_CHAR, COMMA_CHAR, PARAM_DELIMITER, ESCAPE_CHAR);
|
||||
|
||||
private final CookieAttributeHandler[] attribHandlers;
|
||||
private final Map<String, CookieAttributeHandler> attribHandlerMap;
|
||||
private final TokenParser tokenParser;
|
||||
|
||||
RFC6265CookieSpecBase(final CommonCookieAttributeHandler... handlers) {
|
||||
super();
|
||||
this.attribHandlers = handlers.clone();
|
||||
this.attribHandlerMap = new ConcurrentHashMap<String, CookieAttributeHandler>(handlers.length);
|
||||
for (CommonCookieAttributeHandler handler: handlers) {
|
||||
this.attribHandlerMap.put(handler.getAttributeName().toLowerCase(Locale.ROOT), handler);
|
||||
}
|
||||
this.tokenParser = TokenParser.INSTANCE;
|
||||
}
|
||||
|
||||
static String getDefaultPath(final CookieOrigin origin) {
|
||||
String defaultPath = origin.getPath();
|
||||
int lastSlashIndex = defaultPath.lastIndexOf('/');
|
||||
if (lastSlashIndex >= 0) {
|
||||
if (lastSlashIndex == 0) {
|
||||
//Do not remove the very first slash
|
||||
lastSlashIndex = 1;
|
||||
}
|
||||
defaultPath = defaultPath.substring(0, lastSlashIndex);
|
||||
}
|
||||
return defaultPath;
|
||||
}
|
||||
|
||||
static String getDefaultDomain(final CookieOrigin origin) {
|
||||
return origin.getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<Cookie> parse(final Header header, final CookieOrigin origin) throws MalformedCookieException {
|
||||
Args.notNull(header, "Header");
|
||||
Args.notNull(origin, "Cookie origin");
|
||||
if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) {
|
||||
throw new MalformedCookieException("Unrecognized cookie header: '" + header.toString() + "'");
|
||||
}
|
||||
final CharArrayBuffer buffer;
|
||||
final ParserCursor cursor;
|
||||
if (header instanceof FormattedHeader) {
|
||||
buffer = ((FormattedHeader) header).getBuffer();
|
||||
cursor = new ParserCursor(((FormattedHeader) header).getValuePos(), buffer.length());
|
||||
} else {
|
||||
final String s = header.getValue();
|
||||
if (s == null) {
|
||||
throw new MalformedCookieException("Header value is null");
|
||||
}
|
||||
buffer = new CharArrayBuffer(s.length());
|
||||
buffer.append(s);
|
||||
cursor = new ParserCursor(0, buffer.length());
|
||||
}
|
||||
final String name = tokenParser.parseToken(buffer, cursor, TOKEN_DELIMS);
|
||||
if (name.length() == 0) {
|
||||
throw new MalformedCookieException("Cookie name is invalid: '" + header.toString() + "'");
|
||||
}
|
||||
if (cursor.atEnd()) {
|
||||
throw new MalformedCookieException("Cookie value is invalid: '" + header.toString() + "'");
|
||||
}
|
||||
final int valueDelim = buffer.charAt(cursor.getPos());
|
||||
cursor.updatePos(cursor.getPos() + 1);
|
||||
if (valueDelim != '=') {
|
||||
throw new MalformedCookieException("Cookie value is invalid: '" + header.toString() + "'");
|
||||
}
|
||||
final String value = tokenParser.parseValue(buffer, cursor, VALUE_DELIMS);
|
||||
if (!cursor.atEnd()) {
|
||||
cursor.updatePos(cursor.getPos() + 1);
|
||||
}
|
||||
final BasicClientCookie cookie = new BasicClientCookie(name, value);
|
||||
cookie.setPath(getDefaultPath(origin));
|
||||
cookie.setDomain(getDefaultDomain(origin));
|
||||
cookie.setCreationDate(new Date());
|
||||
|
||||
final Map<String, String> attribMap = new LinkedHashMap<String, String>();
|
||||
while (!cursor.atEnd()) {
|
||||
final String paramName = tokenParser.parseToken(buffer, cursor, TOKEN_DELIMS);
|
||||
String paramValue = null;
|
||||
if (!cursor.atEnd()) {
|
||||
final int paramDelim = buffer.charAt(cursor.getPos());
|
||||
cursor.updatePos(cursor.getPos() + 1);
|
||||
if (paramDelim == EQUAL_CHAR) {
|
||||
paramValue = tokenParser.parseToken(buffer, cursor, VALUE_DELIMS);
|
||||
if (!cursor.atEnd()) {
|
||||
cursor.updatePos(cursor.getPos() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
cookie.setAttribute(paramName.toLowerCase(Locale.ROOT), paramValue);
|
||||
attribMap.put(paramName, paramValue);
|
||||
}
|
||||
// Ignore 'Expires' if 'Max-Age' is present
|
||||
if (attribMap.containsKey(ClientCookie.MAX_AGE_ATTR)) {
|
||||
attribMap.remove(ClientCookie.EXPIRES_ATTR);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry: attribMap.entrySet()) {
|
||||
final String paramName = entry.getKey();
|
||||
final String paramValue = entry.getValue();
|
||||
final CookieAttributeHandler handler = this.attribHandlerMap.get(paramName);
|
||||
if (handler != null) {
|
||||
handler.parse(cookie, paramValue);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.<Cookie>singletonList(cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void validate(final Cookie cookie, final CookieOrigin origin)
|
||||
throws MalformedCookieException {
|
||||
Args.notNull(cookie, "Cookie");
|
||||
Args.notNull(origin, "Cookie origin");
|
||||
for (final CookieAttributeHandler handler: this.attribHandlers) {
|
||||
handler.validate(cookie, origin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean match(final Cookie cookie, final CookieOrigin origin) {
|
||||
Args.notNull(cookie, "Cookie");
|
||||
Args.notNull(origin, "Cookie origin");
|
||||
for (final CookieAttributeHandler handler: this.attribHandlers) {
|
||||
if (!handler.match(cookie, origin)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Header> formatCookies(final List<Cookie> cookies) {
|
||||
Args.notEmpty(cookies, "List of cookies");
|
||||
final List<? extends Cookie> sortedCookies;
|
||||
if (cookies.size() > 1) {
|
||||
// Create a mutable copy and sort the copy.
|
||||
sortedCookies = new ArrayList<Cookie>(cookies);
|
||||
Collections.sort(sortedCookies, CookiePriorityComparator.INSTANCE);
|
||||
} else {
|
||||
sortedCookies = cookies;
|
||||
}
|
||||
final CharArrayBuffer buffer = new CharArrayBuffer(20 * sortedCookies.size());
|
||||
buffer.append(SM.COOKIE);
|
||||
buffer.append(": ");
|
||||
for (int n = 0; n < sortedCookies.size(); n++) {
|
||||
final Cookie cookie = sortedCookies.get(n);
|
||||
if (n > 0) {
|
||||
buffer.append(PARAM_DELIMITER);
|
||||
buffer.append(' ');
|
||||
}
|
||||
buffer.append(cookie.getName());
|
||||
final String s = cookie.getValue();
|
||||
if (s != null) {
|
||||
buffer.append(EQUAL_CHAR);
|
||||
if (containsSpecialChar(s)) {
|
||||
buffer.append(DQUOTE_CHAR);
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
final char ch = s.charAt(i);
|
||||
if (ch == DQUOTE_CHAR || ch == ESCAPE_CHAR) {
|
||||
buffer.append(ESCAPE_CHAR);
|
||||
}
|
||||
buffer.append(ch);
|
||||
}
|
||||
buffer.append(DQUOTE_CHAR);
|
||||
} else {
|
||||
buffer.append(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
final List<Header> headers = new ArrayList<Header>(1);
|
||||
headers.add(new BufferedHeader(buffer));
|
||||
return headers;
|
||||
}
|
||||
|
||||
boolean containsSpecialChar(final CharSequence s) {
|
||||
return containsChars(s, SPECIAL_CHARS);
|
||||
}
|
||||
|
||||
boolean containsChars(final CharSequence s, final BitSet chars) {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
final char ch = s.charAt(i);
|
||||
if (chars.get(ch)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Header getVersionHeader() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.impl.cookie;
|
||||
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.conn.util.PublicSuffixMatcher;
|
||||
import org.apache.http.cookie.Cookie;
|
||||
import org.apache.http.cookie.CookieOrigin;
|
||||
import org.apache.http.cookie.CookieSpec;
|
||||
import org.apache.http.cookie.CookieSpecProvider;
|
||||
import org.apache.http.cookie.MalformedCookieException;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
* {@link org.apache.http.cookie.CookieSpecProvider} implementation that provides an instance of
|
||||
* RFC 6265 conformant cookie policy. The instance returned by this factory can be shared by
|
||||
* multiple threads.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@Immutable
|
||||
public class RFC6265CookieSpecProvider implements CookieSpecProvider {
|
||||
|
||||
public enum CompatibilityLevel {
|
||||
STRICT,
|
||||
RELAXED,
|
||||
IE_MEDIUM_SECURITY
|
||||
}
|
||||
|
||||
private final CompatibilityLevel compatibilityLevel;
|
||||
private final PublicSuffixMatcher publicSuffixMatcher;
|
||||
|
||||
private volatile CookieSpec cookieSpec;
|
||||
|
||||
public RFC6265CookieSpecProvider(
|
||||
final CompatibilityLevel compatibilityLevel,
|
||||
final PublicSuffixMatcher publicSuffixMatcher) {
|
||||
super();
|
||||
this.compatibilityLevel = compatibilityLevel != null ? compatibilityLevel : CompatibilityLevel.RELAXED;
|
||||
this.publicSuffixMatcher = publicSuffixMatcher;
|
||||
}
|
||||
|
||||
public RFC6265CookieSpecProvider(final PublicSuffixMatcher publicSuffixMatcher) {
|
||||
this(CompatibilityLevel.RELAXED, publicSuffixMatcher);
|
||||
}
|
||||
|
||||
public RFC6265CookieSpecProvider() {
|
||||
this(CompatibilityLevel.RELAXED, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CookieSpec create(final HttpContext context) {
|
||||
if (cookieSpec == null) {
|
||||
synchronized (this) {
|
||||
if (cookieSpec == null) {
|
||||
switch (this.compatibilityLevel) {
|
||||
case STRICT:
|
||||
this.cookieSpec = new RFC6265StrictSpec(
|
||||
new BasicPathHandler(),
|
||||
PublicSuffixDomainFilter.decorate(
|
||||
new BasicDomainHandler(), this.publicSuffixMatcher),
|
||||
new BasicMaxAgeHandler(),
|
||||
new BasicSecureHandler(),
|
||||
new BasicExpiresHandler(RFC6265StrictSpec.DATE_PATTERNS));
|
||||
case IE_MEDIUM_SECURITY:
|
||||
this.cookieSpec = new RFC6265LaxSpec(
|
||||
new BasicPathHandler() {
|
||||
@Override
|
||||
public void validate(
|
||||
final Cookie cookie,
|
||||
final CookieOrigin origin) throws MalformedCookieException {
|
||||
// No validation
|
||||
}
|
||||
},
|
||||
PublicSuffixDomainFilter.decorate(
|
||||
new BasicDomainHandler(), this.publicSuffixMatcher),
|
||||
new BasicMaxAgeHandler(),
|
||||
new BasicSecureHandler(),
|
||||
new BasicExpiresHandler(RFC6265StrictSpec.DATE_PATTERNS));
|
||||
default:
|
||||
this.cookieSpec = new RFC6265LaxSpec(
|
||||
new BasicPathHandler(),
|
||||
PublicSuffixDomainFilter.decorate(
|
||||
new BasicDomainHandler(), this.publicSuffixMatcher),
|
||||
new LaxMaxAgeHandler(),
|
||||
new BasicSecureHandler(),
|
||||
new LaxExpiresHandler());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.cookieSpec;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.impl.cookie;
|
||||
|
||||
import org.apache.http.annotation.ThreadSafe;
|
||||
import org.apache.http.cookie.CommonCookieAttributeHandler;
|
||||
|
||||
/**
|
||||
* Standard {@link org.apache.http.cookie.CookieSpec} implementation that enforces a more relaxed
|
||||
* interpretation of the HTTP state management specification (RFC 6265, section 5)
|
||||
* for interoprability with existing servers that do not conform to the well behaved profile
|
||||
* (RFC 6265, section 4).
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class RFC6265LaxSpec extends RFC6265CookieSpecBase {
|
||||
|
||||
public RFC6265LaxSpec() {
|
||||
super(new BasicPathHandler(),
|
||||
new BasicDomainHandler(),
|
||||
new LaxMaxAgeHandler(),
|
||||
new BasicSecureHandler(),
|
||||
new LaxExpiresHandler());
|
||||
}
|
||||
|
||||
RFC6265LaxSpec(final CommonCookieAttributeHandler... handlers) {
|
||||
super(handlers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "rfc6265-lax";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.impl.cookie;
|
||||
|
||||
import org.apache.http.annotation.ThreadSafe;
|
||||
import org.apache.http.client.utils.DateUtils;
|
||||
import org.apache.http.cookie.CommonCookieAttributeHandler;
|
||||
|
||||
/**
|
||||
* Standard {@link org.apache.http.cookie.CookieSpec} implementation that enforces syntax
|
||||
* and semantics of the well-behaved profile of the HTTP state management specification
|
||||
* (RFC 6265, section 4).
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class RFC6265StrictSpec extends RFC6265CookieSpecBase {
|
||||
|
||||
final static String[] DATE_PATTERNS = {
|
||||
DateUtils.PATTERN_RFC1123,
|
||||
DateUtils.PATTERN_RFC1036,
|
||||
DateUtils.PATTERN_ASCTIME
|
||||
};
|
||||
|
||||
public RFC6265StrictSpec() {
|
||||
super(new BasicPathHandler(),
|
||||
new BasicDomainHandler(),
|
||||
new BasicMaxAgeHandler(),
|
||||
new BasicSecureHandler(),
|
||||
new BasicExpiresHandler(DATE_PATTERNS));
|
||||
}
|
||||
|
||||
RFC6265StrictSpec(final CommonCookieAttributeHandler... handlers) {
|
||||
super(handlers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "rfc6265-strict";
|
||||
}
|
||||
|
||||
}
|
@ -57,6 +57,7 @@
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class TestRequestAddCookies {
|
||||
|
||||
@ -371,10 +372,13 @@ public void testExcludeExpiredCookies() throws Exception {
|
||||
cookie3.setVersion(1);
|
||||
cookie3.setDomain("localhost.local");
|
||||
cookie3.setPath("/");
|
||||
cookie3.setExpiryDate(new Date(System.currentTimeMillis() - (24 * 60 * 60 * 1000)));
|
||||
|
||||
cookie3.setExpiryDate(new Date(System.currentTimeMillis() + 100));
|
||||
this.cookieStore.addCookie(cookie3);
|
||||
|
||||
Assert.assertEquals(3, this.cookieStore.getCookies().size());
|
||||
|
||||
this.cookieStore = Mockito.spy(this.cookieStore);
|
||||
|
||||
final HttpRoute route = new HttpRoute(this.target, null, false);
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
@ -383,6 +387,9 @@ public void testExcludeExpiredCookies() throws Exception {
|
||||
context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
|
||||
context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
|
||||
|
||||
// Make sure the third cookie expires
|
||||
Thread.sleep(200);
|
||||
|
||||
final HttpRequestInterceptor interceptor = new RequestAddCookies();
|
||||
interceptor.process(request, context);
|
||||
|
||||
@ -394,6 +401,8 @@ public void testExcludeExpiredCookies() throws Exception {
|
||||
final Header[] headers2 = request.getHeaders(SM.COOKIE2);
|
||||
Assert.assertNotNull(headers2);
|
||||
Assert.assertEquals(0, headers2.length);
|
||||
|
||||
Mockito.verify(this.cookieStore, Mockito.times(1)).clearExpired(Mockito.<Date>any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.http.impl.cookie.BasicClientCookie;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Test cases for {@link org.apache.http.cookie.CookiePriorityComparator}.
|
||||
*/
|
||||
public class TestCookiePriorityComparator {
|
||||
|
||||
private Comparator<Cookie> comparator;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
comparator = CookiePriorityComparator.INSTANCE;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnequality() {
|
||||
final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value");
|
||||
cookie1.setPath("/a/b/");
|
||||
final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value");
|
||||
cookie2.setPath("/a/");
|
||||
Assert.assertTrue(comparator.compare(cookie1, cookie2) < 0);
|
||||
Assert.assertTrue(comparator.compare(cookie2, cookie1) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquality() {
|
||||
final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value");
|
||||
cookie1.setPath("/a");
|
||||
final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value");
|
||||
cookie2.setPath("/a");
|
||||
Assert.assertTrue(comparator.compare(cookie1, cookie2) == 0);
|
||||
Assert.assertTrue(comparator.compare(cookie2, cookie1) == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnequalityTrailingSlash() {
|
||||
final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value");
|
||||
cookie1.setPath("/a/");
|
||||
final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value");
|
||||
cookie2.setPath("/a");
|
||||
Assert.assertTrue(comparator.compare(cookie1, cookie2) < 0);
|
||||
Assert.assertTrue(comparator.compare(cookie2, cookie1) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualityNullPath() {
|
||||
final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value");
|
||||
cookie1.setPath(null);
|
||||
final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value");
|
||||
cookie2.setPath("/");
|
||||
Assert.assertTrue(comparator.compare(cookie1, cookie2) == 0);
|
||||
Assert.assertTrue(comparator.compare(cookie2, cookie1) == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualitySameLength() {
|
||||
final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value");
|
||||
cookie1.setPath("/this");
|
||||
final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value");
|
||||
cookie2.setPath("/that");
|
||||
Assert.assertTrue(comparator.compare(cookie1, cookie2) == 0);
|
||||
Assert.assertTrue(comparator.compare(cookie2, cookie1) == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnequalityCreationDate() {
|
||||
final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value");
|
||||
cookie1.setPath("/blah");
|
||||
cookie1.setCreationDate(new Date(System.currentTimeMillis() - 200000));
|
||||
final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value");
|
||||
cookie2.setPath("/blah");
|
||||
cookie2.setCreationDate(new Date(System.currentTimeMillis()));
|
||||
Assert.assertTrue(comparator.compare(cookie1, cookie2) < 0);
|
||||
Assert.assertTrue(comparator.compare(cookie2, cookie1) > 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,143 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.impl.cookie;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.Header;
|
||||
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;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestAbstractCookieSpec {
|
||||
|
||||
private static class DummyCookieSpec extends AbstractCookieSpec {
|
||||
|
||||
@Override
|
||||
public List<Header> formatCookies(final List<Cookie> cookies) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(final Cookie cookie, final CookieOrigin origin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> parse(final Header header, final CookieOrigin origin) throws MalformedCookieException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header getVersionHeader() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DummyCookieAttribHandler implements CookieAttributeHandler {
|
||||
|
||||
@Override
|
||||
public boolean match(final Cookie cookie, final CookieOrigin origin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(final SetCookie cookie, final String value) throws MalformedCookieException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRegisterAndGet() {
|
||||
final CookieAttributeHandler h1 = new DummyCookieAttribHandler();
|
||||
final CookieAttributeHandler h2 = new DummyCookieAttribHandler();
|
||||
|
||||
final AbstractCookieSpec cookiespec = new DummyCookieSpec();
|
||||
cookiespec.registerAttribHandler("this", h1);
|
||||
cookiespec.registerAttribHandler("that", h2);
|
||||
cookiespec.registerAttribHandler("thistoo", h1);
|
||||
cookiespec.registerAttribHandler("thattoo", h2);
|
||||
|
||||
Assert.assertTrue(h1 == cookiespec.getAttribHandler("this"));
|
||||
Assert.assertTrue(h2 == cookiespec.getAttribHandler("that"));
|
||||
Assert.assertTrue(h1 == cookiespec.getAttribHandler("thistoo"));
|
||||
Assert.assertTrue(h2 == cookiespec.getAttribHandler("thattoo"));
|
||||
|
||||
final Iterator<CookieAttributeHandler> it = cookiespec.getAttribHandlers().iterator();
|
||||
Assert.assertNotNull(it.next());
|
||||
Assert.assertNotNull(it.next());
|
||||
Assert.assertNotNull(it.next());
|
||||
Assert.assertNotNull(it.next());
|
||||
Assert.assertFalse(it.hasNext());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testInvalidHandler() {
|
||||
final CookieAttributeHandler h1 = new DummyCookieAttribHandler();
|
||||
final CookieAttributeHandler h2 = new DummyCookieAttribHandler();
|
||||
|
||||
final AbstractCookieSpec cookiespec = new DummyCookieSpec();
|
||||
cookiespec.registerAttribHandler("this", h1);
|
||||
cookiespec.registerAttribHandler("that", h2);
|
||||
|
||||
Assert.assertNull(cookiespec.findAttribHandler("whatever"));
|
||||
cookiespec.getAttribHandler("whatever");
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testBasicPathInvalidInput1() throws Exception {
|
||||
final AbstractCookieSpec cookiespec = new DummyCookieSpec();
|
||||
cookiespec.registerAttribHandler(null, null);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testBasicPathInvalidInput2() throws Exception {
|
||||
final AbstractCookieSpec cookiespec = new DummyCookieSpec();
|
||||
cookiespec.registerAttribHandler("whatever", null);
|
||||
}
|
||||
|
||||
}
|
@ -35,6 +35,7 @@
|
||||
|
||||
import org.apache.http.client.utils.DateUtils;
|
||||
import org.apache.http.conn.util.PublicSuffixMatcher;
|
||||
import org.apache.http.cookie.ClientCookie;
|
||||
import org.apache.http.cookie.CookieAttributeHandler;
|
||||
import org.apache.http.cookie.CookieOrigin;
|
||||
import org.apache.http.cookie.MalformedCookieException;
|
||||
@ -140,6 +141,7 @@ public void testBasicDomainMatch1() throws Exception {
|
||||
final CookieAttributeHandler h = new BasicDomainHandler();
|
||||
|
||||
cookie.setDomain("somedomain.com");
|
||||
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "somedomain.com");
|
||||
Assert.assertTrue(h.match(cookie, origin));
|
||||
|
||||
cookie.setDomain(".somedomain.com");
|
||||
@ -153,6 +155,7 @@ public void testBasicDomainMatch2() throws Exception {
|
||||
final CookieAttributeHandler h = new BasicDomainHandler();
|
||||
|
||||
cookie.setDomain("somedomain.com");
|
||||
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "somedomain.com");
|
||||
Assert.assertTrue(h.match(cookie, origin));
|
||||
|
||||
cookie.setDomain(".somedomain.com");
|
||||
@ -162,6 +165,28 @@ public void testBasicDomainMatch2() throws Exception {
|
||||
Assert.assertFalse(h.match(cookie, origin));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicDomainMatchOneLetterPrefix() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieOrigin origin = new CookieOrigin("a.somedomain.com", 80, "/", false);
|
||||
final CookieAttributeHandler h = new BasicDomainHandler();
|
||||
|
||||
cookie.setDomain("somedomain.com");
|
||||
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "somedomain.com");
|
||||
Assert.assertTrue(h.match(cookie, origin));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicDomainMatchMixedCase() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieOrigin origin = new CookieOrigin("a.SomeDomain.com", 80, "/", false);
|
||||
final CookieAttributeHandler h = new BasicDomainHandler();
|
||||
|
||||
cookie.setDomain("somedoMain.Com");
|
||||
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "somedoMain.Com");
|
||||
Assert.assertTrue(h.match(cookie, origin));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicDomainInvalidInput() throws Exception {
|
||||
final CookieAttributeHandler h = new BasicDomainHandler();
|
||||
|
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.impl.cookie;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.http.cookie.CookieAttributeHandler;
|
||||
import org.apache.http.cookie.MalformedCookieException;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestLaxCookieAttribHandlers {
|
||||
|
||||
@Test
|
||||
public void testParseMaxAge() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxMaxAgeHandler();
|
||||
h.parse(cookie, "2000");
|
||||
Assert.assertNotNull(cookie.getExpiryDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseMaxNegative() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxMaxAgeHandler();
|
||||
h.parse(cookie, "-2000");
|
||||
Assert.assertNotNull(cookie.getExpiryDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseMaxZero() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxMaxAgeHandler();
|
||||
h.parse(cookie, "0000");
|
||||
Assert.assertNotNull(cookie.getExpiryDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicMaxAgeParseEmpty() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxMaxAgeHandler();
|
||||
h.parse(cookie, " ");
|
||||
Assert.assertNull(cookie.getExpiryDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicMaxAgeParseInvalid() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxMaxAgeHandler();
|
||||
h.parse(cookie, "garbage");
|
||||
Assert.assertNull(cookie.getExpiryDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicMaxAgeInvalidInput() throws Exception {
|
||||
final CookieAttributeHandler h = new LaxMaxAgeHandler();
|
||||
try {
|
||||
h.parse(null, "stuff");
|
||||
Assert.fail("IllegalArgumentException must have been thrown");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testExpiryGarbage() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, ";;blah,blah;yada ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseExpiry() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "1:0:12 8-jan-2012");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2012, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.JANUARY, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(8, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(1, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(0, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(12, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidTime1() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "1:0:122 8 dec 1980");
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidTime2() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "24:00:00 8 dec 1980");
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidTime3() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:60:00 8 dec 1980");
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidTime4() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:00:60 8 dec 1980");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseExpiryFunnyTime() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "1:59:00blah; 8-feb-2000");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2000, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.FEBRUARY, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(8, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(1, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(59, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(0, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidDayOfMonth1() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "12:00:00 888 mar 1880");
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidDayOfMonth2() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "12:00:00 0 mar 1880");
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidDayOfMonth3() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "12:00:00 32 mar 1880");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseExpiryFunnyDayOfMonth() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "12:00:00 8blah;mar;1880");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(1880, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.MARCH, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(8, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(12, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(0, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(0, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidMonth() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "1:00:00 8 dek 80");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseExpiryFunnyMonth() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-ApriLLLLL-2008");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2008, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.APRIL, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(1, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(23, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(59, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(59, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidYearTooShort() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "1:00:00 8 dec 8");
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidYearTooLong() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "1:00:00 8 dec 88888");
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseExpiryInvalidYearTooLongAgo() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "1:00:00 8 dec 1600");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseExpiryFunnyYear() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-Apr-2008blah");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2008, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.APRIL, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(1, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(23, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(59, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(59, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseExpiryYearTwoDigit1() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-Apr-70");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(1970, c.get(Calendar.YEAR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseExpiryYearTwoDigit2() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-Apr-99");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(1999, c.get(Calendar.YEAR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseExpiryYearTwoDigit3() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-Apr-00");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2000, c.get(Calendar.YEAR));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.impl.cookie;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.Header;
|
||||
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;
|
||||
import org.apache.http.cookie.SetCookie;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class TestRFC6265CookieSpecBase {
|
||||
|
||||
@Test
|
||||
public void testParseCookieBasics() throws Exception {
|
||||
final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h1.getAttributeName()).thenReturn("this");
|
||||
final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h2.getAttributeName()).thenReturn("that");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase(h1, h2);
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "name = value ; this = stuff;");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
final List<Cookie> cookies = cookiespec.parse(header, origin);
|
||||
|
||||
Assert.assertEquals(1, cookies.size());
|
||||
final Cookie cookie = cookies.get(0);
|
||||
Assert.assertEquals("name", cookie.getName());
|
||||
Assert.assertEquals("value", cookie.getValue());
|
||||
Assert.assertEquals("/path", cookie.getPath());
|
||||
Assert.assertEquals("host", cookie.getDomain());
|
||||
Assert.assertTrue(cookie instanceof ClientCookie);
|
||||
final ClientCookie clientCookie = (ClientCookie) cookie;
|
||||
Assert.assertEquals("stuff", clientCookie.getAttribute("this"));
|
||||
Assert.assertEquals(null, clientCookie.getAttribute("that"));
|
||||
|
||||
Mockito.verify(h1).parse(Mockito.<SetCookie>any(), Mockito.eq("stuff"));
|
||||
Mockito.verify(h2, Mockito.never()).parse(Mockito.<SetCookie>any(), Mockito.anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCookieQuotedValue() throws Exception {
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase();
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "name = \" one, two, three; four \" ; this = stuff;");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
final List<Cookie> cookies = cookiespec.parse(header, origin);
|
||||
|
||||
Assert.assertEquals(1, cookies.size());
|
||||
final Cookie cookie = cookies.get(0);
|
||||
Assert.assertEquals("name", cookie.getName());
|
||||
Assert.assertEquals(" one, two, three; four ", cookie.getValue());
|
||||
Assert.assertTrue(cookie instanceof ClientCookie);
|
||||
final ClientCookie clientCookie = (ClientCookie) cookie;
|
||||
Assert.assertEquals("stuff", clientCookie.getAttribute("this"));
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseCookieWrongHeader() throws Exception {
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase();
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie2", "blah");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
cookiespec.parse(header, origin);
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseCookieMissingName() throws Exception {
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase();
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "=blah ; this = stuff;");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
cookiespec.parse(header, origin);
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseCookieMissingValue1() throws Exception {
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase();
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "blah");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
cookiespec.parse(header, origin);
|
||||
}
|
||||
|
||||
@Test(expected = MalformedCookieException.class)
|
||||
public void testParseCookieMissingValue2() throws Exception {
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase();
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "blah;");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
cookiespec.parse(header, origin);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCookieEmptyValue() throws Exception {
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase();
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "blah=;");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
final List<Cookie> cookies = cookiespec.parse(header, origin);
|
||||
Assert.assertEquals(1, cookies.size());
|
||||
final Cookie cookie = cookies.get(0);
|
||||
Assert.assertEquals("blah", cookie.getName());
|
||||
Assert.assertEquals("", cookie.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCookieWithAttributes() throws Exception {
|
||||
final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h1.getAttributeName()).thenReturn("this");
|
||||
final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h2.getAttributeName()).thenReturn("that");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase(h1, h2);
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "name = value ; p1 = v ; p2 = v,0; p3 ; p4");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
final List<Cookie> cookies = cookiespec.parse(header, origin);
|
||||
|
||||
Assert.assertEquals(1, cookies.size());
|
||||
final Cookie cookie = cookies.get(0);
|
||||
Assert.assertEquals("name", cookie.getName());
|
||||
Assert.assertEquals("value", cookie.getValue());
|
||||
Assert.assertTrue(cookie instanceof ClientCookie);
|
||||
final ClientCookie clientCookie = (ClientCookie) cookie;
|
||||
Assert.assertEquals("v", clientCookie.getAttribute("p1"));
|
||||
Assert.assertEquals("v,0", clientCookie.getAttribute("p2"));
|
||||
Assert.assertTrue(clientCookie.containsAttribute("p3"));
|
||||
Assert.assertTrue(clientCookie.containsAttribute("p4"));
|
||||
Assert.assertFalse(clientCookie.containsAttribute("p5"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCookieWithAttributes2() throws Exception {
|
||||
final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h1.getAttributeName()).thenReturn("this");
|
||||
final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h2.getAttributeName()).thenReturn("that");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase(h1, h2);
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "name = value ; p1 = v");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
final List<Cookie> cookies = cookiespec.parse(header, origin);
|
||||
|
||||
Assert.assertEquals(1, cookies.size());
|
||||
final Cookie cookie = cookies.get(0);
|
||||
Assert.assertEquals("name", cookie.getName());
|
||||
Assert.assertEquals("value", cookie.getValue());
|
||||
Assert.assertTrue(cookie instanceof ClientCookie);
|
||||
final ClientCookie clientCookie = (ClientCookie) cookie;
|
||||
Assert.assertEquals("v", clientCookie.getAttribute("p1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCookieWithAttributes3() throws Exception {
|
||||
final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h1.getAttributeName()).thenReturn("this");
|
||||
final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h2.getAttributeName()).thenReturn("that");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase(h1, h2);
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "name = value ; p1 =");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
final List<Cookie> cookies = cookiespec.parse(header, origin);
|
||||
|
||||
Assert.assertEquals(1, cookies.size());
|
||||
final Cookie cookie = cookies.get(0);
|
||||
Assert.assertEquals("name", cookie.getName());
|
||||
Assert.assertEquals("value", cookie.getValue());
|
||||
Assert.assertTrue(cookie instanceof ClientCookie);
|
||||
final ClientCookie clientCookie = (ClientCookie) cookie;
|
||||
Assert.assertEquals("", clientCookie.getAttribute("p1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCookieBasics() throws Exception {
|
||||
final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h1.getAttributeName()).thenReturn("this");
|
||||
final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h2.getAttributeName()).thenReturn("that");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase(h1, h2);
|
||||
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
cookiespec.validate(cookie, origin);
|
||||
|
||||
Mockito.verify(h1).validate(cookie, origin);
|
||||
Mockito.verify(h2).validate(cookie, origin);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchCookie() throws Exception {
|
||||
final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h1.getAttributeName()).thenReturn("this");
|
||||
final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h2.getAttributeName()).thenReturn("that");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase(h1, h2);
|
||||
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
|
||||
Mockito.when(h1.match(cookie, origin)).thenReturn(true);
|
||||
Mockito.when(h2.match(cookie, origin)).thenReturn(true);
|
||||
|
||||
Assert.assertTrue(cookiespec.match(cookie, origin));
|
||||
|
||||
Mockito.verify(h1).match(cookie, origin);
|
||||
Mockito.verify(h2).match(cookie, origin);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchCookieNoMatch() throws Exception {
|
||||
final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h1.getAttributeName()).thenReturn("this");
|
||||
final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h2.getAttributeName()).thenReturn("that");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase(h1, h2);
|
||||
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
|
||||
Mockito.when(h1.match(cookie, origin)).thenReturn(false);
|
||||
Mockito.when(h2.match(cookie, origin)).thenReturn(false);
|
||||
|
||||
Assert.assertFalse(cookiespec.match(cookie, origin));
|
||||
|
||||
Mockito.verify(h1).match(cookie, origin);
|
||||
Mockito.verify(h2, Mockito.never()).match(cookie, origin);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLegacy() throws Exception {
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase();
|
||||
|
||||
Assert.assertEquals(0, cookiespec.getVersion());
|
||||
Assert.assertEquals(null, cookiespec.getVersionHeader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatCookiesBasics() throws Exception {
|
||||
final Cookie cookie1 = new BasicClientCookie("name1", "value");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase();
|
||||
final List<Header> headers = cookiespec.formatCookies(Arrays.asList(cookie1));
|
||||
Assert.assertNotNull(headers);
|
||||
Assert.assertEquals(1, headers.size());
|
||||
final Header header = headers.get(0);
|
||||
Assert.assertEquals("Cookie", header.getName());
|
||||
Assert.assertEquals("name1=value", header.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatCookiesIllegalCharsInValue() throws Exception {
|
||||
final Cookie cookie1 = new BasicClientCookie("name1", "value");
|
||||
final Cookie cookie2 = new BasicClientCookie("name2", "some value");
|
||||
final Cookie cookie3 = new BasicClientCookie("name3", "\"\\\"");
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase();
|
||||
final List<Header> headers = cookiespec.formatCookies(Arrays.asList(cookie1, cookie2, cookie3));
|
||||
Assert.assertNotNull(headers);
|
||||
Assert.assertEquals(1, headers.size());
|
||||
final Header header = headers.get(0);
|
||||
Assert.assertEquals("Cookie", header.getName());
|
||||
Assert.assertEquals("name1=value; name2=\"some value\"; name3=\"\\\"\\\\\\\"\"", header.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCookieMultipleAttributes() throws Exception {
|
||||
final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h1.getAttributeName()).thenReturn("this");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase(h1);
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "name = value ; this = stuff; this = morestuff;");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
cookiespec.parse(header, origin);
|
||||
|
||||
Mockito.verify(h1).parse(Mockito.<SetCookie>any(), Mockito.eq("morestuff"));
|
||||
Mockito.verify(h1, Mockito.times(1)).parse(Mockito.<SetCookie>any(), Mockito.anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCookieMaxAgeOverExpires() throws Exception {
|
||||
final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h1.getAttributeName()).thenReturn("Expires");
|
||||
final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
|
||||
Mockito.when(h2.getAttributeName()).thenReturn("Max-Age");
|
||||
|
||||
final RFC6265CookieSpecBase cookiespec = new RFC6265CookieSpecBase(h1, h2);
|
||||
|
||||
final Header header = new BasicHeader("Set-Cookie", "name = value ; expires = stuff; max-age = otherstuff;");
|
||||
final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
|
||||
cookiespec.parse(header, origin);
|
||||
|
||||
Mockito.verify(h1, Mockito.never()).parse(Mockito.<SetCookie>any(), Mockito.anyString());
|
||||
Mockito.verify(h2).parse(Mockito.<SetCookie>any(), Mockito.eq("otherstuff"));
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user