mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109Spec.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /*
     2  * ====================================================================
     3  * Licensed to the Apache Software Foundation (ASF) under one
     4  * or more contributor license agreements.  See the NOTICE file
     5  * distributed with this work for additional information
     6  * regarding copyright ownership.  The ASF licenses this file
     7  * to you under the Apache License, Version 2.0 (the
     8  * "License"); you may not use this file except in compliance
     9  * with the License.  You may obtain a copy of the License at
    10  *
    11  *   http://www.apache.org/licenses/LICENSE-2.0
    12  *
    13  * Unless required by applicable law or agreed to in writing,
    14  * software distributed under the License is distributed on an
    15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    16  * KIND, either express or implied.  See the License for the
    17  * specific language governing permissions and limitations
    18  * under the License.
    19  * ====================================================================
    20  *
    21  * This software consists of voluntary contributions made by many
    22  * individuals on behalf of the Apache Software Foundation.  For more
    23  * information on the Apache Software Foundation, please see
    24  * <http://www.apache.org/>.
    25  *
    26  */
    28 package ch.boye.httpclientandroidlib.impl.cookie;
    30 import java.util.ArrayList;
    31 import java.util.Collections;
    32 import java.util.List;
    34 import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
    36 import ch.boye.httpclientandroidlib.Header;
    37 import ch.boye.httpclientandroidlib.HeaderElement;
    38 import ch.boye.httpclientandroidlib.cookie.ClientCookie;
    39 import ch.boye.httpclientandroidlib.cookie.Cookie;
    40 import ch.boye.httpclientandroidlib.cookie.CookieOrigin;
    41 import ch.boye.httpclientandroidlib.cookie.CookiePathComparator;
    42 import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException;
    43 import ch.boye.httpclientandroidlib.cookie.CookieSpec;
    44 import ch.boye.httpclientandroidlib.cookie.MalformedCookieException;
    45 import ch.boye.httpclientandroidlib.cookie.SM;
    46 import ch.boye.httpclientandroidlib.message.BufferedHeader;
    47 import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
    49 /**
    50  * RFC 2109 compliant {@link CookieSpec} implementation. This is an older
    51  * version of the official HTTP state management specification superseded
    52  * by RFC 2965.
    53  *
    54  * @see RFC2965Spec
    55  *
    56  * @since 4.0
    57  */
    58 @NotThreadSafe // superclass is @NotThreadSafe
    59 public class RFC2109Spec extends CookieSpecBase {
    61     private final static CookiePathComparator PATH_COMPARATOR = new CookiePathComparator();
    63     private final static String[] DATE_PATTERNS = {
    64         DateUtils.PATTERN_RFC1123,
    65         DateUtils.PATTERN_RFC1036,
    66         DateUtils.PATTERN_ASCTIME
    67     };
    69     private final String[] datepatterns;
    70     private final boolean oneHeader;
    72     /** Default constructor */
    73     public RFC2109Spec(final String[] datepatterns, boolean oneHeader) {
    74         super();
    75         if (datepatterns != null) {
    76             this.datepatterns = datepatterns.clone();
    77         } else {
    78             this.datepatterns = DATE_PATTERNS;
    79         }
    80         this.oneHeader = oneHeader;
    81         registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2109VersionHandler());
    82         registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler());
    83         registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2109DomainHandler());
    84         registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler());
    85         registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler());
    86         registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler());
    87         registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler(
    88                 this.datepatterns));
    89     }
    91     /** Default constructor */
    92     public RFC2109Spec() {
    93         this(null, false);
    94     }
    96     public List<Cookie> parse(final Header header, final CookieOrigin origin)
    97             throws MalformedCookieException {
    98         if (header == null) {
    99             throw new IllegalArgumentException("Header may not be null");
   100         }
   101         if (origin == null) {
   102             throw new IllegalArgumentException("Cookie origin may not be null");
   103         }
   104         if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) {
   105             throw new MalformedCookieException("Unrecognized cookie header '"
   106                     + header.toString() + "'");
   107         }
   108         HeaderElement[] elems = header.getElements();
   109         return parse(elems, origin);
   110     }
   112     @Override
   113     public void validate(final Cookie cookie, final CookieOrigin origin)
   114             throws MalformedCookieException {
   115         if (cookie == null) {
   116             throw new IllegalArgumentException("Cookie may not be null");
   117         }
   118         String name = cookie.getName();
   119         if (name.indexOf(' ') != -1) {
   120             throw new CookieRestrictionViolationException("Cookie name may not contain blanks");
   121         }
   122         if (name.startsWith("$")) {
   123             throw new CookieRestrictionViolationException("Cookie name may not start with $");
   124         }
   125         super.validate(cookie, origin);
   126     }
   128     public List<Header> formatCookies(List<Cookie> cookies) {
   129         if (cookies == null) {
   130             throw new IllegalArgumentException("List of cookies may not be null");
   131         }
   132         if (cookies.isEmpty()) {
   133             throw new IllegalArgumentException("List of cookies may not be empty");
   134         }
   135         if (cookies.size() > 1) {
   136             // Create a mutable copy and sort the copy.
   137             cookies = new ArrayList<Cookie>(cookies);
   138             Collections.sort(cookies, PATH_COMPARATOR);
   139         }
   140         if (this.oneHeader) {
   141             return doFormatOneHeader(cookies);
   142         } else {
   143             return doFormatManyHeaders(cookies);
   144         }
   145     }
   147     private List<Header> doFormatOneHeader(final List<Cookie> cookies) {
   148         int version = Integer.MAX_VALUE;
   149         // Pick the lowest common denominator
   150         for (Cookie cookie : cookies) {
   151             if (cookie.getVersion() < version) {
   152                 version = cookie.getVersion();
   153             }
   154         }
   155         CharArrayBuffer buffer = new CharArrayBuffer(40 * cookies.size());
   156         buffer.append(SM.COOKIE);
   157         buffer.append(": ");
   158         buffer.append("$Version=");
   159         buffer.append(Integer.toString(version));
   160         for (Cookie cooky : cookies) {
   161             buffer.append("; ");
   162             Cookie cookie = cooky;
   163             formatCookieAsVer(buffer, cookie, version);
   164         }
   165         List<Header> headers = new ArrayList<Header>(1);
   166         headers.add(new BufferedHeader(buffer));
   167         return headers;
   168     }
   170     private List<Header> doFormatManyHeaders(final List<Cookie> cookies) {
   171         List<Header> headers = new ArrayList<Header>(cookies.size());
   172         for (Cookie cookie : cookies) {
   173             int version = cookie.getVersion();
   174             CharArrayBuffer buffer = new CharArrayBuffer(40);
   175             buffer.append("Cookie: ");
   176             buffer.append("$Version=");
   177             buffer.append(Integer.toString(version));
   178             buffer.append("; ");
   179             formatCookieAsVer(buffer, cookie, version);
   180             headers.add(new BufferedHeader(buffer));
   181         }
   182         return headers;
   183     }
   185     /**
   186      * Return a name/value string suitable for sending in a <tt>"Cookie"</tt>
   187      * header as defined in RFC 2109 for backward compatibility with cookie
   188      * version 0
   189      * @param buffer The char array buffer to use for output
   190      * @param name The cookie name
   191      * @param value The cookie value
   192      * @param version The cookie version
   193      */
   194     protected void formatParamAsVer(final CharArrayBuffer buffer,
   195             final String name, final String value, int version) {
   196         buffer.append(name);
   197         buffer.append("=");
   198         if (value != null) {
   199             if (version > 0) {
   200                 buffer.append('\"');
   201                 buffer.append(value);
   202                 buffer.append('\"');
   203             } else {
   204                 buffer.append(value);
   205             }
   206         }
   207     }
   209     /**
   210      * Return a string suitable for sending in a <tt>"Cookie"</tt> header
   211      * as defined in RFC 2109 for backward compatibility with cookie version 0
   212      * @param buffer The char array buffer to use for output
   213      * @param cookie The {@link Cookie} to be formatted as string
   214      * @param version The version to use.
   215      */
   216     protected void formatCookieAsVer(final CharArrayBuffer buffer,
   217             final Cookie cookie, int version) {
   218         formatParamAsVer(buffer, cookie.getName(), cookie.getValue(), version);
   219         if (cookie.getPath() != null) {
   220             if (cookie instanceof ClientCookie
   221                     && ((ClientCookie) cookie).containsAttribute(ClientCookie.PATH_ATTR)) {
   222                 buffer.append("; ");
   223                 formatParamAsVer(buffer, "$Path", cookie.getPath(), version);
   224             }
   225         }
   226         if (cookie.getDomain() != null) {
   227             if (cookie instanceof ClientCookie
   228                     && ((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) {
   229                 buffer.append("; ");
   230                 formatParamAsVer(buffer, "$Domain", cookie.getDomain(), version);
   231             }
   232         }
   233     }
   235     public int getVersion() {
   236         return 1;
   237     }
   239     public Header getVersionHeader() {
   240         return null;
   241     }
   243     @Override
   244     public String toString() {
   245         return "rfc2109";
   246     }
   248 }

mercurial