• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpec.java $
3  * $Revision: 657334 $
4  * $Date: 2008-05-17 04:44:16 -0700 (Sat, 17 May 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.List;
36 import java.util.Locale;
37 
38 import org.apache.http.FormattedHeader;
39 import org.apache.http.Header;
40 import org.apache.http.HeaderElement;
41 import org.apache.http.cookie.ClientCookie;
42 import org.apache.http.cookie.Cookie;
43 import org.apache.http.cookie.CookieOrigin;
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.message.ParserCursor;
48 import org.apache.http.util.CharArrayBuffer;
49 
50 /**
51  * Cookie specification that strives to closely mimic (mis)behavior of
52  * common web browser applications such as Microsoft Internet Explorer
53  * and Mozilla FireFox.
54  *
55  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
56  *
57  * @since 4.0
58  */
59 public class BrowserCompatSpec extends CookieSpecBase {
60 
61     /** Valid date patterns used per default */
62     protected static final String[] DATE_PATTERNS = new String[] {
63             DateUtils.PATTERN_RFC1123,
64             DateUtils.PATTERN_RFC1036,
65             DateUtils.PATTERN_ASCTIME,
66             "EEE, dd-MMM-yyyy HH:mm:ss z",
67             "EEE, dd-MMM-yyyy HH-mm-ss z",
68             "EEE, dd MMM yy HH:mm:ss z",
69             "EEE dd-MMM-yyyy HH:mm:ss z",
70             "EEE dd MMM yyyy HH:mm:ss z",
71             "EEE dd-MMM-yyyy HH-mm-ss z",
72             "EEE dd-MMM-yy HH:mm:ss z",
73             "EEE dd MMM yy HH:mm:ss z",
74             "EEE,dd-MMM-yy HH:mm:ss z",
75             "EEE,dd-MMM-yyyy HH:mm:ss z",
76             "EEE, dd-MM-yyyy HH:mm:ss z",
77         };
78 
79     private final String[] datepatterns;
80 
81     /** Default constructor */
BrowserCompatSpec(final String[] datepatterns)82     public BrowserCompatSpec(final String[] datepatterns) {
83         super();
84         if (datepatterns != null) {
85             this.datepatterns = datepatterns.clone();
86         } else {
87             this.datepatterns = DATE_PATTERNS;
88         }
89         registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler());
90         registerAttribHandler(ClientCookie.DOMAIN_ATTR, new BasicDomainHandler());
91         registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler());
92         registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler());
93         registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler());
94         registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler(
95                 this.datepatterns));
96     }
97 
98     /** Default constructor */
BrowserCompatSpec()99     public BrowserCompatSpec() {
100         this(null);
101     }
102 
parse(final Header header, final CookieOrigin origin)103     public List<Cookie> parse(final Header header, final CookieOrigin origin)
104             throws MalformedCookieException {
105         if (header == null) {
106             throw new IllegalArgumentException("Header may not be null");
107         }
108         if (origin == null) {
109             throw new IllegalArgumentException("Cookie origin may not be null");
110         }
111         String headervalue = header.getValue();
112         boolean isNetscapeCookie = false;
113         int i1 = headervalue.toLowerCase(Locale.ENGLISH).indexOf("expires=");
114         if (i1 != -1) {
115             i1 += "expires=".length();
116             int i2 = headervalue.indexOf(';', i1);
117             if (i2 == -1) {
118                 i2 = headervalue.length();
119             }
120             try {
121                 DateUtils.parseDate(headervalue.substring(i1, i2), this.datepatterns);
122                 isNetscapeCookie = true;
123             } catch (DateParseException e) {
124                 // Does not look like a valid expiry date
125             }
126         }
127         HeaderElement[] elems = null;
128         if (isNetscapeCookie) {
129             NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT;
130             CharArrayBuffer buffer;
131             ParserCursor cursor;
132             if (header instanceof FormattedHeader) {
133                 buffer = ((FormattedHeader) header).getBuffer();
134                 cursor = new ParserCursor(
135                         ((FormattedHeader) header).getValuePos(),
136                         buffer.length());
137             } else {
138                 String s = header.getValue();
139                 if (s == null) {
140                     throw new MalformedCookieException("Header value is null");
141                 }
142                 buffer = new CharArrayBuffer(s.length());
143                 buffer.append(s);
144                 cursor = new ParserCursor(0, buffer.length());
145             }
146             elems = new HeaderElement[] { parser.parseHeader(buffer, cursor) };
147         } else {
148             elems = header.getElements();
149         }
150         return parse(elems, origin);
151     }
152 
formatCookies(final List<Cookie> cookies)153     public List<Header> formatCookies(final List<Cookie> cookies) {
154         if (cookies == null) {
155             throw new IllegalArgumentException("List of cookies may not be null");
156         }
157         if (cookies.isEmpty()) {
158             throw new IllegalArgumentException("List of cookies may not be empty");
159         }
160         CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size());
161         buffer.append(SM.COOKIE);
162         buffer.append(": ");
163         for (int i = 0; i < cookies.size(); i++) {
164             Cookie cookie = cookies.get(i);
165             if (i > 0) {
166                 buffer.append("; ");
167             }
168             buffer.append(cookie.getName());
169             buffer.append("=");
170             String s = cookie.getValue();
171             if (s != null) {
172                 buffer.append(s);
173             }
174         }
175         List<Header> headers = new ArrayList<Header>(1);
176         headers.add(new BufferedHeader(buffer));
177         return headers;
178     }
179 
getVersion()180     public int getVersion() {
181         return 0;
182     }
183 
getVersionHeader()184     public Header getVersionHeader() {
185         return null;
186     }
187 
188 }
189