Mercurial Hosting > luan
annotate src/org/eclipse/jetty/http/HttpFields.java @ 1019:f126d30e04a4
start replacing BufferCache with StringCache
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 31 Oct 2016 03:33:42 -0600 |
parents | fa6158f29c45 |
children | 6be43ef1eb96 |
rev | line source |
---|---|
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
2 // ======================================================================== |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
4 // ------------------------------------------------------------------------ |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
5 // All rights reserved. This program and the accompanying materials |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
6 // are made available under the terms of the Eclipse Public License v1.0 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
7 // and Apache License v2.0 which accompanies this distribution. |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
8 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
9 // The Eclipse Public License is available at |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
10 // http://www.eclipse.org/legal/epl-v10.html |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
11 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
12 // The Apache License v2.0 is available at |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
13 // http://www.opensource.org/licenses/apache2.0.php |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
14 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
15 // You may elect to redistribute this code under either of these licenses. |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
16 // ======================================================================== |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
17 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
18 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
19 package org.eclipse.jetty.http; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
20 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
21 import java.io.IOException; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
22 import java.io.UnsupportedEncodingException; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
23 import java.text.SimpleDateFormat; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
24 import java.util.ArrayList; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
25 import java.util.Calendar; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
26 import java.util.Collections; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
27 import java.util.Collection; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
28 import java.util.Date; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
29 import java.util.Enumeration; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
30 import java.util.GregorianCalendar; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
31 import java.util.HashMap; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
32 import java.util.Iterator; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
33 import java.util.List; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
34 import java.util.Locale; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
35 import java.util.Map; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
36 import java.util.NoSuchElementException; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
37 import java.util.StringTokenizer; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
38 import java.util.TimeZone; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
39 import java.util.concurrent.ConcurrentHashMap; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
40 import java.util.concurrent.ConcurrentMap; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
41 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
42 import org.eclipse.jetty.io.Buffer; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
43 import org.eclipse.jetty.io.BufferCache; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
44 import org.eclipse.jetty.io.BufferCache.CachedBuffer; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
45 import org.eclipse.jetty.io.BufferUtil; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
46 import org.eclipse.jetty.io.ByteArrayBuffer; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
47 import org.eclipse.jetty.util.LazyList; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
48 import org.eclipse.jetty.util.QuotedStringTokenizer; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
49 import org.eclipse.jetty.util.StringUtil; |
820
8e9db0bbf4f9
remove org.eclipse.jetty.util.log and upgrade slf4j
Franklin Schmidt <fschmidt@gmail.com>
parents:
802
diff
changeset
|
50 import org.slf4j.Logger; |
8e9db0bbf4f9
remove org.eclipse.jetty.util.log and upgrade slf4j
Franklin Schmidt <fschmidt@gmail.com>
parents:
802
diff
changeset
|
51 import org.slf4j.LoggerFactory; |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
52 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
53 /* ------------------------------------------------------------ */ |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
54 /** |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
55 * HTTP Fields. A collection of HTTP header and or Trailer fields. |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
56 * |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
57 * <p>This class is not synchronized as it is expected that modifications will only be performed by a |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
58 * single thread. |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
59 * |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
60 * |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
61 */ |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
62 public final class HttpFields |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
63 { |
831 | 64 private static final Logger LOG = LoggerFactory.getLogger(HttpFields.class); |
65 | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
66 private static final String __COOKIE_DELIM="\"\\\n\r\t\f\b%+ ;="; |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
67 private static final TimeZone __GMT = TimeZone.getTimeZone("GMT"); |
831 | 68 |
69 private static final String[] DAYS = | |
70 { "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; | |
71 private static final String[] MONTHS = | |
72 { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan"}; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
73 |
831 | 74 |
75 private static class DateGenerator | |
76 { | |
77 private final StringBuilder buf = new StringBuilder(32); | |
78 private final GregorianCalendar gc = new GregorianCalendar(__GMT); | |
79 | |
80 /** | |
81 * Format HTTP date "EEE, dd MMM yyyy HH:mm:ss 'GMT'" | |
82 */ | |
83 public String formatDate(long date) | |
84 { | |
85 buf.setLength(0); | |
86 gc.setTimeInMillis(date); | |
87 | |
88 int day_of_week = gc.get(Calendar.DAY_OF_WEEK); | |
89 int day_of_month = gc.get(Calendar.DAY_OF_MONTH); | |
90 int month = gc.get(Calendar.MONTH); | |
91 int year = gc.get(Calendar.YEAR); | |
92 int century = year / 100; | |
93 year = year % 100; | |
94 | |
95 int hours = gc.get(Calendar.HOUR_OF_DAY); | |
96 int minutes = gc.get(Calendar.MINUTE); | |
97 int seconds = gc.get(Calendar.SECOND); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
98 |
831 | 99 buf.append(DAYS[day_of_week]); |
100 buf.append(','); | |
101 buf.append(' '); | |
102 StringUtil.append2digits(buf, day_of_month); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
103 |
831 | 104 buf.append(' '); |
105 buf.append(MONTHS[month]); | |
106 buf.append(' '); | |
107 StringUtil.append2digits(buf, century); | |
108 StringUtil.append2digits(buf, year); | |
109 | |
110 buf.append(' '); | |
111 StringUtil.append2digits(buf, hours); | |
112 buf.append(':'); | |
113 StringUtil.append2digits(buf, minutes); | |
114 buf.append(':'); | |
115 StringUtil.append2digits(buf, seconds); | |
116 buf.append(" GMT"); | |
117 return buf.toString(); | |
118 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
119 |
831 | 120 /* ------------------------------------------------------------ */ |
121 /** | |
122 * Format "EEE, dd-MMM-yy HH:mm:ss 'GMT'" for cookies | |
123 */ | |
124 public void formatCookieDate(StringBuilder buf, long date) | |
125 { | |
126 gc.setTimeInMillis(date); | |
127 | |
128 int day_of_week = gc.get(Calendar.DAY_OF_WEEK); | |
129 int day_of_month = gc.get(Calendar.DAY_OF_MONTH); | |
130 int month = gc.get(Calendar.MONTH); | |
131 int year = gc.get(Calendar.YEAR); | |
132 year = year % 10000; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
133 |
831 | 134 int epoch = (int) ((date / 1000) % (60 * 60 * 24)); |
135 int seconds = epoch % 60; | |
136 epoch = epoch / 60; | |
137 int minutes = epoch % 60; | |
138 int hours = epoch / 60; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
139 |
831 | 140 buf.append(DAYS[day_of_week]); |
141 buf.append(','); | |
142 buf.append(' '); | |
143 StringUtil.append2digits(buf, day_of_month); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
144 |
831 | 145 buf.append('-'); |
146 buf.append(MONTHS[month]); | |
147 buf.append('-'); | |
148 StringUtil.append2digits(buf, year/100); | |
149 StringUtil.append2digits(buf, year%100); | |
150 | |
151 buf.append(' '); | |
152 StringUtil.append2digits(buf, hours); | |
153 buf.append(':'); | |
154 StringUtil.append2digits(buf, minutes); | |
155 buf.append(':'); | |
156 StringUtil.append2digits(buf, seconds); | |
157 buf.append(" GMT"); | |
158 } | |
159 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
160 |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
161 private static final ThreadLocal<DateGenerator> __dateGenerator = new ThreadLocal<DateGenerator>() |
831 | 162 { |
163 @Override | |
164 protected DateGenerator initialValue() | |
165 { | |
166 return new DateGenerator(); | |
167 } | |
168 }; | |
169 | |
170 /* ------------------------------------------------------------ */ | |
171 /** | |
172 * Format HTTP date "EEE, dd MMM yyyy HH:mm:ss 'GMT'" | |
173 */ | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
174 private static String formatDate(long date) |
831 | 175 { |
176 return __dateGenerator.get().formatDate(date); | |
177 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
178 |
831 | 179 /* ------------------------------------------------------------ */ |
180 /** | |
181 * Format "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'" for cookies | |
182 */ | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
183 private static void formatCookieDate(StringBuilder buf, long date) |
831 | 184 { |
185 __dateGenerator.get().formatCookieDate(buf,date); | |
186 } | |
187 | |
188 /* ------------------------------------------------------------ */ | |
189 /** | |
190 * Format "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'" for cookies | |
191 */ | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
192 private static String formatCookieDate(long date) |
831 | 193 { |
194 StringBuilder buf = new StringBuilder(28); | |
195 formatCookieDate(buf, date); | |
196 return buf.toString(); | |
197 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
198 |
831 | 199 private final static String __dateReceiveFmt[] = |
200 { | |
201 "EEE, dd MMM yyyy HH:mm:ss zzz", | |
202 "EEE, dd-MMM-yy HH:mm:ss", | |
203 "EEE MMM dd HH:mm:ss yyyy", | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
204 |
831 | 205 "EEE, dd MMM yyyy HH:mm:ss", "EEE dd MMM yyyy HH:mm:ss zzz", |
206 "EEE dd MMM yyyy HH:mm:ss", "EEE MMM dd yyyy HH:mm:ss zzz", "EEE MMM dd yyyy HH:mm:ss", | |
207 "EEE MMM-dd-yyyy HH:mm:ss zzz", "EEE MMM-dd-yyyy HH:mm:ss", "dd MMM yyyy HH:mm:ss zzz", | |
208 "dd MMM yyyy HH:mm:ss", "dd-MMM-yy HH:mm:ss zzz", "dd-MMM-yy HH:mm:ss", "MMM dd HH:mm:ss yyyy zzz", | |
209 "MMM dd HH:mm:ss yyyy", "EEE MMM dd HH:mm:ss yyyy zzz", | |
210 "EEE, MMM dd HH:mm:ss yyyy zzz", "EEE, MMM dd HH:mm:ss yyyy", "EEE, dd-MMM-yy HH:mm:ss zzz", | |
211 "EEE dd-MMM-yy HH:mm:ss zzz", "EEE dd-MMM-yy HH:mm:ss", | |
212 }; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
213 |
831 | 214 private static class DateParser |
215 { | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
216 final SimpleDateFormat _dateReceive[] = new SimpleDateFormat[__dateReceiveFmt.length]; |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
217 |
831 | 218 long parse(final String dateVal) |
219 { | |
220 for (int i = 0; i < _dateReceive.length; i++) | |
221 { | |
222 if (_dateReceive[i] == null) | |
223 { | |
224 _dateReceive[i] = new SimpleDateFormat(__dateReceiveFmt[i], Locale.US); | |
225 _dateReceive[i].setTimeZone(__GMT); | |
226 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
227 |
831 | 228 try |
229 { | |
230 Date date = (Date) _dateReceive[i].parseObject(dateVal); | |
231 return date.getTime(); | |
232 } | |
233 catch (java.lang.Exception e) | |
234 { | |
235 // LOG.ignore(e); | |
236 } | |
237 } | |
238 | |
239 if (dateVal.endsWith(" GMT")) | |
240 { | |
241 final String val = dateVal.substring(0, dateVal.length() - 4); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
242 |
831 | 243 for (int i = 0; i < _dateReceive.length; i++) |
244 { | |
245 try | |
246 { | |
247 Date date = (Date) _dateReceive[i].parseObject(val); | |
248 return date.getTime(); | |
249 } | |
250 catch (java.lang.Exception e) | |
251 { | |
252 // LOG.ignore(e); | |
253 } | |
254 } | |
255 } | |
256 return -1; | |
257 } | |
258 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
259 |
831 | 260 private static final ThreadLocal<DateParser> __dateParser =new ThreadLocal<DateParser>() |
261 { | |
262 @Override | |
263 protected DateParser initialValue() | |
264 { | |
265 return new DateParser(); | |
266 } | |
267 }; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
268 |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
269 private final static String __01Jan1970 = formatDate(0); |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
270 private final static Buffer __01Jan1970_BUFFER = new ByteArrayBuffer(__01Jan1970); |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
271 private final static String __01Jan1970_COOKIE = formatCookieDate(0).trim(); |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
272 |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
273 |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
274 |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
275 |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
276 |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
277 |
831 | 278 private final ArrayList<Field> _fields = new ArrayList<Field>(20); |
279 private final HashMap<Buffer,Field> _names = new HashMap<Buffer,Field>(32); | |
280 | |
281 /* ------------------------------------------------------------ */ | |
282 /** | |
283 * Constructor. | |
284 */ | |
285 public HttpFields() | |
286 { | |
287 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
288 |
831 | 289 // TODO externalize this cache so it can be configurable |
290 private static ConcurrentMap<String, Buffer> __cache = new ConcurrentHashMap<String, Buffer>(); | |
291 private static int __cacheSize = Integer.getInteger("org.eclipse.jetty.http.HttpFields.CACHE",2000); | |
292 | |
293 /* -------------------------------------------------------------- */ | |
294 private Buffer convertValue(String value) | |
295 { | |
296 Buffer buffer = __cache.get(value); | |
297 if (buffer!=null) | |
298 return buffer; | |
299 | |
300 try | |
301 { | |
302 buffer = new ByteArrayBuffer(value,StringUtil.__ISO_8859_1); | |
303 | |
304 if (__cacheSize>0) | |
305 { | |
306 if (__cache.size()>__cacheSize) | |
307 __cache.clear(); | |
308 Buffer b=__cache.putIfAbsent(value,buffer); | |
309 if (b!=null) | |
310 buffer=b; | |
311 } | |
312 | |
313 return buffer; | |
314 } | |
315 catch (UnsupportedEncodingException e) | |
316 { | |
317 throw new RuntimeException(e); | |
318 } | |
319 } | |
320 | |
321 /* -------------------------------------------------------------- */ | |
322 /** | |
323 * Get Collection of header names. | |
324 */ | |
325 public Collection<String> getFieldNamesCollection() | |
326 { | |
327 final List<String> list = new ArrayList<String>(_fields.size()); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
328 |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
329 for (Field f : _fields) |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
330 { |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
331 if (f!=null) |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
332 list.add(BufferUtil.to8859_1_String(f._name)); |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
333 } |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
334 return list; |
831 | 335 } |
336 | |
337 /* -------------------------------------------------------------- */ | |
338 /** | |
339 * Get enumeration of header _names. Returns an enumeration of strings representing the header | |
340 * _names for this request. | |
341 */ | |
342 public Enumeration<String> getFieldNames() | |
343 { | |
344 final Enumeration<?> buffers = Collections.enumeration(_names.keySet()); | |
345 return new Enumeration<String>() | |
346 { | |
347 public String nextElement() | |
348 { | |
349 return buffers.nextElement().toString(); | |
350 } | |
351 | |
352 public boolean hasMoreElements() | |
353 { | |
354 return buffers.hasMoreElements(); | |
355 } | |
356 }; | |
357 } | |
358 | |
359 /* ------------------------------------------------------------ */ | |
360 public int size() | |
361 { | |
362 return _fields.size(); | |
363 } | |
364 | |
365 /* ------------------------------------------------------------ */ | |
366 /** | |
367 * Get a Field by index. | |
368 * @return A Field value or null if the Field value has not been set | |
369 * | |
370 */ | |
371 public Field getField(int i) | |
372 { | |
373 return _fields.get(i); | |
374 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
375 |
831 | 376 /* ------------------------------------------------------------ */ |
377 private Field getField(String name) | |
378 { | |
379 return _names.get(HttpHeaders.CACHE.lookup(name)); | |
380 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
381 |
831 | 382 /* ------------------------------------------------------------ */ |
383 private Field getField(Buffer name) | |
384 { | |
385 return _names.get(HttpHeaders.CACHE.lookup(name)); | |
386 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
387 |
831 | 388 /* ------------------------------------------------------------ */ |
389 public boolean containsKey(Buffer name) | |
390 { | |
391 return _names.containsKey(HttpHeaders.CACHE.lookup(name)); | |
392 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
393 |
831 | 394 /* ------------------------------------------------------------ */ |
395 public boolean containsKey(String name) | |
396 { | |
397 return _names.containsKey(HttpHeaders.CACHE.lookup(name)); | |
398 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
399 |
831 | 400 /* -------------------------------------------------------------- */ |
401 /** | |
402 * @return the value of a field, or null if not found. For multiple fields of the same name, | |
403 * only the first is returned. | |
404 * @param name the case-insensitive field name | |
405 */ | |
406 public String getStringField(String name) | |
407 { | |
408 Field field = getField(name); | |
409 return field==null?null:field.getValue(); | |
410 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
411 |
831 | 412 /* -------------------------------------------------------------- */ |
413 /** | |
414 * @return the value of a field, or null if not found. For multiple fields of the same name, | |
415 * only the first is returned. | |
416 * @param name the case-insensitive field name | |
417 */ | |
418 public String getStringField(Buffer name) | |
419 { | |
420 Field field = getField(name); | |
421 return field==null?null:field.getValue(); | |
422 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
423 |
831 | 424 /* -------------------------------------------------------------- */ |
425 /** | |
426 * @return the value of a field, or null if not found. For multiple fields of the same name, | |
427 * only the first is returned. | |
428 * @param name the case-insensitive field name | |
429 */ | |
430 public Buffer get(Buffer name) | |
431 { | |
432 Field field = getField(name); | |
433 return field==null?null:field._value; | |
434 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
435 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
436 |
831 | 437 /* -------------------------------------------------------------- */ |
438 /** | |
439 * Get multi headers | |
440 * | |
441 * @return Enumeration of the values, or null if no such header. | |
442 * @param name the case-insensitive field name | |
443 */ | |
444 public Collection<String> getValuesCollection(String name) | |
445 { | |
446 Field field = getField(name); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
447 if (field==null) |
831 | 448 return null; |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
449 |
831 | 450 final List<String> list = new ArrayList<String>(); |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
451 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
452 while(field!=null) |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
453 { |
831 | 454 list.add(field.getValue()); |
455 field=field._next; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
456 } |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
457 return list; |
831 | 458 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
459 |
831 | 460 /* -------------------------------------------------------------- */ |
461 /** | |
462 * Get multi headers | |
463 * | |
464 * @return Enumeration of the values | |
465 * @param name the case-insensitive field name | |
466 */ | |
467 public Enumeration<String> getValues(String name) | |
468 { | |
469 final Field field = getField(name); | |
470 if (field == null) | |
471 { | |
472 List<String> empty=Collections.emptyList(); | |
473 return Collections.enumeration(empty); | |
474 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
475 |
831 | 476 return new Enumeration<String>() |
477 { | |
478 Field f = field; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
479 |
831 | 480 public boolean hasMoreElements() |
481 { | |
482 return f != null; | |
483 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
484 |
831 | 485 public String nextElement() throws NoSuchElementException |
486 { | |
487 if (f == null) throw new NoSuchElementException(); | |
488 Field n = f; | |
489 f = f._next; | |
490 return n.getValue(); | |
491 } | |
492 }; | |
493 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
494 |
831 | 495 /* -------------------------------------------------------------- */ |
496 /** | |
497 * Get multi headers | |
498 * | |
499 * @return Enumeration of the value Strings | |
500 * @param name the case-insensitive field name | |
501 */ | |
502 public Enumeration<String> getValues(Buffer name) | |
503 { | |
504 final Field field = getField(name); | |
505 if (field == null) | |
506 { | |
507 List<String> empty=Collections.emptyList(); | |
508 return Collections.enumeration(empty); | |
509 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
510 |
831 | 511 return new Enumeration<String>() |
512 { | |
513 Field f = field; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
514 |
831 | 515 public boolean hasMoreElements() |
516 { | |
517 return f != null; | |
518 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
519 |
831 | 520 public String nextElement() throws NoSuchElementException |
521 { | |
522 if (f == null) throw new NoSuchElementException(); | |
523 Field n = f; | |
524 f = f._next; | |
525 return n.getValue(); | |
526 } | |
527 }; | |
528 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
529 |
831 | 530 /* -------------------------------------------------------------- */ |
531 /** | |
532 * Get multi field values with separator. The multiple values can be represented as separate | |
533 * headers of the same name, or by a single header using the separator(s), or a combination of | |
534 * both. Separators may be quoted. | |
535 * | |
536 * @param name the case-insensitive field name | |
537 * @param separators String of separators. | |
538 * @return Enumeration of the values, or null if no such header. | |
539 */ | |
540 public Enumeration<String> getValues(String name, final String separators) | |
541 { | |
542 final Enumeration<String> e = getValues(name); | |
543 if (e == null) | |
544 return null; | |
545 return new Enumeration<String>() | |
546 { | |
547 QuotedStringTokenizer tok = null; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
548 |
831 | 549 public boolean hasMoreElements() |
550 { | |
551 if (tok != null && tok.hasMoreElements()) return true; | |
552 while (e.hasMoreElements()) | |
553 { | |
554 String value = e.nextElement(); | |
555 tok = new QuotedStringTokenizer(value, separators, false, false); | |
556 if (tok.hasMoreElements()) return true; | |
557 } | |
558 tok = null; | |
559 return false; | |
560 } | |
561 | |
562 public String nextElement() throws NoSuchElementException | |
563 { | |
564 if (!hasMoreElements()) throw new NoSuchElementException(); | |
565 String next = (String) tok.nextElement(); | |
566 if (next != null) next = next.trim(); | |
567 return next; | |
568 } | |
569 }; | |
570 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
571 |
831 | 572 |
573 /* -------------------------------------------------------------- */ | |
574 /** | |
575 * Set a field. | |
576 * | |
577 * @param name the name of the field | |
578 * @param value the value of the field. If null the field is cleared. | |
579 */ | |
580 public void put(String name, String value) | |
581 { | |
582 if (value==null) | |
583 remove(name); | |
584 else | |
585 { | |
586 Buffer n = HttpHeaders.CACHE.lookup(name); | |
587 Buffer v = convertValue(value); | |
588 put(n, v); | |
589 } | |
590 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
591 |
831 | 592 /* -------------------------------------------------------------- */ |
593 /** | |
594 * Set a field. | |
595 * | |
596 * @param name the name of the field | |
597 * @param value the value of the field. If null the field is cleared. | |
598 */ | |
599 public void put(Buffer name, String value) | |
600 { | |
601 Buffer n = HttpHeaders.CACHE.lookup(name); | |
602 Buffer v = convertValue(value); | |
603 put(n, v); | |
604 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
605 |
831 | 606 /* -------------------------------------------------------------- */ |
607 /** | |
608 * Set a field. | |
609 * | |
610 * @param name the name of the field | |
611 * @param value the value of the field. If null the field is cleared. | |
612 */ | |
613 public void put(Buffer name, Buffer value) | |
614 { | |
615 remove(name); | |
616 if (value == null) | |
617 return; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
618 |
831 | 619 if (!(name instanceof BufferCache.CachedBuffer)) |
620 name = HttpHeaders.CACHE.lookup(name); | |
621 if (!(value instanceof CachedBuffer)) | |
622 value= HttpHeaderValues.CACHE.lookup(value).asImmutableBuffer(); | |
623 | |
624 // new value; | |
625 Field field = new Field(name, value); | |
626 _fields.add(field); | |
627 _names.put(name, field); | |
628 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
629 |
831 | 630 /* -------------------------------------------------------------- */ |
631 /** | |
632 * Set a field. | |
633 * | |
634 * @param name the name of the field | |
635 * @param list the List value of the field. If null the field is cleared. | |
636 */ | |
637 public void put(String name, List<?> list) | |
638 { | |
639 if (list == null || list.size() == 0) | |
640 { | |
641 remove(name); | |
642 return; | |
643 } | |
644 Buffer n = HttpHeaders.CACHE.lookup(name); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
645 |
831 | 646 Object v = list.get(0); |
647 if (v != null) | |
648 put(n, HttpHeaderValues.CACHE.lookup(v.toString())); | |
649 else | |
650 remove(n); | |
651 | |
652 if (list.size() > 1) | |
653 { | |
654 java.util.Iterator<?> iter = list.iterator(); | |
655 iter.next(); | |
656 while (iter.hasNext()) | |
657 { | |
658 v = iter.next(); | |
659 if (v != null) put(n, HttpHeaderValues.CACHE.lookup(v.toString())); | |
660 } | |
661 } | |
662 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
663 |
831 | 664 /* -------------------------------------------------------------- */ |
665 /** | |
666 * Add to or set a field. If the field is allowed to have multiple values, add will add multiple | |
667 * headers of the same name. | |
668 * | |
669 * @param name the name of the field | |
670 * @param value the value of the field. | |
671 * @exception IllegalArgumentException If the name is a single valued field and already has a | |
672 * value. | |
673 */ | |
674 public void add(String name, String value) throws IllegalArgumentException | |
675 { | |
676 if (value==null) | |
677 return; | |
678 Buffer n = HttpHeaders.CACHE.lookup(name); | |
679 Buffer v = convertValue(value); | |
680 add(n, v); | |
681 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
682 |
831 | 683 /* -------------------------------------------------------------- */ |
684 /** | |
685 * Add to or set a field. If the field is allowed to have multiple values, add will add multiple | |
686 * headers of the same name. | |
687 * | |
688 * @param name the name of the field | |
689 * @param value the value of the field. | |
690 * @exception IllegalArgumentException If the name is a single valued field and already has a | |
691 * value. | |
692 */ | |
693 public void add(Buffer name, Buffer value) throws IllegalArgumentException | |
694 { | |
695 if (value == null) throw new IllegalArgumentException("null value"); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
696 |
831 | 697 if (!(name instanceof CachedBuffer)) |
698 name = HttpHeaders.CACHE.lookup(name); | |
699 name=name.asImmutableBuffer(); | |
700 | |
701 if (!(value instanceof CachedBuffer) && HttpHeaderValues.hasKnownValues(HttpHeaders.CACHE.getOrdinal(name))) | |
702 value= HttpHeaderValues.CACHE.lookup(value); | |
703 value=value.asImmutableBuffer(); | |
704 | |
705 Field field = _names.get(name); | |
706 Field last = null; | |
707 while (field != null) | |
708 { | |
709 last = field; | |
710 field = field._next; | |
711 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
712 |
831 | 713 // create the field |
714 field = new Field(name, value); | |
715 _fields.add(field); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
716 |
831 | 717 // look for chain to add too |
718 if (last != null) | |
719 last._next = field; | |
720 else | |
721 _names.put(name, field); | |
722 } | |
723 | |
724 /* ------------------------------------------------------------ */ | |
725 /** | |
726 * Remove a field. | |
727 * | |
728 * @param name | |
729 */ | |
730 public void remove(String name) | |
731 { | |
732 remove(HttpHeaders.CACHE.lookup(name)); | |
733 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
734 |
831 | 735 /* ------------------------------------------------------------ */ |
736 /** | |
737 * Remove a field. | |
738 * | |
739 * @param name | |
740 */ | |
741 public void remove(Buffer name) | |
742 { | |
743 if (!(name instanceof BufferCache.CachedBuffer)) | |
744 name = HttpHeaders.CACHE.lookup(name); | |
745 Field field = _names.remove(name); | |
746 while (field != null) | |
747 { | |
748 _fields.remove(field); | |
749 field = field._next; | |
750 } | |
751 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
752 |
831 | 753 /* -------------------------------------------------------------- */ |
754 /** | |
755 * Get a header as an long value. Returns the value of an integer field or -1 if not found. The | |
756 * case of the field name is ignored. | |
757 * | |
758 * @param name the case-insensitive field name | |
759 * @exception NumberFormatException If bad long found | |
760 */ | |
761 public long getLongField(String name) throws NumberFormatException | |
762 { | |
763 Field field = getField(name); | |
764 return field==null?-1L:field.getLongValue(); | |
765 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
766 |
831 | 767 /* -------------------------------------------------------------- */ |
768 /** | |
769 * Get a header as an long value. Returns the value of an integer field or -1 if not found. The | |
770 * case of the field name is ignored. | |
771 * | |
772 * @param name the case-insensitive field name | |
773 * @exception NumberFormatException If bad long found | |
774 */ | |
775 public long getLongField(Buffer name) throws NumberFormatException | |
776 { | |
777 Field field = getField(name); | |
778 return field==null?-1L:field.getLongValue(); | |
779 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
780 |
831 | 781 /* -------------------------------------------------------------- */ |
782 /** | |
783 * Get a header as a date value. Returns the value of a date field, or -1 if not found. The case | |
784 * of the field name is ignored. | |
785 * | |
786 * @param name the case-insensitive field name | |
787 */ | |
788 public long getDateField(String name) | |
789 { | |
790 Field field = getField(name); | |
791 if (field == null) | |
792 return -1; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
793 |
831 | 794 String val = valueParameters(BufferUtil.to8859_1_String(field._value), null); |
795 if (val == null) | |
796 return -1; | |
797 | |
798 final long date = __dateParser.get().parse(val); | |
799 if (date==-1) | |
800 throw new IllegalArgumentException("Cannot convert date: " + val); | |
801 return date; | |
802 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
803 |
831 | 804 /* -------------------------------------------------------------- */ |
805 /** | |
806 * Sets the value of an long field. | |
807 * | |
808 * @param name the field name | |
809 * @param value the field long value | |
810 */ | |
811 public void putLongField(Buffer name, long value) | |
812 { | |
813 Buffer v = BufferUtil.toBuffer(value); | |
814 put(name, v); | |
815 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
816 |
831 | 817 /* -------------------------------------------------------------- */ |
818 /** | |
819 * Sets the value of an long field. | |
820 * | |
821 * @param name the field name | |
822 * @param value the field long value | |
823 */ | |
824 public void putLongField(String name, long value) | |
825 { | |
826 Buffer n = HttpHeaders.CACHE.lookup(name); | |
827 Buffer v = BufferUtil.toBuffer(value); | |
828 put(n, v); | |
829 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
830 |
831 | 831 /* -------------------------------------------------------------- */ |
832 /** | |
833 * Sets the value of an long field. | |
834 * | |
835 * @param name the field name | |
836 * @param value the field long value | |
837 */ | |
838 public void addLongField(String name, long value) | |
839 { | |
840 Buffer n = HttpHeaders.CACHE.lookup(name); | |
841 Buffer v = BufferUtil.toBuffer(value); | |
842 add(n, v); | |
843 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
844 |
831 | 845 /* -------------------------------------------------------------- */ |
846 /** | |
847 * Sets the value of an long field. | |
848 * | |
849 * @param name the field name | |
850 * @param value the field long value | |
851 */ | |
852 public void addLongField(Buffer name, long value) | |
853 { | |
854 Buffer v = BufferUtil.toBuffer(value); | |
855 add(name, v); | |
856 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
857 |
831 | 858 /* -------------------------------------------------------------- */ |
859 /** | |
860 * Sets the value of a date field. | |
861 * | |
862 * @param name the field name | |
863 * @param date the field date value | |
864 */ | |
865 public void putDateField(Buffer name, long date) | |
866 { | |
867 String d=formatDate(date); | |
868 Buffer v = new ByteArrayBuffer(d); | |
869 put(name, v); | |
870 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
871 |
831 | 872 /* -------------------------------------------------------------- */ |
873 /** | |
874 * Sets the value of a date field. | |
875 * | |
876 * @param name the field name | |
877 * @param date the field date value | |
878 */ | |
879 public void putDateField(String name, long date) | |
880 { | |
881 Buffer n = HttpHeaders.CACHE.lookup(name); | |
882 putDateField(n,date); | |
883 } | |
884 | |
885 /* -------------------------------------------------------------- */ | |
886 /** | |
887 * Sets the value of a date field. | |
888 * | |
889 * @param name the field name | |
890 * @param date the field date value | |
891 */ | |
892 public void addDateField(String name, long date) | |
893 { | |
894 String d=formatDate(date); | |
895 Buffer n = HttpHeaders.CACHE.lookup(name); | |
896 Buffer v = new ByteArrayBuffer(d); | |
897 add(n, v); | |
898 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
899 |
831 | 900 /* ------------------------------------------------------------ */ |
901 /** | |
902 * Format a set cookie value | |
903 * | |
904 * @param cookie The cookie. | |
905 */ | |
906 public void addSetCookie(HttpCookie cookie) | |
907 { | |
908 addSetCookie( | |
909 cookie.getName(), | |
910 cookie.getValue(), | |
911 cookie.getDomain(), | |
912 cookie.getPath(), | |
913 cookie.getMaxAge(), | |
914 cookie.getComment(), | |
915 cookie.isSecure(), | |
916 cookie.isHttpOnly(), | |
917 cookie.getVersion()); | |
918 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
919 |
831 | 920 /** |
921 * Format a set cookie value | |
922 * | |
923 * @param name the name | |
924 * @param value the value | |
925 * @param domain the domain | |
926 * @param path the path | |
927 * @param maxAge the maximum age | |
928 * @param comment the comment (only present on versions > 0) | |
929 * @param isSecure true if secure cookie | |
930 * @param isHttpOnly true if for http only | |
931 * @param version version of cookie logic to use (0 == default behavior) | |
932 */ | |
933 public void addSetCookie( | |
934 final String name, | |
935 final String value, | |
936 final String domain, | |
937 final String path, | |
938 final long maxAge, | |
939 final String comment, | |
940 final boolean isSecure, | |
941 final boolean isHttpOnly, | |
942 int version) | |
943 { | |
944 String delim=__COOKIE_DELIM; | |
945 | |
946 // Check arguments | |
947 if (name == null || name.length() == 0) | |
948 throw new IllegalArgumentException("Bad cookie name"); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
949 |
831 | 950 // Format value and params |
951 StringBuilder buf = new StringBuilder(128); | |
952 String name_value_params; | |
953 QuotedStringTokenizer.quoteIfNeeded(buf, name, delim); | |
954 buf.append('='); | |
955 String start=buf.toString(); | |
956 boolean hasDomain = false; | |
957 boolean hasPath = false; | |
958 | |
959 if (value != null && value.length() > 0) | |
960 QuotedStringTokenizer.quoteIfNeeded(buf, value, delim); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
961 |
831 | 962 if (comment != null && comment.length() > 0) |
963 { | |
964 buf.append(";Comment="); | |
965 QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim); | |
966 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
967 |
831 | 968 if (path != null && path.length() > 0) |
969 { | |
970 hasPath = true; | |
971 buf.append(";Path="); | |
972 if (path.trim().startsWith("\"")) | |
973 buf.append(path); | |
974 else | |
975 QuotedStringTokenizer.quoteIfNeeded(buf,path,delim); | |
976 } | |
977 if (domain != null && domain.length() > 0) | |
978 { | |
979 hasDomain = true; | |
980 buf.append(";Domain="); | |
981 QuotedStringTokenizer.quoteIfNeeded(buf,domain.toLowerCase(Locale.ENGLISH),delim); | |
982 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
983 |
831 | 984 if (maxAge >= 0) |
985 { | |
986 // Always add the expires param as some browsers still don't handle max-age | |
987 buf.append(";Expires="); | |
988 if (maxAge == 0) | |
989 buf.append(__01Jan1970_COOKIE); | |
990 else | |
991 formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge); | |
992 | |
993 if (version >0) | |
994 { | |
995 buf.append(";Max-Age="); | |
996 buf.append(maxAge); | |
997 } | |
998 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
999 |
831 | 1000 if (isSecure) |
1001 buf.append(";Secure"); | |
1002 if (isHttpOnly) | |
1003 buf.append(";HttpOnly"); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1004 |
831 | 1005 name_value_params = buf.toString(); |
1006 | |
1007 // remove existing set-cookie of same name | |
1008 Field field = getField(HttpHeaders.SET_COOKIE); | |
1009 Field last=null; | |
1010 while (field!=null) | |
1011 { | |
1012 String val = (field._value == null ? null : field._value.toString()); | |
1013 if (val!=null && val.startsWith(start)) | |
1014 { | |
1015 //existing cookie has same name, does it also match domain and path? | |
1016 if (((!hasDomain && !val.contains("Domain")) || (hasDomain && val.contains("Domain="+domain))) && | |
1017 ((!hasPath && !val.contains("Path")) || (hasPath && val.contains("Path="+path)))) | |
1018 { | |
1019 _fields.remove(field); | |
1020 if (last==null) | |
1021 _names.put(HttpHeaders.SET_COOKIE_BUFFER,field._next); | |
1022 else | |
1023 last._next=field._next; | |
1024 break; | |
1025 } | |
1026 } | |
1027 last=field; | |
1028 field=field._next; | |
1029 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1030 |
831 | 1031 add(HttpHeaders.SET_COOKIE_BUFFER, new ByteArrayBuffer(name_value_params)); |
1032 | |
1033 // Expire responses with set-cookie headers so they do not get cached. | |
1034 put(HttpHeaders.EXPIRES_BUFFER, __01Jan1970_BUFFER); | |
1035 } | |
1036 | |
1037 /* -------------------------------------------------------------- */ | |
1038 public void putTo(Buffer buffer) throws IOException | |
1039 { | |
1040 for (int i = 0; i < _fields.size(); i++) | |
1041 { | |
1042 Field field = _fields.get(i); | |
1043 if (field != null) | |
1044 field.putTo(buffer); | |
1045 } | |
1046 BufferUtil.putCRLF(buffer); | |
1047 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1048 |
831 | 1049 /* -------------------------------------------------------------- */ |
1050 public String toString() | |
1051 { | |
1052 try | |
1053 { | |
1054 StringBuffer buffer = new StringBuffer(); | |
1055 for (int i = 0; i < _fields.size(); i++) | |
1056 { | |
1057 Field field = (Field) _fields.get(i); | |
1058 if (field != null) | |
1059 { | |
1060 String tmp = field.getName(); | |
1061 if (tmp != null) buffer.append(tmp); | |
1062 buffer.append(": "); | |
1063 tmp = field.getValue(); | |
1064 if (tmp != null) buffer.append(tmp); | |
1065 buffer.append("\r\n"); | |
1066 } | |
1067 } | |
1068 buffer.append("\r\n"); | |
1069 return buffer.toString(); | |
1070 } | |
1071 catch (Exception e) | |
1072 { | |
1073 LOG.warn("",e); | |
1074 return e.toString(); | |
1075 } | |
1076 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1077 |
831 | 1078 /* ------------------------------------------------------------ */ |
1079 /** | |
1080 * Clear the header. | |
1081 */ | |
1082 public void clear() | |
1083 { | |
1084 _fields.clear(); | |
1085 _names.clear(); | |
1086 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1087 |
831 | 1088 /* ------------------------------------------------------------ */ |
1089 /** | |
1090 * Add fields from another HttpFields instance. Single valued fields are replaced, while all | |
1091 * others are added. | |
1092 * | |
1093 * @param fields | |
1094 */ | |
1095 public void add(HttpFields fields) | |
1096 { | |
1097 if (fields == null) return; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1098 |
831 | 1099 Enumeration e = fields.getFieldNames(); |
1100 while (e.hasMoreElements()) | |
1101 { | |
1102 String name = (String) e.nextElement(); | |
1103 Enumeration values = fields.getValues(name); | |
1104 while (values.hasMoreElements()) | |
1105 add(name, (String) values.nextElement()); | |
1106 } | |
1107 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1108 |
831 | 1109 /* ------------------------------------------------------------ */ |
1110 /** | |
1111 * Get field value parameters. Some field values can have parameters. This method separates the | |
1112 * value from the parameters and optionally populates a map with the parameters. For example: | |
1113 * | |
1114 * <PRE> | |
1115 * | |
1116 * FieldName : Value ; param1=val1 ; param2=val2 | |
1117 * | |
1118 * </PRE> | |
1119 * | |
1120 * @param value The Field value, possibly with parameteres. | |
1121 * @param parameters A map to populate with the parameters, or null | |
1122 * @return The value. | |
1123 */ | |
1124 public static String valueParameters(String value, Map<String,String> parameters) | |
1125 { | |
1126 if (value == null) return null; | |
1127 | |
1128 int i = value.indexOf(';'); | |
1129 if (i < 0) return value; | |
1130 if (parameters == null) return value.substring(0, i).trim(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1131 |
831 | 1132 StringTokenizer tok1 = new QuotedStringTokenizer(value.substring(i), ";", false, true); |
1133 while (tok1.hasMoreTokens()) | |
1134 { | |
1135 String token = tok1.nextToken(); | |
1136 StringTokenizer tok2 = new QuotedStringTokenizer(token, "= "); | |
1137 if (tok2.hasMoreTokens()) | |
1138 { | |
1139 String paramName = tok2.nextToken(); | |
1140 String paramVal = null; | |
1141 if (tok2.hasMoreTokens()) paramVal = tok2.nextToken(); | |
1142 parameters.put(paramName, paramVal); | |
1143 } | |
1144 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1145 |
831 | 1146 return value.substring(0, i).trim(); |
1147 } | |
1148 | |
1149 /* ------------------------------------------------------------ */ | |
1150 private static final Float __zero = Float.valueOf("0.0"); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1151 |
831 | 1152 /* ------------------------------------------------------------ */ |
1153 public static float getQuality(String value) | |
1154 { | |
1155 if (value == null) return 0f; | |
1156 | |
1157 if( value.indexOf(";") == -1 ) | |
1158 return 1f; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1159 |
831 | 1160 Map params = new HashMap(); |
1161 valueParameters(value, params); | |
1162 String qs = (String) params.get("q"); | |
1163 try { | |
1164 return Float.parseFloat(qs); | |
1165 } catch (NumberFormatException e) { | |
1166 return 1f; | |
1167 } | |
1168 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1169 |
831 | 1170 /* ------------------------------------------------------------ */ |
1171 /** | |
1172 * List values in quality order. | |
1173 * | |
1174 * @param e Enumeration of values with quality parameters | |
1175 * @return values in quality order. | |
1176 */ | |
1177 public static List qualityList(Enumeration e) | |
1178 { | |
1179 if (e == null || !e.hasMoreElements()) return Collections.EMPTY_LIST; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1180 |
831 | 1181 Object list = null; |
1182 Object qual = null; | |
1183 | |
1184 // Assume list will be well ordered and just add nonzero | |
1185 while (e.hasMoreElements()) | |
1186 { | |
1187 String v = e.nextElement().toString(); | |
1188 Float q = getQuality(v); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1189 |
831 | 1190 if (q.floatValue() >= 0.001) |
1191 { | |
1192 list = LazyList.add(list, v); | |
1193 qual = LazyList.add(qual, q); | |
1194 } | |
1195 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1196 |
831 | 1197 List vl = LazyList.getList(list, false); |
1198 if (vl.size() < 2) return vl; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1199 |
831 | 1200 List ql = LazyList.getList(qual, false); |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1201 |
831 | 1202 // sort list with swaps |
1203 Float last = __zero; | |
1204 for (int i = vl.size(); i-- > 0;) | |
1205 { | |
1206 Float q = (Float) ql.get(i); | |
1207 if (last.compareTo(q) > 0) | |
1208 { | |
1209 Object tmp = vl.get(i); | |
1210 vl.set(i, vl.get(i + 1)); | |
1211 vl.set(i + 1, tmp); | |
1212 ql.set(i, ql.get(i + 1)); | |
1213 ql.set(i + 1, q); | |
1214 last = __zero; | |
1215 i = vl.size(); | |
1216 continue; | |
1217 } | |
1218 last = q; | |
1219 } | |
1220 ql.clear(); | |
1221 return vl; | |
1222 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1223 |
831 | 1224 /* ------------------------------------------------------------ */ |
1225 /* ------------------------------------------------------------ */ | |
1226 /* ------------------------------------------------------------ */ | |
1227 public static final class Field | |
1228 { | |
1229 private Buffer _name; | |
1230 private Buffer _value; | |
1231 private Field _next; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1232 |
831 | 1233 /* ------------------------------------------------------------ */ |
1234 private Field(Buffer name, Buffer value) | |
1235 { | |
1236 _name = name; | |
1237 _value = value; | |
1238 _next = null; | |
1239 } | |
1240 | |
1241 /* ------------------------------------------------------------ */ | |
1242 public void putTo(Buffer buffer) throws IOException | |
1243 { | |
1244 int o=(_name instanceof CachedBuffer)?((CachedBuffer)_name).getOrdinal():-1; | |
1245 if (o>=0) | |
1246 buffer.put(_name); | |
1247 else | |
1248 { | |
1249 int s=_name.getIndex(); | |
1250 int e=_name.putIndex(); | |
1251 while (s<e) | |
1252 { | |
1253 byte b=_name.peek(s++); | |
1254 switch(b) | |
1255 { | |
1256 case '\r': | |
1257 case '\n': | |
1258 case ':' : | |
1259 continue; | |
1260 default: | |
1261 buffer.put(b); | |
1262 } | |
1263 } | |
1264 } | |
1265 | |
1266 buffer.put((byte) ':'); | |
1267 buffer.put((byte) ' '); | |
1268 | |
1269 o=(_value instanceof CachedBuffer)?((CachedBuffer)_value).getOrdinal():-1; | |
1270 if (o>=0) | |
1271 buffer.put(_value); | |
1272 else | |
1273 { | |
1274 int s=_value.getIndex(); | |
1275 int e=_value.putIndex(); | |
1276 while (s<e) | |
1277 { | |
1278 byte b=_value.peek(s++); | |
1279 switch(b) | |
1280 { | |
1281 case '\r': | |
1282 case '\n': | |
1283 continue; | |
1284 default: | |
1285 buffer.put(b); | |
1286 } | |
1287 } | |
1288 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1289 |
831 | 1290 BufferUtil.putCRLF(buffer); |
1291 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1292 |
831 | 1293 /* ------------------------------------------------------------ */ |
1294 public String getName() | |
1295 { | |
1296 return BufferUtil.to8859_1_String(_name); | |
1297 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1298 |
831 | 1299 /* ------------------------------------------------------------ */ |
1300 Buffer getNameBuffer() | |
1301 { | |
1302 return _name; | |
1303 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1304 |
831 | 1305 /* ------------------------------------------------------------ */ |
1306 public int getNameOrdinal() | |
1307 { | |
1308 return HttpHeaders.CACHE.getOrdinal(_name); | |
1309 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1310 |
831 | 1311 /* ------------------------------------------------------------ */ |
1312 public String getValue() | |
1313 { | |
1314 return BufferUtil.to8859_1_String(_value); | |
1315 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1316 |
831 | 1317 /* ------------------------------------------------------------ */ |
1318 public Buffer getValueBuffer() | |
1319 { | |
1320 return _value; | |
1321 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1322 |
831 | 1323 /* ------------------------------------------------------------ */ |
1324 public int getValueOrdinal() | |
1325 { | |
1326 return HttpHeaderValues.CACHE.getOrdinal(_value); | |
1327 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1328 |
831 | 1329 /* ------------------------------------------------------------ */ |
1330 public int getIntValue() | |
1331 { | |
1332 return (int) getLongValue(); | |
1333 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1334 |
831 | 1335 /* ------------------------------------------------------------ */ |
1336 public long getLongValue() | |
1337 { | |
1338 return BufferUtil.toLong(_value); | |
1339 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1340 |
831 | 1341 /* ------------------------------------------------------------ */ |
1342 public String toString() | |
1343 { | |
1344 return ("[" + getName() + "=" + _value + (_next == null ? "" : "->") + "]"); | |
1345 } | |
1346 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1347 } |