* RFC2965 now rejects Set-Cookie headers as unrecognized

* Changed CookieIdentityComparator to correctly compare domain attributes of cookies transmitted with SetCookie and SetCookie2 headers



git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@708890 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2008-10-29 12:31:57 +00:00
parent e434f1367a
commit 379a83514a
11 changed files with 164 additions and 66 deletions

View File

@ -53,6 +53,7 @@ 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.CookieSpecRegistry; import org.apache.http.cookie.CookieSpecRegistry;
import org.apache.http.cookie.SetCookie2;
import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.ExecutionContext;
@ -174,7 +175,7 @@ public class RequestAddCookies implements HttpRequestInterceptor {
if (ver > 0) { if (ver > 0) {
boolean needVersionHeader = false; boolean needVersionHeader = false;
for (Cookie cookie : matchedCookies) { for (Cookie cookie : matchedCookies) {
if (ver != cookie.getVersion()) { if (ver != cookie.getVersion() || !(cookie instanceof SetCookie2)) {
needVersionHeader = true; needVersionHeader = true;
} }
} }

View File

@ -86,7 +86,7 @@ public class ResponseProcessCookies implements HttpResponseInterceptor {
CookieStore cookieStore = (CookieStore) context.getAttribute( CookieStore cookieStore = (CookieStore) context.getAttribute(
ClientContext.COOKIE_STORE); ClientContext.COOKIE_STORE);
if (cookieStore == null) { if (cookieStore == null) {
this.log.info("Cookie store not available in HTTP context"); this.log.info("CookieStore not available in HTTP context");
return; return;
} }
// Obtain actual CookieOrigin instance // Obtain actual CookieOrigin instance

View File

@ -55,10 +55,14 @@ public class CookieIdentityComparator implements Serializable, Comparator<Cookie
String d1 = c1.getDomain(); String d1 = c1.getDomain();
if (d1 == null) { if (d1 == null) {
d1 = ""; d1 = "";
} else if (d1.indexOf('.') == -1) {
d1 = d1 + ".local";
} }
String d2 = c2.getDomain(); String d2 = c2.getDomain();
if (d2 == null) { if (d2 == null) {
d2 = ""; d2 = "";
} else if (d2.indexOf('.') == -1) {
d2 = d2 + ".local";
} }
res = d1.compareToIgnoreCase(d2); res = d1.compareToIgnoreCase(d2);
} }

View File

@ -108,7 +108,12 @@ public class BrowserCompatSpec extends CookieSpecBase {
if (origin == null) { if (origin == null) {
throw new IllegalArgumentException("Cookie origin may not be null"); throw new IllegalArgumentException("Cookie origin may not be null");
} }
String headername = header.getName();
String headervalue = header.getValue(); String headervalue = header.getValue();
if (!headername.equalsIgnoreCase(SM.SET_COOKIE)) {
throw new MalformedCookieException("Unrecognized cookie header '"
+ header.toString() + "'");
}
boolean isNetscapeCookie = false; boolean isNetscapeCookie = false;
int i1 = headervalue.toLowerCase(Locale.ENGLISH).indexOf("expires="); int i1 = headervalue.toLowerCase(Locale.ENGLISH).indexOf("expires=");
if (i1 != -1) { if (i1 != -1) {

View File

@ -124,6 +124,10 @@ public class NetscapeDraftSpec extends CookieSpecBase {
if (origin == null) { if (origin == null) {
throw new IllegalArgumentException("Cookie origin may not be null"); throw new IllegalArgumentException("Cookie origin may not be null");
} }
if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) {
throw new MalformedCookieException("Unrecognized cookie header '"
+ header.toString() + "'");
}
NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT;
CharArrayBuffer buffer; CharArrayBuffer buffer;
ParserCursor cursor; ParserCursor cursor;

View File

@ -108,6 +108,10 @@ public class RFC2109Spec extends CookieSpecBase {
if (origin == null) { if (origin == null) {
throw new IllegalArgumentException("Cookie origin may not be null"); throw new IllegalArgumentException("Cookie origin may not be null");
} }
if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) {
throw new MalformedCookieException("Unrecognized cookie header '"
+ header.toString() + "'");
}
HeaderElement[] elems = header.getElements(); HeaderElement[] elems = header.getElements();
return parse(elems, origin); return parse(elems, origin);
} }

View File

@ -58,44 +58,6 @@ import org.apache.http.util.CharArrayBuffer;
*/ */
public class RFC2965Spec extends RFC2109Spec { public class RFC2965Spec extends RFC2109Spec {
private static final ClientCookieFactory COOKIE_FACTORY = new BasicClientCookieFactory();
private static final ClientCookieFactory COOKIE2_FACTORY = new BasicClientCookie2Factory();
private static interface ClientCookieFactory {
BasicClientCookie createCookie(String name, String value, CookieOrigin origin);
}
private static class BasicClientCookieFactory implements ClientCookieFactory {
public BasicClientCookie createCookie(
final String name,
final String value,
final CookieOrigin origin) {
BasicClientCookie cookie = new BasicClientCookie(name, value);
cookie.setPath(getDefaultPath(origin));
cookie.setDomain(getDefaultDomain(origin));
return cookie;
}
}
private static class BasicClientCookie2Factory implements ClientCookieFactory {
public BasicClientCookie createCookie(
final String name,
final String value,
final CookieOrigin origin) {
BasicClientCookie2 cookie = new BasicClientCookie2(name, value);
cookie.setPath(getDefaultPath(origin));
cookie.setDomain(getDefaultDomain(origin));
cookie.setPorts(new int [] { origin.getPort() });
return cookie;
}
}
/** /**
* Default constructor * Default constructor
* *
@ -123,16 +85,13 @@ public class RFC2965Spec extends RFC2109Spec {
if (origin == null) { if (origin == null) {
throw new IllegalArgumentException("Cookie origin may not be null"); throw new IllegalArgumentException("Cookie origin may not be null");
} }
if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE2)) {
throw new MalformedCookieException("Unrecognized cookie header '"
+ header.toString() + "'");
}
origin = adjustEffectiveHost(origin); origin = adjustEffectiveHost(origin);
HeaderElement[] elems = header.getElements(); HeaderElement[] elems = header.getElements();
ClientCookieFactory cookieFactory; return createCookies(elems, origin);
if (header.getName().equals(SM.SET_COOKIE2)) {
cookieFactory = COOKIE2_FACTORY;
} else {
cookieFactory = COOKIE_FACTORY;
}
return createCookies(elems, origin, cookieFactory);
} }
@Override @Override
@ -140,13 +99,12 @@ public class RFC2965Spec extends RFC2109Spec {
final HeaderElement[] elems, final HeaderElement[] elems,
CookieOrigin origin) throws MalformedCookieException { CookieOrigin origin) throws MalformedCookieException {
origin = adjustEffectiveHost(origin); origin = adjustEffectiveHost(origin);
return createCookies(elems, origin, COOKIE2_FACTORY); return createCookies(elems, origin);
} }
private List<Cookie> createCookies( private List<Cookie> createCookies(
final HeaderElement[] elems, final HeaderElement[] elems,
final CookieOrigin origin, final CookieOrigin origin) throws MalformedCookieException {
final ClientCookieFactory cookieFactory) throws MalformedCookieException {
List<Cookie> cookies = new ArrayList<Cookie>(elems.length); List<Cookie> cookies = new ArrayList<Cookie>(elems.length);
for (HeaderElement headerelement : elems) { for (HeaderElement headerelement : elems) {
String name = headerelement.getName(); String name = headerelement.getName();
@ -155,7 +113,10 @@ public class RFC2965Spec extends RFC2109Spec {
throw new MalformedCookieException("Cookie name may not be empty"); throw new MalformedCookieException("Cookie name may not be empty");
} }
BasicClientCookie cookie = cookieFactory.createCookie(name, value, origin); BasicClientCookie2 cookie = new BasicClientCookie2(name, value);
cookie.setPath(getDefaultPath(origin));
cookie.setDomain(getDefaultDomain(origin));
cookie.setPorts(new int [] { origin.getPort() });
// cycle through the parameters // cycle through the parameters
NameValuePair[] attribs = headerelement.getParameters(); NameValuePair[] attribs = headerelement.getParameters();

View File

@ -103,7 +103,7 @@ public class TestCookie2Support extends ServerTestBase {
this.localServer.register("*", new CookieVer0Service()); this.localServer.register("*", new CookieVer0Service());
DefaultHttpClient client = new DefaultHttpClient(); DefaultHttpClient client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2965); client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BEST_MATCH);
CookieStore cookieStore = new BasicCookieStore(); CookieStore cookieStore = new BasicCookieStore();
HttpContext context = new BasicHttpContext(); HttpContext context = new BasicHttpContext();
@ -154,7 +154,7 @@ public class TestCookie2Support extends ServerTestBase {
this.localServer.register("*", new CookieVer1Service()); this.localServer.register("*", new CookieVer1Service());
DefaultHttpClient client = new DefaultHttpClient(); DefaultHttpClient client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2965); client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BEST_MATCH);
CookieStore cookieStore = new BasicCookieStore(); CookieStore cookieStore = new BasicCookieStore();
HttpContext context = new BasicHttpContext(); HttpContext context = new BasicHttpContext();
@ -181,7 +181,8 @@ public class TestCookie2Support extends ServerTestBase {
HttpRequest reqWrapper = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST); HttpRequest reqWrapper = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
Header cookiesupport = reqWrapper.getFirstHeader(SM.COOKIE2); Header cookiesupport = reqWrapper.getFirstHeader(SM.COOKIE2);
assertNull(cookiesupport); assertNotNull(cookiesupport);
assertEquals("$Version=1", cookiesupport.getValue());
} }
private static class CookieVer2Service implements HttpRequestHandler { private static class CookieVer2Service implements HttpRequestHandler {
@ -203,7 +204,7 @@ public class TestCookie2Support extends ServerTestBase {
this.localServer.register("*", new CookieVer2Service()); this.localServer.register("*", new CookieVer2Service());
DefaultHttpClient client = new DefaultHttpClient(); DefaultHttpClient client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2965); client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BEST_MATCH);
CookieStore cookieStore = new BasicCookieStore(); CookieStore cookieStore = new BasicCookieStore();
HttpContext context = new BasicHttpContext(); HttpContext context = new BasicHttpContext();
@ -254,7 +255,7 @@ public class TestCookie2Support extends ServerTestBase {
this.localServer.register("*", new SetCookieVersionMixService()); this.localServer.register("*", new SetCookieVersionMixService());
DefaultHttpClient client = new DefaultHttpClient(); DefaultHttpClient client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2965); client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BEST_MATCH);
CookieStore cookieStore = new BasicCookieStore(); CookieStore cookieStore = new BasicCookieStore();
HttpContext context = new BasicHttpContext(); HttpContext context = new BasicHttpContext();

View File

@ -47,6 +47,7 @@ public class TestAllHttpClientImpl extends TestCase {
suite.addTest(TestDefaultClientRequestDirector.suite()); suite.addTest(TestDefaultClientRequestDirector.suite());
suite.addTest(TestStatefulConnManagement.suite()); suite.addTest(TestStatefulConnManagement.suite());
suite.addTest(TestDefaultConnKeepAliveStrategy.suite()); suite.addTest(TestDefaultConnKeepAliveStrategy.suite());
suite.addTest(TestCookieIdentityComparator.suite());
return suite; return suite;
} }

View File

@ -0,0 +1,119 @@
/*
* $HeadURL:$
* $Revision:$
* $Date:$
* ====================================================================
*
* 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.client;
import org.apache.http.cookie.CookieIdentityComparator;
import org.apache.http.impl.cookie.BasicClientCookie;
import junit.framework.*;
/**
* Simple tests for {@link CookieIdentityComparator}.
*
* @version $Id:$
*/
public class TestCookieIdentityComparator extends TestCase {
// ------------------------------------------------------------ Constructor
public TestCookieIdentityComparator(String testName) {
super(testName);
}
// ------------------------------------------------------------------- Main
public static void main(String args[]) {
String[] testCaseName = { TestCookieIdentityComparator.class.getName() };
junit.textui.TestRunner.main(testCaseName);
}
// ------------------------------------------------------- TestCase Methods
public static Test suite() {
return new TestSuite(TestCookieIdentityComparator.class);
}
// ----------------------------------------------------------- Test Methods
public void testCookieIdentityComparasionByName() {
CookieIdentityComparator comparator = new CookieIdentityComparator();
BasicClientCookie c1 = new BasicClientCookie("name", "value1");
BasicClientCookie c2 = new BasicClientCookie("name", "value2");
assertTrue(comparator.compare(c1, c2) == 0);
BasicClientCookie c3 = new BasicClientCookie("name1", "value");
BasicClientCookie c4 = new BasicClientCookie("name2", "value");
assertFalse(comparator.compare(c3, c4) == 0);
}
public void testCookieIdentityComparasionByNameAndDomain() {
CookieIdentityComparator comparator = new CookieIdentityComparator();
BasicClientCookie c1 = new BasicClientCookie("name", "value1");
c1.setDomain("www.domain.com");
BasicClientCookie c2 = new BasicClientCookie("name", "value2");
c2.setDomain("www.domain.com");
assertTrue(comparator.compare(c1, c2) == 0);
BasicClientCookie c3 = new BasicClientCookie("name", "value1");
c3.setDomain("www.domain.com");
BasicClientCookie c4 = new BasicClientCookie("name", "value2");
c4.setDomain("domain.com");
assertFalse(comparator.compare(c3, c4) == 0);
}
public void testCookieIdentityComparasionByNameAndNullDomain() {
CookieIdentityComparator comparator = new CookieIdentityComparator();
BasicClientCookie c1 = new BasicClientCookie("name", "value1");
c1.setDomain(null);
BasicClientCookie c2 = new BasicClientCookie("name", "value2");
c2.setDomain(null);
assertTrue(comparator.compare(c1, c2) == 0);
BasicClientCookie c3 = new BasicClientCookie("name", "value1");
c3.setDomain("www.domain.com");
BasicClientCookie c4 = new BasicClientCookie("name", "value2");
c4.setDomain(null);
assertFalse(comparator.compare(c3, c4) == 0);
}
public void testCookieIdentityComparasionByNameAndLocalHost() {
CookieIdentityComparator comparator = new CookieIdentityComparator();
BasicClientCookie c1 = new BasicClientCookie("name", "value1");
c1.setDomain("localhost");
BasicClientCookie c2 = new BasicClientCookie("name", "value2");
c2.setDomain("localhost");
assertTrue(comparator.compare(c1, c2) == 0);
BasicClientCookie c3 = new BasicClientCookie("name", "value1");
c3.setDomain("localhost.local");
BasicClientCookie c4 = new BasicClientCookie("name", "value2");
c4.setDomain("localhost");
assertTrue(comparator.compare(c3, c4) == 0);
}
}

View File

@ -972,19 +972,17 @@ public class TestCookieRFC2965Spec extends TestCase {
// ------------------------------------------------------- Backward compatibility tests // ------------------------------------------------------- Backward compatibility tests
/** /**
* Test backward compatibility with <tt>Set-Cookie</tt> header. * Test rejection of <tt>Set-Cookie</tt> header.
*/ */
public void testCompatibilityWithSetCookie() throws Exception { public void testRejectSetCookie() throws Exception {
CookieSpec cookiespec = new RFC2965Spec(); CookieSpec cookiespec = new RFC2965Spec();
CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false);
Header header = new BasicHeader("Set-Cookie", "name=value; domain=.domain.com; version=1"); Header header = new BasicHeader("Set-Cookie", "name=value; domain=.domain.com; version=1");
List<Cookie> cookies = cookiespec.parse(header, origin); try {
assertNotNull(cookies); cookiespec.parse(header, origin);
assertEquals(1, cookies.size()); } catch (MalformedCookieException ex) {
assertEquals("name", cookies.get(0).getName()); // expected
assertEquals("value", cookies.get(0).getValue()); }
assertEquals(".domain.com", cookies.get(0).getDomain());
assertEquals("/", cookies.get(0).getPath());
} }
} }