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