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;
37 namespace System.Web {
40 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
41 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
44 public abstract class HttpWorkerRequest {
46 public delegate void EndOfSendNotification (HttpWorkerRequest wr, object extraData);
48 public const int HeaderCacheControl = 0;
49 public const int HeaderConnection = 1;
50 public const int HeaderDate = 2;
51 public const int HeaderKeepAlive = 3;
52 public const int HeaderPragma = 4;
53 public const int HeaderTrailer = 5;
54 public const int HeaderTransferEncoding = 6;
55 public const int HeaderUpgrade = 7;
56 public const int HeaderVia = 8;
57 public const int HeaderWarning = 9;
58 public const int HeaderAllow = 10;
59 public const int HeaderContentLength = 11;
60 public const int HeaderContentType = 12;
61 public const int HeaderContentEncoding = 13;
62 public const int HeaderContentLanguage = 14;
63 public const int HeaderContentLocation = 15;
64 public const int HeaderContentMd5 = 16;
65 public const int HeaderContentRange = 17;
66 public const int HeaderExpires = 18;
67 public const int HeaderLastModified = 19;
68 public const int HeaderAccept = 20;
69 public const int HeaderAcceptCharset = 21;
70 public const int HeaderAcceptEncoding = 22;
71 public const int HeaderAcceptLanguage = 23;
72 public const int HeaderAuthorization = 24;
73 public const int HeaderCookie = 25;
74 public const int HeaderExpect = 26;
75 public const int HeaderFrom = 27;
76 public const int HeaderHost = 28;
77 public const int HeaderIfMatch = 29;
78 public const int HeaderIfModifiedSince = 30;
79 public const int HeaderIfNoneMatch = 31;
80 public const int HeaderIfRange = 32;
81 public const int HeaderIfUnmodifiedSince = 33;
82 public const int HeaderMaxForwards = 34;
83 public const int HeaderProxyAuthorization = 35;
84 public const int HeaderReferer = 36;
85 public const int HeaderRange = 37;
86 public const int HeaderTe = 38;
87 public const int HeaderUserAgent = 39;
88 public const int RequestHeaderMaximum = 40;
90 public const int HeaderAcceptRanges = 20;
91 public const int HeaderAge = 21;
92 public const int HeaderEtag = 22;
93 public const int HeaderLocation = 23;
94 public const int HeaderProxyAuthenticate = 24;
95 public const int HeaderRetryAfter = 25;
96 public const int HeaderServer = 26;
97 public const int HeaderSetCookie = 27;
98 public const int HeaderVary = 28;
99 public const int HeaderWwwAuthenticate = 29;
100 public const int ResponseHeaderMaximum = 30;
102 public const int ReasonResponseCacheMiss = 0;
103 public const int ReasonFileHandleCacheMiss = 1;
104 public const int ReasonCachePolicy = 2;
105 public const int ReasonCacheSecurity = 3;
106 public const int ReasonClientDisconnect = 4;
107 public const int ReasonDefault = 0;
109 static readonly Hashtable RequestHeaderIndexer;
110 static readonly Hashtable ResponseHeaderIndexer;
112 static HttpWorkerRequest() {
113 RequestHeaderIndexer = CollectionsUtil.CreateCaseInsensitiveHashtable(RequestHeaderMaximum);
114 for (int i = 0; i < RequestHeaderMaximum; i++)
115 RequestHeaderIndexer[GetKnownRequestHeaderName(i)] = i;
117 ResponseHeaderIndexer = CollectionsUtil.CreateCaseInsensitiveHashtable(ResponseHeaderMaximum);
118 for (int i = 0; i < ResponseHeaderMaximum; i++)
119 ResponseHeaderIndexer[GetKnownResponseHeaderName(i)] = i;
122 public virtual string MachineConfigPath {
128 public virtual string MachineInstallDirectory {
135 public virtual Guid RequestTraceIdentifier {
136 get { return Guid.Empty; }
139 public virtual string RootWebConfigPath {
144 public virtual void CloseConnection ()
148 public virtual string GetAppPath ()
153 public virtual string GetAppPathTranslated ()
158 public virtual string GetAppPoolID ()
163 public virtual long GetBytesRead ()
168 public virtual string GetFilePath ()
173 public virtual string GetFilePathTranslated ()
178 public virtual string GetKnownRequestHeader (int index)
183 public virtual string GetPathInfo ()
188 public virtual byte [] GetPreloadedEntityBody ()
193 public virtual int GetPreloadedEntityBody (byte[] buffer, int offset)
198 public virtual int GetPreloadedEntityBodyLength ()
203 public virtual string GetProtocol ()
211 public virtual byte [] GetQueryStringRawBytes ()
216 public virtual string GetRemoteName ()
218 return GetRemoteAddress ();
221 public virtual int GetRequestReason ()
226 public virtual string GetServerName ()
228 return GetLocalAddress ();
231 public virtual string GetServerVariable (string name)
236 public virtual int GetTotalEntityBodyLength ()
241 public virtual string GetUnknownRequestHeader (string name)
246 [CLSCompliant (false)]
247 public virtual string [][] GetUnknownRequestHeaders ()
252 public virtual IntPtr GetUserToken ()
257 public bool HasEntityBody ()
259 // TODO this is not virtual.
264 public virtual bool HeadersSent ()
269 public virtual bool IsClientConnected ()
274 public virtual bool IsEntireEntityBodyIsPreloaded ()
279 public virtual bool IsSecure ()
284 public virtual string MapPath (string virtualPath)
289 public virtual int ReadEntityBody (byte [] buffer, int size)
294 public virtual int ReadEntityBody (byte [] buffer, int offset, int size)
299 public virtual void SendCalculatedContentLength (int contentLength)
301 throw new NotImplementedException ();
305 public virtual void SendResponseFromMemory (IntPtr data, int length)
307 throw new NotImplementedException("SendResponseFromMemory: unsafe buffers (IntPtr) are not supported");
310 public virtual void SendResponseFromMemory (IntPtr data, int length)
312 if (data != IntPtr.Zero) {
313 byte [] copy = new byte [length];
314 Marshal.Copy (data, copy, 0, length);
315 SendResponseFromMemory (copy, length);
320 public virtual void SetEndOfSendNotification (HttpWorkerRequest.EndOfSendNotification callback, object extraData)
324 #region Abstract methods
325 public abstract void EndOfRequest ();
326 public abstract void FlushResponse (bool finalFlush);
327 public abstract string GetHttpVerbName ();
328 public abstract string GetHttpVersion ();
329 public abstract string GetLocalAddress ();
330 public abstract int GetLocalPort ();
331 public abstract string GetQueryString ();
332 public abstract string GetRawUrl ();
333 public abstract string GetRemoteAddress ();
334 public abstract int GetRemotePort ();
335 public abstract string GetUriPath ();
336 public abstract void SendKnownResponseHeader (int index, string value);
337 public abstract void SendResponseFromFile (IntPtr handle, long offset, long length);
338 public abstract void SendResponseFromFile (string filename, long offset, long length);
339 public abstract void SendResponseFromMemory (byte [] data, int length);
340 public abstract void SendStatus (int statusCode, string statusDescription);
341 public abstract void SendUnknownResponseHeader (string name, string value);
344 #region Static methods
346 public static int GetKnownRequestHeaderIndex (string header)
349 case "Cache-Control": return HeaderCacheControl;
350 case "Connection": return HeaderConnection;
351 case "Date": return HeaderDate;
352 case "Keep-Alive": return HeaderKeepAlive;
353 case "Pragma": return HeaderPragma;
354 case "Trailer": return HeaderTrailer;
355 case "Transfer-Encoding": return HeaderTransferEncoding;
356 case "Upgrade": return HeaderUpgrade;
357 case "Via": return HeaderVia;
358 case "Warning": return HeaderWarning;
359 case "Allow": return HeaderAllow;
360 case "Content-Length": return HeaderContentLength;
361 case "Content-Type": return HeaderContentType;
362 case "Content-Encoding": return HeaderContentEncoding;
363 case "Content-Language": return HeaderContentLanguage;
364 case "Content-Location": return HeaderContentLocation;
365 case "Content-MD5": return HeaderContentMd5;
366 case "Content-Range": return HeaderContentRange;
367 case "Expires": return HeaderExpires;
368 case "Last-Modified": return HeaderLastModified;
369 case "Accept": return HeaderAccept;
370 case "Accept-Charset": return HeaderAcceptCharset;
371 case "Accept-Encoding": return HeaderAcceptEncoding;
372 case "Accept-Language": return HeaderAcceptLanguage;
373 case "Authorization": return HeaderAuthorization;
374 case "Cookie": return HeaderCookie;
375 case "Expect": return HeaderExpect;
376 case "From": return HeaderFrom;
377 case "Host": return HeaderHost;
378 case "If-Match": return HeaderIfMatch;
379 case "If-Modified-Since": return HeaderIfModifiedSince;
380 case "If-None-Match": return HeaderIfNoneMatch;
381 case "If-Range": return HeaderIfRange;
382 case "If-Unmodified-Since": return HeaderIfUnmodifiedSince;
383 case "Max-Forwards": return HeaderMaxForwards;
384 case "Proxy-Authorization": return HeaderProxyAuthorization;
385 case "Referer": return HeaderReferer;
386 case "Range": return HeaderRange;
387 case "TE": return HeaderTe;
388 case "User-Agent": return HeaderUserAgent;
391 object index = RequestHeaderIndexer[header];
398 public static string GetKnownRequestHeaderName (int index)
401 case HeaderCacheControl: return "Cache-Control";
402 case HeaderConnection: return "Connection";
403 case HeaderDate: return "Date";
404 case HeaderKeepAlive: return "Keep-Alive";
405 case HeaderPragma: return "Pragma";
406 case HeaderTrailer: return "Trailer";
407 case HeaderTransferEncoding: return "Transfer-Encoding";
408 case HeaderUpgrade: return "Upgrade";
409 case HeaderVia: return "Via";
410 case HeaderWarning: return "Warning";
411 case HeaderAllow: return "Allow";
412 case HeaderContentLength: return "Content-Length";
413 case HeaderContentType: return "Content-Type";
414 case HeaderContentEncoding: return "Content-Encoding";
415 case HeaderContentLanguage: return "Content-Language";
416 case HeaderContentLocation: return "Content-Location";
417 case HeaderContentMd5: return "Content-MD5";
418 case HeaderContentRange: return "Content-Range";
419 case HeaderExpires: return "Expires";
420 case HeaderLastModified: return "Last-Modified";
421 case HeaderAccept: return "Accept";
422 case HeaderAcceptCharset: return "Accept-Charset";
423 case HeaderAcceptEncoding: return "Accept-Encoding";
424 case HeaderAcceptLanguage: return "Accept-Language";
425 case HeaderAuthorization: return "Authorization";
426 case HeaderCookie: return "Cookie";
427 case HeaderExpect: return "Expect";
428 case HeaderFrom: return "From";
429 case HeaderHost: return "Host";
430 case HeaderIfMatch: return "If-Match";
431 case HeaderIfModifiedSince: return "If-Modified-Since";
432 case HeaderIfNoneMatch: return "If-None-Match";
433 case HeaderIfRange: return "If-Range";
434 case HeaderIfUnmodifiedSince: return "If-Unmodified-Since";
435 case HeaderMaxForwards: return "Max-Forwards";
436 case HeaderProxyAuthorization: return "Proxy-Authorization";
437 case HeaderReferer: return "Referer";
438 case HeaderRange: return "Range";
439 case HeaderTe: return "TE";
440 case HeaderUserAgent: return "User-Agent";
442 throw new IndexOutOfRangeException ("index");
446 public static int GetKnownResponseHeaderIndex (string header)
449 case "Cache-Control": return HeaderCacheControl;
450 case "Connection": return HeaderConnection;
451 case "Date": return HeaderDate;
452 case "Keep-Alive": return HeaderKeepAlive;
453 case "Pragma": return HeaderPragma;
454 case "Trailer": return HeaderTrailer;
455 case "Transfer-Encoding": return HeaderTransferEncoding;
456 case "Upgrade": return HeaderUpgrade;
457 case "Via": return HeaderVia;
458 case "Warning": return HeaderWarning;
459 case "Allow": return HeaderAllow;
460 case "Content-Length": return HeaderContentLength;
461 case "Content-Type": return HeaderContentType;
462 case "Content-Encoding": return HeaderContentEncoding;
463 case "Content-Language": return HeaderContentLanguage;
464 case "Content-Location": return HeaderContentLocation;
465 case "Content-MD5": return HeaderContentMd5;
466 case "Content-Range": return HeaderContentRange;
467 case "Expires": return HeaderExpires;
468 case "Last-Modified": return HeaderLastModified;
469 case "Accept-Ranges": return HeaderAcceptRanges;
470 case "Age": return HeaderAge;
471 case "ETag": return HeaderEtag;
472 case "Location": return HeaderLocation;
473 case "Proxy-Authenticate":return HeaderProxyAuthenticate;
474 case "Retry-After": return HeaderRetryAfter;
475 case "Server": return HeaderServer;
476 case "Set-Cookie": return HeaderSetCookie;
477 case "Vary": return HeaderVary;
478 case "WWW-Authenticate": return HeaderWwwAuthenticate;
481 object index = ResponseHeaderIndexer[header];
488 public static string GetKnownResponseHeaderName (int index)
491 case HeaderCacheControl: return "Cache-Control";
492 case HeaderConnection: return "Connection";
493 case HeaderDate: return "Date";
494 case HeaderKeepAlive: return "Keep-Alive";
495 case HeaderPragma: return "Pragma";
496 case HeaderTrailer: return "Trailer";
497 case HeaderTransferEncoding: return "Transfer-Encoding";
498 case HeaderUpgrade: return "Upgrade";
499 case HeaderVia: return "Via";
500 case HeaderWarning: return "Warning";
501 case HeaderAllow: return "Allow";
502 case HeaderContentLength: return "Content-Length";
503 case HeaderContentType: return "Content-Type";
504 case HeaderContentEncoding: return "Content-Encoding";
505 case HeaderContentLanguage: return "Content-Language";
506 case HeaderContentLocation: return "Content-Location";
507 case HeaderContentMd5: return "Content-MD5";
508 case HeaderContentRange: return "Content-Range";
509 case HeaderExpires: return "Expires";
510 case HeaderLastModified: return "Last-Modified";
511 case HeaderAcceptRanges: return "Accept-Ranges";
512 case HeaderAge: return "Age";
513 case HeaderEtag: return "ETag";
514 case HeaderLocation: return "Location";
515 case HeaderProxyAuthenticate: return "Proxy-Authenticate";
516 case HeaderRetryAfter: return "Retry-After";
517 case HeaderServer: return "Server";
518 case HeaderSetCookie: return "Set-Cookie";
519 case HeaderVary: return "Vary";
520 case HeaderWwwAuthenticate: return "WWW-Authenticate";
523 throw new IndexOutOfRangeException ("index");
526 public static string GetStatusDescription (int code)
529 case 100: return "Continue";
530 case 101: return "Switching Protocols";
531 case 102: return "Processing";
532 case 200: return "OK";
533 case 201: return "Created";
534 case 202: return "Accepted";
535 case 203: return "Non-Authoritative Information";
536 case 204: return "No Content";
537 case 205: return "Reset Content";
538 case 206: return "Partial Content";
539 case 207: return "Multi-Status";
540 case 300: return "Multiple Choices";
541 case 301: return "Moved Permanently";
542 case 302: return "Found";
543 case 303: return "See Other";
544 case 304: return "Not Modified";
545 case 305: return "Use Proxy";
546 case 307: return "Temporary Redirect";
547 case 400: return "Bad Request";
548 case 401: return "Unauthorized";
549 case 402: return "Payment Required";
550 case 403: return "Forbidden";
551 case 404: return "Not Found";
552 case 405: return "Method Not Allowed";
553 case 406: return "Not Acceptable";
554 case 407: return "Proxy Authentication Required";
555 case 408: return "Request Timeout";
556 case 409: return "Conflict";
557 case 410: return "Gone";
558 case 411: return "Length Required";
559 case 412: return "Precondition Failed";
560 case 413: return "Request Entity Too Large";
561 case 414: return "Request-Uri Too Long";
562 case 415: return "Unsupported Media Type";
563 case 416: return "Requested Range Not Satisfiable";
564 case 417: return "Expectation Failed";
565 case 422: return "Unprocessable Entity";
566 case 423: return "Locked";
567 case 424: return "Failed Dependency";
568 case 500: return "Internal Server Error";
569 case 501: return "Not Implemented";
570 case 502: return "Bad Gateway";
571 case 503: return "Service Unavailable";
572 case 504: return "Gateway Timeout";
573 case 505: return "Http Version Not Supported";
574 case 507: return "Insufficient Storage";
582 // These are exposed on the public API, but are for internal consumption
584 public virtual byte [] GetClientCertificate ()
589 public virtual byte [] GetClientCertificateBinaryIssuer ()
594 public virtual int GetClientCertificateEncoding ()
599 public virtual byte [] GetClientCertificatePublicKey ()
604 public virtual DateTime GetClientCertificateValidFrom ()
609 public virtual DateTime GetClientCertificateValidUntil ()
614 public virtual long GetConnectionID ()
619 public virtual long GetUrlContextID ()
624 public virtual IntPtr GetVirtualPathToken ()