comparison tango/tango/net/http/HttpHeaders.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
comparison
equal deleted inserted replaced
131:5825d48b27d1 132:1700239cab2e
1 /*******************************************************************************
2
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved
4
5 license: BSD style: $(LICENSE)
6
7 version: Initial release: April 2004
8
9 author: Kris
10
11 *******************************************************************************/
12
13 module tango.net.http.HttpHeaders;
14
15 private import tango.time.Time;
16
17 private import tango.io.model.IBuffer;
18
19 public import tango.net.http.HttpConst;
20
21 private import tango.net.http.HttpTokens;
22
23 private import tango.text.stream.LineIterator;
24
25 /******************************************************************************
26
27 Exposes freachable HttpHeader instances
28
29 ******************************************************************************/
30
31 struct HeaderElement
32 {
33 HttpHeaderName name;
34 char[] value;
35 }
36
37 /******************************************************************************
38
39 Maintains a set of input headers. These are placed into an input
40 buffer and indexed via a HttpStack.
41
42 ******************************************************************************/
43
44 class HttpHeadersView : HttpTokens
45 {
46 // tell compiler to used super.parse() also
47 alias HttpTokens.parse parse;
48
49 private LineIterator!(char) line;
50
51 /**********************************************************************
52
53 Construct this set of headers, using a HttpStack based
54 upon a ':' delimiter
55
56 **********************************************************************/
57
58 this ()
59 {
60 // separator is a ':', and specify we want it included as
61 // part of the name whilst iterating
62 super (':', true);
63
64 // construct a line tokenizer for later usage
65 line = new LineIterator!(char);
66 }
67
68 /**********************************************************************
69
70 Clone a source set of HttpHeaders
71
72 **********************************************************************/
73
74 this (HttpHeadersView source)
75 {
76 super (source);
77 }
78
79 /**********************************************************************
80
81 Clone this set of HttpHeadersView
82
83 **********************************************************************/
84
85 HttpHeadersView clone ()
86 {
87 return new HttpHeadersView (this);
88 }
89
90 /**********************************************************************
91
92 Read all header lines. Everything is mapped rather
93 than being allocated & copied
94
95 **********************************************************************/
96
97 void parse (IBuffer input)
98 {
99 setParsed (true);
100 line.set (input);
101
102 while (line.next && line.get.length)
103 stack.push (line.get);
104 }
105
106 /**********************************************************************
107
108 Return the value of the provided header, or null if the
109 header does not exist
110
111 **********************************************************************/
112
113 char[] get (HttpHeaderName name, char[] def = null)
114 {
115 return super.get (name.value, def);
116 }
117
118 /**********************************************************************
119
120 Return the integer value of the provided header, or -1
121 if the header does not exist
122
123 **********************************************************************/
124
125 int getInt (HttpHeaderName name, int def = -1)
126 {
127 return super.getInt (name.value, def);
128 }
129
130 /**********************************************************************
131
132 Return the date value of the provided header, or Time.epoch
133 if the header does not exist
134
135 **********************************************************************/
136
137 Time getDate (HttpHeaderName name, Time def = Time.epoch)
138 {
139 return super.getDate (name.value, def);
140 }
141
142 /**********************************************************************
143
144 Iterate over the set of headers. This is a shell around
145 the superclass, where we can convert the HttpToken into
146 a HeaderElement instead.
147
148 **********************************************************************/
149
150 int opApply (int delegate(inout HeaderElement) dg)
151 {
152 HeaderElement element;
153 int result = 0;
154
155 foreach (HttpToken token; super)
156 {
157 element.name.value = token.name;
158 element.value = token.value;
159 result = dg (element);
160 if (result)
161 break;
162 }
163 return result;
164 }
165
166 /**********************************************************************
167
168 Create a filter for iterating of a set of named headers.
169 We have to create a filter since we can't pass additional
170 arguments directly to an opApply() method.
171
172 **********************************************************************/
173
174 FilteredHeaders createFilter (HttpHeaderName header)
175 {
176 return new FilteredHeaders (this, header);
177 }
178
179 /**********************************************************************
180
181 Filter class for isolating a set of named headers.
182
183 **********************************************************************/
184
185 private static class FilteredHeaders : FilteredTokens
186 {
187 /**************************************************************
188
189 Construct a filter upon the specified headers, for
190 the given header name.
191
192 **************************************************************/
193
194 this (HttpHeadersView headers, HttpHeaderName header)
195 {
196 super (headers, header.value);
197 }
198
199 /**************************************************************
200
201 Iterate over all headers matching the given name.
202 This wraps the HttpToken iterator to convert the
203 output into a HeaderElement instead.
204
205 **************************************************************/
206
207 int opApply (int delegate(inout HeaderElement) dg)
208 {
209 HeaderElement element;
210 int result = 0;
211
212 foreach (HttpToken token; super)
213 {
214 element.name.value = token.name;
215 element.value = token.value;
216 result = dg (element);
217 if (result)
218 break;
219 }
220 return result;
221 }
222
223 }
224 }
225
226
227 /******************************************************************************
228
229 Maintains a set of output headers. These are held in an output
230 buffer, and indexed via a HttpStack. Deleting a header could be
231 supported by setting the HttpStack entry to null, and ignoring
232 such values when it's time to write the headers.
233
234 ******************************************************************************/
235
236 class HttpHeaders : HttpHeadersView
237 {
238 /**********************************************************************
239
240 Construct output headers, using the provided buffer as
241 a place to stash the header content.
242
243 **********************************************************************/
244
245 this (IBuffer output)
246 {
247 super ();
248 super.setOutputBuffer (output);
249 }
250
251 /**********************************************************************
252
253 Clone a source set of HttpHeaders
254
255 **********************************************************************/
256
257 this (HttpHeaders source)
258 {
259 super (source);
260 }
261
262 /**********************************************************************
263
264 Clone this set of HttpHeaders
265
266 **********************************************************************/
267
268 HttpHeaders clone ()
269 {
270 return new HttpHeaders (this);
271 }
272
273 /**********************************************************************
274
275 Add the specified header, and use a callback to provide
276 the content.
277
278 **********************************************************************/
279
280 void add (HttpHeaderName name, void delegate (IBuffer) dg)
281 {
282 super.add (name.value, dg);
283 }
284
285 /**********************************************************************
286
287 Add the specified header and text
288
289 **********************************************************************/
290
291 void add (HttpHeaderName name, char[] value)
292 {
293 super.add (name.value, value);
294 }
295
296 /**********************************************************************
297
298 Add the specified header and integer value
299
300 **********************************************************************/
301
302 void addInt (HttpHeaderName name, int value)
303 {
304 super.addInt (name.value, value);
305 }
306
307 /**********************************************************************
308
309 Add the specified header and long/date value
310
311 **********************************************************************/
312
313 void addDate (HttpHeaderName name, Time value)
314 {
315 super.addDate (name.value, value);
316 }
317
318 /**********************************************************************
319
320 Remove the specified header header. Returns false if not
321 found.
322
323 **********************************************************************/
324
325 bool remove (HttpHeaderName name)
326 {
327 return super.remove (name.value);
328 }
329
330 /**********************************************************************
331
332 Return the output buffer provided during construction.
333
334 **********************************************************************/
335
336 IBuffer getOutputBuffer ()
337 {
338 return super.getOutputBuffer ();
339 }
340 }