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@thinkfree.com">Park, Sung-Gu</a>
54  * @author <a href="mailto:dsale@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@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@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 */
RFC2109Spec(final String[] datepatterns, boolean oneHeader)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 */
RFC2109Spec()104     public RFC2109Spec() {
105         this(null, false);
106     }
107 
parse(final Header header, final CookieOrigin origin)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
validate(final Cookie cookie, final CookieOrigin origin)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 
formatCookies(List<Cookie> cookies)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 
doFormatOneHeader(final List<Cookie> cookies)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 
doFormatManyHeaders(final List<Cookie> cookies)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      */
formatParamAsVer(final CharArrayBuffer buffer, final String name, final String value, int version)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      */
formatCookieAsVer(final CharArrayBuffer buffer, final Cookie cookie, int version)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 
getVersion()243     public int getVersion() {
244         return 1;
245     }
246 
getVersionHeader()247     public Header getVersionHeader() {
248         return null;
249     }
250 
251 }
252