Home | History | Annotate | Download | only in cookie
      1 /*
      2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java $
      3  * $Revision: 677240 $
      4  * $Date: 2008-07-16 04:25:47 -0700 (Wed, 16 Jul 2008) $
      5  *
      6  * ====================================================================
      7  * Licensed to the Apache Software Foundation (ASF) under one
      8  * or more contributor license agreements.  See the NOTICE file
      9  * distributed with this work for additional information
     10  * regarding copyright ownership.  The ASF licenses this file
     11  * to you under the Apache License, Version 2.0 (the
     12  * "License"); you may not use this file except in compliance
     13  * with the License.  You may obtain a copy of the License at
     14  *
     15  *   http://www.apache.org/licenses/LICENSE-2.0
     16  *
     17  * Unless required by applicable law or agreed to in writing,
     18  * software distributed under the License is distributed on an
     19  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     20  * KIND, either express or implied.  See the License for the
     21  * specific language governing permissions and limitations
     22  * under the License.
     23  * ====================================================================
     24  *
     25  * This software consists of voluntary contributions made by many
     26  * individuals on behalf of the Apache Software Foundation.  For more
     27  * information on the Apache Software Foundation, please see
     28  * <http://www.apache.org/>.
     29  *
     30  */
     31 
     32 package org.apache.http.impl.cookie;
     33 
     34 import java.util.ArrayList;
     35 import java.util.Collections;
     36 import java.util.List;
     37 
     38 import org.apache.http.Header;
     39 import org.apache.http.HeaderElement;
     40 import org.apache.http.cookie.ClientCookie;
     41 import org.apache.http.cookie.Cookie;
     42 import org.apache.http.cookie.CookieOrigin;
     43 import org.apache.http.cookie.CookiePathComparator;
     44 import org.apache.http.cookie.MalformedCookieException;
     45 import org.apache.http.cookie.SM;
     46 import org.apache.http.message.BufferedHeader;
     47 import org.apache.http.util.CharArrayBuffer;
     48 
     49 /**
     50  * RFC 2109 compliant cookie policy
     51  *
     52  * @author  B.C. Holmes
     53  * @author <a href="mailto:jericho (at) thinkfree.com">Park, Sung-Gu</a>
     54  * @author <a href="mailto:dsale (at) us.britannica.com">Doug Sale</a>
     55  * @author Rod Waldhoff
     56  * @author dIon Gillard
     57  * @author Sean C. Sullivan
     58  * @author <a href="mailto:JEvans (at) Cyveillance.com">John Evans</a>
     59  * @author Marc A. Saegesser
     60  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
     61  * @author <a href="mailto:mbowler (at) GargoyleSoftware.com">Mike Bowler</a>
     62  *
     63  * @since 4.0
     64  *
     65  * @deprecated Please use {@link java.net.URL#openConnection} instead.
     66  *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
     67  *     for further details.
     68  */
     69 
     70 @Deprecated
     71 public class RFC2109Spec extends CookieSpecBase {
     72 
     73     private final static CookiePathComparator PATH_COMPARATOR = new CookiePathComparator();
     74 
     75     private final static String[] DATE_PATTERNS = {
     76         DateUtils.PATTERN_RFC1123,
     77         DateUtils.PATTERN_RFC1036,
     78         DateUtils.PATTERN_ASCTIME
     79     };
     80 
     81     private final String[] datepatterns;
     82     private final boolean oneHeader;
     83 
     84     /** Default constructor */
     85     public RFC2109Spec(final String[] datepatterns, boolean oneHeader) {
     86         super();
     87         if (datepatterns != null) {
     88             this.datepatterns = datepatterns.clone();
     89         } else {
     90             this.datepatterns = DATE_PATTERNS;
     91         }
     92         this.oneHeader = oneHeader;
     93         registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2109VersionHandler());
     94         registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler());
     95         registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2109DomainHandler());
     96         registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler());
     97         registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler());
     98         registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler());
     99         registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler(
    100                 this.datepatterns));
    101     }
    102 
    103     /** Default constructor */
    104     public RFC2109Spec() {
    105         this(null, false);
    106     }
    107 
    108     public List<Cookie> parse(final Header header, final CookieOrigin origin)
    109             throws MalformedCookieException {
    110         if (header == null) {
    111             throw new IllegalArgumentException("Header may not be null");
    112         }
    113         if (origin == null) {
    114             throw new IllegalArgumentException("Cookie origin may not be null");
    115         }
    116         HeaderElement[] elems = header.getElements();
    117         return parse(elems, origin);
    118     }
    119 
    120     @Override
    121     public void validate(final Cookie cookie, final CookieOrigin origin)
    122             throws MalformedCookieException {
    123         if (cookie == null) {
    124             throw new IllegalArgumentException("Cookie may not be null");
    125         }
    126         String name = cookie.getName();
    127         if (name.indexOf(' ') != -1) {
    128             throw new MalformedCookieException("Cookie name may not contain blanks");
    129         }
    130         if (name.startsWith("$")) {
    131             throw new MalformedCookieException("Cookie name may not start with $");
    132         }
    133         super.validate(cookie, origin);
    134     }
    135 
    136     public List<Header> formatCookies(List<Cookie> cookies) {
    137         if (cookies == null) {
    138             throw new IllegalArgumentException("List of cookies may not be null");
    139         }
    140         if (cookies.isEmpty()) {
    141             throw new IllegalArgumentException("List of cookies may not be empty");
    142         }
    143         if (cookies.size() > 1) {
    144             // Create a mutable copy and sort the copy.
    145             cookies = new ArrayList<Cookie>(cookies);
    146             Collections.sort(cookies, PATH_COMPARATOR);
    147         }
    148         if (this.oneHeader) {
    149             return doFormatOneHeader(cookies);
    150         } else {
    151             return doFormatManyHeaders(cookies);
    152         }
    153     }
    154 
    155     private List<Header> doFormatOneHeader(final List<Cookie> cookies) {
    156         int version = Integer.MAX_VALUE;
    157         // Pick the lowest common denominator
    158         for (Cookie cookie : cookies) {
    159             if (cookie.getVersion() < version) {
    160                 version = cookie.getVersion();
    161             }
    162         }
    163         CharArrayBuffer buffer = new CharArrayBuffer(40 * cookies.size());
    164         buffer.append(SM.COOKIE);
    165         buffer.append(": ");
    166         buffer.append("$Version=");
    167         buffer.append(Integer.toString(version));
    168         for (Cookie cooky : cookies) {
    169             buffer.append("; ");
    170             Cookie cookie = cooky;
    171             formatCookieAsVer(buffer, cookie, version);
    172         }
    173         List<Header> headers = new ArrayList<Header>(1);
    174         headers.add(new BufferedHeader(buffer));
    175         return headers;
    176     }
    177 
    178     private List<Header> doFormatManyHeaders(final List<Cookie> cookies) {
    179         List<Header> headers = new ArrayList<Header>(cookies.size());
    180         for (Cookie cookie : cookies) {
    181             int version = cookie.getVersion();
    182             CharArrayBuffer buffer = new CharArrayBuffer(40);
    183             buffer.append("Cookie: ");
    184             buffer.append("$Version=");
    185             buffer.append(Integer.toString(version));
    186             buffer.append("; ");
    187             formatCookieAsVer(buffer, cookie, version);
    188             headers.add(new BufferedHeader(buffer));
    189         }
    190         return headers;
    191     }
    192 
    193     /**
    194      * Return a name/value string suitable for sending in a <tt>"Cookie"</tt>
    195      * header as defined in RFC 2109 for backward compatibility with cookie
    196      * version 0
    197      * @param buffer The char array buffer to use for output
    198      * @param name The cookie name
    199      * @param value The cookie value
    200      * @param version The cookie version
    201      */
    202     protected void formatParamAsVer(final CharArrayBuffer buffer,
    203             final String name, final String value, int version) {
    204         buffer.append(name);
    205         buffer.append("=");
    206         if (value != null) {
    207             if (version > 0) {
    208                 buffer.append('\"');
    209                 buffer.append(value);
    210                 buffer.append('\"');
    211             } else {
    212                 buffer.append(value);
    213             }
    214         }
    215     }
    216 
    217     /**
    218      * Return a string suitable for sending in a <tt>"Cookie"</tt> header
    219      * as defined in RFC 2109 for backward compatibility with cookie version 0
    220      * @param buffer The char array buffer to use for output
    221      * @param cookie The {@link Cookie} to be formatted as string
    222      * @param version The version to use.
    223      */
    224     protected void formatCookieAsVer(final CharArrayBuffer buffer,
    225             final Cookie cookie, int version) {
    226         formatParamAsVer(buffer, cookie.getName(), cookie.getValue(), version);
    227         if (cookie.getPath() != null) {
    228             if (cookie instanceof ClientCookie
    229                     && ((ClientCookie) cookie).containsAttribute(ClientCookie.PATH_ATTR)) {
    230                 buffer.append("; ");
    231                 formatParamAsVer(buffer, "$Path", cookie.getPath(), version);
    232             }
    233         }
    234         if (cookie.getDomain() != null) {
    235             if (cookie instanceof ClientCookie
    236                     && ((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) {
    237                 buffer.append("; ");
    238                 formatParamAsVer(buffer, "$Domain", cookie.getDomain(), version);
    239             }
    240         }
    241     }
    242 
    243     public int getVersion() {
    244         return 1;
    245     }
    246 
    247     public Header getVersionHeader() {
    248         return null;
    249     }
    250 
    251 }
    252