Fixed parsing and validation of RFC2109 compliant Set-Cookie headers by the Best-Match cookie spec
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@708579 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1fb53e28c2
commit
c3b6c426ca
|
@ -1,6 +1,10 @@
|
||||||
Changes since 4.0 beta 1
|
Changes since 4.0 beta 1
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
* Fixed parsing and validation of RFC2109 compliant Set-Cookie headers
|
||||||
|
by the Best-Match cookie spec.
|
||||||
|
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||||
|
|
||||||
* Fixed bug that can cause a managed connection to be returned from the
|
* Fixed bug that can cause a managed connection to be returned from the
|
||||||
pool in an inconsistent state.
|
pool in an inconsistent state.
|
||||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||||
|
|
|
@ -39,6 +39,8 @@ import org.apache.http.cookie.Cookie;
|
||||||
import org.apache.http.cookie.CookieOrigin;
|
import org.apache.http.cookie.CookieOrigin;
|
||||||
import org.apache.http.cookie.CookieSpec;
|
import org.apache.http.cookie.CookieSpec;
|
||||||
import org.apache.http.cookie.MalformedCookieException;
|
import org.apache.http.cookie.MalformedCookieException;
|
||||||
|
import org.apache.http.cookie.SM;
|
||||||
|
import org.apache.http.cookie.SetCookie2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'Meta' cookie specification that selects a cookie policy depending
|
* 'Meta' cookie specification that selects a cookie policy depending
|
||||||
|
@ -54,6 +56,7 @@ public class BestMatchSpec implements CookieSpec {
|
||||||
private final boolean oneHeader;
|
private final boolean oneHeader;
|
||||||
|
|
||||||
private RFC2965Spec strict;
|
private RFC2965Spec strict;
|
||||||
|
private RFC2109Spec obsoleteStrict;
|
||||||
private BrowserCompatSpec compat;
|
private BrowserCompatSpec compat;
|
||||||
private NetscapeDraftSpec netscape;
|
private NetscapeDraftSpec netscape;
|
||||||
|
|
||||||
|
@ -74,6 +77,13 @@ public class BestMatchSpec implements CookieSpec {
|
||||||
return strict;
|
return strict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RFC2109Spec getObsoleteStrict() {
|
||||||
|
if (this.obsoleteStrict == null) {
|
||||||
|
this.obsoleteStrict = new RFC2109Spec(this.datepatterns, this.oneHeader);
|
||||||
|
}
|
||||||
|
return obsoleteStrict;
|
||||||
|
}
|
||||||
|
|
||||||
private BrowserCompatSpec getCompat() {
|
private BrowserCompatSpec getCompat() {
|
||||||
if (this.compat == null) {
|
if (this.compat == null) {
|
||||||
this.compat = new BrowserCompatSpec(this.datepatterns);
|
this.compat = new BrowserCompatSpec(this.datepatterns);
|
||||||
|
@ -111,13 +121,14 @@ public class BestMatchSpec implements CookieSpec {
|
||||||
if (helem.getParameterByName("expires") != null) {
|
if (helem.getParameterByName("expires") != null) {
|
||||||
netscape = true;
|
netscape = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (netscape) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// Do we have a cookie with a version attribute?
|
// Do we have a cookie with a version attribute?
|
||||||
if (versioned) {
|
if (versioned) {
|
||||||
return getStrict().parse(helems, origin);
|
if (SM.SET_COOKIE2.equals(header.getName())) {
|
||||||
|
return getStrict().parse(helems, origin);
|
||||||
|
} else {
|
||||||
|
return getObsoleteStrict().parse(helems, origin);
|
||||||
|
}
|
||||||
} else if (netscape) {
|
} else if (netscape) {
|
||||||
// Need to parse the header again,
|
// Need to parse the header again,
|
||||||
// because Netscape draft cannot handle
|
// because Netscape draft cannot handle
|
||||||
|
@ -138,7 +149,11 @@ public class BestMatchSpec implements CookieSpec {
|
||||||
throw new IllegalArgumentException("Cookie origin may not be null");
|
throw new IllegalArgumentException("Cookie origin may not be null");
|
||||||
}
|
}
|
||||||
if (cookie.getVersion() > 0) {
|
if (cookie.getVersion() > 0) {
|
||||||
getStrict().validate(cookie, origin);
|
if (cookie instanceof SetCookie2) {
|
||||||
|
getStrict().validate(cookie, origin);
|
||||||
|
} else {
|
||||||
|
getObsoleteStrict().validate(cookie, origin);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
getCompat().validate(cookie, origin);
|
getCompat().validate(cookie, origin);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +167,11 @@ public class BestMatchSpec implements CookieSpec {
|
||||||
throw new IllegalArgumentException("Cookie origin may not be null");
|
throw new IllegalArgumentException("Cookie origin may not be null");
|
||||||
}
|
}
|
||||||
if (cookie.getVersion() > 0) {
|
if (cookie.getVersion() > 0) {
|
||||||
return getStrict().match(cookie, origin);
|
if (cookie instanceof SetCookie2) {
|
||||||
|
return getStrict().match(cookie, origin);
|
||||||
|
} else {
|
||||||
|
return getObsoleteStrict().match(cookie, origin);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return getCompat().match(cookie, origin);
|
return getCompat().match(cookie, origin);
|
||||||
}
|
}
|
||||||
|
@ -163,13 +182,21 @@ public class BestMatchSpec implements CookieSpec {
|
||||||
throw new IllegalArgumentException("List of cookie may not be null");
|
throw new IllegalArgumentException("List of cookie may not be null");
|
||||||
}
|
}
|
||||||
int version = Integer.MAX_VALUE;
|
int version = Integer.MAX_VALUE;
|
||||||
|
boolean isSetCookie2 = true;
|
||||||
for (Cookie cookie: cookies) {
|
for (Cookie cookie: cookies) {
|
||||||
|
if (!(cookie instanceof SetCookie2)) {
|
||||||
|
isSetCookie2 = false;
|
||||||
|
}
|
||||||
if (cookie.getVersion() < version) {
|
if (cookie.getVersion() < version) {
|
||||||
version = cookie.getVersion();
|
version = cookie.getVersion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (version > 0) {
|
if (version > 0) {
|
||||||
return getStrict().formatCookies(cookies);
|
if (isSetCookie2) {
|
||||||
|
return getStrict().formatCookies(cookies);
|
||||||
|
} else {
|
||||||
|
return getObsoleteStrict().formatCookies(cookies);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return getCompat().formatCookies(cookies);
|
return getCompat().formatCookies(cookies);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,15 +106,24 @@ public class TestCookieBestMatchSpec extends TestCase {
|
||||||
CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false);
|
CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false);
|
||||||
|
|
||||||
// Make sure the strict (RFC2965) cookie parsing
|
// Make sure the strict (RFC2965) cookie parsing
|
||||||
// and validation is used for version 1 cookies
|
// and validation is used for version 1 Set-Cookie2 headers
|
||||||
Header header = new BasicHeader("Set-Cookie", "name=value;path=/;domain=b.domain.com; version=1");
|
Header header = new BasicHeader("Set-Cookie2", "name=value;path=/;domain=b.domain.com; version=1");
|
||||||
|
|
||||||
List<Cookie> cookies = cookiespec.parse(header, origin);
|
List<Cookie> cookies = cookiespec.parse(header, origin);
|
||||||
for (int i = 0; i < cookies.size(); i++) {
|
for (int i = 0; i < cookies.size(); i++) {
|
||||||
cookiespec.validate(cookies.get(i), origin);
|
cookiespec.validate(cookies.get(i), origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
header = new BasicHeader("Set-Cookie", "name=value;path=/;domain=domain.com; version=1");
|
// Make sure the strict (RFC2109) cookie parsing
|
||||||
|
// and validation is used for version 1 Set-Cookie headers
|
||||||
|
header = new BasicHeader("Set-Cookie", "name=value;path=/;domain=.b.domain.com; version=1");
|
||||||
|
|
||||||
|
cookies = cookiespec.parse(header, origin);
|
||||||
|
for (int i = 0; i < cookies.size(); i++) {
|
||||||
|
cookiespec.validate(cookies.get(i), origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
header = new BasicHeader("Set-Cookie2", "name=value;path=/;domain=domain.com; version=1");
|
||||||
try {
|
try {
|
||||||
cookies = cookiespec.parse(header, origin);
|
cookies = cookiespec.parse(header, origin);
|
||||||
cookiespec.validate(cookies.get(0), origin);
|
cookiespec.validate(cookies.get(0), origin);
|
||||||
|
@ -134,8 +143,8 @@ public class TestCookieBestMatchSpec extends TestCase {
|
||||||
for (int i = 0; i < cookies.size(); i++) {
|
for (int i = 0; i < cookies.size(); i++) {
|
||||||
Cookie cookie = cookies.get(i);
|
Cookie cookie = cookies.get(i);
|
||||||
cookiespec.validate(cookie, origin);
|
cookiespec.validate(cookie, origin);
|
||||||
assertEquals("localhost.local", cookie.getDomain());
|
assertEquals("localhost", cookie.getDomain());
|
||||||
assertTrue(cookie instanceof SetCookie2);
|
assertFalse(cookie instanceof SetCookie2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +184,7 @@ public class TestCookieBestMatchSpec extends TestCase {
|
||||||
|
|
||||||
// Make sure the strict (RFC2965) cookie matching
|
// Make sure the strict (RFC2965) cookie matching
|
||||||
// is used for version 1 cookies
|
// is used for version 1 cookies
|
||||||
BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
BasicClientCookie2 cookie = new BasicClientCookie2("name", "value");
|
||||||
cookie.setVersion(1);
|
cookie.setVersion(1);
|
||||||
cookie.setDomain(".domain.com");
|
cookie.setDomain(".domain.com");
|
||||||
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain());
|
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain());
|
||||||
|
|
Loading…
Reference in New Issue