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
320 public virtual void SendResponseFromMemory (IntPtr data, int length)
322 if (data != IntPtr.Zero) {
323 byte [] copy = new byte [length];
324 Marshal.Copy (data, copy, 0, length);
325 SendResponseFromMemory (copy, length);
329 public virtual void SetEndOfSendNotification (HttpWorkerRequest.EndOfSendNotification callback, object extraData)
333 #region Abstract methods
334 public abstract void EndOfRequest ();
335 public abstract void FlushResponse (bool finalFlush);
336 public abstract string GetHttpVerbName ();
337 public abstract string GetHttpVersion ();
338 public abstract string GetLocalAddress ();
339 public abstract int GetLocalPort ();
340 public abstract string GetQueryString ();
341 public abstract string GetRawUrl ();
342 public abstract string GetRemoteAddress ();
343 public abstract int GetRemotePort ();
344 public abstract string GetUriPath ();
345 public abstract void SendKnownResponseHeader (int index, string value);
346 public abstract void SendResponseFromFile (IntPtr handle, long offset, long length);
347 public abstract void SendResponseFromFile (string filename, long offset, long length);
348 public abstract void SendResponseFromMemory (byte [] data, int length);
349 public abstract void SendStatus (int statusCode, string statusDescription);
350 public abstract void SendUnknownResponseHeader (string name, string value);
353 #region Static methods
355 public static int GetKnownRequestHeaderIndex (string header)
358 if (RequestHeaderIndexer.TryGetValue (header, out index))
364 public static string GetKnownRequestHeaderName (int index)
367 case HeaderCacheControl: return "Cache-Control";
368 case HeaderConnection: return "Connection";
369 case HeaderDate: return "Date";
370 case HeaderKeepAlive: return "Keep-Alive";
371 case HeaderPragma: return "Pragma";
372 case HeaderTrailer: return "Trailer";
373 case HeaderTransferEncoding: return "Transfer-Encoding";
374 case HeaderUpgrade: return "Upgrade";
375 case HeaderVia: return "Via";
376 case HeaderWarning: return "Warning";
377 case HeaderAllow: return "Allow";
378 case HeaderContentLength: return "Content-Length";
379 case HeaderContentType: return "Content-Type";
380 case HeaderContentEncoding: return "Content-Encoding";
381 case HeaderContentLanguage: return "Content-Language";
382 case HeaderContentLocation: return "Content-Location";
383 case HeaderContentMd5: return "Content-MD5";
384 case HeaderContentRange: return "Content-Range";
385 case HeaderExpires: return "Expires";
386 case HeaderLastModified: return "Last-Modified";
387 case HeaderAccept: return "Accept";
388 case HeaderAcceptCharset: return "Accept-Charset";
389 case HeaderAcceptEncoding: return "Accept-Encoding";
390 case HeaderAcceptLanguage: return "Accept-Language";
391 case HeaderAuthorization: return "Authorization";
392 case HeaderCookie: return "Cookie";
393 case HeaderExpect: return "Expect";
394 case HeaderFrom: return "From";
395 case HeaderHost: return "Host";
396 case HeaderIfMatch: return "If-Match";
397 case HeaderIfModifiedSince: return "If-Modified-Since";
398 case HeaderIfNoneMatch: return "If-None-Match";
399 case HeaderIfRange: return "If-Range";
400 case HeaderIfUnmodifiedSince: return "If-Unmodified-Since";
401 case HeaderMaxForwards: return "Max-Forwards";
402 case HeaderProxyAuthorization: return "Proxy-Authorization";
403 case HeaderReferer: return "Referer";
404 case HeaderRange: return "Range";
405 case HeaderTe: return "TE";
406 case HeaderUserAgent: return "User-Agent";
408 throw new IndexOutOfRangeException ("index");
412 public static int GetKnownResponseHeaderIndex (string header)
415 if (ResponseHeaderIndexer.TryGetValue (header, out index))
421 public static string GetKnownResponseHeaderName (int index)
424 case HeaderCacheControl: return "Cache-Control";
425 case HeaderConnection: return "Connection";
426 case HeaderDate: return "Date";
427 case HeaderKeepAlive: return "Keep-Alive";
428 case HeaderPragma: return "Pragma";
429 case HeaderTrailer: return "Trailer";
430 case HeaderTransferEncoding: return "Transfer-Encoding";
431 case HeaderUpgrade: return "Upgrade";
432 case HeaderVia: return "Via";
433 case HeaderWarning: return "Warning";
434 case HeaderAllow: return "Allow";
435 case HeaderContentLength: return "Content-Length";
436 case HeaderContentType: return "Content-Type";
437 case HeaderContentEncoding: return "Content-Encoding";
438 case HeaderContentLanguage: return "Content-Language";
439 case HeaderContentLocation: return "Content-Location";
440 case HeaderContentMd5: return "Content-MD5";
441 case HeaderContentRange: return "Content-Range";
442 case HeaderExpires: return "Expires";
443 case HeaderLastModified: return "Last-Modified";
444 case HeaderAcceptRanges: return "Accept-Ranges";
445 case HeaderAge: return "Age";
446 case HeaderEtag: return "ETag";
447 case HeaderLocation: return "Location";
448 case HeaderProxyAuthenticate: return "Proxy-Authenticate";
449 case HeaderRetryAfter: return "Retry-After";
450 case HeaderServer: return "Server";
451 case HeaderSetCookie: return "Set-Cookie";
452 case HeaderVary: return "Vary";
453 case HeaderWwwAuthenticate: return "WWW-Authenticate";
456 throw new IndexOutOfRangeException ("index");
459 public static string GetStatusDescription (int code)
462 case 100: return "Continue";
463 case 101: return "Switching Protocols";
464 case 102: return "Processing";
465 case 200: return "OK";
466 case 201: return "Created";
467 case 202: return "Accepted";
468 case 203: return "Non-Authoritative Information";
469 case 204: return "No Content";
470 case 205: return "Reset Content";
471 case 206: return "Partial Content";
472 case 207: return "Multi-Status";
473 case 300: return "Multiple Choices";
474 case 301: return "Moved Permanently";
475 case 302: return "Found";
476 case 303: return "See Other";
477 case 304: return "Not Modified";
478 case 305: return "Use Proxy";
479 case 307: return "Temporary Redirect";
480 case 400: return "Bad Request";
481 case 401: return "Unauthorized";
482 case 402: return "Payment Required";
483 case 403: return "Forbidden";
484 case 404: return "Not Found";
485 case 405: return "Method Not Allowed";
486 case 406: return "Not Acceptable";
487 case 407: return "Proxy Authentication Required";
488 case 408: return "Request Timeout";
489 case 409: return "Conflict";
490 case 410: return "Gone";
491 case 411: return "Length Required";
492 case 412: return "Precondition Failed";
493 case 413: return "Request Entity Too Large";
494 case 414: return "Request-Uri Too Long";
495 case 415: return "Unsupported Media Type";
496 case 416: return "Requested Range Not Satisfiable";
497 case 417: return "Expectation Failed";
498 case 422: return "Unprocessable Entity";
499 case 423: return "Locked";
500 case 424: return "Failed Dependency";
501 case 500: return "Internal Server Error";
502 case 501: return "Not Implemented";
503 case 502: return "Bad Gateway";
504 case 503: return "Service Unavailable";
505 case 504: return "Gateway Timeout";
506 case 505: return "Http Version Not Supported";
507 case 507: return "Insufficient Storage";
515 // These are exposed on the public API, but are for internal consumption
517 public virtual byte [] GetClientCertificate ()
522 public virtual byte [] GetClientCertificateBinaryIssuer ()
527 public virtual int GetClientCertificateEncoding ()
532 public virtual byte [] GetClientCertificatePublicKey ()
537 public virtual DateTime GetClientCertificateValidFrom ()
542 public virtual DateTime GetClientCertificateValidUntil ()
547 public virtual long GetConnectionID ()
552 public virtual long GetUrlContextID ()
557 public virtual IntPtr GetVirtualPathToken ()