1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http;
17
18 import io.netty.handler.codec.CharSequenceValueConverter;
19 import io.netty.handler.codec.DateFormatter;
20 import io.netty.handler.codec.DefaultHeaders;
21 import io.netty.handler.codec.DefaultHeaders.NameValidator;
22 import io.netty.handler.codec.DefaultHeaders.ValueValidator;
23 import io.netty.handler.codec.DefaultHeadersImpl;
24 import io.netty.handler.codec.HeadersUtils;
25 import io.netty.handler.codec.ValueConverter;
26
27 import java.util.ArrayList;
28 import java.util.Calendar;
29 import java.util.Collections;
30 import java.util.Date;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Map.Entry;
35 import java.util.Set;
36
37 import static io.netty.util.AsciiString.CASE_INSENSITIVE_HASHER;
38 import static io.netty.util.AsciiString.CASE_SENSITIVE_HASHER;
39
40
41
42
43 public class DefaultHttpHeaders extends HttpHeaders {
44 private final DefaultHeaders<CharSequence, CharSequence, ?> headers;
45
46
47
48
49
50
51 public DefaultHttpHeaders() {
52 this(nameValidator(true), valueValidator(true));
53 }
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 @Deprecated
70 public DefaultHttpHeaders(boolean validate) {
71 this(nameValidator(validate), valueValidator(validate));
72 }
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 protected DefaultHttpHeaders(boolean validateValues, NameValidator<CharSequence> nameValidator) {
92 this(nameValidator, valueValidator(validateValues));
93 }
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 protected DefaultHttpHeaders(
114 NameValidator<CharSequence> nameValidator,
115 ValueValidator<CharSequence> valueValidator) {
116 this(nameValidator, valueValidator, 16);
117 }
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 protected DefaultHttpHeaders(
139 NameValidator<CharSequence> nameValidator,
140 ValueValidator<CharSequence> valueValidator,
141 int sizeHint) {
142 this(new DefaultHeadersImpl<CharSequence, CharSequence>(
143 CASE_INSENSITIVE_HASHER,
144 HeaderValueConverter.INSTANCE,
145 nameValidator,
146 sizeHint,
147 valueValidator));
148 }
149
150 protected DefaultHttpHeaders(DefaultHeaders<CharSequence, CharSequence, ?> headers) {
151 this.headers = headers;
152 }
153
154 @Override
155 public HttpHeaders add(HttpHeaders headers) {
156 if (headers instanceof DefaultHttpHeaders) {
157 this.headers.add(((DefaultHttpHeaders) headers).headers);
158 return this;
159 } else {
160 return super.add(headers);
161 }
162 }
163
164 @Override
165 public HttpHeaders set(HttpHeaders headers) {
166 if (headers instanceof DefaultHttpHeaders) {
167 this.headers.set(((DefaultHttpHeaders) headers).headers);
168 return this;
169 } else {
170 return super.set(headers);
171 }
172 }
173
174 @Override
175 public HttpHeaders add(String name, Object value) {
176 headers.addObject(name, value);
177 return this;
178 }
179
180 @Override
181 public HttpHeaders add(CharSequence name, Object value) {
182 headers.addObject(name, value);
183 return this;
184 }
185
186 @Override
187 public HttpHeaders add(String name, Iterable<?> values) {
188 headers.addObject(name, values);
189 return this;
190 }
191
192 @Override
193 public HttpHeaders add(CharSequence name, Iterable<?> values) {
194 headers.addObject(name, values);
195 return this;
196 }
197
198 @Override
199 public HttpHeaders addInt(CharSequence name, int value) {
200 headers.addInt(name, value);
201 return this;
202 }
203
204 @Override
205 public HttpHeaders addShort(CharSequence name, short value) {
206 headers.addShort(name, value);
207 return this;
208 }
209
210 @Override
211 public HttpHeaders remove(String name) {
212 headers.remove(name);
213 return this;
214 }
215
216 @Override
217 public HttpHeaders remove(CharSequence name) {
218 headers.remove(name);
219 return this;
220 }
221
222 @Override
223 public HttpHeaders set(String name, Object value) {
224 headers.setObject(name, value);
225 return this;
226 }
227
228 @Override
229 public HttpHeaders set(CharSequence name, Object value) {
230 headers.setObject(name, value);
231 return this;
232 }
233
234 @Override
235 public HttpHeaders set(String name, Iterable<?> values) {
236 headers.setObject(name, values);
237 return this;
238 }
239
240 @Override
241 public HttpHeaders set(CharSequence name, Iterable<?> values) {
242 headers.setObject(name, values);
243 return this;
244 }
245
246 @Override
247 public HttpHeaders setInt(CharSequence name, int value) {
248 headers.setInt(name, value);
249 return this;
250 }
251
252 @Override
253 public HttpHeaders setShort(CharSequence name, short value) {
254 headers.setShort(name, value);
255 return this;
256 }
257
258 @Override
259 public HttpHeaders clear() {
260 headers.clear();
261 return this;
262 }
263
264 @Override
265 public String get(String name) {
266 return get((CharSequence) name);
267 }
268
269 @Override
270 public String get(CharSequence name) {
271 return HeadersUtils.getAsString(headers, name);
272 }
273
274 @Override
275 public Integer getInt(CharSequence name) {
276 return headers.getInt(name);
277 }
278
279 @Override
280 public int getInt(CharSequence name, int defaultValue) {
281 return headers.getInt(name, defaultValue);
282 }
283
284 @Override
285 public Short getShort(CharSequence name) {
286 return headers.getShort(name);
287 }
288
289 @Override
290 public short getShort(CharSequence name, short defaultValue) {
291 return headers.getShort(name, defaultValue);
292 }
293
294 @Override
295 public Long getTimeMillis(CharSequence name) {
296 return headers.getTimeMillis(name);
297 }
298
299 @Override
300 public long getTimeMillis(CharSequence name, long defaultValue) {
301 return headers.getTimeMillis(name, defaultValue);
302 }
303
304 @Override
305 public List<String> getAll(String name) {
306 return getAll((CharSequence) name);
307 }
308
309 @Override
310 public List<String> getAll(CharSequence name) {
311 return HeadersUtils.getAllAsString(headers, name);
312 }
313
314 @Override
315 public List<Entry<String, String>> entries() {
316 if (isEmpty()) {
317 return Collections.emptyList();
318 }
319 List<Entry<String, String>> entriesConverted = new ArrayList<Entry<String, String>>(
320 headers.size());
321 for (Entry<String, String> entry : this) {
322 entriesConverted.add(entry);
323 }
324 return entriesConverted;
325 }
326
327 @Deprecated
328 @Override
329 public Iterator<Map.Entry<String, String>> iterator() {
330 return HeadersUtils.iteratorAsString(headers);
331 }
332
333 @Override
334 public Iterator<Entry<CharSequence, CharSequence>> iteratorCharSequence() {
335 return headers.iterator();
336 }
337
338 @Override
339 public Iterator<String> valueStringIterator(CharSequence name) {
340 final Iterator<CharSequence> itr = valueCharSequenceIterator(name);
341 return new Iterator<String>() {
342 @Override
343 public boolean hasNext() {
344 return itr.hasNext();
345 }
346
347 @Override
348 public String next() {
349 return itr.next().toString();
350 }
351
352 @Override
353 public void remove() {
354 itr.remove();
355 }
356 };
357 }
358
359 @Override
360 public Iterator<CharSequence> valueCharSequenceIterator(CharSequence name) {
361 return headers.valueIterator(name);
362 }
363
364 @Override
365 public boolean contains(String name) {
366 return contains((CharSequence) name);
367 }
368
369 @Override
370 public boolean contains(CharSequence name) {
371 return headers.contains(name);
372 }
373
374 @Override
375 public boolean isEmpty() {
376 return headers.isEmpty();
377 }
378
379 @Override
380 public int size() {
381 return headers.size();
382 }
383
384 @Override
385 public boolean contains(String name, String value, boolean ignoreCase) {
386 return contains((CharSequence) name, (CharSequence) value, ignoreCase);
387 }
388
389 @Override
390 public boolean contains(CharSequence name, CharSequence value, boolean ignoreCase) {
391 return headers.contains(name, value, ignoreCase ? CASE_INSENSITIVE_HASHER : CASE_SENSITIVE_HASHER);
392 }
393
394 @Override
395 public Set<String> names() {
396 return HeadersUtils.namesAsString(headers);
397 }
398
399 @Override
400 public boolean equals(Object o) {
401 return o instanceof DefaultHttpHeaders
402 && headers.equals(((DefaultHttpHeaders) o).headers, CASE_SENSITIVE_HASHER);
403 }
404
405 @Override
406 public int hashCode() {
407 return headers.hashCode(CASE_SENSITIVE_HASHER);
408 }
409
410 @Override
411 public HttpHeaders copy() {
412 return new DefaultHttpHeaders(headers.copy());
413 }
414
415 static ValueConverter<CharSequence> valueConverter() {
416 return HeaderValueConverter.INSTANCE;
417 }
418
419 static ValueValidator<CharSequence> valueValidator(boolean validate) {
420 return validate ? DefaultHttpHeadersFactory.headersFactory().getValueValidator() :
421 DefaultHttpHeadersFactory.headersFactory().withValidation(false).getValueValidator();
422 }
423
424 static NameValidator<CharSequence> nameValidator(boolean validate) {
425 return validate ? DefaultHttpHeadersFactory.headersFactory().getNameValidator() :
426 DefaultHttpHeadersFactory.headersFactory().withNameValidation(false).getNameValidator();
427 }
428
429 private static class HeaderValueConverter extends CharSequenceValueConverter {
430 static final HeaderValueConverter INSTANCE = new HeaderValueConverter();
431
432 @Override
433 public CharSequence convertObject(Object value) {
434 if (value instanceof CharSequence) {
435 return (CharSequence) value;
436 }
437 if (value instanceof Date) {
438 return DateFormatter.format((Date) value);
439 }
440 if (value instanceof Calendar) {
441 return DateFormatter.format(((Calendar) value).getTime());
442 }
443 return value.toString();
444 }
445 }
446 }