Mercurial Hosting > luan
annotate src/org/eclipse/jetty/http/HttpFields.java @ 1045:48506d03e230
tutorial fix
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 06 Nov 2016 14:54:43 -0700 |
parents | eca26899c4bc |
children | 2b769da7f67d |
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.BufferUtil; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
44 import org.eclipse.jetty.util.LazyList; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
45 import org.eclipse.jetty.util.QuotedStringTokenizer; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
46 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
|
47 import org.slf4j.Logger; |
8e9db0bbf4f9
remove org.eclipse.jetty.util.log and upgrade slf4j
Franklin Schmidt <fschmidt@gmail.com>
parents:
802
diff
changeset
|
48 import org.slf4j.LoggerFactory; |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
49 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
50 /* ------------------------------------------------------------ */ |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
51 /** |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
52 * 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
|
53 * |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
54 * <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
|
55 * single thread. |
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 * |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
58 */ |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
59 public final class HttpFields |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
60 { |
831 | 61 private static final Logger LOG = LoggerFactory.getLogger(HttpFields.class); |
62 | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
63 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
|
64 private static final TimeZone __GMT = TimeZone.getTimeZone("GMT"); |
831 | 65 |
66 private static final String[] DAYS = | |
67 { "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; | |
68 private static final String[] MONTHS = | |
69 { "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
|
70 |
831 | 71 |
72 private static class DateGenerator | |
73 { | |
74 private final StringBuilder buf = new StringBuilder(32); | |
75 private final GregorianCalendar gc = new GregorianCalendar(__GMT); | |
76 | |
77 /** | |
78 * Format HTTP date "EEE, dd MMM yyyy HH:mm:ss 'GMT'" | |
79 */ | |
80 public String formatDate(long date) | |
81 { | |
82 buf.setLength(0); | |
83 gc.setTimeInMillis(date); | |
84 | |
85 int day_of_week = gc.get(Calendar.DAY_OF_WEEK); | |
86 int day_of_month = gc.get(Calendar.DAY_OF_MONTH); | |
87 int month = gc.get(Calendar.MONTH); | |
88 int year = gc.get(Calendar.YEAR); | |
89 int century = year / 100; | |
90 year = year % 100; | |
91 | |
92 int hours = gc.get(Calendar.HOUR_OF_DAY); | |
93 int minutes = gc.get(Calendar.MINUTE); | |
94 int seconds = gc.get(Calendar.SECOND); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
95 |
831 | 96 buf.append(DAYS[day_of_week]); |
97 buf.append(','); | |
98 buf.append(' '); | |
99 StringUtil.append2digits(buf, day_of_month); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
100 |
831 | 101 buf.append(' '); |
102 buf.append(MONTHS[month]); | |
103 buf.append(' '); | |
104 StringUtil.append2digits(buf, century); | |
105 StringUtil.append2digits(buf, year); | |
106 | |
107 buf.append(' '); | |
108 StringUtil.append2digits(buf, hours); | |
109 buf.append(':'); | |
110 StringUtil.append2digits(buf, minutes); | |
111 buf.append(':'); | |
112 StringUtil.append2digits(buf, seconds); | |
113 buf.append(" GMT"); | |
114 return buf.toString(); | |
115 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
116 |
831 | 117 /* ------------------------------------------------------------ */ |
118 /** | |
119 * Format "EEE, dd-MMM-yy HH:mm:ss 'GMT'" for cookies | |
120 */ | |
121 public void formatCookieDate(StringBuilder buf, long date) | |
122 { | |
123 gc.setTimeInMillis(date); | |
124 | |
125 int day_of_week = gc.get(Calendar.DAY_OF_WEEK); | |
126 int day_of_month = gc.get(Calendar.DAY_OF_MONTH); | |
127 int month = gc.get(Calendar.MONTH); | |
128 int year = gc.get(Calendar.YEAR); | |
129 year = year % 10000; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
130 |
831 | 131 int epoch = (int) ((date / 1000) % (60 * 60 * 24)); |
132 int seconds = epoch % 60; | |
133 epoch = epoch / 60; | |
134 int minutes = epoch % 60; | |
135 int hours = epoch / 60; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
136 |
831 | 137 buf.append(DAYS[day_of_week]); |
138 buf.append(','); | |
139 buf.append(' '); | |
140 StringUtil.append2digits(buf, day_of_month); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
141 |
831 | 142 buf.append('-'); |
143 buf.append(MONTHS[month]); | |
144 buf.append('-'); | |
145 StringUtil.append2digits(buf, year/100); | |
146 StringUtil.append2digits(buf, year%100); | |
147 | |
148 buf.append(' '); | |
149 StringUtil.append2digits(buf, hours); | |
150 buf.append(':'); | |
151 StringUtil.append2digits(buf, minutes); | |
152 buf.append(':'); | |
153 StringUtil.append2digits(buf, seconds); | |
154 buf.append(" GMT"); | |
155 } | |
156 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
157 |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
158 private static final ThreadLocal<DateGenerator> __dateGenerator = new ThreadLocal<DateGenerator>() |
831 | 159 { |
160 @Override | |
161 protected DateGenerator initialValue() | |
162 { | |
163 return new DateGenerator(); | |
164 } | |
165 }; | |
166 | |
167 /* ------------------------------------------------------------ */ | |
168 /** | |
169 * Format HTTP date "EEE, dd MMM yyyy HH:mm:ss 'GMT'" | |
170 */ | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
171 private static String formatDate(long date) |
831 | 172 { |
173 return __dateGenerator.get().formatDate(date); | |
174 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
175 |
831 | 176 /* ------------------------------------------------------------ */ |
177 /** | |
178 * Format "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'" for cookies | |
179 */ | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
180 private static void formatCookieDate(StringBuilder buf, long date) |
831 | 181 { |
182 __dateGenerator.get().formatCookieDate(buf,date); | |
183 } | |
184 | |
185 /* ------------------------------------------------------------ */ | |
186 /** | |
187 * Format "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'" for cookies | |
188 */ | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
189 private static String formatCookieDate(long date) |
831 | 190 { |
191 StringBuilder buf = new StringBuilder(28); | |
192 formatCookieDate(buf, date); | |
193 return buf.toString(); | |
194 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
195 |
831 | 196 private final static String __dateReceiveFmt[] = |
197 { | |
198 "EEE, dd MMM yyyy HH:mm:ss zzz", | |
199 "EEE, dd-MMM-yy HH:mm:ss", | |
200 "EEE MMM dd HH:mm:ss yyyy", | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
201 |
831 | 202 "EEE, dd MMM yyyy HH:mm:ss", "EEE dd MMM yyyy HH:mm:ss zzz", |
203 "EEE dd MMM yyyy HH:mm:ss", "EEE MMM dd yyyy HH:mm:ss zzz", "EEE MMM dd yyyy HH:mm:ss", | |
204 "EEE MMM-dd-yyyy HH:mm:ss zzz", "EEE MMM-dd-yyyy HH:mm:ss", "dd MMM yyyy HH:mm:ss zzz", | |
205 "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", | |
206 "MMM dd HH:mm:ss yyyy", "EEE MMM dd HH:mm:ss yyyy zzz", | |
207 "EEE, MMM dd HH:mm:ss yyyy zzz", "EEE, MMM dd HH:mm:ss yyyy", "EEE, dd-MMM-yy HH:mm:ss zzz", | |
208 "EEE dd-MMM-yy HH:mm:ss zzz", "EEE dd-MMM-yy HH:mm:ss", | |
209 }; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
210 |
831 | 211 private static class DateParser |
212 { | |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
213 final SimpleDateFormat _dateReceive[] = new SimpleDateFormat[__dateReceiveFmt.length]; |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
214 |
831 | 215 long parse(final String dateVal) |
216 { | |
217 for (int i = 0; i < _dateReceive.length; i++) | |
218 { | |
219 if (_dateReceive[i] == null) | |
220 { | |
221 _dateReceive[i] = new SimpleDateFormat(__dateReceiveFmt[i], Locale.US); | |
222 _dateReceive[i].setTimeZone(__GMT); | |
223 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
224 |
831 | 225 try |
226 { | |
227 Date date = (Date) _dateReceive[i].parseObject(dateVal); | |
228 return date.getTime(); | |
229 } | |
230 catch (java.lang.Exception e) | |
231 { | |
232 // LOG.ignore(e); | |
233 } | |
234 } | |
235 | |
236 if (dateVal.endsWith(" GMT")) | |
237 { | |
238 final String val = dateVal.substring(0, dateVal.length() - 4); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
239 |
831 | 240 for (int i = 0; i < _dateReceive.length; i++) |
241 { | |
242 try | |
243 { | |
244 Date date = (Date) _dateReceive[i].parseObject(val); | |
245 return date.getTime(); | |
246 } | |
247 catch (java.lang.Exception e) | |
248 { | |
249 // LOG.ignore(e); | |
250 } | |
251 } | |
252 } | |
253 return -1; | |
254 } | |
255 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
256 |
831 | 257 private static final ThreadLocal<DateParser> __dateParser =new ThreadLocal<DateParser>() |
258 { | |
259 @Override | |
260 protected DateParser initialValue() | |
261 { | |
262 return new DateParser(); | |
263 } | |
264 }; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
265 |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
266 private final static String __01Jan1970 = formatDate(0); |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
267 private final static String __01Jan1970_COOKIE = formatCookieDate(0).trim(); |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
268 |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
269 |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
270 |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
271 |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
272 |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
273 |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
274 private final ArrayList<Field> _fields = new ArrayList<Field>(); |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
275 private final HashMap<String,Field> _names = new HashMap<String,Field>(); |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
276 |
831 | 277 |
278 /* -------------------------------------------------------------- */ | |
279 /** | |
280 * Get Collection of header names. | |
281 */ | |
282 public Collection<String> getFieldNamesCollection() | |
283 { | |
284 final List<String> list = new ArrayList<String>(_fields.size()); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
285 |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
286 for (Field f : _fields) |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
287 { |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
288 if (f!=null) |
1021 | 289 list.add(f._name.toString()); |
1019
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
290 } |
f126d30e04a4
start replacing BufferCache with StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
855
diff
changeset
|
291 return list; |
831 | 292 } |
293 | |
294 /* -------------------------------------------------------------- */ | |
295 /** | |
296 * Get enumeration of header _names. Returns an enumeration of strings representing the header | |
297 * _names for this request. | |
298 */ | |
299 public Enumeration<String> getFieldNames() | |
300 { | |
301 final Enumeration<?> buffers = Collections.enumeration(_names.keySet()); | |
302 return new Enumeration<String>() | |
303 { | |
304 public String nextElement() | |
305 { | |
306 return buffers.nextElement().toString(); | |
307 } | |
308 | |
309 public boolean hasMoreElements() | |
310 { | |
311 return buffers.hasMoreElements(); | |
312 } | |
313 }; | |
314 } | |
315 | |
316 /* ------------------------------------------------------------ */ | |
317 public int size() | |
318 { | |
319 return _fields.size(); | |
320 } | |
321 | |
322 /* ------------------------------------------------------------ */ | |
323 /** | |
324 * Get a Field by index. | |
325 * @return A Field value or null if the Field value has not been set | |
326 * | |
327 */ | |
328 public Field getField(int i) | |
329 { | |
330 return _fields.get(i); | |
331 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
332 |
831 | 333 private Field getField(String name) |
334 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
335 return _names.get(name.toLowerCase()); |
831 | 336 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
337 |
831 | 338 public boolean containsKey(String name) |
339 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
340 return _names.containsKey(name.toLowerCase()); |
831 | 341 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
342 |
831 | 343 /* -------------------------------------------------------------- */ |
344 /** | |
345 * @return the value of a field, or null if not found. For multiple fields of the same name, | |
346 * only the first is returned. | |
347 * @param name the case-insensitive field name | |
348 */ | |
349 public String getStringField(String name) | |
350 { | |
351 Field field = getField(name); | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
352 return field==null ? null : field.getValue(); |
831 | 353 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
354 |
831 | 355 /* -------------------------------------------------------------- */ |
356 /** | |
357 * Get multi headers | |
358 * | |
359 * @return Enumeration of the values, or null if no such header. | |
360 * @param name the case-insensitive field name | |
361 */ | |
362 public Collection<String> getValuesCollection(String name) | |
363 { | |
364 Field field = getField(name); | |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
365 if (field==null) |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
366 return null; |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
367 |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
368 final List<String> list = new ArrayList<String>(); |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
369 |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
370 while(field!=null) |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
371 { |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
372 list.add(field.getValue()); |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
373 field=field._next; |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
374 } |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
375 return list; |
831 | 376 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
377 |
831 | 378 /* -------------------------------------------------------------- */ |
379 /** | |
380 * Get multi headers | |
381 * | |
382 * @return Enumeration of the values | |
383 * @param name the case-insensitive field name | |
384 */ | |
385 public Enumeration<String> getValues(String name) | |
386 { | |
387 final Field field = getField(name); | |
388 if (field == null) | |
389 { | |
390 List<String> empty=Collections.emptyList(); | |
391 return Collections.enumeration(empty); | |
392 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
393 |
831 | 394 return new Enumeration<String>() |
395 { | |
396 Field f = field; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
397 |
831 | 398 public boolean hasMoreElements() |
399 { | |
400 return f != null; | |
401 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
402 |
831 | 403 public String nextElement() throws NoSuchElementException |
404 { | |
405 if (f == null) throw new NoSuchElementException(); | |
406 Field n = f; | |
407 f = f._next; | |
408 return n.getValue(); | |
409 } | |
410 }; | |
411 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
412 |
831 | 413 /* -------------------------------------------------------------- */ |
414 /** | |
415 * Get multi field values with separator. The multiple values can be represented as separate | |
416 * headers of the same name, or by a single header using the separator(s), or a combination of | |
417 * both. Separators may be quoted. | |
418 * | |
419 * @param name the case-insensitive field name | |
420 * @param separators String of separators. | |
421 * @return Enumeration of the values, or null if no such header. | |
422 */ | |
423 public Enumeration<String> getValues(String name, final String separators) | |
424 { | |
425 final Enumeration<String> e = getValues(name); | |
426 if (e == null) | |
427 return null; | |
428 return new Enumeration<String>() | |
429 { | |
430 QuotedStringTokenizer tok = null; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
431 |
831 | 432 public boolean hasMoreElements() |
433 { | |
434 if (tok != null && tok.hasMoreElements()) return true; | |
435 while (e.hasMoreElements()) | |
436 { | |
437 String value = e.nextElement(); | |
438 tok = new QuotedStringTokenizer(value, separators, false, false); | |
439 if (tok.hasMoreElements()) return true; | |
440 } | |
441 tok = null; | |
442 return false; | |
443 } | |
444 | |
445 public String nextElement() throws NoSuchElementException | |
446 { | |
447 if (!hasMoreElements()) throw new NoSuchElementException(); | |
448 String next = (String) tok.nextElement(); | |
449 if (next != null) next = next.trim(); | |
450 return next; | |
451 } | |
452 }; | |
453 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
454 |
831 | 455 |
456 /* -------------------------------------------------------------- */ | |
457 /** | |
458 * Set a field. | |
459 * | |
460 * @param name the name of the field | |
461 * @param value the value of the field. If null the field is cleared. | |
462 */ | |
463 public void put(String name, String value) | |
464 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
465 String nameLower = name.toLowerCase(); |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
466 removeLower(nameLower); |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
467 if (value == null) |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
468 return; |
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
469 |
831 | 470 // new value; |
471 Field field = new Field(name, value); | |
472 _fields.add(field); | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
473 _names.put(nameLower, field); |
831 | 474 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
475 |
831 | 476 /* -------------------------------------------------------------- */ |
477 /** | |
478 * Add to or set a field. If the field is allowed to have multiple values, add will add multiple | |
479 * headers of the same name. | |
480 * | |
481 * @param name the name of the field | |
482 * @param value the value of the field. | |
483 * @exception IllegalArgumentException If the name is a single valued field and already has a | |
484 * value. | |
485 */ | |
486 public void add(String name, String value) throws IllegalArgumentException | |
487 { | |
488 if (value == null) throw new IllegalArgumentException("null value"); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
489 |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
490 String nameLower = name.toLowerCase(); |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
491 |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
492 Field field = _names.get(nameLower); |
831 | 493 Field last = null; |
494 while (field != null) | |
495 { | |
496 last = field; | |
497 field = field._next; | |
498 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
499 |
831 | 500 // create the field |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
501 field = new Field(name, value); |
831 | 502 _fields.add(field); |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
503 |
831 | 504 // look for chain to add too |
505 if (last != null) | |
506 last._next = field; | |
507 else | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
508 _names.put(nameLower, field); |
831 | 509 } |
510 | |
511 /* ------------------------------------------------------------ */ | |
512 /** | |
513 * Remove a field. | |
514 * | |
515 * @param name | |
516 */ | |
517 public void remove(String name) | |
518 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
519 removeLower(name.toLowerCase()); |
831 | 520 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
521 |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
522 private void removeLower(String nameLower) { |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
523 Field field = _names.remove(nameLower); |
831 | 524 while (field != null) |
525 { | |
526 _fields.remove(field); | |
527 field = field._next; | |
528 } | |
529 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
530 |
831 | 531 /* -------------------------------------------------------------- */ |
532 /** | |
533 * Get a header as an long value. Returns the value of an integer field or -1 if not found. The | |
534 * case of the field name is ignored. | |
535 * | |
536 * @param name the case-insensitive field name | |
537 * @exception NumberFormatException If bad long found | |
538 */ | |
539 public long getLongField(String name) throws NumberFormatException | |
540 { | |
541 Field field = getField(name); | |
542 return field==null?-1L:field.getLongValue(); | |
543 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
544 |
831 | 545 /* -------------------------------------------------------------- */ |
546 /** | |
547 * Get a header as a date value. Returns the value of a date field, or -1 if not found. The case | |
548 * of the field name is ignored. | |
549 * | |
550 * @param name the case-insensitive field name | |
551 */ | |
552 public long getDateField(String name) | |
553 { | |
554 Field field = getField(name); | |
555 if (field == null) | |
556 return -1; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
557 |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
558 String val = valueParameters(field._value, null); |
831 | 559 if (val == null) |
560 return -1; | |
561 | |
562 final long date = __dateParser.get().parse(val); | |
563 if (date==-1) | |
564 throw new IllegalArgumentException("Cannot convert date: " + val); | |
565 return date; | |
566 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
567 |
831 | 568 /* -------------------------------------------------------------- */ |
569 /** | |
570 * Sets the value of an long field. | |
571 * | |
572 * @param name the field name | |
573 * @param value the field long value | |
574 */ | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
575 public void putLongField(String name, long value) |
831 | 576 { |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
577 String v = Long.toString(value); |
831 | 578 put(name, v); |
579 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
580 |
831 | 581 /* -------------------------------------------------------------- */ |
582 /** | |
583 * Sets the value of an long field. | |
584 * | |
585 * @param name the field name | |
586 * @param value the field long value | |
587 */ | |
588 public void addLongField(String name, long value) | |
589 { | |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
590 String v = Long.toString(value); |
831 | 591 add(name, v); |
592 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
593 |
831 | 594 /* -------------------------------------------------------------- */ |
595 /** | |
596 * Sets the value of a date field. | |
597 * | |
598 * @param name the field name | |
599 * @param date the field date value | |
600 */ | |
601 public void putDateField(String name, long date) | |
602 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
603 String d = formatDate(date); |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
604 put(name, d); |
831 | 605 } |
606 | |
607 /* -------------------------------------------------------------- */ | |
608 /** | |
609 * Sets the value of a date field. | |
610 * | |
611 * @param name the field name | |
612 * @param date the field date value | |
613 */ | |
614 public void addDateField(String name, long date) | |
615 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
616 String d = formatDate(date); |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
617 add(name, d); |
831 | 618 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
619 |
831 | 620 /* ------------------------------------------------------------ */ |
621 /** | |
622 * Format a set cookie value | |
623 * | |
624 * @param cookie The cookie. | |
625 */ | |
626 public void addSetCookie(HttpCookie cookie) | |
627 { | |
628 addSetCookie( | |
629 cookie.getName(), | |
630 cookie.getValue(), | |
631 cookie.getDomain(), | |
632 cookie.getPath(), | |
633 cookie.getMaxAge(), | |
634 cookie.getComment(), | |
635 cookie.isSecure(), | |
636 cookie.isHttpOnly(), | |
637 cookie.getVersion()); | |
638 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
639 |
831 | 640 /** |
641 * Format a set cookie value | |
642 * | |
643 * @param name the name | |
644 * @param value the value | |
645 * @param domain the domain | |
646 * @param path the path | |
647 * @param maxAge the maximum age | |
648 * @param comment the comment (only present on versions > 0) | |
649 * @param isSecure true if secure cookie | |
650 * @param isHttpOnly true if for http only | |
651 * @param version version of cookie logic to use (0 == default behavior) | |
652 */ | |
653 public void addSetCookie( | |
654 final String name, | |
655 final String value, | |
656 final String domain, | |
657 final String path, | |
658 final long maxAge, | |
659 final String comment, | |
660 final boolean isSecure, | |
661 final boolean isHttpOnly, | |
662 int version) | |
663 { | |
664 String delim=__COOKIE_DELIM; | |
665 | |
666 // Check arguments | |
667 if (name == null || name.length() == 0) | |
668 throw new IllegalArgumentException("Bad cookie name"); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
669 |
831 | 670 // Format value and params |
671 StringBuilder buf = new StringBuilder(128); | |
672 String name_value_params; | |
673 QuotedStringTokenizer.quoteIfNeeded(buf, name, delim); | |
674 buf.append('='); | |
675 String start=buf.toString(); | |
676 boolean hasDomain = false; | |
677 boolean hasPath = false; | |
678 | |
679 if (value != null && value.length() > 0) | |
680 QuotedStringTokenizer.quoteIfNeeded(buf, value, delim); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
681 |
831 | 682 if (comment != null && comment.length() > 0) |
683 { | |
684 buf.append(";Comment="); | |
685 QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim); | |
686 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
687 |
831 | 688 if (path != null && path.length() > 0) |
689 { | |
690 hasPath = true; | |
691 buf.append(";Path="); | |
692 if (path.trim().startsWith("\"")) | |
693 buf.append(path); | |
694 else | |
695 QuotedStringTokenizer.quoteIfNeeded(buf,path,delim); | |
696 } | |
697 if (domain != null && domain.length() > 0) | |
698 { | |
699 hasDomain = true; | |
700 buf.append(";Domain="); | |
701 QuotedStringTokenizer.quoteIfNeeded(buf,domain.toLowerCase(Locale.ENGLISH),delim); | |
702 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
703 |
831 | 704 if (maxAge >= 0) |
705 { | |
706 // Always add the expires param as some browsers still don't handle max-age | |
707 buf.append(";Expires="); | |
708 if (maxAge == 0) | |
709 buf.append(__01Jan1970_COOKIE); | |
710 else | |
711 formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge); | |
712 | |
713 if (version >0) | |
714 { | |
715 buf.append(";Max-Age="); | |
716 buf.append(maxAge); | |
717 } | |
718 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
719 |
831 | 720 if (isSecure) |
721 buf.append(";Secure"); | |
722 if (isHttpOnly) | |
723 buf.append(";HttpOnly"); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
724 |
831 | 725 name_value_params = buf.toString(); |
726 | |
727 // remove existing set-cookie of same name | |
728 Field field = getField(HttpHeaders.SET_COOKIE); | |
729 Field last=null; | |
730 while (field!=null) | |
731 { | |
732 String val = (field._value == null ? null : field._value.toString()); | |
733 if (val!=null && val.startsWith(start)) | |
734 { | |
735 //existing cookie has same name, does it also match domain and path? | |
736 if (((!hasDomain && !val.contains("Domain")) || (hasDomain && val.contains("Domain="+domain))) && | |
737 ((!hasPath && !val.contains("Path")) || (hasPath && val.contains("Path="+path)))) | |
738 { | |
739 _fields.remove(field); | |
740 if (last==null) | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
741 _names.put(HttpHeaders.SET_COOKIE,field._next); |
831 | 742 else |
743 last._next=field._next; | |
744 break; | |
745 } | |
746 } | |
747 last=field; | |
748 field=field._next; | |
749 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
750 |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
751 add(HttpHeaders.SET_COOKIE, name_value_params); |
831 | 752 |
753 // Expire responses with set-cookie headers so they do not get cached. | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
754 put(HttpHeaders.EXPIRES, __01Jan1970); |
831 | 755 } |
756 | |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
757 @Override |
831 | 758 public String toString() |
759 { | |
760 try | |
761 { | |
762 StringBuffer buffer = new StringBuffer(); | |
763 for (int i = 0; i < _fields.size(); i++) | |
764 { | |
765 Field field = (Field) _fields.get(i); | |
766 if (field != null) | |
767 { | |
768 String tmp = field.getName(); | |
769 if (tmp != null) buffer.append(tmp); | |
770 buffer.append(": "); | |
771 tmp = field.getValue(); | |
772 if (tmp != null) buffer.append(tmp); | |
773 buffer.append("\r\n"); | |
774 } | |
775 } | |
776 buffer.append("\r\n"); | |
777 return buffer.toString(); | |
778 } | |
779 catch (Exception e) | |
780 { | |
781 LOG.warn("",e); | |
782 return e.toString(); | |
783 } | |
784 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
785 |
831 | 786 /* ------------------------------------------------------------ */ |
787 /** | |
788 * Clear the header. | |
789 */ | |
790 public void clear() | |
791 { | |
792 _fields.clear(); | |
793 _names.clear(); | |
794 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
795 |
831 | 796 /* ------------------------------------------------------------ */ |
797 /** | |
798 * Add fields from another HttpFields instance. Single valued fields are replaced, while all | |
799 * others are added. | |
800 * | |
801 * @param fields | |
802 */ | |
803 public void add(HttpFields fields) | |
804 { | |
805 if (fields == null) return; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
806 |
831 | 807 Enumeration e = fields.getFieldNames(); |
808 while (e.hasMoreElements()) | |
809 { | |
810 String name = (String) e.nextElement(); | |
811 Enumeration values = fields.getValues(name); | |
812 while (values.hasMoreElements()) | |
813 add(name, (String) values.nextElement()); | |
814 } | |
815 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
816 |
831 | 817 /* ------------------------------------------------------------ */ |
818 /** | |
819 * Get field value parameters. Some field values can have parameters. This method separates the | |
820 * value from the parameters and optionally populates a map with the parameters. For example: | |
821 * | |
822 * <PRE> | |
823 * | |
824 * FieldName : Value ; param1=val1 ; param2=val2 | |
825 * | |
826 * </PRE> | |
827 * | |
828 * @param value The Field value, possibly with parameteres. | |
829 * @param parameters A map to populate with the parameters, or null | |
830 * @return The value. | |
831 */ | |
832 public static String valueParameters(String value, Map<String,String> parameters) | |
833 { | |
834 if (value == null) return null; | |
835 | |
836 int i = value.indexOf(';'); | |
837 if (i < 0) return value; | |
838 if (parameters == null) return value.substring(0, i).trim(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
839 |
831 | 840 StringTokenizer tok1 = new QuotedStringTokenizer(value.substring(i), ";", false, true); |
841 while (tok1.hasMoreTokens()) | |
842 { | |
843 String token = tok1.nextToken(); | |
844 StringTokenizer tok2 = new QuotedStringTokenizer(token, "= "); | |
845 if (tok2.hasMoreTokens()) | |
846 { | |
847 String paramName = tok2.nextToken(); | |
848 String paramVal = null; | |
849 if (tok2.hasMoreTokens()) paramVal = tok2.nextToken(); | |
850 parameters.put(paramName, paramVal); | |
851 } | |
852 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
853 |
831 | 854 return value.substring(0, i).trim(); |
855 } | |
856 | |
857 /* ------------------------------------------------------------ */ | |
858 private static final Float __zero = Float.valueOf("0.0"); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
859 |
831 | 860 /* ------------------------------------------------------------ */ |
861 public static float getQuality(String value) | |
862 { | |
863 if (value == null) return 0f; | |
864 | |
865 if( value.indexOf(";") == -1 ) | |
866 return 1f; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
867 |
831 | 868 Map params = new HashMap(); |
869 valueParameters(value, params); | |
870 String qs = (String) params.get("q"); | |
871 try { | |
872 return Float.parseFloat(qs); | |
873 } catch (NumberFormatException e) { | |
874 return 1f; | |
875 } | |
876 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
877 |
831 | 878 /* ------------------------------------------------------------ */ |
879 /** | |
880 * List values in quality order. | |
881 * | |
882 * @param e Enumeration of values with quality parameters | |
883 * @return values in quality order. | |
884 */ | |
885 public static List qualityList(Enumeration e) | |
886 { | |
887 if (e == null || !e.hasMoreElements()) return Collections.EMPTY_LIST; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
888 |
831 | 889 Object list = null; |
890 Object qual = null; | |
891 | |
892 // Assume list will be well ordered and just add nonzero | |
893 while (e.hasMoreElements()) | |
894 { | |
895 String v = e.nextElement().toString(); | |
896 Float q = getQuality(v); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
897 |
831 | 898 if (q.floatValue() >= 0.001) |
899 { | |
900 list = LazyList.add(list, v); | |
901 qual = LazyList.add(qual, q); | |
902 } | |
903 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
904 |
831 | 905 List vl = LazyList.getList(list, false); |
906 if (vl.size() < 2) return vl; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
907 |
831 | 908 List ql = LazyList.getList(qual, false); |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
909 |
831 | 910 // sort list with swaps |
911 Float last = __zero; | |
912 for (int i = vl.size(); i-- > 0;) | |
913 { | |
914 Float q = (Float) ql.get(i); | |
915 if (last.compareTo(q) > 0) | |
916 { | |
917 Object tmp = vl.get(i); | |
918 vl.set(i, vl.get(i + 1)); | |
919 vl.set(i + 1, tmp); | |
920 ql.set(i, ql.get(i + 1)); | |
921 ql.set(i + 1, q); | |
922 last = __zero; | |
923 i = vl.size(); | |
924 continue; | |
925 } | |
926 last = q; | |
927 } | |
928 ql.clear(); | |
929 return vl; | |
930 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
931 |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
932 |
831 | 933 public static final class Field |
934 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
935 private final String _name; |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
936 private final String _value; |
831 | 937 private Field _next; |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
938 |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
939 private Field(String name, String value) |
831 | 940 { |
941 _name = name; | |
942 _value = value; | |
943 _next = null; | |
944 } | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
945 |
831 | 946 public void putTo(Buffer buffer) throws IOException |
947 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
948 byte[] nameBytes = StringUtil.getBytes(_name); |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
949 if (getNameOrdinal() >=0 ) |
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
950 buffer.put(nameBytes); |
831 | 951 else |
952 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
953 for( byte b : nameBytes ) { |
831 | 954 switch(b) |
955 { | |
956 case '\r': | |
957 case '\n': | |
958 case ':' : | |
959 continue; | |
960 default: | |
961 buffer.put(b); | |
962 } | |
963 } | |
964 } | |
965 | |
966 buffer.put((byte) ':'); | |
967 buffer.put((byte) ' '); | |
968 | |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
969 byte[] valueBytes = StringUtil.getBytes(_value); |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
970 if (getValueOrdinal() >= 0) |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
971 buffer.put(valueBytes); |
831 | 972 else |
973 { | |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
974 for( byte b : valueBytes ) { |
831 | 975 switch(b) |
976 { | |
977 case '\r': | |
978 case '\n': | |
979 continue; | |
980 default: | |
981 buffer.put(b); | |
982 } | |
983 } | |
984 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
985 |
831 | 986 BufferUtil.putCRLF(buffer); |
987 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
988 |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
989 private String getName() |
831 | 990 { |
1021 | 991 return _name.toString(); |
831 | 992 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
993 |
831 | 994 public int getNameOrdinal() |
995 { | |
996 return HttpHeaders.CACHE.getOrdinal(_name); | |
997 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
998 |
831 | 999 public String getValue() |
1000 { | |
1001 return _value; | |
1002 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1003 |
831 | 1004 public int getValueOrdinal() |
1005 { | |
1022
3718afd99988
HttpHeaders uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1021
diff
changeset
|
1006 return HttpHeaderValues.CACHE.getOrdinal(_value); |
831 | 1007 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1008 |
831 | 1009 public int getIntValue() |
1010 { | |
1011 return (int) getLongValue(); | |
1012 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1013 |
831 | 1014 public long getLongValue() |
1015 { | |
1016 return BufferUtil.toLong(_value); | |
1017 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1018 |
1020
6be43ef1eb96
HttpHeaderValues uses StringCache
Franklin Schmidt <fschmidt@gmail.com>
parents:
1019
diff
changeset
|
1019 @Override |
831 | 1020 public String toString() |
1021 { | |
1022 return ("[" + getName() + "=" + _value + (_next == null ? "" : "->") + "]"); | |
1023 } | |
1024 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1025 } |