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 package org.apache.http.impl.cookie;
28
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Locale;
33 import java.util.Map;
34
35 import org.apache.http.Header;
36 import org.apache.http.HeaderElement;
37 import org.apache.http.NameValuePair;
38 import org.apache.http.annotation.Contract;
39 import org.apache.http.annotation.Obsolete;
40 import org.apache.http.annotation.ThreadingBehavior;
41 import org.apache.http.cookie.ClientCookie;
42 import org.apache.http.cookie.CommonCookieAttributeHandler;
43 import org.apache.http.cookie.Cookie;
44 import org.apache.http.cookie.CookieAttributeHandler;
45 import org.apache.http.cookie.CookieOrigin;
46 import org.apache.http.cookie.CookieRestrictionViolationException;
47 import org.apache.http.cookie.MalformedCookieException;
48 import org.apache.http.cookie.SM;
49 import org.apache.http.message.BufferedHeader;
50 import org.apache.http.util.Args;
51 import org.apache.http.util.CharArrayBuffer;
52
53
54
55
56
57
58
59
60
61 @Obsolete
62 @Contract(threading = ThreadingBehavior.SAFE)
63 public class RFC2965Spec extends RFC2109Spec {
64
65
66
67
68 public RFC2965Spec() {
69 this(null, false);
70 }
71
72 public RFC2965Spec(final String[] datepatterns, final boolean oneHeader) {
73 super(oneHeader,
74 new RFC2965VersionAttributeHandler(),
75 new BasicPathHandler() {
76
77 @Override
78 public void validate(
79 final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException {
80 if (!match(cookie, origin)) {
81 throw new CookieRestrictionViolationException(
82 "Illegal 'path' attribute \"" + cookie.getPath()
83 + "\". Path of origin: \"" + origin.getPath() + "\"");
84 }
85 }
86
87 },
88 new RFC2965DomainAttributeHandler(),
89 new RFC2965PortAttributeHandler(),
90 new BasicMaxAgeHandler(),
91 new BasicSecureHandler(),
92 new BasicCommentHandler(),
93 new BasicExpiresHandler(
94 datepatterns != null ? datepatterns.clone() : DATE_PATTERNS),
95 new RFC2965CommentUrlAttributeHandler(),
96 new RFC2965DiscardAttributeHandler());
97 }
98
99 RFC2965Spec(final boolean oneHeader,
100 final CommonCookieAttributeHandler... handlers) {
101 super(oneHeader, handlers);
102 }
103
104 @Override
105 public List<Cookie> parse(
106 final Header header,
107 final CookieOrigin origin) throws MalformedCookieException {
108 Args.notNull(header, "Header");
109 Args.notNull(origin, "Cookie origin");
110 if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE2)) {
111 throw new MalformedCookieException("Unrecognized cookie header '"
112 + header.toString() + "'");
113 }
114 final HeaderElement[] elems = header.getElements();
115 return createCookies(elems, adjustEffectiveHost(origin));
116 }
117
118 @Override
119 protected List<Cookie> parse(
120 final HeaderElement[] elems,
121 final CookieOrigin origin) throws MalformedCookieException {
122 return createCookies(elems, adjustEffectiveHost(origin));
123 }
124
125 private List<Cookie> createCookies(
126 final HeaderElement[] elems,
127 final CookieOrigin origin) throws MalformedCookieException {
128 final List<Cookie> cookies = new ArrayList<Cookie>(elems.length);
129 for (final HeaderElement headerelement : elems) {
130 final String name = headerelement.getName();
131 final String value = headerelement.getValue();
132 if (name == null || name.isEmpty()) {
133 throw new MalformedCookieException("Cookie name may not be empty");
134 }
135
136 final BasicClientCookie2ntCookie2.html#BasicClientCookie2">BasicClientCookie2 cookie = new BasicClientCookie2(name, value);
137 cookie.setPath(getDefaultPath(origin));
138 cookie.setDomain(getDefaultDomain(origin));
139 cookie.setPorts(new int [] { origin.getPort() });
140
141 final NameValuePair[] attribs = headerelement.getParameters();
142
143
144
145 final Map<String, NameValuePair> attribmap =
146 new HashMap<String, NameValuePair>(attribs.length);
147 for (int j = attribs.length - 1; j >= 0; j--) {
148 final NameValuePair param = attribs[j];
149 attribmap.put(param.getName().toLowerCase(Locale.ROOT), param);
150 }
151 for (final Map.Entry<String, NameValuePair> entry : attribmap.entrySet()) {
152 final NameValuePair attrib = entry.getValue();
153 final String s = attrib.getName().toLowerCase(Locale.ROOT);
154
155 cookie.setAttribute(s, attrib.getValue());
156
157 final CookieAttributeHandler handler = findAttribHandler(s);
158 if (handler != null) {
159 handler.parse(cookie, attrib.getValue());
160 }
161 }
162 cookies.add(cookie);
163 }
164 return cookies;
165 }
166
167 @Override
168 public void validate(
169 final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException {
170 Args.notNull(cookie, "Cookie");
171 Args.notNull(origin, "Cookie origin");
172 super.validate(cookie, adjustEffectiveHost(origin));
173 }
174
175 @Override
176 public boolean match(final Cookie cookie, final CookieOrigin origin) {
177 Args.notNull(cookie, "Cookie");
178 Args.notNull(origin, "Cookie origin");
179 return super.match(cookie, adjustEffectiveHost(origin));
180 }
181
182
183
184
185 @Override
186 protected void formatCookieAsVer(final CharArrayBuffer buffer,
187 final Cookie cookie, final int version) {
188 super.formatCookieAsVer(buffer, cookie, version);
189
190 if (cookie instanceof ClientCookie) {
191
192 final String s = ((ClientCookie) cookie).getAttribute(ClientCookie.PORT_ATTR);
193 if (s != null) {
194 buffer.append("; $Port");
195 buffer.append("=\"");
196 if (!s.trim().isEmpty()) {
197 final int[] ports = cookie.getPorts();
198 if (ports != null) {
199 final int len = ports.length;
200 for (int i = 0; i < len; i++) {
201 if (i > 0) {
202 buffer.append(",");
203 }
204 buffer.append(Integer.toString(ports[i]));
205 }
206 }
207 }
208 buffer.append("\"");
209 }
210 }
211 }
212
213
214
215
216
217
218
219
220
221
222
223 private static CookieOriginkieOrigin">CookieOrigin adjustEffectiveHost(final CookieOrigin origin) {
224 final String host = origin.getHost();
225
226
227
228 boolean isLocalHost = true;
229 for (int i = 0; i < host.length(); i++) {
230 final char ch = host.charAt(i);
231 if (ch == '.' || ch == ':') {
232 isLocalHost = false;
233 break;
234 }
235 }
236 return isLocalHost
237 ? new CookieOrigin(
238 host + ".local",
239 origin.getPort(),
240 origin.getPath(),
241 origin.isSecure())
242 : origin;
243 }
244
245 @Override
246 public int getVersion() {
247 return 1;
248 }
249
250 @Override
251 public Header getVersionHeader() {
252 final CharArrayBuffer buffer = new CharArrayBuffer(40);
253 buffer.append(SM.COOKIE2);
254 buffer.append(": ");
255 buffer.append("$Version=");
256 buffer.append(Integer.toString(getVersion()));
257 return new BufferedHeader(buffer);
258 }
259
260 @Override
261 public String toString() {
262 return "rfc2965";
263 }
264
265 }
266