Mercurial > projects > ldc
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 } |