2 // System.Web.HttoWorkerRequest.cs
5 // Miguel de Icaza (miguel@novell.com)
9 // Copyright (C) 2005-2009 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.Collections.Generic;
33 using System.Collections.Specialized;
34 using System.Runtime.InteropServices;
35 using System.Security.Permissions;
41 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
42 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
45 public abstract partial class HttpWorkerRequest
47 public delegate void EndOfSendNotification (HttpWorkerRequest wr, object extraData);
49 public const int HeaderCacheControl = 0;
50 public const int HeaderConnection = 1;
51 public const int HeaderDate = 2;
52 public const int HeaderKeepAlive = 3;
53 public const int HeaderPragma = 4;
54 public const int HeaderTrailer = 5;
55 public const int HeaderTransferEncoding = 6;
56 public const int HeaderUpgrade = 7;
57 public const int HeaderVia = 8;
58 public const int HeaderWarning = 9;
59 public const int HeaderAllow = 10;
60 public const int HeaderContentLength = 11;
61 public const int HeaderContentType = 12;
62 public const int HeaderContentEncoding = 13;
63 public const int HeaderContentLanguage = 14;
64 public const int HeaderContentLocation = 15;
65 public const int HeaderContentMd5 = 16;
66 public const int HeaderContentRange = 17;
67 public const int HeaderExpires = 18;
68 public const int HeaderLastModified = 19;
69 public const int HeaderAccept = 20;
70 public const int HeaderAcceptCharset = 21;
71 public const int HeaderAcceptEncoding = 22;
72 public const int HeaderAcceptLanguage = 23;
73 public const int HeaderAuthorization = 24;
74 public const int HeaderCookie = 25;
75 public const int HeaderExpect = 26;
76 public const int HeaderFrom = 27;
77 public const int HeaderHost = 28;
78 public const int HeaderIfMatch = 29;
79 public const int HeaderIfModifiedSince = 30;
80 public const int HeaderIfNoneMatch = 31;
81 public const int HeaderIfRange = 32;
82 public const int HeaderIfUnmodifiedSince = 33;
83 public const int HeaderMaxForwards = 34;
84 public const int HeaderProxyAuthorization = 35;
85 public const int HeaderReferer = 36;
86 public const int HeaderRange = 37;
87 public const int HeaderTe = 38;
88 public const int HeaderUserAgent = 39;
89 public const int RequestHeaderMaximum = 40;
91 public const int HeaderAcceptRanges = 20;
92 public const int HeaderAge = 21;
93 public const int HeaderEtag = 22;
94 public const int HeaderLocation = 23;
95 public const int HeaderProxyAuthenticate = 24;
96 public const int HeaderRetryAfter = 25;
97 public const int HeaderServer = 26;
98 public const int HeaderSetCookie = 27;
99 public const int HeaderVary = 28;
100 public const int HeaderWwwAuthenticate = 29;
101 public const int ResponseHeaderMaximum = 30;
103 public const int ReasonResponseCacheMiss = 0;
104 public const int ReasonFileHandleCacheMiss = 1;
105 public const int ReasonCachePolicy = 2;
106 public const int ReasonCacheSecurity = 3;
107 public const int ReasonClientDisconnect = 4;
108 public const int ReasonDefault = 0;
109 static readonly Dictionary <string, int> RequestHeaderIndexer;
110 static readonly Dictionary <string, int> ResponseHeaderIndexer;
112 static HttpWorkerRequest ()
114 RequestHeaderIndexer = new Dictionary <string, int> (StringComparer.OrdinalIgnoreCase);
115 for (int i = 0; i < RequestHeaderMaximum; i++)
116 RequestHeaderIndexer.Add (GetKnownRequestHeaderName(i), i);
118 ResponseHeaderIndexer = new Dictionary <string, int> (StringComparer.OrdinalIgnoreCase);
119 for (int i = 0; i < ResponseHeaderMaximum; i++)
120 ResponseHeaderIndexer.Add (GetKnownResponseHeaderName(i), i);
123 bool started_internally;
124 internal bool StartedInternally {
125 get { return started_internally; }
126 set { started_internally = value; }
129 public virtual string MachineConfigPath {
135 public virtual string MachineInstallDirectory {
141 public virtual Guid RequestTraceIdentifier {
142 get { return Guid.Empty; }
145 public virtual string RootWebConfigPath {
149 public virtual void CloseConnection ()
153 public virtual string GetAppPath ()
158 public virtual string GetAppPathTranslated ()
163 public virtual string GetAppPoolID ()
168 public virtual long GetBytesRead ()
173 public virtual string GetFilePath ()
178 public virtual string GetFilePathTranslated ()
183 public virtual string GetKnownRequestHeader (int index)
188 public virtual string GetPathInfo ()
193 public virtual byte [] GetPreloadedEntityBody ()
198 public virtual int GetPreloadedEntityBody (byte[] buffer, int offset)
203 public virtual int GetPreloadedEntityBodyLength ()
208 public virtual string GetProtocol ()
216 public virtual byte [] GetQueryStringRawBytes ()
221 public virtual string GetRemoteName ()
223 return GetRemoteAddress ();
226 public virtual int GetRequestReason ()
231 public virtual string GetServerName ()
233 return GetLocalAddress ();
236 public virtual string GetServerVariable (string name)
241 public virtual int GetTotalEntityBodyLength ()
246 public virtual string GetUnknownRequestHeader (string name)
251 [CLSCompliant (false)]
252 public virtual string [][] GetUnknownRequestHeaders ()
257 public virtual IntPtr GetUserToken ()
262 public bool HasEntityBody ()
264 // TODO this is not virtual.
269 public virtual bool HeadersSent ()
274 public virtual bool IsClientConnected ()
279 public virtual bool IsEntireEntityBodyIsPreloaded ()
284 public virtual bool IsSecure ()
289 public virtual string MapPath (string virtualPath)
294 public virtual int ReadEntityBody (byte [] buffer, int size)
299 public virtual int ReadEntityBody (byte [] buffer, int offset, int size)
301 byte[] temp = new byte [size];
302 int n = ReadEntityBody (temp, size);
305 Array.Copy (temp, 0, buffer, offset, n);
310 public virtual void SendCalculatedContentLength (long contentLength)
312 SendCalculatedContentLength ((int)contentLength);
315 public virtual void SendCalculatedContentLength (int contentLength)
317 // apparently does nothing in MS.NET
321 public virtual void SendResponseFromMemory (IntPtr data, int length)
323 if (data != IntPtr.Zero) {
324 byte [] copy = new byte [length];
325 Marshal.Copy (data, copy, 0, length);
326 SendResponseFromMemory (copy, length);
331 public virtual void SetEndOfSendNotification (HttpWorkerRequest.EndOfSendNotification callback, object extraData)
335 #region Abstract methods
336 public abstract void EndOfRequest ();
337 public abstract void FlushResponse (bool finalFlush);
338 public abstract string GetHttpVerbName ();
339 public abstract string GetHttpVersion ();
340 public abstract string GetLocalAddress ();
341 public abstract int GetLocalPort ();
342 public abstract string GetQueryString ();
343 public abstract string GetRawUrl ();
344 public abstract string GetRemoteAddress ();
345 public abstract int GetRemotePort ();
346 public abstract string GetUriPath ();
347 public abstract void SendKnownResponseHeader (int index, string value);
348 public abstract void SendResponseFromFile (IntPtr handle, long offset, long length);
349 public abstract void SendResponseFromFile (string filename, long offset, long length);
350 public abstract void SendResponseFromMemory (byte [] data, int length);
351 public abstract void SendStatus (int statusCode, string statusDescription);
352 public abstract void SendUnknownResponseHeader (string name, string value);
355 #region Static methods
357 public static int GetKnownRequestHeaderIndex (string header)
360 if (RequestHeaderIndexer.TryGetValue (header, out index))
366 public static string GetKnownRequestHeaderName (int index)
369 case HeaderCacheControl: return "Cache-Control";
370 case HeaderConnection: return "Connection";
371 case HeaderDate: return "Date";
372 case HeaderKeepAlive: return "Keep-Alive";
373 case HeaderPragma: return "Pragma";
374 case HeaderTrailer: return "Trailer";
375 case HeaderTransferEncoding: return "Transfer-Encoding";
376 case HeaderUpgrade: return "Upgrade";
377 case HeaderVia: return "Via";
378 case HeaderWarning: return "Warning";
379 case HeaderAllow: return "Allow";
380 case HeaderContentLength: return "Content-Length";
381 case HeaderContentType: return "Content-Type";
382 case HeaderContentEncoding: return "Content-Encoding";
383 case HeaderContentLanguage: return "Content-Language";
384 case HeaderContentLocation: return "Content-Location";
385 case HeaderContentMd5: return "Content-MD5";
386 case HeaderContentRange: return "Content-Range";
387 case HeaderExpires: return "Expires";
388 case HeaderLastModified: return "Last-Modified";
389 case HeaderAccept: return "Accept";
390 case HeaderAcceptCharset: return "Accept-Charset";
391 case HeaderAcceptEncoding: return "Accept-Encoding";
392 case HeaderAcceptLanguage: return "Accept-Language";
393 case HeaderAuthorization: return "Authorization";
394 case HeaderCookie: return "Cookie";
395 case HeaderExpect: return "Expect";
396 case HeaderFrom: return "From";
397 case HeaderHost: return "Host";
398 case HeaderIfMatch: return "If-Match";
399 case HeaderIfModifiedSince: return "If-Modified-Since";
400 case HeaderIfNoneMatch: return "If-None-Match";
401 case HeaderIfRange: return "If-Range";
402 case HeaderIfUnmodifiedSince: return "If-Unmodified-Since";
403 case HeaderMaxForwards: return "Max-Forwards";
404 case HeaderProxyAuthorization: return "Proxy-Authorization";
405 case HeaderReferer: return "Referer";
406 case HeaderRange: return "Range";
407 case HeaderTe: return "TE";
408 case HeaderUserAgent: return "User-Agent";
410 throw new IndexOutOfRangeException ("index");
414 public static int GetKnownResponseHeaderIndex (string header)
417 if (ResponseHeaderIndexer.TryGetValue (header, out index))
423 public static string GetKnownResponseHeaderName (int index)
426 case HeaderCacheControl: return "Cache-Control";
427 case HeaderConnection: return "Connection";
428 case HeaderDate: return "Date";
429 case HeaderKeepAlive: return "Keep-Alive";
430 case HeaderPragma: return "Pragma";
431 case HeaderTrailer: return "Trailer";
432 case HeaderTransferEncoding: return "Transfer-Encoding";
433 case HeaderUpgrade: return "Upgrade";
434 case HeaderVia: return "Via";
435 case HeaderWarning: return "Warning";
436 case HeaderAllow: return "Allow";
437 case HeaderContentLength: return "Content-Length";
438 case HeaderContentType: return "Content-Type";
439 case HeaderContentEncoding: return "Content-Encoding";
440 case HeaderContentLanguage: return "Content-Language";
441 case HeaderContentLocation: return "Content-Location";
442 case HeaderContentMd5: return "Content-MD5";
443 case HeaderContentRange: return "Content-Range";
444 case HeaderExpires: return "Expires";
445 case HeaderLastModified: return "Last-Modified";
446 case HeaderAcceptRanges: return "Accept-Ranges";
447 case HeaderAge: return "Age";
448 case HeaderEtag: return "ETag";
449 case HeaderLocation: return "Location";
450 case HeaderProxyAuthenticate: return "Proxy-Authenticate";
451 case HeaderRetryAfter: return "Retry-After";
452 case HeaderServer: return "Server";
453 case HeaderSetCookie: return "Set-Cookie";
454 case HeaderVary: return "Vary";
455 case HeaderWwwAuthenticate: return "WWW-Authenticate";
458 throw new IndexOutOfRangeException ("index");
461 public static string GetStatusDescription (int code)
464 case 100: return "Continue";
465 case 101: return "Switching Protocols";
466 case 102: return "Processing";
467 case 200: return "OK";
468 case 201: return "Created";
469 case 202: return "Accepted";
470 case 203: return "Non-Authoritative Information";
471 case 204: return "No Content";
472 case 205: return "Reset Content";
473 case 206: return "Partial Content";
474 case 207: return "Multi-Status";
475 case 300: return "Multiple Choices";
476 case 301: return "Moved Permanently";
477 case 302: return "Found";
478 case 303: return "See Other";
479 case 304: return "Not Modified";
480 case 305: return "Use Proxy";
481 case 307: return "Temporary Redirect";
482 case 400: return "Bad Request";
483 case 401: return "Unauthorized";
484 case 402: return "Payment Required";
485 case 403: return "Forbidden";
486 case 404: return "Not Found";
487 case 405: return "Method Not Allowed";
488 case 406: return "Not Acceptable";
489 case 407: return "Proxy Authentication Required";
490 case 408: return "Request Timeout";
491 case 409: return "Conflict";
492 case 410: return "Gone";
493 case 411: return "Length Required";
494 case 412: return "Precondition Failed";
495 case 413: return "Request Entity Too Large";
496 case 414: return "Request-Uri Too Long";
497 case 415: return "Unsupported Media Type";
498 case 416: return "Requested Range Not Satisfiable";
499 case 417: return "Expectation Failed";
500 case 422: return "Unprocessable Entity";
501 case 423: return "Locked";
502 case 424: return "Failed Dependency";
503 case 500: return "Internal Server Error";
504 case 501: return "Not Implemented";
505 case 502: return "Bad Gateway";
506 case 503: return "Service Unavailable";
507 case 504: return "Gateway Timeout";
508 case 505: return "Http Version Not Supported";
509 case 507: return "Insufficient Storage";
517 // These are exposed on the public API, but are for internal consumption
519 public virtual byte [] GetClientCertificate ()
524 public virtual byte [] GetClientCertificateBinaryIssuer ()
529 public virtual int GetClientCertificateEncoding ()
534 public virtual byte [] GetClientCertificatePublicKey ()
539 public virtual DateTime GetClientCertificateValidFrom ()
544 public virtual DateTime GetClientCertificateValidUntil ()
549 public virtual long GetConnectionID ()
554 public virtual long GetUrlContextID ()
559 public virtual IntPtr GetVirtualPathToken ()