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