hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r581953 [1/2] - in /jakarta/httpcomponents/httpclient/trunk/module-client/src: main/java/org/apache/http/impl/client/ main/java/org/apache/http/impl/cookie/ test/java/org/apache/http/impl/cookie/
Date Thu, 04 Oct 2007 15:53:55 GMT
Author: olegk
Date: Thu Oct  4 08:53:50 2007
New Revision: 581953

URL: http://svn.apache.org/viewvc?rev=581953&view=rev
Log:
Ported RFC 2965 cookie spec from HttpClient 3.x branch

Added:
    jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java
      - copied, changed from r563548, jakarta/httpcomponents/oac.hc3x/trunk/src/java/org/apache/commons/httpclient/cookie/RFC2965Spec.java
    jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.java   (with props)
    jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestCookieRFC2965Spec.java
      - copied, changed from r581883, jakarta/httpcomponents/oac.hc3x/trunk/src/test/org/apache/commons/httpclient/cookie/TestCookieRFC2965Spec.java
Modified:
    jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java
    jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.java
    jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicClientCookie2.java
    jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.java
    jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java
    jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java
    jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java
    jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAbstractCookieSpec.java
    jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAllCookieImpl.java

Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java?rev=581953&r1=581952&r2=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java Thu Oct  4 08:53:50 2007
@@ -81,7 +81,6 @@
 import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpParamsLinker;
 import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;

Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.java?rev=581953&r1=581952&r2=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.java Thu Oct  4 08:53:50 2007
@@ -31,16 +31,13 @@
 
 package org.apache.http.impl.cookie;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.http.cookie.CookieAttributeHandler;
 import org.apache.http.cookie.CookieSpec;
 
-
 /**
  * Abstract cookie specification which can delegate the job of parsing,
  * validation or matching cookie attributes to a number of arbitrary 
@@ -53,11 +50,6 @@
 public abstract class AbstractCookieSpec implements CookieSpec {
     
     /**
-     * Stores the list of attribute handlers
-     */
-    private final List attribHandlerList;
-    
-    /**
     * Stores attribute name -> attribute handler mappings
     */
     private final Map attribHandlerMap;
@@ -68,7 +60,6 @@
     public AbstractCookieSpec() {
         super();
         this.attribHandlerMap = new HashMap(10);        
-        this.attribHandlerList = new ArrayList(10);
     }
 
     public void registerAttribHandler(
@@ -79,9 +70,6 @@
         if (handler == null) {
             throw new IllegalArgumentException("Attribute handler may not be null");
         }
-        if (!this.attribHandlerList.contains(handler)) {
-            this.attribHandlerList.add(handler);
-        }
         this.attribHandlerMap.put(name, handler);
     }
     
@@ -116,7 +104,7 @@
     }
 
     protected Iterator getAttribHandlerIterator() {
-        return this.attribHandlerList.iterator();
+        return this.attribHandlerMap.values().iterator();
     }
     
 }

Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicClientCookie2.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicClientCookie2.java?rev=581953&r1=581952&r2=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicClientCookie2.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicClientCookie2.java Thu Oct  4 08:53:50 2007
@@ -31,6 +31,8 @@
 
 package org.apache.http.impl.cookie;
 
+import java.util.Date;
+
 import org.apache.http.cookie.SetCookie2;
 
 /**
@@ -80,5 +82,9 @@
         return !this.discard && super.isPersistent();
     }
 
+    public boolean isExpired(final Date date) {
+        return this.discard || super.isExpired(date);
+    }
+    
 }
 

Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.java?rev=581953&r1=581952&r2=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.java Thu Oct  4 08:53:50 2007
@@ -56,6 +56,10 @@
             throw new MalformedCookieException ("Invalid max-age attribute: " 
                     + value);
         }
+        if (age < 0) {
+            throw new MalformedCookieException ("Negative max-age attribute: " 
+                    + value);
+        }
         cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L));
     }
     

Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java?rev=581953&r1=581952&r2=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java Thu Oct  4 08:53:50 2007
@@ -186,7 +186,7 @@
      * @param param The parameter.
      * @param version The cookie version 
      */
