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.http.QuotedCSV;
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 public class CookieCutter
41 {
42 private static final Logger LOG = Log.getLogger(CookieCutter.class);
43
44 private Cookie[] _cookies;
45 private Cookie[] _lastCookies;
46 private final List<String> _fieldList = new ArrayList<>();
47 int _fields;
48
49 public CookieCutter()
50 {
51 }
52
53 public Cookie[] getCookies()
54 {
55 if (_cookies!=null)
56 return _cookies;
57
58 if (_lastCookies!=null && _fields==_fieldList.size())
59 _cookies=_lastCookies;
60 else
61 parseFields();
62 _lastCookies=_cookies;
63 return _cookies;
64 }
65
66 public void setCookies(Cookie[] cookies)
67 {
68 _cookies=cookies;
69 _lastCookies=null;
70 _fieldList.clear();
71 _fields=0;
72 }
73
74 public void reset()
75 {
76 _cookies=null;
77 _fields=0;
78 }
79
80 public void addCookieField(String f)
81 {
82 if (f==null)
83 return;
84 f=f.trim();
85 if (f.length()==0)
86 return;
87
88 if (_fieldList.size()>_fields)
89 {
90 if (f.equals(_fieldList.get(_fields)))
91 {
92 _fields++;
93 return;
94 }
95
96 while (_fieldList.size()>_fields)
97 _fieldList.remove(_fields);
98 }
99 _cookies=null;
100 _lastCookies=null;
101 _fieldList.add(_fields++,f);
102 }
103
104
105 protected void parseFields()
106 {
107 _lastCookies=null;
108 _cookies=null;
109
110 List<Cookie> cookies = new ArrayList<>();
111
112 int version = 0;
113
114
115 while (_fieldList.size()>_fields)
116 _fieldList.remove(_fields);
117
118
119 for (String hdr : _fieldList)
120 {
121
122 String name = null;
123 String value = null;
124
125 Cookie cookie = null;
126
127 boolean invalue=false;
128 boolean quoted=false;
129 boolean escaped=false;
130 int tokenstart=-1;
131 int tokenend=-1;
132 for (int i = 0, length = hdr.length(), last=length-1; i < length; i++)
133 {
134 char c = hdr.charAt(i);
135
136
137 if (quoted)
138 {
139 if (escaped)
140 {
141 escaped=false;
142 continue;
143 }
144
145 switch (c)
146 {
147 case '"':
148 tokenend=i;
149 quoted=false;
150
151
152 if (i==last)
153 {
154 if (invalue)
155 value = hdr.substring(tokenstart, tokenend+1);
156 else
157 {
158 name = hdr.substring(tokenstart, tokenend+1);
159 value = "";
160 }
161 }
162 break;
163
164 case '\\':
165 escaped=true;
166 continue;
167 default:
168 continue;
169 }
170 }
171 else
172 {
173
174 if (invalue)
175 {
176
177 switch (c)
178 {
179 case ' ':
180 case '\t':
181 continue;
182
183 case '"':
184 if (tokenstart<0)
185 {
186 quoted=true;
187 tokenstart=i;
188 }
189 tokenend=i;
190 if (i==last)
191 {
192 value = hdr.substring(tokenstart, tokenend+1);
193 break;
194 }
195 continue;
196
197 case ';':
198 if (tokenstart>=0)
199 value = hdr.substring(tokenstart, tokenend+1);
200 else
201 value="";
202 tokenstart = -1;
203 invalue=false;
204 break;
205
206 default:
207 if (tokenstart<0)
208 tokenstart=i;
209 tokenend=i;
210 if (i==last)
211 {
212 value = hdr.substring(tokenstart, tokenend+1);
213 break;
214 }
215 continue;
216 }
217 }
218 else
219 {
220
221 switch (c)
222 {
223 case ' ':
224 case '\t':
225 continue;
226
227 case '"':
228 if (tokenstart<0)
229 {
230 quoted=true;
231 tokenstart=i;
232 }
233 tokenend=i;
234 if (i==last)
235 {
236 name = hdr.substring(tokenstart, tokenend+1);
237 value = "";
238 break;
239 }
240 continue;
241
242 case ';':
243 if (tokenstart>=0)
244 {
245 name = hdr.substring(tokenstart, tokenend+1);
246 value = "";
247 }
248 tokenstart = -1;
249 break;
250
251 case '=':
252 if (tokenstart>=0)
253 name = hdr.substring(tokenstart, tokenend+1);
254 tokenstart = -1;
255 invalue=true;
256 continue;
257
258 default:
259 if (tokenstart<0)
260 tokenstart=i;
261 tokenend=i;
262 if (i==last)
263 {
264 name = hdr.substring(tokenstart, tokenend+1);
265 value = "";
266 break;
267 }
268 continue;
269 }
270 }
271 }
272
273
274 if (value!=null && name!=null)
275 {
276
277 name=QuotedCSV.unquote(name);
278 value=QuotedCSV.unquote(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 }