From b7476807f1937fbbc9022c4bc1555c6402f62292 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Sun, 28 May 2006 19:46:39 +0000 Subject: [PATCH] Refactored the browser compatibility cookie policy ported from the Commons HttpClient 3.x code line git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@409981 13f79535-47bb-0310-9956-ffa450edef68 --- .../impl/BrowserCompatDomainHandler.java | 3 + .../http/cookie/impl/BrowserCompatSpec.java | 137 ++++++++++++++++++ .../http/cookie/impl/CookieSpecBase.java | 3 + 3 files changed, 143 insertions(+) create mode 100644 src/java/org/apache/http/cookie/impl/BrowserCompatSpec.java diff --git a/src/java/org/apache/http/cookie/impl/BrowserCompatDomainHandler.java b/src/java/org/apache/http/cookie/impl/BrowserCompatDomainHandler.java index 637d1bcf2..85c02e88f 100644 --- a/src/java/org/apache/http/cookie/impl/BrowserCompatDomainHandler.java +++ b/src/java/org/apache/http/cookie/impl/BrowserCompatDomainHandler.java @@ -102,6 +102,9 @@ public class BrowserCompatDomainHandler implements CookieAttributeHandler { } String host = origin.getHost(); String domain = cookie.getDomain(); + if (domain == null) { + return false; + } if (host.equals(domain)) { return true; } diff --git a/src/java/org/apache/http/cookie/impl/BrowserCompatSpec.java b/src/java/org/apache/http/cookie/impl/BrowserCompatSpec.java new file mode 100644 index 000000000..3dc44846d --- /dev/null +++ b/src/java/org/apache/http/cookie/impl/BrowserCompatSpec.java @@ -0,0 +1,137 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie.impl; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.io.CharArrayBuffer; +import org.apache.http.util.DateParseException; +import org.apache.http.util.DateUtils; + +/** + * Cookie specification that stives to closely mimic (mis)behavior of + * common web browser applications such as Microsoft Internet Explorer + * and Mozilla FireFox. + * + * @author Oleg Kalnichevski + * + * @since 4.0 + */ +public class BrowserCompatSpec extends CookieSpecBase { + + /** Valid date patterns */ + private String[] datepatterns = new String[] { + DateUtils.PATTERN_RFC1123, + DateUtils.PATTERN_RFC1036, + DateUtils.PATTERN_ASCTIME, + "EEE, dd-MMM-yyyy HH:mm:ss z", + "EEE, dd-MMM-yyyy HH-mm-ss z", + "EEE, dd MMM yy HH:mm:ss z", + "EEE dd-MMM-yyyy HH:mm:ss z", + "EEE dd MMM yyyy HH:mm:ss z", + "EEE dd-MMM-yyyy HH-mm-ss z", + "EEE dd-MMM-yy HH:mm:ss z", + "EEE dd MMM yy HH:mm:ss z", + "EEE,dd-MMM-yy HH:mm:ss z", + "EEE,dd-MMM-yyyy HH:mm:ss z", + "EEE, dd-MM-yyyy HH:mm:ss z", + }; + + /** Default constructor */ + public BrowserCompatSpec() { + super(); + registerAttribHandler("path", new BasicPathHandler()); + registerAttribHandler("domain", new BrowserCompatDomainHandler()); + registerAttribHandler("max-age", new BasicMaxAgeHandler()); + registerAttribHandler("secure", new BasicSecureHandler()); + registerAttribHandler("comment", new BasicCommentHandler()); + registerAttribHandler("expires", new BasicExpiresHandler(this.datepatterns)); + } + + public Cookie[] parse(final Header header, final CookieOrigin origin) + throws MalformedCookieException { + if (header == null) { + throw new IllegalArgumentException("Header may not be null"); + } + if (header == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + String headervalue = header.getValue(); + boolean isNetscapeCookie = false; + int i1 = headervalue.toLowerCase().indexOf("expires="); + if (i1 != -1) { + i1 += "expires=".length(); + int i2 = headervalue.indexOf(";", i1); + if (i2 == -1) { + i2 = headervalue.length(); + } + try { + DateUtils.parseDate(headervalue.substring(i1, i2), this.datepatterns); + isNetscapeCookie = true; + } catch (DateParseException e) { + // Does not look like a valid expiry date + } + } + HeaderElement[] elems = null; + if (isNetscapeCookie) { + elems = new HeaderElement[] { HeaderElement.parse(headervalue) }; + } else { + elems = header.getElements(); + } + return parse(elems, origin); + } + + public Header[] formatCookies(final Cookie[] cookies) { + if (cookies == null) { + throw new IllegalArgumentException("Cookie array may not be null"); + } + if (cookies.length == 0) { + throw new IllegalArgumentException("Cookie array may not be empty"); + } + CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.length); + for (int i = 0; i < cookies.length; i++) { + Cookie cookie = cookies[i]; + if (i > 0) { + buffer.append("; "); + } + buffer.append(cookie.getName()); + buffer.append("="); + String s = cookie.getValue(); + if (s != null) { + buffer.append(s); + } + } + return new Header[] { new Header("Cookie", buffer.toString()) }; + } + +} diff --git a/src/java/org/apache/http/cookie/impl/CookieSpecBase.java b/src/java/org/apache/http/cookie/impl/CookieSpecBase.java index b1fbcecd8..18d463baa 100644 --- a/src/java/org/apache/http/cookie/impl/CookieSpecBase.java +++ b/src/java/org/apache/http/cookie/impl/CookieSpecBase.java @@ -103,6 +103,9 @@ public abstract class CookieSpecBase extends AbstractCookieSpec { if (origin == null) { throw new IllegalArgumentException("Cookie origin may not be null"); } + if (cookie.getName() == null || cookie.getName().trim().equals("")) { + throw new MalformedCookieException("Cookie name may not be blank"); + } for (Iterator i = getAttribHandlerIterator(); i.hasNext();) { CookieAttributeHandler handler = (CookieAttributeHandler) i.next(); handler.validate(cookie, origin);