-    private void formatParamAsVer(final CharArrayBuffer buffer, 
+    protected void formatParamAsVer(final CharArrayBuffer buffer, 
             final String name, final String value, int version) {
         buffer.append(name);
         buffer.append("=");
@@ -208,7 +208,7 @@
      * @param cookie The {@link Cookie} to be formatted as string
      * @param version The version to use.
      */
-    private void formatCookieAsVer(final CharArrayBuffer buffer, 
+    protected void formatCookieAsVer(final CharArrayBuffer buffer, 
             final Cookie cookie, int version) {
         formatParamAsVer(buffer, cookie.getName(), cookie.getValue(), version);
         if (cookie.getPath() != null) {

Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java?rev=581953&r1=581952&r2=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java Thu Oct  4 08:53:50 2007
@@ -78,7 +78,7 @@
         }
         if (cookie instanceof SetCookie2) {
             SetCookie2 cookie2 = (SetCookie2) cookie;
-            if (portValue != null && !portValue.equals("")) {
+            if (portValue != null && portValue.trim().length() > 0) {
                 int[] ports = parsePortAttribute(portValue);
                 cookie2.setPorts(ports);
             }

Copied: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java (from r563548, jakarta/httpcomponents/oac.hc3x/trunk/src/java/org/apache/commons/httpclient/cookie/RFC2965Spec.java)
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java?p2=jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java&p1=jakarta/httpcomponents/oac.hc3x/trunk/src/java/org/apache/commons/httpclient/cookie/RFC2965Spec.java&r1=563548&r2=581953&rev=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/oac.hc3x/trunk/src/java/org/apache/commons/httpclient/cookie/RFC2965Spec.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java Thu Oct  4 08:53:50 2007
@@ -28,524 +28,162 @@
  *
  */
 
-package org.apache.commons.httpclient.cookie;
+package org.apache.http.impl.cookie;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
-import java.util.StringTokenizer;
 
-import org.apache.commons.httpclient.Cookie;
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HeaderElement;
-import org.apache.commons.httpclient.NameValuePair;
-import org.apache.commons.httpclient.util.ParameterFormatter;
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.NameValuePair;
+import org.apache.http.cookie.ClientCookie;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.cookie.CookieAttributeHandler;
+import org.apache.http.cookie.CookieOrigin;
+import org.apache.http.cookie.CookieVersionSupport;
+import org.apache.http.cookie.MalformedCookieException;
+import org.apache.http.cookie.SM;
+import org.apache.http.message.BufferedHeader;
+import org.apache.http.util.CharArrayBuffer;
 
 /**
  * <p>RFC 2965 specific cookie management functions.</p>
  * 
  * @author jain.samit@gmail.com (Samit Jain)
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
  *
  * @since 3.1
  */
-public class RFC2965Spec extends CookieSpecBase implements CookieVersionSupport {
+public class RFC2965Spec extends RFC2109Spec implements CookieVersionSupport {
 
-    private static final Comparator PATH_COMPOARATOR = new CookiePathComparator();
-    
-    /**
-    * Cookie Response Header  name for cookies processed
-    * by this spec.
-    */
-    public final static String SET_COOKIE2_KEY = "set-cookie2";
-    
-    /**
-    * used for formatting RFC 2956 style cookies
-    */
-    private final ParameterFormatter formatter;
-     
-    /**
-     * Stores the list of attribute handlers
-     */
-    private final List attribHandlerList;
-    
-    /**
-    * Stores attribute name -> attribute handler mappings
-    */
-    private final Map attribHandlerMap;
-
-    /**
-     * Fallback cookie spec (RFC 2109)
-     */
-    private final CookieSpec rfc2109;
-    
     /** 
      * Default constructor 
-     * */
-    public RFC2965Spec() {
-        super();
-        this.formatter = new ParameterFormatter();
-        this.formatter.setAlwaysUseQuotes(true);
-        this.attribHandlerMap = new HashMap(10);        
-        this.attribHandlerList = new ArrayList(10);
-        this.rfc2109 = new RFC2109Spec();
-        
-        registerAttribHandler(Cookie2.PATH, new Cookie2PathAttributeHandler());
-        registerAttribHandler(Cookie2.DOMAIN, new Cookie2DomainAttributeHandler());
-        registerAttribHandler(Cookie2.PORT, new Cookie2PortAttributeHandler());
-        registerAttribHandler(Cookie2.MAXAGE, new Cookie2MaxageAttributeHandler());
-        registerAttribHandler(Cookie2.SECURE, new CookieSecureAttributeHandler());
-        registerAttribHandler(Cookie2.COMMENT, new CookieCommentAttributeHandler());
-        registerAttribHandler(Cookie2.COMMENTURL, new CookieCommentUrlAttributeHandler());
-        registerAttribHandler(Cookie2.DISCARD, new CookieDiscardAttributeHandler());
-        registerAttribHandler(Cookie2.VERSION, new Cookie2VersionAttributeHandler());
-    }
-
-    protected void registerAttribHandler(
-            final String name, final CookieAttributeHandler handler) {
-        if (name == null) {
-            throw new IllegalArgumentException("Attribute name may not be null");
-        }
-        if (handler == null) {
-            throw new IllegalArgumentException("Attribute handler may not be null");
-        }
-        if (!this.attribHandlerList.contains(handler)) {
-            this.attribHandlerList.add(handler);
-        }
-        this.attribHandlerMap.put(name, handler);
-    }
-    
-    /**
-     * Finds an attribute handler {@link CookieAttributeHandler} for the
-     * given attribute. Returns <tt>null</tt> if no attribute handler is
-     * found for the specified attribute.
-     *
-     * @param name attribute name. e.g. Domain, Path, etc.
-     * @return an attribute handler or <tt>null</tt>
+     * 
      */
-    protected CookieAttributeHandler findAttribHandler(final String name) {
-        return (CookieAttributeHandler) this.attribHandlerMap.get(name);
+    public RFC2965Spec() {
+        this(null, false);
     }
     
-    /**
-     * Gets attribute handler {@link CookieAttributeHandler} for the
-     * given attribute.
-     *
-     * @param name attribute name. e.g. Domain, Path, etc.
-     * @throws IllegalStateException if handler not found for the
-     *          specified attribute.
-     */
-    protected CookieAttributeHandler getAttribHandler(final String name) {
-        CookieAttributeHandler handler = findAttribHandler(name);
-        if (handler == null) {
-            throw new IllegalStateException("Handler not registered for " +
-                                            name + " attribute.");
-        } else {
-            return handler;
-        }
-    }
-
-    protected Iterator getAttribHandlerIterator() {
-        return this.attribHandlerList.iterator();
+    public RFC2965Spec(final String[] datepatterns, boolean oneHeader) {
+        super(datepatterns, oneHeader);
+        registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2965DomainAttributeHandler());
+        registerAttribHandler(ClientCookie.PORT_ATTR, new RFC2965PortAttributeHandler());
+        registerAttribHandler(ClientCookie.COMMENTURL_ATTR, new RFC2965CommentUrlAttributeHandler());
+        registerAttribHandler(ClientCookie.DISCARD_ATTR, new RFC2965DiscardAttributeHandler());
+        registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2965VersionAttributeHandler());
     }
     
-    /**
-     * Parses the Set-Cookie2 value into an array of <tt>Cookie</tt>s.
-     *
-     * <P>The syntax for the Set-Cookie2 response header is:
-     *
-     * <PRE>
-     * set-cookie      =    "Set-Cookie2:" cookies
-     * cookies         =    1#cookie
-     * cookie          =    NAME "=" VALUE * (";" cookie-av)
-     * NAME            =    attr
-     * VALUE           =    value
-     * cookie-av       =    "Comment" "=" value
-     *                 |    "CommentURL" "=" <"> http_URL <">
-     *                 |    "Discard"
-     *                 |    "Domain" "=" value
-     *                 |    "Max-Age" "=" value
-     *                 |    "Path" "=" value
-     *                 |    "Port" [ "=" <"> portlist <"> ]
-     *                 |    "Secure"
-     *                 |    "Version" "=" 1*DIGIT
-     * portlist        =       1#portnum
-     * portnum         =       1*DIGIT
-     * </PRE>
-     *
-     * @param host the host from which the <tt>Set-Cookie2</tt> value was
-     * received
-     * @param port the port from which the <tt>Set-Cookie2</tt> value was
-     * received
-     * @param path the path from which the <tt>Set-Cookie2</tt> value was
-     * received
-     * @param secure <tt>true</tt> when the <tt>Set-Cookie2</tt> value was
-     * received over secure conection
-     * @param header the <tt>Set-Cookie2</tt> <tt>Header</tt> received from the server
-     * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie2 value
-     * @throws MalformedCookieException if an exception occurs during parsing
-     */
     public Cookie[] parse(
-            String host, int port, String path, boolean secure, final Header header)
-            throws MalformedCookieException {
-        LOG.trace("enter RFC2965.parse("
-                  + "String, int, String, boolean, Header)");
-
-        if (header == null) {
-            throw new IllegalArgumentException("Header may not be null.");
-        }
-        if (header.getName() == null) {
-            throw new IllegalArgumentException("Header name may not be null.");
-        }
-
-        if (header.getName().equalsIgnoreCase(SET_COOKIE2_KEY)) {
-            // parse cookie2 cookies
-            return parse(host, port, path, secure, header.getValue());
-        } else if (header.getName().equalsIgnoreCase(RFC2109Spec.SET_COOKIE_KEY)) {
-            // delegate parsing of old-style cookies to rfc2109Spec
-            return this.rfc2109.parse(host, port, path, secure, header.getValue());
-        } else {
-            throw new MalformedCookieException("Header name is not valid. " +
-                                               "RFC 2965 supports \"set-cookie\" " +
-                                               "and \"set-cookie2\" headers.");
-        }
-    }
-
-    /**
-     * @see #parse(String, int, String, boolean, org.apache.commons.httpclient.Header)
-     */
-    public Cookie[] parse(String host, int port, String path,
-                          boolean secure, final String header)
-            throws MalformedCookieException {
-        LOG.trace("enter RFC2965Spec.parse("
-                  + "String, int, String, boolean, String)");
-
-        // before we do anything, lets check validity of arguments
-        if (host == null) {
-            throw new IllegalArgumentException(
-                    "Host of origin may not be null");
-        }
-        if (host.trim().equals("")) {
-            throw new IllegalArgumentException(
-                    "Host of origin may not be blank");
-        }
-        if (port < 0) {
-            throw new IllegalArgumentException("Invalid port: " + port);
-        }
-        if (path == null) {
-            throw new IllegalArgumentException(
-                    "Path of origin may not be null.");
-        }
+            final Header header, 
+            CookieOrigin origin) throws MalformedCookieException {
         if (header == null) {
-            throw new IllegalArgumentException("Header may not be null.");
+            throw new IllegalArgumentException("Header may not be null");
         }
-
-        if (path.trim().equals("")) {
-            path = PATH_DELIM;
+        if (origin == null) {
+            throw new IllegalArgumentException("Cookie origin may not be null");
         }
-        host = getEffectiveHost(host);
-
-        HeaderElement[] headerElements =
-                HeaderElement.parseElements(header.toCharArray());
+        
+        origin = adjustEffectiveHost(origin);
+        
+        HeaderElement[] elems = header.getElements();
 
-        List cookies = new LinkedList();
-        for (int i = 0; i < headerElements.length; i++) {
-            HeaderElement headerelement = headerElements[i];
-            Cookie2 cookie = null;
-            try {
-                cookie = new Cookie2(host,
-                                    headerelement.getName(),
-                                    headerelement.getValue(),
-                                    path,
-                                    null,
-                                    false,
-                                    new int[] {port});
-            } catch (IllegalArgumentException ex) {
-                throw new MalformedCookieException(ex.getMessage());
-            }
-            NameValuePair[] parameters = headerelement.getParameters();
-            // could be null. In case only a header element and no parameters.
-            if (parameters != null) {
-                // Eliminate duplicate attribues. The first occurence takes precedence
-                Map attribmap = new HashMap(parameters.length); 
-                for (int j = parameters.length - 1; j >= 0; j--) {
-                    NameValuePair param = parameters[j];
-                    attribmap.put(param.getName().toLowerCase(), param);
-                }
-                for (Iterator it = attribmap.entrySet().iterator(); it.hasNext(); ) {
-                    Map.Entry entry = (Map.Entry) it.next();
-                    parseAttribute((NameValuePair) entry.getValue(), cookie);
+        Cookie[] cookies = new Cookie[elems.length];
+        for (int i = 0; i < elems.length; i++) {
+            HeaderElement headerelement = elems[i];
+
+            String name = headerelement.getName();
+            String value = headerelement.getValue();
+            if (name == null || name.equals("")) {
+                throw new MalformedCookieException("Cookie name may not be empty");
+            }
+            
+            BasicClientCookie2 cookie = new BasicClientCookie2(name, value);
+            cookie.setPath(getDefaultPath(origin));
+            cookie.setDomain(getDefaultDomain(origin));
+            cookie.setPorts(new int [] { origin.getPort() });
+            
+            // cycle through the parameters
+            NameValuePair[] attribs = headerelement.getParameters();
+            
+            // Eliminate duplicate attributes. The first occurrence takes precedence
+            // See RFC2965: 3.2  Origin Server Role
+            Map attribmap = new HashMap(attribs.length); 
+            for (int j = attribs.length - 1; j >= 0; j--) {
+                NameValuePair param = attribs[j];
+                attribmap.put(param.getName().toLowerCase(), param);
+            }
+            for (Iterator it = attribmap.entrySet().iterator(); it.hasNext(); ) {
+                Map.Entry entry = (Map.Entry) it.next();
+                NameValuePair attrib = (NameValuePair) entry.getValue();
+                String s = attrib.getName().toLowerCase();
+                
+                cookie.setAttribute(s, attrib.getValue());
+                
+                CookieAttributeHandler handler = findAttribHandler(s);
+                if (handler != null) {
+                    handler.parse(cookie, attrib.getValue());
                 }
             }
-            cookies.add(cookie);
-            // cycle through the parameters
+            cookies[i] = cookie;
         }
-        return (Cookie[]) cookies.toArray(new Cookie[cookies.size()]);
+        return cookies;
     }
 
-    /**
-     * Parse RFC 2965 specific cookie attribute and update the corresponsing
-     * {@link org.apache.commons.httpclient.Cookie} properties.
-     *
-     * @param attribute {@link org.apache.commons.httpclient.NameValuePair} cookie attribute from the
-     * <tt>Set-Cookie2</tt> header.
-     * @param cookie {@link org.apache.commons.httpclient.Cookie} to be updated
-     * @throws MalformedCookieException if an exception occurs during parsing
-     */
-    public void parseAttribute(
-            final NameValuePair attribute, final Cookie cookie)
+    public void validate(final Cookie cookie, CookieOrigin origin)
             throws MalformedCookieException {
-        if (attribute == null) {
-            throw new IllegalArgumentException("Attribute may not be null.");
-        }
-        if (attribute.getName() == null) {
-            throw new IllegalArgumentException("Attribute Name may not be null.");
-        }
-        if (cookie == null) {
-            throw new IllegalArgumentException("Cookie may not be null.");
-        }
-        final String paramName = attribute.getName().toLowerCase();
-        final String paramValue = attribute.getValue();
-
-        CookieAttributeHandler handler = findAttribHandler(paramName);
-        if (handler == null) {
-            // ignore unknown attribute-value pairs
-            if (LOG.isDebugEnabled())
-                LOG.debug("Unrecognized cookie attribute: " +
-                          attribute.toString());
-        } else {
-            handler.parse(cookie, paramValue);
-        }
-    }
-
-    /**
-     * Performs RFC 2965 compliant {@link org.apache.commons.httpclient.Cookie} validation
-     *
-     * @param host the host from which the {@link org.apache.commons.httpclient.Cookie} was received
-     * @param port the port from which the {@link org.apache.commons.httpclient.Cookie} was received
-     * @param path the path from which the {@link org.apache.commons.httpclient.Cookie} was received
-     * @param secure <tt>true</tt> when the {@link org.apache.commons.httpclient.Cookie} was received using a
-     * secure connection
-     * @param cookie The cookie to validate
-     * @throws MalformedCookieException if an exception occurs during
-     * validation
-     */
-    public void validate(final String host, int port, final String path,
-                         boolean secure, final Cookie cookie)
-            throws MalformedCookieException {
-
-        LOG.trace("enter RFC2965Spec.validate(String, int, String, "
-                  + "boolean, Cookie)");
-
-        if (cookie instanceof Cookie2) {
-            if (cookie.getName().indexOf(' ') != -1) {
-                throw new MalformedCookieException("Cookie name may not contain blanks");
-            }
-            if (cookie.getName().startsWith("$")) {
-                throw new MalformedCookieException("Cookie name may not start with $");
-            }
-            CookieOrigin origin = new CookieOrigin(getEffectiveHost(host), port, path, secure); 
-            for (Iterator i = getAttribHandlerIterator(); i.hasNext(); ) {
-              CookieAttributeHandler handler = (CookieAttributeHandler) i.next();
-              handler.validate(cookie, origin);
-            }
-        } else {
-            // old-style cookies are validated according to the old rules
-            this.rfc2109.validate(host, port, path, secure, cookie);
-        }
-    }
-
-    /**
-     * Return <tt>true</tt> if the cookie should be submitted with a request
-     * with given attributes, <tt>false</tt> otherwise.
-     * @param host the host to which the request is being submitted
-     * @param port the port to which the request is being submitted (ignored)
-     * @param path the path to which the request is being submitted
-     * @param secure <tt>true</tt> if the request is using a secure connection
-     * @return true if the cookie matches the criterium
-     */
-    public boolean match(String host, int port, String path,
-                         boolean secure, final Cookie cookie) {
-
-        LOG.trace("enter RFC2965.match("
-                  + "String, int, String, boolean, Cookie");
         if (cookie == null) {
             throw new IllegalArgumentException("Cookie may not be null");
         }
-        if (cookie instanceof Cookie2) {
-            // check if cookie has expired
-            if (cookie.isPersistent() && cookie.isExpired()) {
-                return false;
-            }
-            CookieOrigin origin = new CookieOrigin(getEffectiveHost(host), port, path, secure); 
-            for (Iterator i = getAttribHandlerIterator(); i.hasNext(); ) {
-                CookieAttributeHandler handler = (CookieAttributeHandler) i.next();
-                if (!handler.match(cookie, origin)) {
-                    return false;
-                }
-            }
-            return true;
-        } else {
-            // old-style cookies are matched according to the old rules
-            return this.rfc2109.match(host, port, path, secure, cookie);
+        if (origin == null) {
+            throw new IllegalArgumentException("Cookie origin may not be null");
         }
+        origin = adjustEffectiveHost(origin);
+        super.validate(cookie, origin);
     }
 
-    private void doFormatCookie2(final Cookie2 cookie, final StringBuffer buffer) {
-        String name = cookie.getName();
-        String value = cookie.getValue();
-        if (value == null) {
-            value = "";
-        }
-        this.formatter.format(buffer, new NameValuePair(name, value));
-        // format domain attribute
-        if (cookie.getDomain() != null && cookie.isDomainAttributeSpecified()) {
-            buffer.append("; ");
-            this.formatter.format(buffer, new NameValuePair("$Domain", cookie.getDomain()));
-        }
-        // format path attribute
-        if ((cookie.getPath() != null) && (cookie.isPathAttributeSpecified())) {
-            buffer.append("; ");
-            this.formatter.format(buffer, new NameValuePair("$Path", cookie.getPath()));
-        }
-        // format port attribute
-        if (cookie.isPortAttributeSpecified()) {
-            String portValue = "";
-            if (!cookie.isPortAttributeBlank()) {
-                portValue = createPortAttribute(cookie.getPorts());
-            }
-            buffer.append("; ");
-            this.formatter.format(buffer, new NameValuePair("$Port", portValue));
-        }
-    }
-    
-    /**
-     * Return a string suitable for sending in a <tt>"Cookie"</tt> header as
-     * defined in RFC 2965
-     * @param cookie a {@link org.apache.commons.httpclient.Cookie} to be formatted as string
-     * @return a string suitable for sending in a <tt>"Cookie"</tt> header.
-     */
-    public String formatCookie(final Cookie cookie) {
-        LOG.trace("enter RFC2965Spec.formatCookie(Cookie)");
-
+    public boolean match(final Cookie cookie, CookieOrigin origin) {
         if (cookie == null) {
             throw new IllegalArgumentException("Cookie may not be null");
         }
-        if (cookie instanceof Cookie2) {
-            Cookie2 cookie2 = (Cookie2) cookie;
-            int version = cookie2.getVersion();
-            final StringBuffer buffer = new StringBuffer();
-            this.formatter.format(buffer, new NameValuePair("$Version", Integer.toString(version)));
-            buffer.append("; ");
-            doFormatCookie2(cookie2, buffer);
-            return buffer.toString();
-        } else {
-            // old-style cookies are formatted according to the old rules
-            return this.rfc2109.formatCookie(cookie);
+        if (origin == null) {
+            throw new IllegalArgumentException("Cookie origin may not be null");
         }
+        origin = adjustEffectiveHost(origin);
+        return super.match(cookie, origin);
     }
 
     /**
-     * Create a RFC 2965 compliant <tt>"Cookie"</tt> header value containing all
-     * {@link org.apache.commons.httpclient.Cookie}s suitable for
-     * sending in a <tt>"Cookie"</tt> header
-     * @param cookies an array of {@link org.apache.commons.httpclient.Cookie}s to be formatted
-     * @return a string suitable for sending in a Cookie header.
+     * Adds valid Port attribute value, e.g. "8000,8001,8002"
      */
-    public String formatCookies(final Cookie[] cookies) {
-        LOG.trace("enter RFC2965Spec.formatCookieHeader(Cookie[])");
-
-        if (cookies == null) {
-            throw new IllegalArgumentException("Cookies may not be null");
-        }
-        // check if cookies array contains a set-cookie (old style) cookie
-        boolean hasOldStyleCookie = false;
-        int version = -1;
-        for (int i = 0; i < cookies.length; i++) {
-            Cookie cookie = cookies[i];
-            if (!(cookie instanceof Cookie2)) {
-                hasOldStyleCookie = true;
-                break;
-            }
-            if (cookie.getVersion() > version) {
-                version = cookie.getVersion();
-            }
-        }
-        if (version < 0) {
-            version = 0;
-        }
-        if (hasOldStyleCookie || version < 1) {
-            // delegate old-style cookie formatting to rfc2109Spec
-            return this.rfc2109.formatCookies(cookies);
-        }
-        // Arrange cookies by path
-        Arrays.sort(cookies, PATH_COMPOARATOR);
-        
-        final StringBuffer buffer = new StringBuffer();
-        // format cookie version
-        this.formatter.format(buffer, new NameValuePair("$Version", Integer.toString(version)));
-        for (int i = 0; i < cookies.length; i++) {
-            buffer.append("; ");
-            Cookie2 cookie = (Cookie2) cookies[i];
-            // format cookie attributes
-            doFormatCookie2(cookie, buffer);
-        }
-        return buffer.toString();
-    }
-
-    /**
-     * Retrieves valid Port attribute value for the given ports array.
-     * e.g. "8000,8001,8002"
-     *
-     * @param ports int array of ports
-     */
-    private String createPortAttribute(int[] ports) {
-        StringBuffer portValue = new StringBuffer();
-        for (int i = 0, len = ports.length; i < len; i++) {
-            if (i > 0) {
-                portValue.append(",");
-            }
-            portValue.append(ports[i]);
-        }
-        return portValue.toString();
-    }
-
-    /**
-     * Parses the given Port attribute value (e.g. "8000,8001,8002")
-     * into an array of ports.
-     *
-     * @param portValue port attribute value
-     * @return parsed array of ports
-     * @throws MalformedCookieException if there is a problem in
-     *          parsing due to invalid portValue.
-     */
-    private int[] parsePortAttribute(final String portValue)
-            throws MalformedCookieException {
-        StringTokenizer st = new StringTokenizer(portValue, ",");
-        int[] ports = new int[st.countTokens()];
-        try {
-            int i = 0;
-            while(st.hasMoreTokens()) {
-                ports[i] = Integer.parseInt(st.nextToken().trim());
-                if (ports[i] < 0) {
-                  throw new MalformedCookieException ("Invalid Port attribute.");
+    protected void formatCookieAsVer(final CharArrayBuffer buffer, 
+            final Cookie cookie, int version) {
+        super.formatCookieAsVer(buffer, cookie, version);
+        // format port attribute
+        if (cookie instanceof ClientCookie) {
+            // Test if the port attribute as set by the origin server is not blank
+            String s = ((ClientCookie) cookie).getAttribute(ClientCookie.PORT_ATTR);
+            if (s != null) {
+                buffer.append("; $Port");
+                buffer.append("=\"");
+                if (s.trim().length() > 0) {
+                    int[] ports = cookie.getPorts();
+                    if (ports != null) {
+                        for (int i = 0, len = ports.length; i < len; i++) {
+                            if (i > 0) {
+                                buffer.append(",");
+                            }
+                            buffer.append(Integer.toString(ports[i]));
+                        }
+                    }
                 }
-                ++i;
+                buffer.append("\"");
             }
-        } catch (NumberFormatException e) {
-            throw new MalformedCookieException ("Invalid Port "
-                                                + "attribute: " + e.getMessage());
         }
-        return ports;
     }
-
+    
     /**
-     * Gets 'effective host name' as defined in RFC 2965.
+     * Set 'effective host name' as defined in RFC 2965.
      * <p>
      * If a host name contains no dots, the effective host name is
      * that name with the string .local appended to it.  Otherwise
@@ -555,551 +193,18 @@
      * @param host host name where cookie is received from or being sent to.
      * @return
      */
-    private static String getEffectiveHost(final String host) {
-        String effectiveHost = host.toLowerCase();
-        if (host.indexOf('.') < 0) {
+    private static CookieOrigin adjustEffectiveHost(final CookieOrigin origin) {
+        String effectiveHost = origin.getHost();
+        if (effectiveHost.indexOf('.') < 0) {
             effectiveHost += ".local";
+            return new CookieOrigin(
+                    effectiveHost, 
+                    origin.getPort(), 
+                    origin.getPath(), 
+                    origin.isSecure());
+        } else {
+            return origin;
         }
-        return effectiveHost;
-    }
-
-    /**
-     * Performs domain-match as defined by the RFC2965.
-     * <p>
-     * Host A's name domain-matches host B's if
-     * <ol>
-     *   <ul>their host name strings string-compare equal; or</ul>
-     *   <ul>A is a HDN string and has the form NB, where N is a non-empty
-     *       name string, B has the form .B', and B' is a HDN string.  (So,
-     *       x.y.com domain-matches .Y.com but not Y.com.)</ul>
-     * </ol>
-     *
-     * @param host host name where cookie is received from or being sent to.
-     * @param domain The cookie domain attribute.
-     * @return true if the specified host matches the given domain.
-     */
-    public boolean domainMatch(String host, String domain) {
-        boolean match = host.equals(domain)
-                        || (domain.startsWith(".") && host.endsWith(domain));
-
-        return match;
-    }
-
-    /**
-     * Returns <tt>true</tt> if the given port exists in the given
-     * ports list.
-     *
-     * @param port port of host where cookie was received from or being sent to.
-     * @param ports port list
-     * @return true returns <tt>true</tt> if the given port exists in
-     *         the given ports list; <tt>false</tt> otherwise.
-     */
-    private boolean portMatch(int port, int[] ports) {
-        boolean portInList = false;
-        for (int i = 0, len = ports.length; i < len; i++) {
-            if (port == ports[i]) {
-                portInList = true;
-                break;
-            }
-        }
-        return portInList;
-    }
-
-    /**
-     * <tt>"Path"</tt> attribute handler for RFC 2965 cookie spec.
-     */
-    private class Cookie2PathAttributeHandler
-            implements CookieAttributeHandler {
-
-        /**
-         * Parse cookie path attribute.
-         */
-        public void parse(final Cookie cookie, final String path)
-                throws MalformedCookieException {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (path == null) {
-                throw new MalformedCookieException(
-                        "Missing value for path attribute");
-            }
-            if (path.trim().equals("")) {
-                throw new MalformedCookieException(
-                        "Blank value for path attribute");
-            }
-            cookie.setPath(path);
-            cookie.setPathAttributeSpecified(true);
-        }
-
-        /**
-         * Validate cookie path attribute. The value for the Path attribute must be a
-         * prefix of the request-URI (case-sensitive matching).
-         */
-        public void validate(final Cookie cookie, final CookieOrigin origin)
-                throws MalformedCookieException {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (origin == null) {
-                throw new IllegalArgumentException("Cookie origin may not be null");
-            }
-            String path = origin.getPath();
-            if (path == null) {
-                throw new IllegalArgumentException(
-                        "Path of origin host may not be null.");
-            }
-            if (cookie.getPath() == null) {
-                throw new MalformedCookieException("Invalid cookie state: " +
-                                                   "path attribute is null.");
-            }
-            if (path.trim().equals("")) {
-                path = PATH_DELIM;
-            }
-
-            if (!pathMatch(path, cookie.getPath())) {
-                throw new MalformedCookieException(
-                        "Illegal path attribute \"" + cookie.getPath()
-                        + "\". Path of origin: \"" + path + "\"");
-            }
-        }
-
-        /**
-         * Match cookie path attribute. The value for the Path attribute must be a
-         * prefix of the request-URI (case-sensitive matching).
-         */
-        public boolean match(final Cookie cookie, final CookieOrigin origin) {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (origin == null) {
-                throw new IllegalArgumentException("Cookie origin may not be null");
-            }
-            String path = origin.getPath();
-            if (cookie.getPath() == null) {
-                LOG.warn("Invalid cookie state: path attribute is null.");
-                return false;
-            }
-            if (path.trim().equals("")) {
-                path = PATH_DELIM;
-            }
-
-            if (!pathMatch(path, cookie.getPath())) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    /**
-     * <tt>"Domain"</tt> cookie attribute handler for RFC 2965 cookie spec.
-     */
-    private class Cookie2DomainAttributeHandler
-            implements CookieAttributeHandler {
-
-        /**
-         * Parse cookie domain attribute.
-         */
-        public void parse(final Cookie cookie, String domain)
-                throws MalformedCookieException {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (domain == null) {
-                throw new MalformedCookieException(
-                        "Missing value for domain attribute");
-            }
-            if (domain.trim().equals("")) {
-                throw new MalformedCookieException(
-                        "Blank value for domain attribute");
-            }
-            domain = domain.toLowerCase();
-            if (!domain.startsWith(".")) {
-                // Per RFC 2965 section 3.2.2
-                // "... If an explicitly specified value does not start with
-                // a dot, the user agent supplies a leading dot ..."
-                // That effectively implies that the domain attribute 
-                // MAY NOT be an IP address of a host name
-                domain = "." + domain;
-            }
-            cookie.setDomain(domain);
-            cookie.setDomainAttributeSpecified(true);
-        }
-
-        /**
-         * Validate cookie domain attribute.
-         */
-        public void validate(final Cookie cookie, final CookieOrigin origin)
-                throws MalformedCookieException {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (origin == null) {
-                throw new IllegalArgumentException("Cookie origin may not be null");
-            }
-            String host = origin.getHost().toLowerCase();
-            if (cookie.getDomain() == null) {
-                throw new MalformedCookieException("Invalid cookie state: " +
-                                                   "domain not specified");
-            }
-            String cookieDomain = cookie.getDomain().toLowerCase();
-
-            if (cookie.isDomainAttributeSpecified()) {
-                // Domain attribute must start with a dot
-                if (!cookieDomain.startsWith(".")) {
-                    throw new MalformedCookieException("Domain attribute \"" +
-                        cookie.getDomain() + "\" violates RFC 2109: domain must start with a dot");
-                }
-
-                // Domain attribute must contain atleast one embedded dot,
-                // or the value must be equal to .local.
-                int dotIndex = cookieDomain.indexOf('.', 1);
-                if (((dotIndex < 0) || (dotIndex == cookieDomain.length() - 1))
-                    && (!cookieDomain.equals(".local"))) {
-                    throw new MalformedCookieException(
-                            "Domain attribute \"" + cookie.getDomain()
-                            + "\" violates RFC 2965: the value contains no embedded dots "
-                            + "and the value is not .local");
-                }
-
-                // The effective host name must domain-match domain attribute.
-                if (!domainMatch(host, cookieDomain)) {
-                    throw new MalformedCookieException(
-                            "Domain attribute \"" + cookie.getDomain()
-                            + "\" violates RFC 2965: effective host name does not "
-                            + "domain-match domain attribute.");
-                }
-
-                // effective host name minus domain must not contain any dots
-                String effectiveHostWithoutDomain = host.substring(
-                        0, host.length() - cookieDomain.length());
-                if (effectiveHostWithoutDomain.indexOf('.') != -1) {
-                    throw new MalformedCookieException("Domain attribute \""
-                                                       + cookie.getDomain() + "\" violates RFC 2965: "
-                                                       + "effective host minus domain may not contain any dots");
-                }
-            } else {
-                // Domain was not specified in header. In this case, domain must
-                // string match request host (case-insensitive).
-                if (!cookie.getDomain().equals(host)) {
-                    throw new MalformedCookieException("Illegal domain attribute: \""
-                                                       + cookie.getDomain() + "\"."
-                                                       + "Domain of origin: \""
-                                                       + host + "\"");
-                }
-            }
-        }
-
-        /**
-         * Match cookie domain attribute.
-         */
-        public boolean match(final Cookie cookie, final CookieOrigin origin) {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (origin == null) {
-                throw new IllegalArgumentException("Cookie origin may not be null");
-            }
-            String host = origin.getHost().toLowerCase();
-            String cookieDomain = cookie.getDomain();
-
-            // The effective host name MUST domain-match the Domain
-            // attribute of the cookie.
-            if (!domainMatch(host, cookieDomain)) {
-                return false;
-            }
-            // effective host name minus domain must not contain any dots
-            String effectiveHostWithoutDomain = host.substring(
-                    0, host.length() - cookieDomain.length());
-            if (effectiveHostWithoutDomain.indexOf('.') != -1) {
-                return false;
-            }
-            return true;
-        }
-
-    }
-
-    /**
-     * <tt>"Port"</tt> cookie attribute handler for RFC 2965 cookie spec.
-     */
-    private class Cookie2PortAttributeHandler
-            implements CookieAttributeHandler {
-
-        /**
-         * Parse cookie port attribute.
-         */
-        public void parse(final Cookie cookie, final String portValue)
-                throws MalformedCookieException {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (cookie instanceof Cookie2) {
-                Cookie2 cookie2 = (Cookie2) cookie;
-                if ((portValue == null) || (portValue.trim().equals(""))) {
-                    // If the Port attribute is present but has no value, the
-                    // cookie can only be sent to the request-port.
-                    // Since the default port list contains only request-port, we don't
-                    // need to do anything here.
-                    cookie2.setPortAttributeBlank(true);
-                } else {
-                    int[] ports = parsePortAttribute(portValue);
-                    cookie2.setPorts(ports);
-                }
-                cookie2.setPortAttributeSpecified(true);
-            }
-        }
-
-        /**
-         * Validate cookie port attribute. If the Port attribute was specified
-         * in header, the request port must be in cookie's port list.
-         */
-        public void validate(final Cookie cookie, final CookieOrigin origin)
-                throws MalformedCookieException {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (origin == null) {
-                throw new IllegalArgumentException("Cookie origin may not be null");
-            }
-            if (cookie instanceof Cookie2) {
-                Cookie2 cookie2 = (Cookie2) cookie;
-                int port = origin.getPort();
-                if (cookie2.isPortAttributeSpecified()) {
-                    if (!portMatch(port, cookie2.getPorts())) {
-                        throw new MalformedCookieException(
-                                "Port attribute violates RFC 2965: "
-                                + "Request port not found in cookie's port list.");
-                    }
-                }
-            }
-        }
-
-        /**
-         * Match cookie port attribute. If the Port attribute is not specified
-         * in header, the cookie can be sent to any port. Otherwise, the request port
-         * must be in the cookie's port list.
-         */
-        public boolean match(final Cookie cookie, final CookieOrigin origin) {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (origin == null) {
-                throw new IllegalArgumentException("Cookie origin may not be null");
-            }
-            if (cookie instanceof Cookie2) {
-                Cookie2 cookie2 = (Cookie2) cookie;
-                int port = origin.getPort();
-                if (cookie2.isPortAttributeSpecified()) {
-                    if (cookie2.getPorts() == null) {
-                        LOG.warn("Invalid cookie state: port not specified");
-                        return false;
-                    }
-                    if (!portMatch(port, cookie2.getPorts())) {
-                        return false;
-                    }
-                }
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
-
-  /**
-   * <tt>"Max-age"</tt> cookie attribute handler for RFC 2965 cookie spec.
-   */
-  private class Cookie2MaxageAttributeHandler
-          implements CookieAttributeHandler {
-
-      /**
-       * Parse cookie max-age attribute.
-       */
-      public void parse(final Cookie cookie, final String value)
-              throws MalformedCookieException {
-          if (cookie == null) {
-              throw new IllegalArgumentException("Cookie may not be null");
-          }
-          if (value == null) {
-              throw new MalformedCookieException(
-                      "Missing value for max-age attribute");
-          }
-          int age = -1;
-          try {
-              age = Integer.parseInt(value);
-          } catch (NumberFormatException e) {
-              age = -1;
-          }
-          if (age < 0) {
-              throw new MalformedCookieException ("Invalid max-age attribute.");
-          }
-          cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L));
-      }
-
-      /**
-       * validate cookie max-age attribute.
-       */
-      public void validate(final Cookie cookie, final CookieOrigin origin) {
-      }
-
-      /**
-       * @see CookieAttributeHandler#match(org.apache.commons.httpclient.Cookie, String)
-       */
-      public boolean match(final Cookie cookie, final CookieOrigin origin) {
-          return true;
-      }
-
-  }
-
-  /**
-   * <tt>"Secure"</tt> cookie attribute handler for RFC 2965 cookie spec.
-   */
-  private class CookieSecureAttributeHandler
-          implements CookieAttributeHandler {
-
-      public void parse(final Cookie cookie, final String secure)
-              throws MalformedCookieException {
-          cookie.setSecure(true);
-      }
-
-      public void validate(final Cookie cookie, final CookieOrigin origin)
-              throws MalformedCookieException {
-      }
-
-      public boolean match(final Cookie cookie, final CookieOrigin origin) {
-          if (cookie == null) {
-              throw new IllegalArgumentException("Cookie may not be null");
-          }
-          if (origin == null) {
-              throw new IllegalArgumentException("Cookie origin may not be null");
-          }
-          return cookie.getSecure() == origin.isSecure();
-      }
-      
-  }
-
-  /**
-   * <tt>"Commant"</tt> cookie attribute handler for RFC 2965 cookie spec.
-   */
-  private class CookieCommentAttributeHandler
-          implements CookieAttributeHandler {
-
-      public void parse(final Cookie cookie, final String comment)
-              throws MalformedCookieException {
-          cookie.setComment(comment);
-      }
-
-      public void validate(final Cookie cookie, final CookieOrigin origin)
-              throws MalformedCookieException {
-      }
-
-      public boolean match(final Cookie cookie, final CookieOrigin origin) {
-          return true;
-      }
-      
-  }
-
-  /**
-   * <tt>"CommantURL"</tt> cookie attribute handler for RFC 2965 cookie spec.
-   */
-  private class CookieCommentUrlAttributeHandler
-          implements CookieAttributeHandler {
-
-      public void parse(final Cookie cookie, final String commenturl)
-              throws MalformedCookieException {
-          if (cookie instanceof Cookie2) {
-              Cookie2 cookie2 = (Cookie2) cookie;
-              cookie2.setCommentURL(commenturl);
-          }
-      }
-
-      public void validate(final Cookie cookie, final CookieOrigin origin)
-              throws MalformedCookieException {
-      }
-
-      public boolean match(final Cookie cookie, final CookieOrigin origin) {
-          return true;
-      }
-      
-  }
-
-  /**
-   * <tt>"Discard"</tt> cookie attribute handler for RFC 2965 cookie spec.
-   */
-  private class CookieDiscardAttributeHandler
-          implements CookieAttributeHandler {
-
-      public void parse(final Cookie cookie, final String commenturl)
-              throws MalformedCookieException {
-          if (cookie instanceof Cookie2) {
-              Cookie2 cookie2 = (Cookie2) cookie;
-              cookie2.setDiscard(true);
-          }
-      }
-
-      public void validate(final Cookie cookie, final CookieOrigin origin)
-              throws MalformedCookieException {
-      }
-
-      public boolean match(final Cookie cookie, final CookieOrigin origin) {
-          return true;
-      }
-      
-  }
-
-  /**
-     * <tt>"Version"</tt> cookie attribute handler for RFC 2965 cookie spec.
-     */
-    private class Cookie2VersionAttributeHandler
-            implements CookieAttributeHandler {
-
-        /**
-         * Parse cookie version attribute.
-         */
-        public void parse(final Cookie cookie, final String value)
-                throws MalformedCookieException {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (cookie instanceof Cookie2) {
-                Cookie2 cookie2 = (Cookie2) cookie;
-                if (value == null) {
-                    throw new MalformedCookieException(
-                            "Missing value for version attribute");
-                }
-                int version = -1;
-                try {
-                    version = Integer.parseInt(value);
-                } catch (NumberFormatException e) {
-                    version = -1;
-                }
-                if (version < 0) {
-                    throw new MalformedCookieException("Invalid cookie version.");
-                }
-                cookie2.setVersion(version);
-                cookie2.setVersionAttributeSpecified(true);
-            }
-        }
-
-        /**
-         * validate cookie version attribute. Version attribute is REQUIRED.
-         */
-        public void validate(final Cookie cookie, final CookieOrigin origin)
-                throws MalformedCookieException {
-            if (cookie == null) {
-                throw new IllegalArgumentException("Cookie may not be null");
-            }
-            if (cookie instanceof Cookie2) {
-                Cookie2 cookie2 = (Cookie2) cookie;
-                if (!cookie2.isVersionAttributeSpecified()) {
-                    throw new MalformedCookieException(
-                            "Violates RFC 2965. Version attribute is required.");
-                }
-            }
-        }
-
-        public boolean match(final Cookie cookie, final CookieOrigin origin) {
-            return true;
-        }
-
     }
 
     public int getVersion() {
@@ -1107,11 +212,12 @@
     }
 
     public Header getVersionHeader() {
-        ParameterFormatter formatter = new ParameterFormatter();
-        StringBuffer buffer = new StringBuffer();
-        formatter.format(buffer, new NameValuePair("$Version",
-                Integer.toString(getVersion())));
-        return new Header("Cookie2", buffer.toString(), true);
+        CharArrayBuffer buffer = new CharArrayBuffer(40);
+        buffer.append(SM.COOKIE_2);
+        buffer.append(": ");
+        buffer.append("$Version=");
+        buffer.append(Integer.toString(getVersion()));
+        return new BufferedHeader(buffer);
     }
     
 }

Added: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.java?rev=581953&view=auto
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.java (added)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.java Thu Oct  4 08:53:50 2007
@@ -0,0 +1,57 @@
+/*
+ * $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.cookie;
+
+import org.apache.http.cookie.CookieSpec;
+import org.apache.http.cookie.CookieSpecFactory;
+import org.apache.http.cookie.params.CookieSpecPNames;
+import org.apache.http.params.HttpParams;
+
+/**
+ * 
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ *
+ * @since 4.0
+ */
+public class RFC2965SpecFactory implements CookieSpecFactory {    
+
+    public CookieSpec newInstance(final HttpParams params) {
+        if (params != null) {
+            return new RFC2965Spec(
+                    (String []) params.getParameter(CookieSpecPNames.DATE_PATTERNS), 
+                    params.getBooleanParameter(CookieSpecPNames.SINGLE_COOKIE_HEADER, false));
+        } else {
+            return new RFC2965Spec();
+        }
+    }
+
+}

Propchange: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java?rev=581953&r1=581952&r2=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java Thu Oct  4 08:53:50 2007
@@ -50,7 +50,7 @@
         }
         if (cookie instanceof ClientCookie) {
             if (cookie instanceof ClientCookie 
-                    && ((ClientCookie) cookie).containsAttribute(ClientCookie.VERSION_ATTR)) {
+                    && !((ClientCookie) cookie).containsAttribute(ClientCookie.VERSION_ATTR)) {
                 throw new MalformedCookieException(
                         "Violates RFC 2965. Version attribute is required.");
             }

Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAbstractCookieSpec.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAbstractCookieSpec.java?rev=581953&r1=581952&r2=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAbstractCookieSpec.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAbstractCookieSpec.java Thu Oct  4 08:53:50 2007
@@ -111,6 +111,8 @@
         Iterator it = cookiespec.getAttribHandlerIterator();
         assertNotNull(it.next());
         assertNotNull(it.next());
+        assertNotNull(it.next());
+        assertNotNull(it.next());
         assertFalse(it.hasNext());
     }
 

Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAllCookieImpl.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAllCookieImpl.java?rev=581953&r1=581952&r2=581953&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAllCookieImpl.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/cookie/TestAllCookieImpl.java Thu Oct  4 08:53:50 2007
@@ -50,6 +50,7 @@
         suite.addTest(TestBrowserCompatSpec.suite());
         suite.addTest(TestCookieNetscapeDraft.suite());
         suite.addTest(TestCookieRFC2109Spec.suite());
+        suite.addTest(TestCookieRFC2965Spec.suite());
         return suite;
     }
 



Mime
View raw message