HttpWorkerRequest.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. //
  2. // System.Web.HttoWorkerRequest.cs
  3. //
  4. // Author:
  5. // Miguel de Icaza ([email protected])
  6. //
  7. //
  8. // Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. using System.Collections;
  30. using System.Collections.Generic;
  31. using System.Collections.Specialized;
  32. using System.Runtime.InteropServices;
  33. using System.Security.Permissions;
  34. using System.Web.UI;
  35. namespace System.Web
  36. {
  37. // CAS
  38. [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  39. [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  40. // attributes
  41. [ComVisible (false)]
  42. public abstract partial class HttpWorkerRequest
  43. {
  44. public delegate void EndOfSendNotification (HttpWorkerRequest wr, object extraData);
  45. public const int HeaderCacheControl = 0;
  46. public const int HeaderConnection = 1;
  47. public const int HeaderDate = 2;
  48. public const int HeaderKeepAlive = 3;
  49. public const int HeaderPragma = 4;
  50. public const int HeaderTrailer = 5;
  51. public const int HeaderTransferEncoding = 6;
  52. public const int HeaderUpgrade = 7;
  53. public const int HeaderVia = 8;
  54. public const int HeaderWarning = 9;
  55. public const int HeaderAllow = 10;
  56. public const int HeaderContentLength = 11;
  57. public const int HeaderContentType = 12;
  58. public const int HeaderContentEncoding = 13;
  59. public const int HeaderContentLanguage = 14;
  60. public const int HeaderContentLocation = 15;
  61. public const int HeaderContentMd5 = 16;
  62. public const int HeaderContentRange = 17;
  63. public const int HeaderExpires = 18;
  64. public const int HeaderLastModified = 19;
  65. public const int HeaderAccept = 20;
  66. public const int HeaderAcceptCharset = 21;
  67. public const int HeaderAcceptEncoding = 22;
  68. public const int HeaderAcceptLanguage = 23;
  69. public const int HeaderAuthorization = 24;
  70. public const int HeaderCookie = 25;
  71. public const int HeaderExpect = 26;
  72. public const int HeaderFrom = 27;
  73. public const int HeaderHost = 28;
  74. public const int HeaderIfMatch = 29;
  75. public const int HeaderIfModifiedSince = 30;
  76. public const int HeaderIfNoneMatch = 31;
  77. public const int HeaderIfRange = 32;
  78. public const int HeaderIfUnmodifiedSince = 33;
  79. public const int HeaderMaxForwards = 34;
  80. public const int HeaderProxyAuthorization = 35;
  81. public const int HeaderReferer = 36;
  82. public const int HeaderRange = 37;
  83. public const int HeaderTe = 38;
  84. public const int HeaderUserAgent = 39;
  85. public const int RequestHeaderMaximum = 40;
  86. public const int HeaderAcceptRanges = 20;
  87. public const int HeaderAge = 21;
  88. public const int HeaderEtag = 22;
  89. public const int HeaderLocation = 23;
  90. public const int HeaderProxyAuthenticate = 24;
  91. public const int HeaderRetryAfter = 25;
  92. public const int HeaderServer = 26;
  93. public const int HeaderSetCookie = 27;
  94. public const int HeaderVary = 28;
  95. public const int HeaderWwwAuthenticate = 29;
  96. public const int ResponseHeaderMaximum = 30;
  97. public const int ReasonResponseCacheMiss = 0;
  98. public const int ReasonFileHandleCacheMiss = 1;
  99. public const int ReasonCachePolicy = 2;
  100. public const int ReasonCacheSecurity = 3;
  101. public const int ReasonClientDisconnect = 4;
  102. public const int ReasonDefault = 0;
  103. static readonly Dictionary <string, int> RequestHeaderIndexer;
  104. static readonly Dictionary <string, int> ResponseHeaderIndexer;
  105. static HttpWorkerRequest ()
  106. {
  107. RequestHeaderIndexer = new Dictionary <string, int> (StringComparer.OrdinalIgnoreCase);
  108. for (int i = 0; i < RequestHeaderMaximum; i++)
  109. RequestHeaderIndexer.Add (GetKnownRequestHeaderName(i), i);
  110. ResponseHeaderIndexer = new Dictionary <string, int> (StringComparer.OrdinalIgnoreCase);
  111. for (int i = 0; i < ResponseHeaderMaximum; i++)
  112. ResponseHeaderIndexer.Add (GetKnownResponseHeaderName(i), i);
  113. }
  114. bool started_internally;
  115. internal bool StartedInternally {
  116. get { return started_internally; }
  117. set { started_internally = value; }
  118. }
  119. public virtual string MachineConfigPath {
  120. get {
  121. return null;
  122. }
  123. }
  124. public virtual string MachineInstallDirectory {
  125. get {
  126. return null;
  127. }
  128. }
  129. public virtual Guid RequestTraceIdentifier {
  130. get { return Guid.Empty; }
  131. }
  132. public virtual string RootWebConfigPath {
  133. get { return null; }
  134. }
  135. public virtual void CloseConnection ()
  136. {
  137. }
  138. public virtual string GetAppPath ()
  139. {
  140. return null;
  141. }
  142. public virtual string GetAppPathTranslated ()
  143. {
  144. return null;
  145. }
  146. public virtual string GetAppPoolID ()
  147. {
  148. return null;
  149. }
  150. public virtual long GetBytesRead ()
  151. {
  152. return 0;
  153. }
  154. public virtual string GetFilePath ()
  155. {
  156. return null;
  157. }
  158. public virtual string GetFilePathTranslated ()
  159. {
  160. return null;
  161. }
  162. public virtual string GetKnownRequestHeader (int index)
  163. {
  164. return null;
  165. }
  166. public virtual string GetPathInfo ()
  167. {
  168. return "";
  169. }
  170. public virtual byte [] GetPreloadedEntityBody ()
  171. {
  172. return null;
  173. }
  174. public virtual int GetPreloadedEntityBody (byte[] buffer, int offset)
  175. {
  176. return 0;
  177. }
  178. public virtual int GetPreloadedEntityBodyLength ()
  179. {
  180. return 0;
  181. }
  182. public virtual string GetProtocol ()
  183. {
  184. if (IsSecure ())
  185. return "https";
  186. else
  187. return "http";
  188. }
  189. public virtual byte [] GetQueryStringRawBytes ()
  190. {
  191. return null;
  192. }
  193. public virtual string GetRemoteName ()
  194. {
  195. return GetRemoteAddress ();
  196. }
  197. public virtual int GetRequestReason ()
  198. {
  199. return 0;
  200. }
  201. public virtual string GetServerName ()
  202. {
  203. return GetLocalAddress ();
  204. }
  205. public virtual string GetServerVariable (string name)
  206. {
  207. return null;
  208. }
  209. public virtual int GetTotalEntityBodyLength ()
  210. {
  211. return 0;
  212. }
  213. public virtual string GetUnknownRequestHeader (string name)
  214. {
  215. return null;
  216. }
  217. [CLSCompliant (false)]
  218. public virtual string [][] GetUnknownRequestHeaders ()
  219. {
  220. return null;
  221. }
  222. public virtual IntPtr GetUserToken ()
  223. {
  224. return IntPtr.Zero;
  225. }
  226. public bool HasEntityBody ()
  227. {
  228. // TODO this is not virtual.
  229. return false;
  230. }
  231. public virtual bool HeadersSent ()
  232. {
  233. return true;
  234. }
  235. public virtual bool IsClientConnected ()
  236. {
  237. return true;
  238. }
  239. public virtual bool IsEntireEntityBodyIsPreloaded ()
  240. {
  241. return false;
  242. }
  243. public virtual bool IsSecure ()
  244. {
  245. return false;
  246. }
  247. public virtual string MapPath (string virtualPath)
  248. {
  249. return null;
  250. }
  251. public virtual int ReadEntityBody (byte [] buffer, int size)
  252. {
  253. return 0;
  254. }
  255. public virtual int ReadEntityBody (byte [] buffer, int offset, int size)
  256. {
  257. byte[] temp = new byte [size];
  258. int n = ReadEntityBody (temp, size);
  259. if(n > 0)
  260. Array.Copy (temp, 0, buffer, offset, n);
  261. return n;
  262. }
  263. public virtual void SendCalculatedContentLength (long contentLength)
  264. {
  265. SendCalculatedContentLength ((int)contentLength);
  266. }
  267. public virtual void SendCalculatedContentLength (int contentLength)
  268. {
  269. // apparently does nothing in MS.NET
  270. }
  271. #if !TARGET_JVM
  272. public virtual void SendResponseFromMemory (IntPtr data, int length)
  273. {
  274. if (data != IntPtr.Zero) {
  275. byte [] copy = new byte [length];
  276. Marshal.Copy (data, copy, 0, length);
  277. SendResponseFromMemory (copy, length);
  278. }
  279. }
  280. #endif
  281. public virtual void SetEndOfSendNotification (HttpWorkerRequest.EndOfSendNotification callback, object extraData)
  282. {
  283. }
  284. #region Abstract methods
  285. public abstract void EndOfRequest ();
  286. public abstract void FlushResponse (bool finalFlush);
  287. public abstract string GetHttpVerbName ();
  288. public abstract string GetHttpVersion ();
  289. public abstract string GetLocalAddress ();
  290. public abstract int GetLocalPort ();
  291. public abstract string GetQueryString ();
  292. public abstract string GetRawUrl ();
  293. public abstract string GetRemoteAddress ();
  294. public abstract int GetRemotePort ();
  295. public abstract string GetUriPath ();
  296. public abstract void SendKnownResponseHeader (int index, string value);
  297. public abstract void SendResponseFromFile (IntPtr handle, long offset, long length);
  298. public abstract void SendResponseFromFile (string filename, long offset, long length);
  299. public abstract void SendResponseFromMemory (byte [] data, int length);
  300. public abstract void SendStatus (int statusCode, string statusDescription);
  301. public abstract void SendUnknownResponseHeader (string name, string value);
  302. #endregion
  303. #region Static methods
  304. public static int GetKnownRequestHeaderIndex (string header)
  305. {
  306. int index;
  307. if (RequestHeaderIndexer.TryGetValue (header, out index))
  308. return index;
  309. return -1;
  310. }
  311. public static string GetKnownRequestHeaderName (int index)
  312. {
  313. switch (index){
  314. case HeaderCacheControl: return "Cache-Control";
  315. case HeaderConnection: return "Connection";
  316. case HeaderDate: return "Date";
  317. case HeaderKeepAlive: return "Keep-Alive";
  318. case HeaderPragma: return "Pragma";
  319. case HeaderTrailer: return "Trailer";
  320. case HeaderTransferEncoding: return "Transfer-Encoding";
  321. case HeaderUpgrade: return "Upgrade";
  322. case HeaderVia: return "Via";
  323. case HeaderWarning: return "Warning";
  324. case HeaderAllow: return "Allow";
  325. case HeaderContentLength: return "Content-Length";
  326. case HeaderContentType: return "Content-Type";
  327. case HeaderContentEncoding: return "Content-Encoding";
  328. case HeaderContentLanguage: return "Content-Language";
  329. case HeaderContentLocation: return "Content-Location";
  330. case HeaderContentMd5: return "Content-MD5";
  331. case HeaderContentRange: return "Content-Range";
  332. case HeaderExpires: return "Expires";
  333. case HeaderLastModified: return "Last-Modified";
  334. case HeaderAccept: return "Accept";
  335. case HeaderAcceptCharset: return "Accept-Charset";
  336. case HeaderAcceptEncoding: return "Accept-Encoding";
  337. case HeaderAcceptLanguage: return "Accept-Language";
  338. case HeaderAuthorization: return "Authorization";
  339. case HeaderCookie: return "Cookie";
  340. case HeaderExpect: return "Expect";
  341. case HeaderFrom: return "From";
  342. case HeaderHost: return "Host";
  343. case HeaderIfMatch: return "If-Match";
  344. case HeaderIfModifiedSince: return "If-Modified-Since";
  345. case HeaderIfNoneMatch: return "If-None-Match";
  346. case HeaderIfRange: return "If-Range";
  347. case HeaderIfUnmodifiedSince: return "If-Unmodified-Since";
  348. case HeaderMaxForwards: return "Max-Forwards";
  349. case HeaderProxyAuthorization: return "Proxy-Authorization";
  350. case HeaderReferer: return "Referer";
  351. case HeaderRange: return "Range";
  352. case HeaderTe: return "TE";
  353. case HeaderUserAgent: return "User-Agent";
  354. }
  355. throw new IndexOutOfRangeException ("index");
  356. }
  357. public static int GetKnownResponseHeaderIndex (string header)
  358. {
  359. int index;
  360. if (ResponseHeaderIndexer.TryGetValue (header, out index))
  361. return index;
  362. return -1;
  363. }
  364. public static string GetKnownResponseHeaderName (int index)
  365. {
  366. switch (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 HeaderAcceptRanges: return "Accept-Ranges";
  388. case HeaderAge: return "Age";
  389. case HeaderEtag: return "ETag";
  390. case HeaderLocation: return "Location";
  391. case HeaderProxyAuthenticate: return "Proxy-Authenticate";
  392. case HeaderRetryAfter: return "Retry-After";
  393. case HeaderServer: return "Server";
  394. case HeaderSetCookie: return "Set-Cookie";
  395. case HeaderVary: return "Vary";
  396. case HeaderWwwAuthenticate: return "WWW-Authenticate";
  397. }
  398. throw new IndexOutOfRangeException ("index");
  399. }
  400. public static string GetStatusDescription (int code)
  401. {
  402. switch (code){
  403. case 100: return "Continue";
  404. case 101: return "Switching Protocols";
  405. case 102: return "Processing";
  406. case 200: return "OK";
  407. case 201: return "Created";
  408. case 202: return "Accepted";
  409. case 203: return "Non-Authoritative Information";
  410. case 204: return "No Content";
  411. case 205: return "Reset Content";
  412. case 206: return "Partial Content";
  413. case 207: return "Multi-Status";
  414. case 300: return "Multiple Choices";
  415. case 301: return "Moved Permanently";
  416. case 302: return "Found";
  417. case 303: return "See Other";
  418. case 304: return "Not Modified";
  419. case 305: return "Use Proxy";
  420. case 307: return "Temporary Redirect";
  421. case 400: return "Bad Request";
  422. case 401: return "Unauthorized";
  423. case 402: return "Payment Required";
  424. case 403: return "Forbidden";
  425. case 404: return "Not Found";
  426. case 405: return "Method Not Allowed";
  427. case 406: return "Not Acceptable";
  428. case 407: return "Proxy Authentication Required";
  429. case 408: return "Request Timeout";
  430. case 409: return "Conflict";
  431. case 410: return "Gone";
  432. case 411: return "Length Required";
  433. case 412: return "Precondition Failed";
  434. case 413: return "Request Entity Too Large";
  435. case 414: return "Request-Uri Too Long";
  436. case 415: return "Unsupported Media Type";
  437. case 416: return "Requested Range Not Satisfiable";
  438. case 417: return "Expectation Failed";
  439. case 422: return "Unprocessable Entity";
  440. case 423: return "Locked";
  441. case 424: return "Failed Dependency";
  442. case 500: return "Internal Server Error";
  443. case 501: return "Not Implemented";
  444. case 502: return "Bad Gateway";
  445. case 503: return "Service Unavailable";
  446. case 504: return "Gateway Timeout";
  447. case 505: return "Http Version Not Supported";
  448. case 507: return "Insufficient Storage";
  449. }
  450. return "";
  451. }
  452. #endregion
  453. #region Internals
  454. //
  455. // These are exposed on the public API, but are for internal consumption
  456. //
  457. public virtual byte [] GetClientCertificate ()
  458. {
  459. return new byte [0];
  460. }
  461. public virtual byte [] GetClientCertificateBinaryIssuer ()
  462. {
  463. return new byte [0];
  464. }
  465. public virtual int GetClientCertificateEncoding ()
  466. {
  467. return 0;
  468. }
  469. public virtual byte [] GetClientCertificatePublicKey ()
  470. {
  471. return new byte [0];
  472. }
  473. public virtual DateTime GetClientCertificateValidFrom ()
  474. {
  475. return DateTime.Now;
  476. }
  477. public virtual DateTime GetClientCertificateValidUntil ()
  478. {
  479. return DateTime.Now;
  480. }
  481. public virtual long GetConnectionID ()
  482. {
  483. return 0;
  484. }
  485. public virtual long GetUrlContextID ()
  486. {
  487. return 0;
  488. }
  489. public virtual IntPtr GetVirtualPathToken ()
  490. {
  491. return IntPtr.Zero;
  492. }
  493. #endregion
  494. }
  495. }