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
32package org.apache.http.impl.cookie;
33
34import java.util.ArrayList;
35import java.util.List;
36import java.util.Locale;
37
38import org.apache.http.FormattedHeader;
39import org.apache.http.Header;
40import org.apache.http.HeaderElement;
41import org.apache.http.cookie.ClientCookie;
42import org.apache.http.cookie.Cookie;
43import org.apache.http.cookie.CookieOrigin;
44import org.apache.http.cookie.MalformedCookieException;
45import org.apache.http.cookie.SM;
46import org.apache.http.message.BufferedHeader;
47import org.apache.http.message.ParserCursor;
48import 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 * @deprecated Please use {@link java.net.URL#openConnection} instead.
60 *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
61 *     for further details.
62 */
63@Deprecated
64public class BrowserCompatSpec extends CookieSpecBase {
65
66    /** Valid date patterns used per default */
67    protected static final String[] DATE_PATTERNS = new String[] {
68            DateUtils.PATTERN_RFC1123,
69            DateUtils.PATTERN_RFC1036,
70            DateUtils.PATTERN_ASCTIME,
71            "EEE, dd-MMM-yyyy HH:mm:ss z",
72            "EEE, dd-MMM-yyyy HH-mm-ss z",
73            "EEE, dd MMM yy HH:mm:ss z",
74            "EEE dd-MMM-yyyy HH:mm:ss z",
75            "EEE dd MMM yyyy HH:mm:ss z",
76            "EEE dd-MMM-yyyy HH-mm-ss z",
77            "EEE dd-MMM-yy HH:mm:ss z",
78            "EEE dd MMM yy HH:mm:ss z",
79            "EEE,dd-MMM-yy HH:mm:ss z",
80            "EEE,dd-MMM-yyyy HH:mm:ss z",
81            "EEE, dd-MM-yyyy HH:mm:ss z",
82        };
83
84    private final String[] datepatterns;
85
86    /** Default constructor */
87    public BrowserCompatSpec(final String[] datepatterns) {
88        super();
89        if (datepatterns != null) {
90            this.datepatterns = datepatterns.clone();
91        } else {
92            this.datepatterns = DATE_PATTERNS;
93        }
94        registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler());
95        registerAttribHandler(ClientCookie.DOMAIN_ATTR, new BasicDomainHandler());
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 BrowserCompatSpec() {
105        this(null);
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        String headervalue = header.getValue();
117        boolean isNetscapeCookie = false;
118        int i1 = headervalue.toLowerCase(Locale.ENGLISH).indexOf("expires=");
119        if (i1 != -1) {
120            i1 += "expires=".length();
121            int i2 = headervalue.indexOf(';', i1);
122            if (i2 == -1) {
123                i2 = headervalue.length();
124            }
125            try {
126                DateUtils.parseDate(headervalue.substring(i1, i2), this.datepatterns);
127                isNetscapeCookie = true;
128            } catch (DateParseException e) {
129                // Does not look like a valid expiry date
130            }
131        }
132        HeaderElement[] elems = null;
133        if (isNetscapeCookie) {
134            NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT;
135            CharArrayBuffer buffer;
136            ParserCursor cursor;
137            if (header instanceof FormattedHeader) {
138                buffer = ((FormattedHeader) header).getBuffer();
139                cursor = new ParserCursor(
140                        ((FormattedHeader) header).getValuePos(),
141                        buffer.length());
142            } else {
143                String s = header.getValue();
144                if (s == null) {
145                    throw new MalformedCookieException("Header value is null");
146                }
147                buffer = new CharArrayBuffer(s.length());
148                buffer.append(s);
149                cursor = new ParserCursor(0, buffer.length());
150            }
151            elems = new HeaderElement[] { parser.parseHeader(buffer, cursor) };
152        } else {
153            elems = header.getElements();
154        }
155        return parse(elems, origin);
156    }
157
158    public List<Header> formatCookies(final List<Cookie> cookies) {
159        if (cookies == null) {
160            throw new IllegalArgumentException("List of cookies may not be null");
161        }
162        if (cookies.isEmpty()) {
163            throw new IllegalArgumentException("List of cookies may not be empty");
164        }
165        CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size());
166        buffer.append(SM.COOKIE);
167        buffer.append(": ");
168        for (int i = 0; i < cookies.size(); i++) {
169            Cookie cookie = cookies.get(i);
170            if (i > 0) {
171                buffer.append("; ");
172            }
173            buffer.append(cookie.getName());
174            buffer.append("=");
175            String s = cookie.getValue();
176            if (s != null) {
177                buffer.append(s);
178            }
179        }
180        List<Header> headers = new ArrayList<Header>(1);
181        headers.add(new BufferedHeader(buffer));
182        return headers;
183    }
184
185    public int getVersion() {
186        return 0;
187    }
188
189    public Header getVersionHeader() {
190        return null;
191    }
192
193}
194