Wed, 31 Dec 2014 07:22:50 +0100
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.List;
33 import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
35 import ch.boye.httpclientandroidlib.FormattedHeader;
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.CookieSpec;
42 import ch.boye.httpclientandroidlib.cookie.MalformedCookieException;
43 import ch.boye.httpclientandroidlib.cookie.SM;
44 import ch.boye.httpclientandroidlib.message.BufferedHeader;
45 import ch.boye.httpclientandroidlib.message.ParserCursor;
46 import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
48 /**
49 * This {@link CookieSpec} implementation conforms to the original draft
50 * specification published by Netscape Communications. It should be avoided
51 * unless absolutely necessary for compatibility with legacy code.
52 *
53 * @since 4.0
54 */
55 @NotThreadSafe // superclass is @NotThreadSafe
56 public class NetscapeDraftSpec extends CookieSpecBase {
58 protected static final String EXPIRES_PATTERN = "EEE, dd-MMM-yy HH:mm:ss z";
60 private final String[] datepatterns;
62 /** Default constructor */
63 public NetscapeDraftSpec(final String[] datepatterns) {
64 super();
65 if (datepatterns != null) {
66 this.datepatterns = datepatterns.clone();
67 } else {
68 this.datepatterns = new String[] { EXPIRES_PATTERN };
69 }
70 registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler());
71 registerAttribHandler(ClientCookie.DOMAIN_ATTR, new NetscapeDomainHandler());
72 registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler());
73 registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler());
74 registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler());
75 registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler(
76 this.datepatterns));
77 }
79 /** Default constructor */
80 public NetscapeDraftSpec() {
81 this(null);
82 }
84 /**
85 * Parses the Set-Cookie value into an array of <tt>Cookie</tt>s.
86 *
87 * <p>Syntax of the Set-Cookie HTTP Response Header:</p>
88 *
89 * <p>This is the format a CGI script would use to add to
90 * the HTTP headers a new piece of data which is to be stored by
91 * the client for later retrieval.</p>
92 *
93 * <PRE>
94 * Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
95 * </PRE>
96 *
97 * <p>Please note that the Netscape draft specification does not fully conform to the HTTP
98 * header format. Comma character if present in <code>Set-Cookie</code> will not be treated
99 * as a header element separator</p>
100 *
101 * @see <a href="http://web.archive.org/web/20020803110822/http://wp.netscape.com/newsref/std/cookie_spec.html">
102 * The Cookie Spec.</a>
103 *
104 * @param header the <tt>Set-Cookie</tt> received from the server
105 * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie value
106 * @throws MalformedCookieException if an exception occurs during parsing
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 if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) {
117 throw new MalformedCookieException("Unrecognized cookie header '"
118 + header.toString() + "'");
119 }
120 NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT;
121 CharArrayBuffer buffer;
122 ParserCursor cursor;
123 if (header instanceof FormattedHeader) {
124 buffer = ((FormattedHeader) header).getBuffer();
125 cursor = new ParserCursor(
126 ((FormattedHeader) header).getValuePos(),
127 buffer.length());
128 } else {
129 String s = header.getValue();
130 if (s == null) {
131 throw new MalformedCookieException("Header value is null");
132 }
133 buffer = new CharArrayBuffer(s.length());
134 buffer.append(s);
135 cursor = new ParserCursor(0, buffer.length());
136 }
137 return parse(new HeaderElement[] { parser.parseHeader(buffer, cursor) }, origin);
138 }
140 public List<Header> formatCookies(final List<Cookie> cookies) {
141 if (cookies == null) {
142 throw new IllegalArgumentException("List of cookies may not be null");
143 }
144 if (cookies.isEmpty()) {
145 throw new IllegalArgumentException("List of cookies may not be empty");
146 }
147 CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size());
148 buffer.append(SM.COOKIE);
149 buffer.append(": ");
150 for (int i = 0; i < cookies.size(); i++) {
151 Cookie cookie = cookies.get(i);
152 if (i > 0) {
153 buffer.append("; ");
154 }
155 buffer.append(cookie.getName());
156 String s = cookie.getValue();
157 if (s != null) {
158 buffer.append("=");
159 buffer.append(s);
160 }
161 }
162 List<Header> headers = new ArrayList<Header>(1);
163 headers.add(new BufferedHeader(buffer));
164 return headers;
165 }
167 public int getVersion() {
168 return 0;
169 }
171 public Header getVersionHeader() {
172 return null;
173 }
175 @Override
176 public String toString() {
177 return "netscape";
178 }
180 }