// // System.Web.HttpWorkerRequest // // Authors: // Patrik Torstensson (Patrik.Torstensson@labs2.com) // (constants from Bob Smith (bob@thestuff.net)) // Gonzalo Paniagua Javier (gonzalo@ximian.com) // // (c) Patrik Torstensson // (c) 2002 Ximian, Inc. (http://www.ximian.com) // using System; using System.Collections; using System.Runtime.InteropServices; namespace System.Web { [ComVisible (false)] public abstract class HttpWorkerRequest : IHttpMapPath { public delegate void EndOfSendNotification (HttpWorkerRequest wr, object extraData); public const int HeaderAccept = 20; public const int HeaderAcceptCharset = 21; public const int HeaderAcceptEncoding = 22; public const int HeaderAcceptLanguage = 23; public const int HeaderAcceptRanges = 20; public const int HeaderAge = 21; public const int HeaderAllow = 10; public const int HeaderAuthorization = 24; public const int HeaderCacheControl = 0; public const int HeaderConnection = 1; public const int HeaderContentEncoding = 13; public const int HeaderContentLanguage = 14; public const int HeaderContentLength = 11; public const int HeaderContentLocation = 15; public const int HeaderContentMd5 = 16; public const int HeaderContentRange = 17; public const int HeaderContentType = 12; public const int HeaderCookie = 25; public const int HeaderDate = 2; public const int HeaderEtag = 22; public const int HeaderExpect = 26; public const int HeaderExpires = 18; public const int HeaderFrom = 27; public const int HeaderHost = 28; public const int HeaderIfMatch = 29; public const int HeaderIfModifiedSince = 30; public const int HeaderIfNoneMatch = 31; public const int HeaderIfRange = 32; public const int HeaderIfUnmodifiedSince = 33; public const int HeaderKeepAlive = 3; public const int HeaderLastModified = 19; public const int HeaderLocation = 23; public const int HeaderMaxForwards = 34; public const int HeaderPragma = 4; public const int HeaderProxyAuthenticate = 24; public const int HeaderProxyAuthorization = 35; public const int HeaderRange = 37; public const int HeaderReferer = 36; public const int HeaderRetryAfter = 25; public const int HeaderServer = 26; public const int HeaderSetCookie = 27; public const int HeaderTe = 38; public const int HeaderTrailer = 5; public const int HeaderTransferEncoding = 6; public const int HeaderUpgrade = 7; public const int HeaderUserAgent = 39; public const int HeaderVary = 28; public const int HeaderVia = 8; public const int HeaderWarning = 9; public const int HeaderWwwAuthenticate = 29; public const int ReasonCachePolicy = 2; public const int ReasonCacheSecurity = 3; public const int ReasonClientDisconnect = 4; public const int ReasonDefault = 0; public const int ReasonFileHandleCacheMiss = 1; public const int ReasonResponseCacheMiss = 0; public const int RequestHeaderMaximum = 40; public const int ResponseHeaderMaximum = 30; static string [][] s_HttpStatusDescriptions; static string [] s_HttpRequestHeaderNames; static string [] s_HttpResponseHeaderNames; static Hashtable s_HttpResponseHeadersTable; static Hashtable s_HttpRequestHeaderTable; static HttpWorkerRequest () { string [] sSubCodes; s_HttpStatusDescriptions = new string [6][]; sSubCodes = new String [3]; sSubCodes [0] = "Continue"; sSubCodes [1] = "Switching Protocols"; sSubCodes [2] = "Processing"; s_HttpStatusDescriptions [1] = sSubCodes; sSubCodes = new String [8]; sSubCodes [0] = "OK"; sSubCodes [1] = "Created"; sSubCodes [2] = "Accepted"; sSubCodes [3] = "Non-Authoritative Information"; sSubCodes [4] = "No Content"; sSubCodes [5] = "Reset Content"; sSubCodes [6] = "Partial Content"; sSubCodes [7] = "Multi-Status"; s_HttpStatusDescriptions [2] = sSubCodes; sSubCodes = new String [8]; sSubCodes [0] = "Multiple Choices"; sSubCodes [1] = "Moved Permanently"; sSubCodes [2] = "Found"; sSubCodes [3] = "See Other"; sSubCodes [4] = "Not Modified"; sSubCodes [5] = "Use Proxy"; sSubCodes [6] = String.Empty; sSubCodes [7] = "Temporary Redirect"; s_HttpStatusDescriptions [3] = sSubCodes; sSubCodes = new String [24]; sSubCodes [0] = "Bad Request"; sSubCodes [1] = "Unauthorized"; sSubCodes [2] = "Payment Required"; sSubCodes [3] = "Forbidden"; sSubCodes [4] = "Not Found"; sSubCodes [5] = "Method Not Allowed"; sSubCodes [6] = "Not Acceptable"; sSubCodes [7] = "Proxy Authentication Required"; sSubCodes [8] = "Request Timeout"; sSubCodes [9] = "Conflict"; sSubCodes [10] = "Gone"; sSubCodes [11] = "Length Required"; sSubCodes [12] = "Precondition Failed"; sSubCodes [13] = "Request Entity Too Large"; sSubCodes [14] = "Request-Uri Too Long"; sSubCodes [15] = "Unsupported Media Type"; sSubCodes [16] = "Requested Range Not Satisfiable"; sSubCodes [17] = "Expectation Failed"; sSubCodes [18] = String.Empty; sSubCodes [19] = String.Empty; sSubCodes [20] = String.Empty; sSubCodes [21] = "Unprocessable Entity"; sSubCodes [22] = "Locked"; sSubCodes [23] = "Failed Dependency"; s_HttpStatusDescriptions [4] = sSubCodes; sSubCodes = new String [8]; sSubCodes [0] = "Internal Server Error"; sSubCodes [1] = "Not Implemented"; sSubCodes [2] = "Bad Gateway"; sSubCodes [3] = "Service Unavailable"; sSubCodes [4] = "Gateway Timeout"; sSubCodes [5] = "Http Version Not Supported"; sSubCodes [6] = String.Empty; sSubCodes [7] = "Insufficient Storage"; s_HttpStatusDescriptions [5] = sSubCodes; InitLookupTables (); } public HttpWorkerRequest () { } static private void InitLookupTables () { // Performance arrays s_HttpRequestHeaderNames = new string [40]; s_HttpResponseHeaderNames = new string [30]; // Lookup tables (name -> id) s_HttpRequestHeaderTable = new Hashtable (); s_HttpResponseHeadersTable = new Hashtable (); AddHeader (true, true, 0, "Cache-Control"); AddHeader (true, true, 1, "Connection"); AddHeader (true, true, 2, "Date"); AddHeader (true, true, 3, "Keep-Alive"); AddHeader (true, true, 4, "Pragma"); AddHeader (true, true, 5, "Trailer"); AddHeader (true, true, 6, "Transfer-Encoding"); AddHeader (true, true, 7, "Upgrade"); AddHeader (true, true, 8, "Via"); AddHeader (true, true, 9, "Warning"); AddHeader (true, true, 10, "Allow"); AddHeader (true, true, 11, "Content-Length"); AddHeader (true, true, 12, "Content-Type"); AddHeader (true, true, 13, "Content-Encoding"); AddHeader (true, true, 14, "Content-Language"); AddHeader (true, true, 15, "Content-Location"); AddHeader (true, true, 16, "Content-MD5"); AddHeader (true, true, 17, "Content-Range"); AddHeader (true, true, 18, "Expires"); AddHeader (true, true, 19, "Last-Modified"); AddHeader (true, false, 20, "Accept"); AddHeader (true, false, 21, "Accept-Charset"); AddHeader (true, false, 22, "Accept-Encoding"); AddHeader (true, false, 23, "Accept-Language"); AddHeader (true, false, 24, "Authorization"); AddHeader (true, false, 25, "Cookie"); AddHeader (true, false, 26, "Expect"); AddHeader (true, false, 27, "From"); AddHeader (true, false, 28, "Host"); AddHeader (true, false, 29, "If-Match"); AddHeader (true, false, 30, "If-Modified-Since"); AddHeader (true, false, 31, "If-None-Match"); AddHeader (true, false, 32, "If-Range"); AddHeader (true, false, 33, "If-Unmodified-Since"); AddHeader (true, false, 34, "Max-Forwards"); AddHeader (true, false, 35, "Proxy-Authorization"); AddHeader (true, false, 36, "Referer"); AddHeader (true, false, 37, "Range"); AddHeader (true, false, 38, "TE"); AddHeader (true, false, 39, "User-Agent"); AddHeader (false, true, 20, "Accept-Ranges"); AddHeader (false, true, 21, "Age"); AddHeader (false, true, 22, "ETag"); AddHeader (false, true, 23, "Location"); AddHeader (false, true, 24, "Proxy-Authenticate"); AddHeader (false, true, 25, "Retry-After"); AddHeader (false, true, 26, "Server"); AddHeader (false, true, 27, "Set-Cookie"); AddHeader (false, true, 28, "Vary"); AddHeader (false, true, 29, "WWW-Authenticate"); } static private void AddHeader(bool bRequest, bool bResponse, int iID, string sHeader) { if (bResponse) { s_HttpResponseHeaderNames [iID] = sHeader; s_HttpResponseHeadersTable.Add (sHeader, iID); } if (bRequest) { s_HttpRequestHeaderNames [iID] = sHeader; s_HttpRequestHeaderTable.Add (sHeader, iID); } } public virtual void CloseConnection () { } public abstract void EndOfRequest (); public abstract void FlushResponse (bool finalFlush); public virtual string GetAppPath () { return null; } public virtual string GetAppPathTranslated () { return null; } public virtual string GetAppPoolID () { return null; } public virtual long GetBytesRead () { return 0; } public virtual byte[] GetClientCertificate () { return new byte[0]; } public virtual byte[] GetClientCertificateBinaryIssuer () { return new byte[0]; } public virtual int GetClientCertificateEncoding () { return 0; } public virtual byte[] GetClientCertificatePublicKey () { return new byte[0]; } public virtual DateTime GetClientCertificateValidFrom () { return DateTime.Now; } public virtual DateTime GetClientCertificateValidUntil () { return DateTime.Now; } public virtual long GetConnectionID () { return 0; } public virtual string GetFilePath () { return GetUriPath(); } public virtual string GetFilePathTranslated () { return null; } public abstract string GetHttpVerbName (); public abstract string GetHttpVersion (); public virtual string GetKnownRequestHeader (int index) { return null; } public static int GetKnownRequestHeaderIndex (string header) { object index; index = s_HttpRequestHeaderTable [header]; if (null != index) return (Int32) index; return -1; } public static string GetKnownRequestHeaderName (int index) { return s_HttpRequestHeaderNames [index]; } public static int GetKnownResponseHeaderIndex (string header) { object index; index = s_HttpResponseHeadersTable [header]; if (null != index) return (Int32) index; return -1; } public static string GetKnownResponseHeaderName(int index) { return s_HttpResponseHeaderNames [index]; } public abstract string GetLocalAddress (); public abstract int GetLocalPort (); public virtual string GetPathInfo () { return String.Empty; } public virtual byte [] GetPreloadedEntityBody () { return null; } public virtual string GetProtocol () { return (IsSecure ()) ? "https" : "http"; } public abstract string GetQueryString (); public virtual byte[] GetQueryStringRawBytes () { return null; } public abstract string GetRawUrl (); public abstract string GetRemoteAddress (); public virtual string GetRemoteName () { return GetRemoteAddress(); } public abstract int GetRemotePort (); public virtual int GetRequestReason () { return 0; } public virtual string GetServerName () { return GetLocalAddress(); } public virtual string GetServerVariable (string name) { return null; } public static string GetStatusDescription (int code) { if (code>= 100 && code < 600) { int iMajor = code / 100; int iMinor = code % 100; if (iMinor < (int) s_HttpStatusDescriptions [iMajor].Length) return s_HttpStatusDescriptions [iMajor][iMinor]; } return String.Empty; } public virtual string GetUnknownRequestHeader (string name) { return null; } [CLSCompliant(false)] public virtual string [][] GetUnknownRequestHeaders () { return null; } public abstract string GetUriPath (); public virtual long GetUrlContextID () { return 0; } public virtual IntPtr GetUserToken () { throw new NotSupportedException (); } public virtual IntPtr GetVirtualPathToken () { throw new NotSupportedException (); } public bool HasEntityBody () { string sContentLength = GetKnownRequestHeader (HeaderContentLength); if (null != sContentLength && sContentLength != "0") return true; if (null != GetKnownRequestHeader (HeaderTransferEncoding)) return true; if (null != GetPreloadedEntityBody () || IsEntireEntityBodyIsPreloaded ()) return true; return false; } public virtual bool HeadersSent () { return true; } public virtual bool IsClientConnected () { return true; } public virtual bool IsEntireEntityBodyIsPreloaded () { return false; } public virtual bool IsSecure () { return false; } public virtual string MapPath (string virtualPath) { return null; } public virtual int ReadEntityBody (byte[] buffer, int size) { return 0; } public virtual void SendCalculatedContentLength (int contentLength) { } public abstract void SendKnownResponseHeader (int index, string value); public abstract void SendResponseFromFile (IntPtr handle, long offset, long length); public abstract void SendResponseFromFile (string filename, long offset, long length); public abstract void SendResponseFromMemory (byte [] data, int length); public virtual void SendResponseFromMemory (IntPtr data, int length) { if (length <= 0) return; byte [] dataBytes = new byte [length]; Marshal.Copy (data, dataBytes, 0, length); SendResponseFromMemory (dataBytes, length); } public abstract void SendStatus (int statusCode, string statusDescription); public abstract void SendUnknownResponseHeader (string name, string value); public virtual void SetEndOfSendNotification (EndOfSendNotification callback, object extraData) { } public virtual string MachineConfigPath { get { return null; } } public virtual string MachineInstallDirectory { get { return null; } } } }