00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 module mango.http.server.HttpHeaders;
00040
00041 private import mango.io.Token,
00042 mango.io.Tokenizer;
00043
00044 private import mango.io.model.IBuffer,
00045 mango.io.model.IWriter;
00046
00047 private import mango.http.utils.TokenStack;
00048
00049 private import mango.http.server.HttpTokens;
00050
00051
00052
00053
00054
00055
00056
00057
00058 struct HttpHeaderName
00059 {
00060 char[] value;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069 struct HttpHeader
00070 {
00071
00072 static const int IOBufferSize = 16 * 1024;
00073
00074
00075 static const int MaxPostParamSize = 4 * 1024;
00076
00077 static const HttpHeaderName Version = {"HTTP/1.0"};
00078 static const HttpHeaderName TextHtml = {"text/html"};
00079
00080 static const HttpHeaderName Accept = {"Accept:"};
00081 static const HttpHeaderName AcceptCharset = {"Accept-Charset:"};
00082 static const HttpHeaderName AcceptEncoding = {"Accept-Encoding:"};
00083 static const HttpHeaderName AcceptLanguage = {"Accept-Language:"};
00084 static const HttpHeaderName AcceptRanges = {"Accept-Ranges:"};
00085 static const HttpHeaderName Age = {"Age:"};
00086 static const HttpHeaderName Allow = {"Allow:"};
00087 static const HttpHeaderName Authorization = {"Authorization:"};
00088 static const HttpHeaderName CacheControl = {"Cache-Control:"};
00089 static const HttpHeaderName Connection = {"Connection:"};
00090 static const HttpHeaderName ContentEncoding = {"Content-Encoding:"};
00091 static const HttpHeaderName ContentLanguage = {"Content-Language:"};
00092 static const HttpHeaderName ContentLength = {"Content-Length:"};
00093 static const HttpHeaderName ContentLocation = {"Content-Location:"};
00094 static const HttpHeaderName ContentRange = {"Content-Range:"};
00095 static const HttpHeaderName ContentType = {"Content-Type:"};
00096 static const HttpHeaderName Cookie = {"Cookie:"};
00097 static const HttpHeaderName Date = {"Date:"};
00098 static const HttpHeaderName ETag = {"ETag:"};
00099 static const HttpHeaderName Expect = {"Expect:"};
00100 static const HttpHeaderName Expires = {"Expires:"};
00101 static const HttpHeaderName From = {"From:"};
00102 static const HttpHeaderName Host = {"Host:"};
00103 static const HttpHeaderName Identity = {"identity:"};
00104 static const HttpHeaderName IfMatch = {"If-Match:"};
00105 static const HttpHeaderName IfModifiedSince = {"If-Modified-Since:"};
00106 static const HttpHeaderName IfNoneMatch = {"If-None-Match:"};
00107 static const HttpHeaderName IfRange = {"If-Range:"};
00108 static const HttpHeaderName IfUnmodifiedSince = {"If-Unmodified-Since:"};
00109 static const HttpHeaderName LastModified = {"Last-Modified:"};
00110 static const HttpHeaderName Location = {"Location:"};
00111 static const HttpHeaderName MaxForwards = {"Max-Forwards:"};
00112 static const HttpHeaderName MimeVersion = {"MIME-Version:"};
00113 static const HttpHeaderName Pragma = {"Pragma:"};
00114 static const HttpHeaderName ProxyAuthenticate = {"Proxy-Authenticate:"};
00115 static const HttpHeaderName ProxyConnection = {"Proxy-Connection:"};
00116 static const HttpHeaderName Range = {"Range:"};
00117 static const HttpHeaderName Referrer = {"Referer:"};
00118 static const HttpHeaderName RetryAfter = {"Retry-After:"};
00119 static const HttpHeaderName Server = {"Server:"};
00120 static const HttpHeaderName ServletEngine = {"Servlet-Engine:"};
00121 static const HttpHeaderName SetCookie = {"Set-Cookie:"};
00122 static const HttpHeaderName SetCookie2 = {"Set-Cookie2:"};
00123 static const HttpHeaderName TE = {"TE:"};
00124 static const HttpHeaderName Trailer = {"Trailer:"};
00125 static const HttpHeaderName TransferEncoding = {"Transfer-Encoding:"};
00126 static const HttpHeaderName Upgrade = {"Upgrade:"};
00127 static const HttpHeaderName UserAgent = {"User-Agent:"};
00128 static const HttpHeaderName Vary = {"Vary:"};
00129 static const HttpHeaderName Warning = {"Warning:"};
00130 static const HttpHeaderName WwwAuthenticate = {"WWW-Authenticate:"};
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 struct HeaderElement
00141 {
00142 HttpHeaderName name;
00143 char[] value;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153 class HttpHeaders : HttpTokens
00154 {
00155 private static BoundToken line;
00156
00157
00158 alias HttpTokens.parse parse;
00159
00160
00161
00162
00163
00164
00165
00166 static this ()
00167 {
00168
00169
00170
00171 line = new BoundToken (new LineTokenizer());
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181 this ()
00182 {
00183
00184
00185 super (':', true);
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 this (HttpHeaders source)
00195 {
00196 super (source);
00197 }
00198
00199
00200
00201
00202
00203
00204
00205 HttpHeaders clone ()
00206 {
00207 return new HttpHeaders (this);
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217 void parse (IBuffer input)
00218 {
00219 setParsed (true);
00220 while (line.next(input) && line.getLength())
00221 stack.push(line);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231 char[] get (HttpHeaderName name, char[] def = null)
00232 {
00233 return super.get (name.value, def);
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243 int getInt (HttpHeaderName name, int def = -1)
00244 {
00245 return super.getInt (name.value, def);
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255 ulong getDate (HttpHeaderName name, ulong def = -1)
00256 {
00257 return super.getDate (name.value, def);
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 int opApply (int delegate(inout HeaderElement) dg)
00269 {
00270 HeaderElement element;
00271 int result = 0;
00272
00273 foreach (HttpToken token; super)
00274 {
00275 element.name.value = token.name;
00276 element.value = token.value;
00277 result = dg (element);
00278 if (result)
00279 break;
00280 }
00281 return result;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 FilteredHeaders createFilter (HttpHeaderName header)
00293 {
00294 return new FilteredHeaders (this, header);
00295 }
00296
00297
00298
00299
00300
00301
00302
00303 private static class FilteredHeaders : FilteredTokens
00304 {
00305
00306
00307
00308
00309
00310
00311
00312 this (HttpHeaders headers, HttpHeaderName header)
00313 {
00314 super (headers, header.value);
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 int opApply (int delegate(inout HeaderElement) dg)
00326 {
00327 HeaderElement element;
00328 int result = 0;
00329
00330 foreach (HttpToken token; super)
00331 {
00332 element.name.value = token.name;
00333 element.value = token.value;
00334 result = dg (element);
00335 if (result)
00336 break;
00337 }
00338 return result;
00339 }
00340
00341 }
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 class HttpMutableHeaders : HttpHeaders
00355 {
00356
00357
00358
00359
00360
00361
00362
00363 this (IBuffer output)
00364 {
00365 super ();
00366 super.setOutputBuffer (output);
00367 }
00368
00369
00370
00371
00372
00373
00374
00375 this (HttpMutableHeaders source)
00376 {
00377 super (source);
00378 }
00379
00380
00381
00382
00383
00384
00385
00386 HttpMutableHeaders clone ()
00387 {
00388 return new HttpMutableHeaders (this);
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398 void add (HttpHeaderName name, void delegate (IBuffer) dg)
00399 {
00400 super.add (name.value, dg);
00401 }
00402
00403
00404
00405
00406
00407
00408
00409 void add (HttpHeaderName name, char[] value)
00410 {
00411 super.add (name.value, value);
00412 }
00413
00414
00415
00416
00417
00418
00419
00420 void addInt (HttpHeaderName name, int value)
00421 {
00422 super.addInt (name.value, value);
00423 }
00424
00425
00426
00427
00428
00429
00430
00431 void addDate (HttpHeaderName name, ulong value)
00432 {
00433 super.addDate (name.value, value);
00434 }
00435
00436
00437
00438
00439
00440
00441
00442 IBuffer getOutputBuffer ()
00443 {
00444 return super.getOutputBuffer ();
00445 }
00446 }