comparison src/org/eclipse/jetty/server/CookieCutter.java @ 802:3428c60d7cfc

replace jetty jars with source
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 07 Sep 2016 21:15:48 -0600
parents
children 8e9db0bbf4f9
comparison
equal deleted inserted replaced
801:6a21393191c1 802:3428c60d7cfc
1 //
2 // ========================================================================
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
8 //
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
11 //
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
14 //
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
17 //
18
19 package org.eclipse.jetty.server;
20 import java.util.Locale;
21
22 import javax.servlet.http.Cookie;
23
24 import org.eclipse.jetty.util.LazyList;
25 import org.eclipse.jetty.util.QuotedStringTokenizer;
26 import org.eclipse.jetty.util.log.Log;
27 import org.eclipse.jetty.util.log.Logger;
28
29
30 /* ------------------------------------------------------------ */
31 /** Cookie parser
32 * <p>Optimized stateful cookie parser. Cookies fields are added with the
33 * {@link #addCookieField(String)} method and parsed on the next subsequent
34 * call to {@link #getCookies()}.
35 * If the added fields are identical to those last added (as strings), then the
36 * cookies are not re parsed.
37 *
38 *
39 */
40 public class CookieCutter
41 {
42 private static final Logger LOG = Log.getLogger(CookieCutter.class);
43
44
45 private Cookie[] _cookies;
46 private Cookie[] _lastCookies;
47 Object _lazyFields;
48 int _fields;
49
50 public CookieCutter()
51 {
52 }
53
54 public Cookie[] getCookies()
55 {
56 if (_cookies!=null)
57 return _cookies;
58
59 if (_lastCookies!=null &&
60 _lazyFields!=null &&
61 _fields==LazyList.size(_lazyFields))
62 _cookies=_lastCookies;
63 else
64 parseFields();
65 _lastCookies=_cookies;
66 return _cookies;
67 }
68
69 public void setCookies(Cookie[] cookies)
70 {
71 _cookies=cookies;
72 _lastCookies=null;
73 _lazyFields=null;
74 _fields=0;
75 }
76
77 public void reset()
78 {
79 _cookies=null;
80 _fields=0;
81 }
82
83 public void addCookieField(String f)
84 {
85 if (f==null)
86 return;
87 f=f.trim();
88 if (f.length()==0)
89 return;
90
91 if (LazyList.size(_lazyFields)>_fields)
92 {
93 if (f.equals(LazyList.get(_lazyFields,_fields)))
94 {
95 _fields++;
96 return;
97 }
98
99 while (LazyList.size(_lazyFields)>_fields)
100 _lazyFields=LazyList.remove(_lazyFields,_fields);
101 }
102 _cookies=null;
103 _lastCookies=null;
104 _lazyFields=LazyList.add(_lazyFields,_fields++,f);
105 }
106
107
108 protected void parseFields()
109 {
110 _lastCookies=null;
111 _cookies=null;
112
113 Object cookies = null;
114
115 int version = 0;
116
117 // delete excess fields
118 while (LazyList.size(_lazyFields)>_fields)
119 _lazyFields=LazyList.remove(_lazyFields,_fields);
120
121 // For each cookie field
122 for (int f=0;f<_fields;f++)
123 {
124 String hdr = LazyList.get(_lazyFields,f);
125
126 // Parse the header
127 String name = null;
128 String value = null;
129
130 Cookie cookie = null;
131
132 boolean invalue=false;
133 boolean quoted=false;
134 boolean escaped=false;
135 int tokenstart=-1;
136 int tokenend=-1;
137 for (int i = 0, length = hdr.length(), last=length-1; i < length; i++)
138 {
139 char c = hdr.charAt(i);
140
141 // Handle quoted values for name or value
142 if (quoted)
143 {
144 if (escaped)
145 {
146 escaped=false;
147 continue;
148 }
149
150 switch (c)
151 {
152 case '"':
153 tokenend=i;
154 quoted=false;
155
156 // handle quote as last character specially
157 if (i==last)
158 {
159 if (invalue)
160 value = hdr.substring(tokenstart, tokenend+1);
161 else
162 {
163 name = hdr.substring(tokenstart, tokenend+1);
164 value = "";
165 }
166 }
167 break;
168
169 case '\\':
170 escaped=true;
171 continue;
172 default:
173 continue;
174 }
175 }
176 else
177 {
178 // Handle name and value state machines
179 if (invalue)
180 {
181 // parse the value
182 switch (c)
183 {
184 case ' ':
185 case '\t':
186 continue;
187
188 case '"':
189 if (tokenstart<0)
190 {
191 quoted=true;
192 tokenstart=i;
193 }
194 tokenend=i;
195 if (i==last)
196 {
197 value = hdr.substring(tokenstart, tokenend+1);
198 break;
199 }
200 continue;
201
202 case ';':
203 // case ',':
204 if (tokenstart>=0)
205 value = hdr.substring(tokenstart, tokenend+1);
206 else
207 value="";
208 tokenstart = -1;
209 invalue=false;
210 break;
211
212 default:
213 if (tokenstart<0)
214 tokenstart=i;
215 tokenend=i;
216 if (i==last)
217 {
218 value = hdr.substring(tokenstart, tokenend+1);
219 break;
220 }
221 continue;
222 }
223 }
224 else
225 {
226 // parse the name
227 switch (c)
228 {
229 case ' ':
230 case '\t':
231 continue;
232
233 case '"':
234 if (tokenstart<0)
235 {
236 quoted=true;
237 tokenstart=i;
238 }
239 tokenend=i;
240 if (i==last)
241 {
242 name = hdr.substring(tokenstart, tokenend+1);
243 value = "";
244 break;
245 }
246 continue;
247
248 case ';':
249 // case ',':
250 if (tokenstart>=0)
251 {
252 name = hdr.substring(tokenstart, tokenend+1);
253 value = "";
254 }
255 tokenstart = -1;
256 break;
257
258 case '=':
259 if (tokenstart>=0)
260 name = hdr.substring(tokenstart, tokenend+1);
261 tokenstart = -1;
262 invalue=true;
263 continue;
264
265 default:
266 if (tokenstart<0)
267 tokenstart=i;
268 tokenend=i;
269 if (i==last)
270 {
271 name = hdr.substring(tokenstart, tokenend+1);
272 value = "";
273 break;
274 }
275 continue;
276 }
277 }
278 }
279
280 // If after processing the current character we have a value and a name, then it is a cookie
281 if (value!=null && name!=null)
282 {
283 // TODO handle unquoting during parsing! But quoting is uncommon
284 name=QuotedStringTokenizer.unquoteOnly(name);
285 value=QuotedStringTokenizer.unquoteOnly(value);
286
287 try
288 {
289 if (name.startsWith("$"))
290 {
291 String lowercaseName = name.toLowerCase(Locale.ENGLISH);
292 if ("$path".equals(lowercaseName))
293 {
294 if (cookie!=null)
295 cookie.setPath(value);
296 }
297 else if ("$domain".equals(lowercaseName))
298 {
299 if (cookie!=null)
300 cookie.setDomain(value);
301 }
302 else if ("$port".equals(lowercaseName))
303 {
304 if (cookie!=null)
305 cookie.setComment("$port="+value);
306 }
307 else if ("$version".equals(lowercaseName))
308 {
309 version = Integer.parseInt(value);
310 }
311 }
312 else
313 {
314 cookie = new Cookie(name, value);
315 if (version > 0)
316 cookie.setVersion(version);
317 cookies = LazyList.add(cookies, cookie);
318 }
319 }
320 catch (Exception e)
321 {
322 LOG.debug(e);
323 }
324
325 name = null;
326 value = null;
327 }
328 }
329 }
330
331 _cookies = (Cookie[]) LazyList.toArray(cookies,Cookie.class);
332 _lastCookies=_cookies;
333 }
334
335 }