1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.server;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.Locale;
23
24 import javax.servlet.http.Cookie;
25
26 import org.eclipse.jetty.util.QuotedStringTokenizer;
27 import org.eclipse.jetty.util.log.Log;
28 import org.eclipse.jetty.util.log.Logger;
29
30
31
32
33
34
35
36
37
38
39
40
41 public class CookieCutter
42 {
43 private static final Logger LOG = Log.getLogger(CookieCutter.class);
44
45 private Cookie[] _cookies;
46 private Cookie[] _lastCookies;
47 private final List<String> _fieldList = new ArrayList<>();
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 && _fields==_fieldList.size())
60 _cookies=_lastCookies;
61 else
62 parseFields();
63 _lastCookies=_cookies;
64 return _cookies;
65 }
66
67 public void setCookies(Cookie[] cookies)
68 {
69 _cookies=cookies;
70 _lastCookies=null;
71 _fieldList.clear();
72 _fields=0;
73 }
74
75 public void reset()
76 {
77 _cookies=null;
78 _fields=0;
79 }
80
81 public void addCookieField(String f)
82 {
83 if (f==null)
84 return;
85 f=f.trim();
86 if (f.length()==0)
87 return;
88
89 if (_fieldList.size()>_fields)
90 {
91 if (f.equals(_fieldList.get(_fields)))
92 {
93 _fields++;
94 return;
95 }
96
97 while (_fieldList.size()>_fields)
98 _fieldList.remove(_fields);
99 }
100 _cookies=null;
101 _lastCookies=null;
102 _fieldList.add(_fields++,f);
103 }
104
105
106 protected void parseFields()
107 {
108 _lastCookies=null;
109 _cookies=null;
110
111 List<Cookie> cookies = new ArrayList<>();
112
113 int version = 0;
114
115
116 while (_fieldList.size()>_fields)
117 _fieldList.remove(_fields);
118
119
120 for (String hdr : _fieldList)
121 {
122
123 String name = null;
124 String value = null;
125
126 Cookie cookie = null;
127
128 boolean invalue=false;
129 boolean quoted=false;
130 boolean escaped=false;
131 int tokenstart=-1;
132 int tokenend=-1;
133 for (int i = 0, length = hdr.length(), last=length-1; i < length; i++)
134 {
135 char c = hdr.charAt(i);
136
137
138 if (quoted)
139 {
140 if (escaped)
141 {
142 escaped=false;
143 continue;
144 }
145
146 switch (c)
147 {
148 case '"':
149 tokenend=i;
150 quoted=false;
151
152
153 if (i==last)
154 {
155 if (invalue)
156 value = hdr.substring(tokenstart, tokenend+1);
157 else
158 {
159 name = hdr.substring(tokenstart, tokenend+1);
160 value = "";
161 }
162 }
163 break;
164
165 case '\\':
166 escaped=true;
167 continue;
168 default:
169 continue;
170 }
171 }
172 else
173 {
174
175 if (invalue)
176 {
177
178 switch (c)
179 {
180 case ' ':
181 case '\t':
182 continue;
183
184 case '"':
185 if (tokenstart<0)
186 {
187 quoted=true;
188 tokenstart=i;
189 }
190 tokenend=i;
191 if (i==last)
192 {
193 value = hdr.substring(tokenstart, tokenend+1);
194 break;
195 }
196 continue;
197
198 case ';':
199 if (tokenstart>=0)
200 value = hdr.substring(tokenstart, tokenend+1);
201 else
202 value="";
203 tokenstart = -1;
204 invalue=false;
205 break;
206
207 default:
208 if (tokenstart<0)
209 tokenstart=i;
210 tokenend=i;
211 if (i==last)
212 {
213 value = hdr.substring(tokenstart, tokenend+1);
214 break;
215 }
216 continue;
217 }
218 }
219 else
220 {
221
222 switch (c)
223 {
224 case ' ':
225 case '\t':
226 continue;
227
228 case '"':
229 if (tokenstart<0)
230 {
231 quoted=true;
232 tokenstart=i;
233 }
234 tokenend=i;
235 if (i==last)
236 {
237 name = hdr.substring(tokenstart, tokenend+1);
238 value = "";
239 break;
240 }
241 continue;
242
243 case ';':
244 if (tokenstart>=0)
245 {
246 name = hdr.substring(tokenstart, tokenend+1);
247 value = "";
248 }
249 tokenstart = -1;
250 break;
251
252 case '=':
253 if (tokenstart>=0)
254 name = hdr.substring(tokenstart, tokenend+1);
255 tokenstart = -1;
256 invalue=true;
257 continue;
258
259 default:
260 if (tokenstart<0)
261 tokenstart=i;
262 tokenend=i;
263 if (i==last)
264 {
265 name = hdr.substring(tokenstart, tokenend+1);
266 value = "";
267 break;
268 }
269 continue;
270 }
271 }
272 }
273
274
275 if (value!=null && name!=null)
276 {
277 name=QuotedStringTokenizer.unquoteOnly(name);
278 value=QuotedStringTokenizer.unquoteOnly(value);
279
280 try
281 {
282 if (name.startsWith("$"))
283 {
284 String lowercaseName = name.toLowerCase(Locale.ENGLISH);
285 if ("$path".equals(lowercaseName))
286 {
287 if (cookie!=null)
288 cookie.setPath(value);
289 }
290 else if ("$domain".equals(lowercaseName))
291 {
292 if (cookie!=null)
293 cookie.setDomain(value);
294 }
295 else if ("$port".equals(lowercaseName))
296 {
297 if (cookie!=null)
298 cookie.setComment("$port="+value);
299 }
300 else if ("$version".equals(lowercaseName))
301 {
302 version = Integer.parseInt(value);
303 }
304 }
305 else
306 {
307 cookie = new Cookie(name, value);
308 if (version > 0)
309 cookie.setVersion(version);
310 cookies.add(cookie);
311 }
312 }
313 catch (Exception e)
314 {
315 LOG.debug(e);
316 }
317
318 name = null;
319 value = null;
320 }
321 }
322 }
323
324 _cookies = (Cookie[]) cookies.toArray(new Cookie[cookies.size()]);
325 _lastCookies=_cookies;
326 }
327
328 }