1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.impl.cookie;
29
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.Locale;
34
35 import org.apache.http.FormattedHeader;
36 import org.apache.http.Header;
37 import org.apache.http.HeaderElement;
38 import org.apache.http.NameValuePair;
39 import org.apache.http.annotation.Contract;
40 import org.apache.http.annotation.ThreadingBehavior;
41 import org.apache.http.client.utils.DateUtils;
42 import org.apache.http.cookie.Cookie;
43 import org.apache.http.cookie.CookieAttributeHandler;
44 import org.apache.http.cookie.CookieOrigin;
45 import org.apache.http.cookie.MalformedCookieException;
46 import org.apache.http.cookie.SM;
47 import org.apache.http.message.BasicHeaderElement;
48 import org.apache.http.message.BasicHeaderValueFormatter;
49 import org.apache.http.message.BufferedHeader;
50 import org.apache.http.message.ParserCursor;
51 import org.apache.http.util.Args;
52 import org.apache.http.util.CharArrayBuffer;
53
54
55
56
57
58
59
60
61
62
63
64 @Deprecated
65 @Contract(threading = ThreadingBehavior.SAFE)
66 public class BrowserCompatSpec extends CookieSpecBase {
67
68
69 private static final String[] DEFAULT_DATE_PATTERNS = new String[] {
70 DateUtils.PATTERN_RFC1123,
71 DateUtils.PATTERN_RFC1036,
72 DateUtils.PATTERN_ASCTIME,
73 "EEE, dd-MMM-yyyy HH:mm:ss z",
74 "EEE, dd-MMM-yyyy HH-mm-ss z",
75 "EEE, dd MMM yy HH:mm:ss z",
76 "EEE dd-MMM-yyyy HH:mm:ss z",
77 "EEE dd MMM yyyy HH:mm:ss z",
78 "EEE dd-MMM-yyyy HH-mm-ss z",
79 "EEE dd-MMM-yy HH:mm:ss z",
80 "EEE dd MMM yy HH:mm:ss z",
81 "EEE,dd-MMM-yy HH:mm:ss z",
82 "EEE,dd-MMM-yyyy HH:mm:ss z",
83 "EEE, dd-MM-yyyy HH:mm:ss z",
84 };
85
86
87 public BrowserCompatSpec(final String[] datepatterns, final BrowserCompatSpecFactory.SecurityLevel securityLevel) {
88 super(new BrowserCompatVersionAttributeHandler(),
89 new BasicDomainHandler(),
90 securityLevel == BrowserCompatSpecFactory.SecurityLevel.SECURITYLEVEL_IE_MEDIUM ?
91 new BasicPathHandler() {
92 @Override
93 public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException {
94
95 }
96 } : new BasicPathHandler(),
97 new BasicMaxAgeHandler(),
98 new BasicSecureHandler(),
99 new BasicCommentHandler(),
100 new BasicExpiresHandler(datepatterns != null ? datepatterns.clone() : DEFAULT_DATE_PATTERNS));
101 }
102
103
104 public BrowserCompatSpec(final String[] datepatterns) {
105 this(datepatterns, BrowserCompatSpecFactory.SecurityLevel.SECURITYLEVEL_DEFAULT);
106 }
107
108
109 public BrowserCompatSpec() {
110 this(null, BrowserCompatSpecFactory.SecurityLevel.SECURITYLEVEL_DEFAULT);
111 }
112
113 @Override
114 public List<Cookie> parse(final Header header, final CookieOrigin origin)
115 throws MalformedCookieException {
116 Args.notNull(header, "Header");
117 Args.notNull(origin, "Cookie origin");
118 final String headername = header.getName();
119 if (!headername.equalsIgnoreCase(SM.SET_COOKIE)) {
120 throw new MalformedCookieException("Unrecognized cookie header '"
121 + header.toString() + "'");
122 }
123 final HeaderElement[] helems = header.getElements();
124 boolean versioned = false;
125 boolean netscape = false;
126 for (final HeaderElement helem: helems) {
127 if (helem.getParameterByName("version") != null) {
128 versioned = true;
129 }
130 if (helem.getParameterByName("expires") != null) {
131 netscape = true;
132 }
133 }
134 if (netscape || !versioned) {
135
136
137 final NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT;
138 final CharArrayBuffer buffer;
139 final ParserCursor cursor;
140 if (header instanceof FormattedHeader) {
141 buffer = ((FormattedHeader) header).getBuffer();
142 cursor = new ParserCursor(
143 ((FormattedHeader) header).getValuePos(),
144 buffer.length());
145 } else {
146 final String s = header.getValue();
147 if (s == null) {
148 throw new MalformedCookieException("Header value is null");
149 }
150 buffer = new CharArrayBuffer(s.length());
151 buffer.append(s);
152 cursor = new ParserCursor(0, buffer.length());
153 }
154 final HeaderElement elem = parser.parseHeader(buffer, cursor);
155 final String name = elem.getName();
156 final String value = elem.getValue();
157 if (name == null || name.isEmpty()) {
158 throw new MalformedCookieException("Cookie name may not be empty");
159 }
160 final BasicClientCookieentCookie.html#BasicClientCookie">BasicClientCookie cookie = new BasicClientCookie(name, value);
161 cookie.setPath(getDefaultPath(origin));
162 cookie.setDomain(getDefaultDomain(origin));
163
164
165 final NameValuePair[] attribs = elem.getParameters();
166 for (int j = attribs.length - 1; j >= 0; j--) {
167 final NameValuePair attrib = attribs[j];
168 final String s = attrib.getName().toLowerCase(Locale.ROOT);
169 cookie.setAttribute(s, attrib.getValue());
170 final CookieAttributeHandler handler = findAttribHandler(s);
171 if (handler != null) {
172 handler.parse(cookie, attrib.getValue());
173 }
174 }
175
176 if (netscape) {
177 cookie.setVersion(0);
178 }
179 return Collections.<Cookie>singletonList(cookie);
180 } else {
181 return parse(helems, origin);
182 }
183 }
184
185 private static boolean isQuoteEnclosed(final String s) {
186 return s != null && s.startsWith("\"") && s.endsWith("\"");
187 }
188
189 @Override
190 public List<Header> formatCookies(final List<Cookie> cookies) {
191 Args.notEmpty(cookies, "List of cookies");
192 final CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size());
193 buffer.append(SM.COOKIE);
194 buffer.append(": ");
195 for (int i = 0; i < cookies.size(); i++) {
196 final Cookie cookie = cookies.get(i);
197 if (i > 0) {
198 buffer.append("; ");
199 }
200 final String cookieName = cookie.getName();
201 final String cookieValue = cookie.getValue();
202 if (cookie.getVersion() > 0 && !isQuoteEnclosed(cookieValue)) {
203 BasicHeaderValueFormatter.INSTANCE.formatHeaderElement(
204 buffer,
205 new BasicHeaderElement(cookieName, cookieValue),
206 false);
207 } else {
208
209 buffer.append(cookieName);
210 buffer.append("=");
211 if (cookieValue != null) {
212 buffer.append(cookieValue);
213 }
214 }
215 }
216 final List<Header> headers = new ArrayList<Header>(1);
217 headers.add(new BufferedHeader(buffer));
218 return headers;
219 }
220
221 @Override
222 public int getVersion() {
223 return 0;
224 }
225
226 @Override
227 public Header getVersionHeader() {
228 return null;
229 }
230
231 @Override
232 public String toString() {
233 return "compatibility";
234 }
235
236 }