2 // System.Web.HttoWorkerRequest.cs
5 // Miguel de Icaza (miguel@novell.com)
9 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections;
32 using System.Runtime.InteropServices;
33 using System.Security.Permissions;
35 using System.Collections.Specialized;
38 using System.Collections.Generic;
41 namespace System.Web {
44 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
45 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48 public abstract partial class HttpWorkerRequest {
50 public delegate void EndOfSendNotification (HttpWorkerRequest wr, object extraData);
52 public const int HeaderCacheControl = 0;
53 public const int HeaderConnection = 1;
54 public const int HeaderDate = 2;
55 public const int HeaderKeepAlive = 3;
56 public const int HeaderPragma = 4;
57 public const int HeaderTrailer = 5;
58 public const int HeaderTransferEncoding = 6;
59 public const int HeaderUpgrade = 7;
60 public const int HeaderVia = 8;
61 public const int HeaderWarning = 9;
62 public const int HeaderAllow = 10;
63 public const int HeaderContentLength = 11;
64 public const int HeaderContentType = 12;
65 public const int HeaderContentEncoding = 13;
66 public const int HeaderContentLanguage = 14;
67 public const int HeaderContentLocation = 15;
68 public const int HeaderContentMd5 = 16;
69 public const int HeaderContentRange = 17;
70 public const int HeaderExpires = 18;
71 public const int HeaderLastModified = 19;
72 public const int HeaderAccept = 20;
73 public const int HeaderAcceptCharset = 21;
74 public const int HeaderAcceptEncoding = 22;
75 public const int HeaderAcceptLanguage = 23;
76 public const int HeaderAuthorization = 24;
77 public const int HeaderCookie = 25;
78 public const int HeaderExpect = 26;
79 public const int HeaderFrom = 27;
80 public const int HeaderHost = 28;
81 public const int HeaderIfMatch = 29;
82 public const int HeaderIfModifiedSince = 30;
83 public const int HeaderIfNoneMatch = 31;
84 public const int HeaderIfRange = 32;
85 public const int HeaderIfUnmodifiedSince = 33;
86 public const int HeaderMaxForwards = 34;
87 public const int HeaderProxyAuthorization = 35;
88 public const int HeaderReferer = 36;
89 public const int HeaderRange = 37;
90 public const int HeaderTe = 38;
91 public const int HeaderUserAgent = 39;
92 public const int RequestHeaderMaximum = 40;
94 public const int HeaderAcceptRanges = 20;
95 public const int HeaderAge = 21;
96 public const int HeaderEtag = 22;
97 public const int HeaderLocation = 23;
98 public const int HeaderProxyAuthenticate = 24;
99 public const int HeaderRetryAfter = 25;
100 public const int HeaderServer = 26;
101 public const int HeaderSetCookie = 27;
102 public const int HeaderVary = 28;
103 public const int HeaderWwwAuthenticate = 29;
104 public const int ResponseHeaderMaximum = 30;
106 public const int ReasonResponseCacheMiss = 0;
107 public const int ReasonFileHandleCacheMiss = 1;
108 public const int ReasonCachePolicy = 2;
109 public const int ReasonCacheSecurity = 3;
110 public const int ReasonClientDisconnect = 4;
111 public const int ReasonDefault = 0;
114 static readonly Dictionary <string, int> RequestHeaderIndexer;
115 static readonly Dictionary <string, int> ResponseHeaderIndexer;
117 static readonly Hashtable RequestHeaderIndexer;
118 static readonly Hashtable ResponseHeaderIndexer;
121 static HttpWorkerRequest ()
124 RequestHeaderIndexer = new Dictionary <string, int> (StringComparer.OrdinalIgnoreCase);
126 RequestHeaderIndexer = CollectionsUtil.CreateCaseInsensitiveHashtable(RequestHeaderMaximum);
129 for (int i = 0; i < RequestHeaderMaximum; i++)
130 RequestHeaderIndexer.Add (GetKnownRequestHeaderName(i), i);
133 ResponseHeaderIndexer = new Dictionary <string, int> (StringComparer.OrdinalIgnoreCase);
135 ResponseHeaderIndexer = CollectionsUtil.CreateCaseInsensitiveHashtable(ResponseHeaderMaximum);
137 for (int i = 0; i < ResponseHeaderMaximum; i++)
138 ResponseHeaderIndexer.Add (GetKnownResponseHeaderName(i), i);
141 bool started_internally;
142 internal bool StartedInternally {
143 get { return started_internally; }
144 set { started_internally = value; }
147 public virtual string MachineConfigPath {
153 public virtual string MachineInstallDirectory {
160 public virtual Guid RequestTraceIdentifier {
161 get { return Guid.Empty; }
164 public virtual string RootWebConfigPath {
169 public virtual void CloseConnection ()
173 public virtual string GetAppPath ()
178 public virtual string GetAppPathTranslated ()
183 public virtual string GetAppPoolID ()
188 public virtual long GetBytesRead ()
193 public virtual string GetFilePath ()
198 public virtual string GetFilePathTranslated ()
203 public virtual string GetKnownRequestHeader (int index)
208 public virtual string GetPathInfo ()
213 public virtual byte [] GetPreloadedEntityBody ()
218 public virtual int GetPreloadedEntityBody (byte[] buffer, int offset)
223 public virtual int GetPreloadedEntityBodyLength ()
228 public virtual string GetProtocol ()
236 public virtual byte [] GetQueryStringRawBytes ()
241 public virtual string GetRemoteName ()
243 return GetRemoteAddress ();
246 public virtual int GetRequestReason ()
251 public virtual string GetServerName ()
253 return GetLocalAddress ();
256 public virtual string GetServerVariable (string name)
261 public virtual int GetTotalEntityBodyLength ()
266 public virtual string GetUnknownRequestHeader (string name)
271 [CLSCompliant (false)]
272 public virtual string [][] GetUnknownRequestHeaders ()
277 public virtual IntPtr GetUserToken ()
282 public bool HasEntityBody ()
284 // TODO this is not virtual.
289 public virtual bool HeadersSent ()
294 public virtual bool IsClientConnected ()
299 public virtual bool IsEntireEntityBodyIsPreloaded ()
304 public virtual bool IsSecure ()
309 public virtual string MapPath (string virtualPath)
314 public virtual int ReadEntityBody (byte [] buffer, int size)
319 public virtual int ReadEntityBody (byte [] buffer, int offset, int size)
324 public virtual void SendCalculatedContentLength (long contentLength)
326 SendCalculatedContentLength ((int)contentLength);
329 public virtual void SendCalculatedContentLength (int contentLength)
331 // apparently does nothing in MS.NET
335 public virtual void SendResponseFromMemory (IntPtr data, int length)
337 if (data != IntPtr.Zero) {
338 byte [] copy = new byte [length];
339 Marshal.Copy (data, copy, 0, length);
340 SendResponseFromMemory (copy, length);
345 public virtual void SetEndOfSendNotification (HttpWorkerRequest.EndOfSendNotification callback, object extraData)
349 #region Abstract methods
350 public abstract void EndOfRequest ();
351 public abstract void FlushResponse (bool finalFlush);
352 public abstract string GetHttpVerbName ();
353 public abstract string GetHttpVersion ();
354 public abstract string GetLocalAddress ();
355 public abstract int GetLocalPort ();
356 public abstract string GetQueryString ();
357 public abstract string GetRawUrl ();
358 public abstract string GetRemoteAddress ();
359 public abstract int GetRemotePort ();
360 public abstract string GetUriPath ();
361 public abstract void SendKnownResponseHeader (int index, string value);
362 public abstract void SendResponseFromFile (IntPtr handle, long offset, long length);
363 public abstract void SendResponseFromFile (string filename, long offset, long length);
364 public abstract void SendResponseFromMemory (byte [] data, int length);
365 public abstract void SendStatus (int statusCode, string statusDescription);
366 public abstract void SendUnknownResponseHeader (string name, string value);
369 #region Static methods
371 public static int GetKnownRequestHeaderIndex (string header)
375 if (RequestHeaderIndexer.TryGetValue (header, out index))
378 object index = RequestHeaderIndexer[header];
386 public static string GetKnownRequestHeaderName (int index)
389 case HeaderCacheControl: return "Cache-Control";
390 case HeaderConnection: return "Connection";
391 case HeaderDate: return "Date";
392 case HeaderKeepAlive: return "Keep-Alive";
393 case HeaderPragma: return "Pragma";
394 case HeaderTrailer: return "Trailer";
395 case HeaderTransferEncoding: return "Transfer-Encoding";
396 case HeaderUpgrade: return "Upgrade";
397 case HeaderVia: return "Via";
398 case HeaderWarning: return "Warning";
399 case HeaderAllow: return "Allow";
400 case HeaderContentLength: return "Content-Length";
401 case HeaderContentType: return "Content-Type";
402 case HeaderContentEncoding: return "Content-Encoding";
403 case HeaderContentLanguage: return "Content-Language";
404 case HeaderContentLocation: return "Content-Location";
405 case HeaderContentMd5: return "Content-MD5";
406 case HeaderContentRange: return "Content-Range";
407 case HeaderExpires: return "Expires";
408 case HeaderLastModified: return "Last-Modified";
409 case HeaderAccept: return "Accept";
410 case HeaderAcceptCharset: return "Accept-Charset";
411 case HeaderAcceptEncoding: return "Accept-Encoding";
412 case HeaderAcceptLanguage: return "Accept-Language";
413 case HeaderAuthorization: return "Authorization";
414 case HeaderCookie: return "Cookie";
415 case HeaderExpect: return "Expect";
416 case HeaderFrom: return "From";
417 case HeaderHost: return "Host";
418 case HeaderIfMatch: return "If-Match";
419 case HeaderIfModifiedSince: return "If-Modified-Since";
420 case HeaderIfNoneMatch: return "If-None-Match";
421 case HeaderIfRange: return "If-Range";
422 case HeaderIfUnmodifiedSince: return "If-Unmodified-Since";
423 case HeaderMaxForwards: return "Max-Forwards";
424 case HeaderProxyAuthorization: return "Proxy-Authorization";
425 case HeaderReferer: return "Referer";
426 case HeaderRange: return "Range";
427 case HeaderTe: return "TE";
428 case HeaderUserAgent: return "User-Agent";
430 throw new IndexOutOfRangeException ("index");
434 public static int GetKnownResponseHeaderIndex (string header)
438 if (ResponseHeaderIndexer.TryGetValue (header, out index))
441 object index = ResponseHeaderIndexer[header];
449 public static string GetKnownResponseHeaderName (int index)
452 case HeaderCacheControl: return "Cache-Control";
453 case HeaderConnection: return "Connection";
454 case HeaderDate: return "Date";
455 case HeaderKeepAlive: return "Keep-Alive";
456 case HeaderPragma: return "Pragma";
457 case HeaderTrailer: return "Trailer";
458 case HeaderTransferEncoding: return "Transfer-Encoding";
459 case HeaderUpgrade: return "Upgrade";
460 case HeaderVia: return "Via";
461 case HeaderWarning: return "Warning";
462 case HeaderAllow: return "Allow";
463 case HeaderContentLength: return "Content-Length";
464 case HeaderContentType: return "Content-Type";
465 case HeaderContentEncoding: return "Content-Encoding";
466 case HeaderContentLanguage: return "Content-Language";
467 case HeaderContentLocation: return "Content-Location";
468 case HeaderContentMd5: return "Content-MD5";
469 case HeaderContentRange: return "Content-Range";
470 case HeaderExpires: return "Expires";
471 case HeaderLastModified: return "Last-Modified";
472 case HeaderAcceptRanges: return "Accept-Ranges";
473 case HeaderAge: return "Age";
474 case HeaderEtag: return "ETag";
475 case HeaderLocation: return "Location";
476 case HeaderProxyAuthenticate: return "Proxy-Authenticate";
477 case HeaderRetryAfter: return "Retry-After";
478 case HeaderServer: return "Server";
479 case HeaderSetCookie: return "Set-Cookie";
480 case HeaderVary: return "Vary";
481 case HeaderWwwAuthenticate: return "WWW-Authenticate";
484 throw new IndexOutOfRangeException ("index");
487 public static string GetStatusDescription (int code)
490 case 100: return "Continue";
491 case 101: return "Switching Protocols";
492 case 102: return "Processing";
493 case 200: return "OK";
494 case 201: return "Created";
495 case 202: return "Accepted";
496 case 203: return "Non-Authoritative Information";
497 case 204: return "No Content";
498 case 205: return "Reset Content";
499 case 206: return "Partial Content";
500 case 207: return "Multi-Status";
501 case 300: return "Multiple Choices";
502 case 301: return "Moved Permanently";
503 case 302: return "Found";
504 case 303: return "See Other";
505 case 304: return "Not Modified";
506 case 305: return "Use Proxy";
507 case 307: return "Temporary Redirect";
508 case 400: return "Bad Request";
509 case 401: return "Unauthorized";
510 case 402: return "Payment Required";
511 case 403: return "Forbidden";
512 case 404: return "Not Found";
513 case 405: return "Method Not Allowed";
514 case 406: return "Not Acceptable";
515 case 407: return "Proxy Authentication Required";
516 case 408: return "Request Timeout";
517 case 409: return "Conflict";
518 case 410: return "Gone";
519 case 411: return "Length Required";
520 case 412: return "Precondition Failed";
521 case 413: return "Request Entity Too Large";
522 case 414: return "Request-Uri Too Long";
523 case 415: return "Unsupported Media Type";
524 case 416: return "Requested Range Not Satisfiable";
525 case 417: return "Expectation Failed";
526 case 422: return "Unprocessable Entity";
527 case 423: return "Locked";
528 case 424: return "Failed Dependency";
529 case 500: return "Internal Server Error";
530 case 501: return "Not Implemented";
531 case 502: return "Bad Gateway";
532 case 503: return "Service Unavailable";
533 case 504: return "Gateway Timeout";
534 case 505: return "Http Version Not Supported";
535 case 507: return "Insufficient Storage";
543 // These are exposed on the public API, but are for internal consumption
545 public virtual byte [] GetClientCertificate ()
550 public virtual byte [] GetClientCertificateBinaryIssuer ()
555 public virtual int GetClientCertificateEncoding ()
560 public virtual byte [] GetClientCertificatePublicKey ()
565 public virtual DateTime GetClientCertificateValidFrom ()
570 public virtual DateTime GetClientCertificateValidUntil ()
575 public virtual long GetConnectionID ()
580 public virtual long GetUrlContextID ()
585 public virtual IntPtr GetVirtualPathToken ()