1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty;
16 import javax.servlet.http.Cookie;
17 import javax.servlet.http.HttpServletRequest;
18
19 import org.mortbay.log.Log;
20 import org.mortbay.util.LazyList;
21 import org.mortbay.util.URIUtil;
22
23
24
25
26
27
28
29
30
31
32
33
34 public class CookieCutter
35 {
36 private static final byte STATE_DELIMITER = 1;
37 private static final byte STATE_NAME = 2;
38 private static final byte STATE_VALUE = 4;
39 private static final byte STATE_QUOTED_VALUE = 8;
40 private static final byte STATE_UNQUOTED_VALUE = 16;
41
42 private Cookie[] _cookies;
43 private String[] _fields;
44 int _added=0;
45 boolean _dirty;
46 HttpServletRequest _request;
47
48 public CookieCutter()
49 {
50
51 }
52
53 public CookieCutter(HttpServletRequest request)
54 {
55 _request = request;
56 }
57
58 public Cookie[] getCookies()
59 {
60 if (_added>0)
61 {
62 if (!_dirty && _added==_fields.length)
63 {
64
65 _added=0;
66 return _cookies;
67 }
68
69 parseFields();
70 }
71 return _cookies;
72 }
73
74 public void setCookies(Cookie[] cookies)
75 {
76 _dirty=false;
77 _added=0;
78 _cookies=cookies;
79 }
80
81 public void reset()
82 {
83 _fields=null;
84 _cookies=null;
85 }
86
87 public void addCookieField(String f)
88 {
89 if (!_dirty &&
90 _fields!=null &&
91 _fields.length>_added &&
92 _fields[_added].equals(f))
93 {
94 _added++;
95 return;
96 }
97
98 if (_dirty)
99 {
100 _added++;
101 _fields=(String[])LazyList.addToArray(_fields,f,String.class);
102 }
103 else
104 {
105 _dirty=true;
106 if (_added>0)
107 {
108 String[] fields=new String[_added+1];
109 System.arraycopy(_fields,0,fields,0,_added);
110 fields[_added++]=f;
111 _fields=fields;
112 }
113 else
114 {
115 _fields = new String[]{f};
116 _added=1;
117 }
118
119 }
120 }
121
122 protected void parseFields()
123 {
124 Object cookies = null;
125
126 int version = 0;
127
128
129 for (int f=0;f<_added;f++)
130 {
131 String hdr = _fields[f];
132
133
134 String name = null;
135 String value = null;
136
137 Cookie cookie = null;
138
139 byte state = STATE_NAME;
140 for (int i = 0, tokenstart = 0, length = hdr.length(); i < length; i++)
141 {
142 char c = hdr.charAt(i);
143 switch (c)
144 {
145 case ',':
146 case ';':
147 switch (state)
148 {
149 case STATE_DELIMITER:
150 state = STATE_NAME;
151 tokenstart = i + 1;
152 break;
153 case STATE_UNQUOTED_VALUE:
154 state = STATE_NAME;
155 value = hdr.substring(tokenstart, i).trim();
156 if(_request!=null && _request.isRequestedSessionIdFromURL())
157 value = URIUtil.decodePath(value);
158 tokenstart = i + 1;
159 break;
160 case STATE_NAME:
161 name = hdr.substring(tokenstart, i);
162 value = "";
163 tokenstart = i + 1;
164 break;
165 case STATE_VALUE:
166 state = STATE_NAME;
167 value = "";
168 tokenstart = i + 1;
169 break;
170 }
171 break;
172 case '=':
173 switch (state)
174 {
175 case STATE_NAME:
176 state = STATE_VALUE;
177 name = hdr.substring(tokenstart, i);
178 tokenstart = i + 1;
179 break;
180 case STATE_VALUE:
181 state = STATE_UNQUOTED_VALUE;
182 tokenstart = i;
183 break;
184 }
185 break;
186 case '"':
187 switch (state)
188 {
189 case STATE_VALUE:
190 state = STATE_QUOTED_VALUE;
191 tokenstart = i + 1;
192 break;
193 case STATE_QUOTED_VALUE:
194 state = STATE_DELIMITER;
195 value = hdr.substring(tokenstart, i);
196 break;
197 }
198 break;
199 case ' ':
200 case '\t':
201 break;
202 default:
203 switch (state)
204 {
205 case STATE_VALUE:
206 state = STATE_UNQUOTED_VALUE;
207 tokenstart = i;
208 break;
209 case STATE_DELIMITER:
210 state = STATE_NAME;
211 tokenstart = i;
212 break;
213 }
214 }
215
216 if (i + 1 == length)
217 {
218 switch (state)
219 {
220 case STATE_UNQUOTED_VALUE:
221 value = hdr.substring(tokenstart).trim();
222 if(_request!=null && _request.isRequestedSessionIdFromURL())
223 value = URIUtil.decodePath(value);
224 break;
225 case STATE_NAME:
226 name = hdr.substring(tokenstart);
227 value = "";
228 break;
229 case STATE_VALUE:
230 value = "";
231 break;
232 }
233 }
234
235 if (name != null && value != null)
236 {
237 name = name.trim();
238
239 try
240 {
241 if (name.startsWith("$"))
242 {
243 String lowercaseName = name.toLowerCase();
244 if ("$path".equals(lowercaseName))
245 {
246 cookie.setPath(value);
247 }
248 else if ("$domain".equals(lowercaseName))
249 {
250 cookie.setDomain(value);
251 }
252 else if ("$version".equals(lowercaseName))
253 {
254 version = Integer.parseInt(value);
255 }
256 }
257 else
258 {
259 cookie = new Cookie(name, value);
260
261 if (version > 0)
262 {
263 cookie.setVersion(version);
264 }
265
266 cookies = LazyList.add(cookies, cookie);
267 }
268 }
269 catch (Exception e)
270 {
271 Log.ignore(e);
272 }
273
274 name = null;
275 value = null;
276 }
277 }
278 }
279
280 int l = LazyList.size(cookies);
281 if (l>0)
282 {
283 if (_cookies != null && _cookies.length == l)
284 {
285 for (int i = 0; i < l; i++)
286 _cookies[i] = (Cookie) LazyList.get(cookies, i);
287 }
288 else
289 _cookies = (Cookie[]) LazyList.toArray(cookies,Cookie.class);
290 }
291
292 _added=0;
293 _dirty=false;
294
295 }
296
297 }