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