HttpWorkerRequest.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. //
  2. // System.Web.HttpWorkerRequest
  3. //
  4. // Authors:
  5. // Patrik Torstensson ([email protected])
  6. // (constants from Bob Smith ([email protected]))
  7. // Gonzalo Paniagua Javier ([email protected])
  8. //
  9. // (c) Patrik Torstensson
  10. // (c) 2002 Ximian, Inc. (http://www.ximian.com)
  11. //
  12. using System;
  13. using System.Collections;
  14. using System.Runtime.InteropServices;
  15. namespace System.Web
  16. {
  17. public abstract class HttpWorkerRequest : IHttpMapPath
  18. {
  19. public delegate void EndOfSendNotification (HttpWorkerRequest wr, object extraData);
  20. public const int HeaderAccept = 20;
  21. public const int HeaderAcceptCharset = 21;
  22. public const int HeaderAcceptEncoding = 22;
  23. public const int HeaderAcceptLanguage = 23;
  24. public const int HeaderAcceptRanges = 20;
  25. public const int HeaderAge = 21;
  26. public const int HeaderAllow = 10;
  27. public const int HeaderAuthorization = 24;
  28. public const int HeaderCacheControl = 0;
  29. public const int HeaderConnection = 1;
  30. public const int HeaderContentEncoding = 13;
  31. public const int HeaderContentLanguage = 14;
  32. public const int HeaderContentLength = 11;
  33. public const int HeaderContentLocation = 15;
  34. public const int HeaderContentMd5 = 16;
  35. public const int HeaderContentRange = 17;
  36. public const int HeaderContentType = 12;
  37. public const int HeaderCookie = 25;
  38. public const int HeaderDate = 2;
  39. public const int HeaderEtag = 22;
  40. public const int HeaderExpect = 26;
  41. public const int HeaderExpires = 18;
  42. public const int HeaderFrom = 27;
  43. public const int HeaderHost = 28;
  44. public const int HeaderIfMatch = 29;
  45. public const int HeaderIfModifiedSince = 30;
  46. public const int HeaderIfNoneMatch = 31;
  47. public const int HeaderIfRange = 32;
  48. public const int HeaderIfUnmodifiedSince = 33;
  49. public const int HeaderKeepAlive = 3;
  50. public const int HeaderLastModified = 19;
  51. public const int HeaderLocation = 23;
  52. public const int HeaderMaxForwards = 34;
  53. public const int HeaderPragma = 4;
  54. public const int HeaderProxyAuthenticate = 24;
  55. public const int HeaderProxyAuthorization = 35;
  56. public const int HeaderRange = 37;
  57. public const int HeaderReferer = 36;
  58. public const int HeaderRetryAfter = 25;
  59. public const int HeaderServer = 26;
  60. public const int HeaderSetCookie = 27;
  61. public const int HeaderTe = 38;
  62. public const int HeaderTrailer = 5;
  63. public const int HeaderTransferEncoding = 6;
  64. public const int HeaderUpgrade = 7;
  65. public const int HeaderUserAgent = 39;
  66. public const int HeaderVary = 28;
  67. public const int HeaderVia = 8;
  68. public const int HeaderWarning = 9;
  69. public const int HeaderWwwAuthenticate = 29;
  70. public const int ReasonCachePolicy = 2;
  71. public const int ReasonCacheSecurity = 3;
  72. public const int ReasonClientDisconnect = 4;
  73. public const int ReasonDefault = 0;
  74. public const int ReasonFileHandleCacheMiss = 1;
  75. public const int ReasonResponseCacheMiss = 0;
  76. public const int RequestHeaderMaximum = 40;
  77. public const int ResponseHeaderMaximum = 30;
  78. static string [][] s_HttpStatusDescriptions;
  79. static string [] s_HttpRequestHeaderNames;
  80. static string [] s_HttpResponseHeaderNames;
  81. static Hashtable s_HttpResponseHeadersTable;
  82. static Hashtable s_HttpRequestHeaderTable;
  83. static HttpWorkerRequest ()
  84. {
  85. string [] sSubCodes;
  86. s_HttpStatusDescriptions = new string [6][];
  87. sSubCodes = new String [3];
  88. sSubCodes [0] = "Continue";
  89. sSubCodes [1] = "Switching Protocols";
  90. sSubCodes [2] = "Processing";
  91. s_HttpStatusDescriptions [1] = sSubCodes;
  92. sSubCodes = new String [8];
  93. sSubCodes [0] = "OK";
  94. sSubCodes [1] = "Created";
  95. sSubCodes [2] = "Accepted";
  96. sSubCodes [3] = "Non-Authoritative Information";
  97. sSubCodes [4] = "No Content";
  98. sSubCodes [5] = "Reset Content";
  99. sSubCodes [6] = "Partial Content";
  100. sSubCodes [7] = "Multi-Status";
  101. s_HttpStatusDescriptions [2] = sSubCodes;
  102. sSubCodes = new String [8];
  103. sSubCodes [0] = "Multiple Choices";
  104. sSubCodes [1] = "Moved Permanently";
  105. sSubCodes [2] = "Found";
  106. sSubCodes [3] = "See Other";
  107. sSubCodes [4] = "Not Modified";
  108. sSubCodes [5] = "Use Proxy";
  109. sSubCodes [6] = String.Empty;
  110. sSubCodes [7] = "Temporary Redirect";
  111. s_HttpStatusDescriptions [3] = sSubCodes;
  112. sSubCodes = new String [24];
  113. sSubCodes [0] = "Bad Request";
  114. sSubCodes [1] = "Unauthorized";
  115. sSubCodes [2] = "Payment Required";
  116. sSubCodes [3] = "Forbidden";
  117. sSubCodes [4] = "Not Found";
  118. sSubCodes [5] = "Method Not Allowed";
  119. sSubCodes [6] = "Not Acceptable";
  120. sSubCodes [7] = "Proxy Authentication Required";
  121. sSubCodes [8] = "Request Timeout";
  122. sSubCodes [9] = "Conflict";
  123. sSubCodes [10] = "Gone";
  124. sSubCodes [11] = "Length Required";
  125. sSubCodes [12] = "Precondition Failed";
  126. sSubCodes [13] = "Request Entity Too Large";
  127. sSubCodes [14] = "Request-Uri Too Long";
  128. sSubCodes [15] = "Unsupported Media Type";
  129. sSubCodes [16] = "Requested Range Not Satisfiable";
  130. sSubCodes [17] = "Expectation Failed";
  131. sSubCodes [18] = String.Empty;
  132. sSubCodes [19] = String.Empty;
  133. sSubCodes [20] = String.Empty;
  134. sSubCodes [21] = "Unprocessable Entity";
  135. sSubCodes [22] = "Locked";
  136. sSubCodes [23] = "Failed Dependency";
  137. s_HttpStatusDescriptions [4] = sSubCodes;
  138. sSubCodes = new String [8];
  139. sSubCodes [0] = "Internal Server Error";
  140. sSubCodes [1] = "Not Implemented";
  141. sSubCodes [2] = "Bad Gateway";
  142. sSubCodes [3] = "Service Unavailable";
  143. sSubCodes [4] = "Gateway Timeout";
  144. sSubCodes [5] = "Http Version Not Supported";
  145. sSubCodes [6] = String.Empty;
  146. sSubCodes [7] = "Insufficient Storage";
  147. s_HttpStatusDescriptions [5] = sSubCodes;
  148. InitLookupTables ();
  149. }
  150. protected HttpWorkerRequest ()
  151. {
  152. }
  153. static private void InitLookupTables ()
  154. {
  155. // Performance arrays
  156. s_HttpRequestHeaderNames = new string [40];
  157. s_HttpResponseHeaderNames = new string [30];
  158. // Lookup tables (name -> id)
  159. s_HttpRequestHeaderTable = new Hashtable ();
  160. s_HttpResponseHeadersTable = new Hashtable ();
  161. AddHeader (true, true, 0, "Cache-Control");
  162. AddHeader (true, true, 1, "Connection");
  163. AddHeader (true, true, 2, "Date");
  164. AddHeader (true, true, 3, "Keep-Alive");
  165. AddHeader (true, true, 4, "Pragma");
  166. AddHeader (true, true, 5, "Trailer");
  167. AddHeader (true, true, 6, "Transfer-Encoding");
  168. AddHeader (true, true, 7, "Upgrade");
  169. AddHeader (true, true, 8, "Via");
  170. AddHeader (true, true, 9, "Warning");
  171. AddHeader (true, true, 10, "Allow");
  172. AddHeader (true, true, 11, "Content-Length");
  173. AddHeader (true, true, 12, "Content-Type");
  174. AddHeader (true, true, 13, "Content-Encoding");
  175. AddHeader (true, true, 14, "Content-Language");
  176. AddHeader (true, true, 15, "Content-Location");
  177. AddHeader (true, true, 16, "Content-MD5");
  178. AddHeader (true, true, 17, "Content-Range");
  179. AddHeader (true, true, 18, "Expires");
  180. AddHeader (true, true, 19, "Last-Modified");
  181. AddHeader (true, false, 20, "Accept");
  182. AddHeader (true, false, 21, "Accept-Charset");
  183. AddHeader (true, false, 22, "Accept-Encoding");
  184. AddHeader (true, false, 23, "Accept-Language");
  185. AddHeader (true, false, 24, "Authorization");
  186. AddHeader (true, false, 25, "Cookie");
  187. AddHeader (true, false, 26, "Expect");
  188. AddHeader (true, false, 27, "From");
  189. AddHeader (true, false, 28, "Host");
  190. AddHeader (true, false, 29, "If-Match");
  191. AddHeader (true, false, 30, "If-Modified-Since");
  192. AddHeader (true, false, 31, "If-None-Match");
  193. AddHeader (true, false, 32, "If-Range");
  194. AddHeader (true, false, 33, "If-Unmodified-Since");
  195. AddHeader (true, false, 34, "Max-Forwards");
  196. AddHeader (true, false, 35, "Proxy-Authorization");
  197. AddHeader (true, false, 36, "Referer");
  198. AddHeader (true, false, 37, "Range");
  199. AddHeader (true, false, 38, "TE");
  200. AddHeader (true, false, 39, "User-Agent");
  201. AddHeader (false, true, 20, "Accept-Ranges");
  202. AddHeader (false, true, 21, "Age");
  203. AddHeader (false, true, 22, "ETag");
  204. AddHeader (false, true, 23, "Location");
  205. AddHeader (false, true, 24, "Proxy-Authenticate");
  206. AddHeader (false, true, 25, "Retry-After");
  207. AddHeader (false, true, 26, "Server");
  208. AddHeader (false, true, 27, "Set-Cookie");
  209. AddHeader (false, true, 28, "Vary");
  210. AddHeader (false, true, 29, "WWW-Authenticate");
  211. }
  212. static private void AddHeader(bool bRequest, bool bResponse, int iID, string sHeader)
  213. {
  214. if (bResponse) {
  215. s_HttpResponseHeaderNames [iID] = sHeader;
  216. s_HttpResponseHeadersTable.Add (sHeader, iID);
  217. }
  218. if (bRequest) {
  219. s_HttpRequestHeaderNames [iID] = sHeader;
  220. s_HttpRequestHeaderTable.Add (sHeader, iID);
  221. }
  222. }
  223. public virtual void CloseConnection ()
  224. {
  225. }
  226. public abstract void EndOfRequest ();
  227. public abstract void FlushResponse (bool finalFlush);
  228. public virtual string GetAppPath ()
  229. {
  230. return null;
  231. }
  232. public virtual string GetAppPathTranslated ()
  233. {
  234. return null;
  235. }
  236. public virtual string GetAppPoolID ()
  237. {
  238. return null;
  239. }
  240. public virtual long GetBytesRead ()
  241. {
  242. return 0;
  243. }
  244. public virtual byte[] GetClientCertificate ()
  245. {
  246. return new byte[0];
  247. }
  248. public virtual byte[] GetClientCertificateBinaryIssuer ()
  249. {
  250. return new byte[0];
  251. }
  252. public virtual int GetClientCertificateEncoding ()
  253. {
  254. return 0;
  255. }
  256. public virtual byte[] GetClientCertificatePublicKey ()
  257. {
  258. return new byte[0];
  259. }
  260. public virtual DateTime GetClientCertificateValidFrom ()
  261. {
  262. return DateTime.Now;
  263. }
  264. public virtual DateTime GetClientCertificateValidUntil ()
  265. {
  266. return DateTime.Now;
  267. }
  268. public virtual long GetConnectionID ()
  269. {
  270. return 0;
  271. }
  272. public virtual string GetFilePath ()
  273. {
  274. return GetUriPath();
  275. }
  276. public virtual string GetFilePathTranslated ()
  277. {
  278. return null;
  279. }
  280. public abstract string GetHttpVerbName ();
  281. public abstract string GetHttpVersion ();
  282. public virtual string GetKnownRequestHeader (int index)
  283. {
  284. return null;
  285. }
  286. public static int GetKnownRequestHeaderIndex (string header)
  287. {
  288. object index;
  289. index = s_HttpRequestHeaderTable [header];
  290. if (null != index)
  291. return (Int32) index;
  292. return -1;
  293. }
  294. public static string GetKnownRequestHeaderName (int index)
  295. {
  296. return s_HttpRequestHeaderNames [index];
  297. }
  298. public static int GetKnownResponseHeaderIndex (string header)
  299. {
  300. object index;
  301. index = s_HttpResponseHeadersTable [header];
  302. if (null != index)
  303. return (Int32) index;
  304. return -1;
  305. }
  306. public static string GetKnownResponseHeaderName(int index)
  307. {
  308. return s_HttpResponseHeaderNames [index];
  309. }
  310. public abstract string GetLocalAddress ();
  311. public abstract int GetLocalPort ();
  312. public virtual string GetPathInfo ()
  313. {
  314. return String.Empty;
  315. }
  316. public virtual byte [] GetPreloadedEntityBody ()
  317. {
  318. return null;
  319. }
  320. public virtual string GetProtocol ()
  321. {
  322. return (IsSecure ()) ? "https" : "http";
  323. }
  324. public abstract string GetQueryString ();
  325. public virtual byte[] GetQueryStringRawBytes ()
  326. {
  327. return null;
  328. }
  329. public abstract string GetRawUrl ();
  330. public abstract string GetRemoteAddress ();
  331. public virtual string GetRemoteName ()
  332. {
  333. return GetRemoteAddress();
  334. }
  335. public abstract int GetRemotePort ();
  336. public virtual int GetRequestReason ()
  337. {
  338. return 0;
  339. }
  340. public virtual string GetServerName ()
  341. {
  342. return GetLocalAddress();
  343. }
  344. public virtual string GetServerVariable (string name)
  345. {
  346. return null;
  347. }
  348. public static string GetStatusDescription (int code)
  349. {
  350. if (code>= 100 && code < 600) {
  351. int iMajor = code / 100;
  352. int iMinor = code % 100;
  353. if (iMinor < (int) s_HttpStatusDescriptions [iMajor].Length)
  354. return s_HttpStatusDescriptions [iMajor][iMinor];
  355. }
  356. return String.Empty;
  357. }
  358. public virtual string GetUnknownRequestHeader (string name)
  359. {
  360. return null;
  361. }
  362. [CLSCompliant(false)]
  363. public virtual string [][] GetUnknownRequestHeaders ()
  364. {
  365. return null;
  366. }
  367. public abstract string GetUriPath ();
  368. public virtual long GetUrlContextID ()
  369. {
  370. return 0;
  371. }
  372. public virtual IntPtr GetUserToken ()
  373. {
  374. throw new NotSupportedException ();
  375. }
  376. public virtual IntPtr GetVirtualPathToken ()
  377. {
  378. throw new NotSupportedException ();
  379. }
  380. public bool HasEntityBody ()
  381. {
  382. string sContentLength = GetKnownRequestHeader (HeaderContentLength);
  383. if (null != sContentLength && sContentLength != "0")
  384. return true;
  385. if (null != GetKnownRequestHeader (HeaderTransferEncoding))
  386. return true;
  387. if (null != GetPreloadedEntityBody () || IsEntireEntityBodyIsPreloaded ())
  388. return true;
  389. return false;
  390. }
  391. public virtual bool HeadersSent ()
  392. {
  393. return true;
  394. }
  395. public virtual bool IsClientConnected ()
  396. {
  397. return true;
  398. }
  399. public virtual bool IsEntireEntityBodyIsPreloaded ()
  400. {
  401. return false;
  402. }
  403. public virtual bool IsSecure ()
  404. {
  405. return false;
  406. }
  407. public virtual string MapPath (string virtualPath)
  408. {
  409. return null;
  410. }
  411. public virtual int ReadEntityBody (byte[] buffer, int size)
  412. {
  413. return 0;
  414. }
  415. public virtual void SendCalculatedContentLength (int contentLength)
  416. {
  417. }
  418. public abstract void SendKnownResponseHeader (int index, string value);
  419. public abstract void SendResponseFromFile (IntPtr handle, long offset, long length);
  420. public abstract void SendResponseFromFile (string filename, long offset, long length);
  421. public abstract void SendResponseFromMemory (byte [] data, int length);
  422. public virtual void SendResponseFromMemory (IntPtr data, int length)
  423. {
  424. if (length <= 0)
  425. return;
  426. byte [] dataBytes = new byte [length];
  427. Marshal.Copy (data, dataBytes, 0, length);
  428. SendResponseFromMemory (dataBytes, length);
  429. }
  430. public abstract void SendStatus (int statusCode, string statusDescription);
  431. public abstract void SendUnknownResponseHeader (string name, string value);
  432. public virtual void SetEndOfSendNotification (EndOfSendNotification callback, object extraData)
  433. {
  434. }
  435. public virtual string MachineConfigPath
  436. {
  437. get {
  438. return null;
  439. }
  440. }
  441. public virtual string MachineInstallDirectory
  442. {
  443. get {
  444. return null;
  445. }
  446. }
  447. }
  448. }