HttpWebRequest.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. //
  2. // System.Net.HttpWebRequest
  3. //
  4. // Author:
  5. // Lawrence Pit ([email protected])
  6. //
  7. using System;
  8. using System.Collections;
  9. using System.IO;
  10. using System.Runtime.Serialization;
  11. using System.Security.Cryptography.X509Certificates;
  12. namespace System.Net
  13. {
  14. [Serializable]
  15. public class HttpWebRequest : WebRequest, ISerializable
  16. {
  17. private Uri requestUri;
  18. private Uri actualUri = null;
  19. private bool allowAutoRedirect = true;
  20. private bool allowBuffering = true;
  21. private X509CertificateCollection certificate = null;
  22. private string connectionGroup = null;
  23. private long contentLength = -1;
  24. private HttpContinueDelegate continueDelegate = null;
  25. private CookieContainer cookieContainer = null;
  26. private ICredentials credentials = null;
  27. private bool haveResponse = false;
  28. private WebHeaderCollection webHeaders;
  29. private bool keepAlive = true;
  30. private int maxAutoRedirect = 50;
  31. private string mediaType = String.Empty;
  32. private string method;
  33. private bool pipelined = true;
  34. private bool preAuthenticate = false;
  35. private Version version;
  36. private IWebProxy proxy;
  37. private bool sendChunked = false;
  38. private ServicePoint servicePoint = null;
  39. private int timeout = System.Threading.Timeout.Infinite;
  40. private bool requestStarted = false;
  41. // Constructors
  42. internal HttpWebRequest (Uri uri)
  43. {
  44. this.requestUri = uri;
  45. this.actualUri = uri;
  46. this.webHeaders = new WebHeaderCollection (true);
  47. // this.webHeaders.SetInternal ("Host", uri.Authority);
  48. // this.webHeaders.SetInternal ("Date", DateTime.Now.ToUniversalTime ().ToString ("r", null));
  49. // this.webHeaders.SetInternal ("Expect", "100-continue");
  50. this.method = "GET";
  51. this.version = HttpVersion.Version11;
  52. this.proxy = GlobalProxySelection.Select;
  53. }
  54. [MonoTODO]
  55. protected HttpWebRequest (SerializationInfo serializationInfo, StreamingContext streamingContext)
  56. {
  57. throw new NotImplementedException ();
  58. }
  59. // Properties
  60. public string Accept {
  61. get { return webHeaders ["Accept"]; }
  62. set {
  63. CheckRequestStarted ();
  64. webHeaders.SetInternal ("Accept", value);
  65. }
  66. }
  67. public Uri Address {
  68. get { return actualUri; }
  69. }
  70. public bool AllowAutoRedirect {
  71. get { return allowAutoRedirect; }
  72. set { this.allowAutoRedirect = value; }
  73. }
  74. public bool AllowWriteStreamBuffering {
  75. get { return allowBuffering; }
  76. set { this.allowBuffering = value; }
  77. }
  78. public X509CertificateCollection ClientCertificates {
  79. get { return certificate; }
  80. }
  81. public string Connection {
  82. get { return webHeaders ["Connection"]; }
  83. set {
  84. CheckRequestStarted ();
  85. string val = value;
  86. if (val != null)
  87. val = val.Trim ().ToLower ();
  88. if (val == null || val.Length == 0) {
  89. webHeaders.RemoveInternal ("Connection");
  90. return;
  91. }
  92. if (val == "keep-alive" || val == "close")
  93. throw new ArgumentException ("value");
  94. if (KeepAlive && val.IndexOf ("keep-alive") == -1)
  95. value = value + ", Keep-Alive";
  96. webHeaders.SetInternal ("Connection", value);
  97. }
  98. }
  99. public override string ConnectionGroupName {
  100. get { return connectionGroup; }
  101. set { connectionGroup = value; }
  102. }
  103. public override long ContentLength {
  104. get { return contentLength; }
  105. set {
  106. CheckRequestStarted ();
  107. if (value < 0)
  108. throw new ArgumentException ("value");
  109. contentLength = value;
  110. webHeaders.SetInternal ("Content-Length", Convert.ToString (value));
  111. }
  112. }
  113. public override string ContentType {
  114. get { return webHeaders ["Content-Type"]; }
  115. set {
  116. CheckRequestStarted ();
  117. if (value == null || value.Trim().Length == 0) {
  118. webHeaders.RemoveInternal ("Content-Type");
  119. return;
  120. }
  121. webHeaders.SetInternal ("Content-Type", value);
  122. }
  123. }
  124. public HttpContinueDelegate ContinueDelegate {
  125. get { return continueDelegate; }
  126. set { continueDelegate = value; }
  127. }
  128. public CookieContainer CookieContainer {
  129. get { return cookieContainer; }
  130. set { cookieContainer = value; }
  131. }
  132. public override ICredentials Credentials {
  133. get { return credentials; }
  134. set { credentials = value; }
  135. }
  136. public string Expect {
  137. get { return webHeaders ["Expect"]; }
  138. set {
  139. CheckRequestStarted ();
  140. string val = value;
  141. if (val != null)
  142. val = val.Trim ().ToLower ();
  143. if (val == null || val.Length == 0) {
  144. webHeaders.RemoveInternal ("Expect");
  145. return;
  146. }
  147. if (val == "100-continue")
  148. throw new ArgumentException ("value");
  149. webHeaders.SetInternal ("Expect", value);
  150. }
  151. }
  152. public bool HaveResponse {
  153. get { return haveResponse; }
  154. }
  155. public override WebHeaderCollection Headers {
  156. get { return webHeaders; }
  157. set {
  158. CheckRequestStarted ();
  159. WebHeaderCollection newHeaders = new WebHeaderCollection (true);
  160. int count = value.Count;
  161. for (int i = 0; i < count; i++)
  162. newHeaders.Add (value.GetKey (i), value.Get (i));
  163. webHeaders = newHeaders;
  164. }
  165. }
  166. public DateTime IfModifiedSince {
  167. get {
  168. string str = webHeaders ["If-Modified-Since"];
  169. if (str == null)
  170. return DateTime.Now;
  171. // TODO:
  172. // HTTP-date = rfc1123-date | rfc850-date | asctime-date
  173. // for now, assume rfc1123 only
  174. try {
  175. DateTime dt = DateTime.ParseExact (str, "r", null);
  176. return dt;
  177. } catch (Exception) {
  178. return DateTime.Now;
  179. }
  180. }
  181. set {
  182. CheckRequestStarted ();
  183. // rfc-1123 pattern
  184. webHeaders.SetInternal ("If-Modified-Since",
  185. value.ToUniversalTime ().ToString ("r", null));
  186. // TODO: check last param when using different locale
  187. }
  188. }
  189. public bool KeepAlive {
  190. get {
  191. CheckRequestStarted ();
  192. return keepAlive;
  193. }
  194. set {
  195. CheckRequestStarted ();
  196. keepAlive = value;
  197. }
  198. }
  199. public int MaximumAutomaticRedirections {
  200. get { return maxAutoRedirect; }
  201. set {
  202. if (value < 0)
  203. throw new ArgumentException ("value");
  204. maxAutoRedirect = value;
  205. }
  206. }
  207. public string MediaType {
  208. get { return mediaType; }
  209. set {
  210. CheckRequestStarted ();
  211. mediaType = value;
  212. }
  213. }
  214. public override string Method {
  215. get { return this.method; }
  216. set {
  217. CheckRequestStarted ();
  218. value = value.ToUpper ();
  219. if (value == null ||
  220. (value != "GET" &&
  221. value != "HEADER" &&
  222. value != "POST" &&
  223. value != "PUT" &&
  224. value != "DELETE" &&
  225. value != "TRACE" &&
  226. value != "OPTIONS"))
  227. throw new ArgumentException ("not a valid method");
  228. if (contentLength != -1 &&
  229. value != "POST" &&
  230. value != "PUT")
  231. throw new ArgumentException ("method must be PUT or POST");
  232. method = value;
  233. }
  234. }
  235. public bool Pipelined {
  236. get { return pipelined; }
  237. set { this.pipelined = value; }
  238. }
  239. public override bool PreAuthenticate {
  240. get { return preAuthenticate; }
  241. set { preAuthenticate = value; }
  242. }
  243. public Version ProtocolVersion {
  244. get { return version; }
  245. set {
  246. if (value != HttpVersion.Version10 && value != HttpVersion.Version11)
  247. throw new ArgumentException ("value");
  248. version = (Version) value;
  249. }
  250. }
  251. public override IWebProxy Proxy {
  252. get { return proxy; }
  253. set {
  254. if (value == null)
  255. throw new ArgumentNullException ("value");
  256. proxy = value;
  257. }
  258. }
  259. public string Referer {
  260. get { return webHeaders ["Referer" ]; }
  261. set {
  262. CheckRequestStarted ();
  263. if (value == null || value.Trim().Length == 0) {
  264. webHeaders.RemoveInternal ("Referer");
  265. return;
  266. }
  267. webHeaders.SetInternal ("Referer", value);
  268. }
  269. }
  270. public override Uri RequestUri {
  271. get { return requestUri; }
  272. }
  273. public bool SendChunked {
  274. get { return sendChunked; }
  275. set {
  276. CheckRequestStarted ();
  277. sendChunked = value;
  278. }
  279. }
  280. public ServicePoint ServicePoint {
  281. get { return servicePoint; }
  282. }
  283. public override int Timeout {
  284. get { return timeout; }
  285. set { timeout = value; }
  286. }
  287. public string TransferEncoding {
  288. get { return webHeaders ["Transfer-Encoding"]; }
  289. set {
  290. CheckRequestStarted ();
  291. if (!sendChunked)
  292. throw new InvalidOperationException ("SendChunked must be True");
  293. string val = value;
  294. if (val != null)
  295. val = val.Trim ().ToLower ();
  296. if (val == null || val.Length == 0) {
  297. webHeaders.RemoveInternal ("Transfer-Encoding");
  298. return;
  299. }
  300. if (val == "chunked")
  301. throw new ArgumentException ("Cannot set value to Chunked");
  302. webHeaders.SetInternal ("Transfer-Encoding", value);
  303. }
  304. }
  305. public string UserAgent {
  306. get { return webHeaders ["User-Agent"]; }
  307. set { webHeaders.SetInternal ("User-Agent", value); }
  308. }
  309. // Methods
  310. [MonoTODO]
  311. public override void Abort()
  312. {
  313. throw new NotImplementedException ();
  314. }
  315. public void AddRange (int range)
  316. {
  317. AddRange ("bytes", range);
  318. }
  319. public void AddRange (int from, int to)
  320. {
  321. AddRange ("bytes", from, to);
  322. }
  323. public void AddRange (string rangeSpecifier, int range)
  324. {
  325. if (rangeSpecifier == null)
  326. throw new ArgumentNullException ("rangeSpecifier");
  327. string value = webHeaders ["Range"];
  328. if (value == null || value.Length == 0)
  329. value = rangeSpecifier + "=";
  330. else if (value.ToLower ().StartsWith (rangeSpecifier.ToLower () + "="))
  331. value += ",";
  332. else
  333. throw new InvalidOperationException ("rangeSpecifier");
  334. webHeaders.SetInternal ("Range", value + range);
  335. }
  336. public void AddRange (string rangeSpecifier, int from, int to)
  337. {
  338. if (rangeSpecifier == null)
  339. throw new ArgumentNullException ("rangeSpecifier");
  340. if (from < 0 || to < 0 || from > to)
  341. throw new ArgumentOutOfRangeException ();
  342. string value = webHeaders ["Range"];
  343. if (value == null || value.Length == 0)
  344. value = rangeSpecifier + "=";
  345. else if (value.ToLower ().StartsWith (rangeSpecifier.ToLower () + "="))
  346. value += ",";
  347. else
  348. throw new InvalidOperationException ("rangeSpecifier");
  349. webHeaders.SetInternal ("Range", value + from + "-" + to);
  350. }
  351. [MonoTODO]
  352. public override IAsyncResult BeginGetRequestStream (AsyncCallback callback, object state)
  353. {
  354. if (!method.Equals ("PUT") && !method.Equals ("POST"))
  355. throw new ProtocolViolationException ("Invalid method");
  356. // if (putting)
  357. // throw new WebException ("Stream already open");
  358. /*
  359. HttpWebRequestAsyncResult requestResult = new HttpWebRequestAsyncResult (stateObject);
  360. Worker worker = new Worker (hostName, requestCallback, requestResult);
  361. Thread child = new Thread (new ThreadStart (worker.GetRequestStream));
  362. child.Start();
  363. return requestResult;
  364. */
  365. throw new NotImplementedException ();
  366. }
  367. [MonoTODO]
  368. public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
  369. {
  370. throw new NotImplementedException ();
  371. }
  372. [MonoTODO]
  373. public override Stream EndGetRequestStream (IAsyncResult asyncResult)
  374. {
  375. throw new NotImplementedException ();
  376. }
  377. [MonoTODO]
  378. public override WebResponse EndGetResponse (IAsyncResult asyncResult)
  379. {
  380. throw new NotImplementedException ();
  381. }
  382. public override int GetHashCode ()
  383. {
  384. return base.GetHashCode ();
  385. }
  386. [MonoTODO]
  387. public override Stream GetRequestStream()
  388. {
  389. throw new NotImplementedException ();
  390. }
  391. [MonoTODO]
  392. public override WebResponse GetResponse()
  393. {
  394. throw new NotImplementedException ();
  395. }
  396. [MonoTODO]
  397. void ISerializable.GetObjectData (SerializationInfo serializationInfo,
  398. StreamingContext streamingContext)
  399. {
  400. throw new NotImplementedException ();
  401. }
  402. // Private Methods
  403. private void CheckRequestStarted ()
  404. {
  405. if (requestStarted)
  406. throw new InvalidOperationException ("request started");
  407. }
  408. // Private Classes
  409. }
  410. }