1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.mimo.netty.handler.codec.icap;
15
16 import java.util.LinkedHashSet;
17 import java.util.Map;
18 import java.util.Set;
19
20
21
22
23
24
25
26
27
28
29 public final class IcapHeaders {
30
31 private Entry base;
32 private Entry head;
33
34
35
36
37
38
39
40 public static final class Names {
41
42
43
44 public static final String CACHE_CONTROL = "Cache-Control";
45
46
47
48 public static final String CONNECTION = "Connection";
49
50
51
52 public static final String DATE = "Date";
53
54
55
56 public static final String EXPIRES = "Expires";
57
58
59
60 public static final String PRAGMA = "Pragma";
61
62
63
64 public static final String TRAILER = "Trailer";
65
66
67
68 public static final String UPGRADE = "Upgrade";
69
70
71
72 public static final String ENCAPSULATED = "Encapsulated";
73
74
75
76 public static final String AUTHORIZATION = "Authorization";
77
78
79
80 public static final String ALLOW = "Allow";
81
82
83
84 public static final String FROM = "From";
85
86
87
88 public static final String HOST = "Host";
89
90
91
92 public static final String REFERER = "Referer";
93
94
95
96 public static final String USER_AGENT = "User-Agent";
97
98
99
100 public static final String PREVIEW = "Preview";
101
102
103
104
105 public static final String ISTAG = "ISTag";
106 }
107
108 public IcapHeaders() {
109 }
110
111 public void clearHeaders() {
112 base = null;
113 head = null;
114 }
115
116
117
118
119
120
121
122
123
124 public void addHeader(String name, Object value) {
125 Entry entry = new Entry(name,value);
126 if(base == null) {
127 base = entry;
128 head = entry;
129 } else {
130 Entry currentHead = head;
131 head = entry;
132 entry.before = currentHead;
133 currentHead.after = entry;
134 }
135 }
136
137
138
139
140
141
142
143
144 public void setHeader(String name, Object value) {
145 removeHeader(name);
146 addHeader(name,value);
147 }
148
149
150
151
152
153
154
155
156 public void setHeader(String name, Iterable<?> values) {
157 removeHeader(name);
158 for(Object value : values) {
159 addHeader(name,value);
160 }
161 }
162
163
164
165
166
167
168
169
170
171
172
173 public String getHeader(String name) {
174 Entry entry = base;
175 while(entry != null) {
176 if(identicalKeys(entry.getKey(),name)) {
177 return entry.getValue();
178 }
179 entry = entry.after;
180 }
181 return null;
182 }
183
184
185
186
187
188
189
190
191 public Set<String> getHeaders(String name) {
192 Set<String> values = new LinkedHashSet<String>();
193 Entry entry = base;
194 while(entry != null) {
195 if(identicalKeys(entry.getKey(),name)) {
196 values.add(entry.getValue());
197 }
198 entry = entry.after;
199 }
200 return values;
201 }
202
203
204
205
206
207
208 public Set<Map.Entry<String, String>> getHeaders() {
209 Set<Map.Entry<String, String>> headers = new LinkedHashSet<Map.Entry<String,String>>();
210 Entry entry = base;
211 while(entry != null) {
212 headers.add(entry);
213 entry = entry.after;
214 }
215 return headers;
216 }
217
218
219
220
221
222
223
224 public boolean containsHeader(String name) {
225 return getHeader(name) != null;
226 }
227
228
229
230
231
232
233 public void removeHeader(String name) {
234 if(base == null) {
235 return;
236 }
237 Entry entry = null;
238 if(base.after == null) {
239 if(identicalKeys(base.getKey(),name)) {
240 base = null;
241 return;
242 }
243 } else {
244 entry = base.after;
245 }
246 while(entry != null) {
247 if(identicalKeys(entry.getKey(),name)) {
248 Entry before = entry.before;
249 Entry after = entry.after;
250 before.after = after;
251 after.before = before;
252 entry = after;
253 } else {
254 entry = entry.after;
255 }
256 }
257 if(identicalKeys(base.getKey(),name)) {
258 base = base.after;
259 base.before = null;
260 }
261 }
262
263
264
265
266
267
268
269 public Set<String> getHeaderNames() {
270 Set<String> names = new LinkedHashSet<String>();
271 Entry entry = base;
272 while(entry != null) {
273 names.add(entry.getKey());
274 entry = entry.after;
275 }
276 return names;
277 }
278
279
280
281
282
283
284
285
286 public int getPreviewHeaderValue() {
287 String value = getHeader(Names.PREVIEW);
288 int result = 0;
289 try {
290 if(value != null) {
291 result = Integer.parseInt(value);
292 }
293 } catch(NumberFormatException nfe) {
294 throw new IcapDecodingError("Unable to understand the preview amount value [" + value + "]");
295 }
296 return result;
297 }
298
299 private boolean identicalKeys(String key1, String key2) {
300 if(key1 != null & key2 != null) {
301 return key1.equalsIgnoreCase(key2);
302 }
303 return false;
304 }
305
306 private static final class Entry implements Map.Entry<String, String> {
307
308 private String key;
309 private String value;
310
311 private Entry before, after;
312
313 Entry(String key, Object value) {
314 IcapCodecUtil.validateHeaderName(key);
315 this.key = key;
316 if(value != null) {
317 this.value = value.toString();
318 IcapCodecUtil.validateHeaderValue(this.value);
319 }
320 }
321
322 public String getKey() {
323 return key;
324 }
325
326 public String getValue() {
327 return value;
328 }
329
330 @Override
331 public String setValue(String value) {
332 return null;
333 }
334 }
335
336 @Override
337 public String toString() {
338 StringBuilder builder = new StringBuilder();
339 for(String name : getHeaderNames()) {
340 builder.append("[" + name + "] = [" + getHeaders(name) + "]");
341 }
342 return builder.toString();
343 }
344 }