WebClient.cs 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553
  1. //
  2. // System.Net.WebClient
  3. //
  4. // Authors:
  5. // Lawrence Pit ([email protected])
  6. // Gonzalo Paniagua Javier ([email protected])
  7. // Atsushi Enomoto ([email protected])
  8. // Miguel de Icaza ([email protected])
  9. //
  10. // Copyright 2003 Ximian, Inc. (http://www.ximian.com)
  11. // Copyright 2006, 2007 Novell, Inc. (http://www.novell.com)
  12. //
  13. //
  14. // Permission is hereby granted, free of charge, to any person obtaining
  15. // a copy of this software and associated documentation files (the
  16. // "Software"), to deal in the Software without restriction, including
  17. // without limitation the rights to use, copy, modify, merge, publish,
  18. // distribute, sublicense, and/or sell copies of the Software, and to
  19. // permit persons to whom the Software is furnished to do so, subject to
  20. // the following conditions:
  21. //
  22. // The above copyright notice and this permission notice shall be
  23. // included in all copies or substantial portions of the Software.
  24. //
  25. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  26. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  27. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  28. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  29. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  30. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  31. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  32. //
  33. //
  34. // Notes on CancelAsync and Async methods:
  35. //
  36. // WebClient.CancelAsync is implemented by calling Thread.Interrupt
  37. // in our helper thread. The various async methods have to cancel
  38. // any ongoing requests by calling request.Abort () at that point.
  39. // In a few places (UploadDataCore, UploadValuesCore,
  40. // UploadFileCore) we catch the ThreadInterruptedException and
  41. // abort the request there.
  42. //
  43. // Higher level routines (the async callbacks) also need to catch
  44. // the exception and raise the OnXXXXCompleted events there with
  45. // the "canceled" flag set to true.
  46. //
  47. // In a few other places where these helper routines are not used
  48. // (OpenReadAsync for example) catching the ThreadAbortException
  49. // also must abort the request.
  50. //
  51. // The Async methods currently differ in their implementation from
  52. // the .NET implementation in that we manually catch any other
  53. // exceptions and correctly raise the OnXXXXCompleted passing the
  54. // Exception that caused the problem. The .NET implementation
  55. // does not seem to have a mechanism to flag errors that happen
  56. // during downloads though. We do this because we still need to
  57. // catch the exception on these helper threads, or we would
  58. // otherwise kill the application (on the 2.x profile, uncaught
  59. // exceptions in threads terminate the application).
  60. //
  61. using System;
  62. using System.Collections.Specialized;
  63. using System.ComponentModel;
  64. using System.IO;
  65. using System.Runtime.InteropServices;
  66. using System.Runtime.Serialization;
  67. using System.Text;
  68. using System.Threading;
  69. #if NET_2_0
  70. using System.Net.Cache;
  71. #endif
  72. namespace System.Net
  73. {
  74. [ComVisible(true)]
  75. public
  76. #if !NET_2_0
  77. sealed
  78. #endif
  79. class WebClient : Component
  80. {
  81. static readonly string urlEncodedCType = "application/x-www-form-urlencoded";
  82. static byte [] hexBytes;
  83. ICredentials credentials;
  84. WebHeaderCollection headers;
  85. WebHeaderCollection responseHeaders;
  86. Uri baseAddress;
  87. string baseString;
  88. NameValueCollection queryString;
  89. bool is_busy;
  90. #if NET_2_0
  91. bool async;
  92. Thread async_thread;
  93. Encoding encoding = Encoding.Default;
  94. IWebProxy proxy;
  95. #endif
  96. // Constructors
  97. static WebClient ()
  98. {
  99. hexBytes = new byte [16];
  100. int index = 0;
  101. for (int i = '0'; i <= '9'; i++, index++)
  102. hexBytes [index] = (byte) i;
  103. for (int i = 'A'; i <= 'F'; i++, index++)
  104. hexBytes [index] = (byte) i;
  105. }
  106. public WebClient ()
  107. {
  108. }
  109. // Properties
  110. public string BaseAddress {
  111. get {
  112. if (baseString == null) {
  113. if (baseAddress == null)
  114. return "";
  115. }
  116. baseString = baseAddress.ToString ();
  117. return baseString;
  118. }
  119. set {
  120. if (value == null || value == "") {
  121. baseAddress = null;
  122. } else {
  123. baseAddress = new Uri (value);
  124. }
  125. }
  126. }
  127. #if NET_2_0
  128. static Exception GetMustImplement ()
  129. {
  130. return new NotImplementedException ();
  131. }
  132. [MonoTODO]
  133. public RequestCachePolicy CachePolicy
  134. {
  135. get {
  136. throw GetMustImplement ();
  137. }
  138. set {
  139. throw GetMustImplement ();
  140. }
  141. }
  142. [MonoTODO]
  143. public bool UseDefaultCredentials
  144. {
  145. get {
  146. throw GetMustImplement ();
  147. }
  148. set {
  149. throw GetMustImplement ();
  150. }
  151. }
  152. #endif
  153. public ICredentials Credentials {
  154. get { return credentials; }
  155. set { credentials = value; }
  156. }
  157. public WebHeaderCollection Headers {
  158. get {
  159. if (headers == null)
  160. headers = new WebHeaderCollection ();
  161. return headers;
  162. }
  163. set { headers = value; }
  164. }
  165. public NameValueCollection QueryString {
  166. get {
  167. if (queryString == null)
  168. queryString = new NameValueCollection ();
  169. return queryString;
  170. }
  171. set { queryString = value; }
  172. }
  173. public WebHeaderCollection ResponseHeaders {
  174. get { return responseHeaders; }
  175. }
  176. #if NET_2_0
  177. public Encoding Encoding {
  178. get { return encoding; }
  179. set {
  180. if (value == null)
  181. throw new ArgumentNullException ("value");
  182. encoding = value;
  183. }
  184. }
  185. public IWebProxy Proxy {
  186. get { return proxy; }
  187. set { proxy = value; }
  188. }
  189. #endif
  190. #if NET_2_0
  191. public bool IsBusy {
  192. get { return is_busy; }
  193. }
  194. #else
  195. bool IsBusy {
  196. get { return is_busy; }
  197. }
  198. #endif
  199. // Methods
  200. void CheckBusy ()
  201. {
  202. if (IsBusy)
  203. throw new NotSupportedException ("WebClient does not support conccurent I/O operations.");
  204. }
  205. void SetBusy ()
  206. {
  207. lock (this) {
  208. CheckBusy ();
  209. is_busy = true;
  210. }
  211. }
  212. // DownloadData
  213. public byte [] DownloadData (string address)
  214. {
  215. #if NET_2_0
  216. if (address == null)
  217. throw new ArgumentNullException ("address");
  218. #endif
  219. return DownloadData (CreateUri (address));
  220. }
  221. #if NET_2_0
  222. public
  223. #endif
  224. byte [] DownloadData (Uri address)
  225. {
  226. #if NET_2_0
  227. if (address == null)
  228. throw new ArgumentNullException ("address");
  229. #endif
  230. try {
  231. SetBusy ();
  232. #if NET_2_0
  233. async = false;
  234. #endif
  235. return DownloadDataCore (address, null);
  236. } finally {
  237. is_busy = false;
  238. }
  239. }
  240. byte [] DownloadDataCore (Uri address, object userToken)
  241. {
  242. WebRequest request = null;
  243. try {
  244. request = SetupRequest (address);
  245. WebResponse response = request.GetResponse ();
  246. Stream st = ProcessResponse (response);
  247. return ReadAll (st, (int) response.ContentLength, userToken);
  248. } catch (ThreadInterruptedException){
  249. if (request != null)
  250. request.Abort ();
  251. throw;
  252. } catch (Exception ex) {
  253. throw new WebException ("An error occurred " +
  254. "performing a WebClient request.", ex);
  255. }
  256. }
  257. // DownloadFile
  258. public void DownloadFile (string address, string fileName)
  259. {
  260. #if NET_2_0
  261. if (address == null)
  262. throw new ArgumentNullException ("address");
  263. #endif
  264. DownloadFile (CreateUri (address), fileName);
  265. }
  266. #if NET_2_0
  267. public
  268. #endif
  269. void DownloadFile (Uri address, string fileName)
  270. {
  271. #if NET_2_0
  272. if (address == null)
  273. throw new ArgumentNullException ("address");
  274. if (fileName == null)
  275. throw new ArgumentNullException ("fileName");
  276. #endif
  277. try {
  278. SetBusy ();
  279. #if NET_2_0
  280. async = false;
  281. #endif
  282. DownloadFileCore (address, fileName, null);
  283. } catch (Exception ex) {
  284. throw new WebException ("An error occurred " +
  285. "performing a WebClient request.", ex);
  286. } finally {
  287. is_busy = false;
  288. }
  289. }
  290. void DownloadFileCore (Uri address, string fileName, object userToken)
  291. {
  292. WebRequest request = null;
  293. using (FileStream f = new FileStream (fileName, FileMode.Create)) {
  294. try {
  295. request = SetupRequest (address);
  296. WebResponse response = request.GetResponse ();
  297. Stream st = ProcessResponse (response);
  298. int cLength = (int) response.ContentLength;
  299. int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
  300. byte [] buffer = new byte [length];
  301. int nread = 0;
  302. #if NET_2_0
  303. long notify_total = 0;
  304. #endif
  305. while ((nread = st.Read (buffer, 0, length)) != 0){
  306. #if NET_2_0
  307. if (async){
  308. notify_total += nread;
  309. OnDownloadProgressChanged (
  310. new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken));
  311. }
  312. #endif
  313. f.Write (buffer, 0, nread);
  314. }
  315. } catch (ThreadInterruptedException){
  316. if (request != null)
  317. request.Abort ();
  318. throw;
  319. }
  320. }
  321. }
  322. // OpenRead
  323. public Stream OpenRead (string address)
  324. {
  325. #if NET_2_0
  326. if (address == null)
  327. throw new ArgumentNullException ("address");
  328. #endif
  329. return OpenRead (CreateUri (address));
  330. }
  331. #if NET_2_0
  332. public
  333. #endif
  334. Stream OpenRead (Uri address)
  335. {
  336. #if NET_2_0
  337. if (address == null)
  338. throw new ArgumentNullException ("address");
  339. #endif
  340. WebRequest request = null;
  341. try {
  342. SetBusy ();
  343. #if NET_2_0
  344. async = false;
  345. #endif
  346. request = SetupRequest (address);
  347. WebResponse response = request.GetResponse ();
  348. return ProcessResponse (response);
  349. } catch (Exception ex) {
  350. throw new WebException ("An error occurred " +
  351. "performing a WebClient request.", ex);
  352. } finally {
  353. is_busy = false;
  354. }
  355. }
  356. // OpenWrite
  357. public Stream OpenWrite (string address)
  358. {
  359. #if NET_2_0
  360. if (address == null)
  361. throw new ArgumentNullException ("address");
  362. #endif
  363. return OpenWrite (CreateUri (address));
  364. }
  365. public Stream OpenWrite (string address, string method)
  366. {
  367. #if NET_2_0
  368. if (address == null)
  369. throw new ArgumentNullException ("address");
  370. #endif
  371. return OpenWrite (CreateUri (address), method);
  372. }
  373. #if NET_2_0
  374. public
  375. #endif
  376. Stream OpenWrite (Uri address)
  377. {
  378. return OpenWrite (address, (string) null);
  379. }
  380. #if NET_2_0
  381. public
  382. #endif
  383. Stream OpenWrite (Uri address, string method)
  384. {
  385. #if NET_2_0
  386. if (address == null)
  387. throw new ArgumentNullException ("address");
  388. #endif
  389. try {
  390. SetBusy ();
  391. #if NET_2_0
  392. async = false;
  393. #endif
  394. WebRequest request = SetupRequest (address, method, true);
  395. return request.GetRequestStream ();
  396. } catch (Exception ex) {
  397. throw new WebException ("An error occurred " +
  398. "performing a WebClient request.", ex);
  399. } finally {
  400. is_busy = false;
  401. }
  402. }
  403. private string DetermineMethod (Uri address, string method, bool is_upload)
  404. {
  405. if (method != null)
  406. return method;
  407. #if NET_2_0
  408. if (address.Scheme == Uri.UriSchemeFtp)
  409. return (is_upload) ? "STOR" : "RETR";
  410. #endif
  411. return (is_upload) ? "POST" : "GET";
  412. }
  413. // UploadData
  414. public byte [] UploadData (string address, byte [] data)
  415. {
  416. #if NET_2_0
  417. if (address == null)
  418. throw new ArgumentNullException ("address");
  419. #endif
  420. return UploadData (CreateUri (address), data);
  421. }
  422. public byte [] UploadData (string address, string method, byte [] data)
  423. {
  424. #if NET_2_0
  425. if (address == null)
  426. throw new ArgumentNullException ("address");
  427. #endif
  428. return UploadData (CreateUri (address), method, data);
  429. }
  430. #if NET_2_0
  431. public
  432. #endif
  433. byte [] UploadData (Uri address, byte [] data)
  434. {
  435. return UploadData (address, (string) null, data);
  436. }
  437. #if NET_2_0
  438. public
  439. #endif
  440. byte [] UploadData (Uri address, string method, byte [] data)
  441. {
  442. #if NET_2_0
  443. if (address == null)
  444. throw new ArgumentNullException ("address");
  445. if (data == null)
  446. throw new ArgumentNullException ("data");
  447. #endif
  448. try {
  449. SetBusy ();
  450. #if NET_2_0
  451. async = false;
  452. #endif
  453. return UploadDataCore (address, method, data, null);
  454. } catch (WebException) {
  455. throw;
  456. } catch (Exception ex) {
  457. throw new WebException ("An error occurred " +
  458. "performing a WebClient request.", ex);
  459. } finally {
  460. is_busy = false;
  461. }
  462. }
  463. byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
  464. {
  465. #if ONLY_1_1
  466. if (address == null)
  467. throw new ArgumentNullException ("address");
  468. if (data == null)
  469. throw new ArgumentNullException ("data");
  470. #endif
  471. WebRequest request = SetupRequest (address, method, true);
  472. try {
  473. int contentLength = data.Length;
  474. request.ContentLength = contentLength;
  475. using (Stream stream = request.GetRequestStream ()) {
  476. stream.Write (data, 0, contentLength);
  477. }
  478. WebResponse response = request.GetResponse ();
  479. Stream st = ProcessResponse (response);
  480. return ReadAll (st, (int) response.ContentLength, userToken);
  481. } catch (ThreadInterruptedException){
  482. if (request != null)
  483. request.Abort ();
  484. throw;
  485. }
  486. }
  487. // UploadFile
  488. public byte [] UploadFile (string address, string fileName)
  489. {
  490. #if NET_2_0
  491. if (address == null)
  492. throw new ArgumentNullException ("address");
  493. #endif
  494. return UploadFile (CreateUri (address), fileName);
  495. }
  496. #if NET_2_0
  497. public
  498. #endif
  499. byte [] UploadFile (Uri address, string fileName)
  500. {
  501. return UploadFile (address, (string) null, fileName);
  502. }
  503. public byte [] UploadFile (string address, string method, string fileName)
  504. {
  505. return UploadFile (CreateUri (address), method, fileName);
  506. }
  507. #if NET_2_0
  508. public
  509. #endif
  510. byte [] UploadFile (Uri address, string method, string fileName)
  511. {
  512. #if NET_2_0
  513. if (address == null)
  514. throw new ArgumentNullException ("address");
  515. if (fileName == null)
  516. throw new ArgumentNullException ("fileName");
  517. #endif
  518. try {
  519. SetBusy ();
  520. #if NET_2_0
  521. async = false;
  522. #endif
  523. return UploadFileCore (address, method, fileName, null);
  524. } catch (Exception ex) {
  525. throw new WebException ("An error occurred " +
  526. "performing a WebClient request.", ex);
  527. } finally {
  528. is_busy = false;
  529. }
  530. }
  531. byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
  532. {
  533. #if ONLY_1_1
  534. if (address == null)
  535. throw new ArgumentNullException ("address");
  536. #endif
  537. string fileCType = Headers ["Content-Type"];
  538. if (fileCType != null) {
  539. string lower = fileCType.ToLower ();
  540. if (lower.StartsWith ("multipart/"))
  541. throw new WebException ("Content-Type cannot be set to a multipart" +
  542. " type for this request.");
  543. } else {
  544. fileCType = "application/octet-stream";
  545. }
  546. string boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
  547. Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
  548. Stream reqStream = null;
  549. Stream fStream = null;
  550. byte [] resultBytes = null;
  551. fileName = Path.GetFullPath (fileName);
  552. WebRequest request = null;
  553. try {
  554. fStream = File.OpenRead (fileName);
  555. request = SetupRequest (address, method, true);
  556. reqStream = request.GetRequestStream ();
  557. byte [] realBoundary = Encoding.ASCII.GetBytes ("--" + boundary + "\r\n");
  558. reqStream.Write (realBoundary, 0, realBoundary.Length);
  559. string partHeaders = String.Format ("Content-Disposition: form-data; " +
  560. "name=\"file\"; filename=\"{0}\"\r\n" +
  561. "Content-Type: {1}\r\n\r\n",
  562. Path.GetFileName (fileName), fileCType);
  563. byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
  564. reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
  565. int nread;
  566. byte [] buffer = new byte [4096];
  567. while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
  568. reqStream.Write (buffer, 0, nread);
  569. reqStream.WriteByte ((byte) '\r');
  570. reqStream.WriteByte ((byte) '\n');
  571. reqStream.Write (realBoundary, 0, realBoundary.Length);
  572. reqStream.Close ();
  573. reqStream = null;
  574. WebResponse response = request.GetResponse ();
  575. Stream st = ProcessResponse (response);
  576. resultBytes = ReadAll (st, (int) response.ContentLength, userToken);
  577. } catch (ThreadInterruptedException){
  578. if (request != null)
  579. request.Abort ();
  580. throw;
  581. } finally {
  582. if (fStream != null)
  583. fStream.Close ();
  584. if (reqStream != null)
  585. reqStream.Close ();
  586. }
  587. return resultBytes;
  588. }
  589. public byte[] UploadValues (string address, NameValueCollection data)
  590. {
  591. #if NET_2_0
  592. if (address == null)
  593. throw new ArgumentNullException ("address");
  594. #endif
  595. return UploadValues (CreateUri (address), data);
  596. }
  597. public byte[] UploadValues (string address, string method, NameValueCollection data)
  598. {
  599. #if NET_2_0
  600. if (address == null)
  601. throw new ArgumentNullException ("address");
  602. #endif
  603. return UploadValues (CreateUri (address), method, data);
  604. }
  605. #if NET_2_0
  606. public
  607. #endif
  608. byte[] UploadValues (Uri address, NameValueCollection data)
  609. {
  610. return UploadValues (address, (string) null, data);
  611. }
  612. #if NET_2_0
  613. public
  614. #endif
  615. byte[] UploadValues (Uri address, string method, NameValueCollection data)
  616. {
  617. #if NET_2_0
  618. if (address == null)
  619. throw new ArgumentNullException ("address");
  620. if (data == null)
  621. throw new ArgumentNullException ("data");
  622. #endif
  623. try {
  624. SetBusy ();
  625. #if NET_2_0
  626. async = false;
  627. #endif
  628. return UploadValuesCore (address, method, data, null);
  629. } catch (Exception ex) {
  630. throw new WebException ("An error occurred " +
  631. "performing a WebClient request.", ex);
  632. } finally {
  633. is_busy = false;
  634. }
  635. }
  636. byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
  637. {
  638. #if ONLY_1_1
  639. if (data == null)
  640. throw new ArgumentNullException ("data");
  641. #endif
  642. string cType = Headers ["Content-Type"];
  643. if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
  644. throw new WebException ("Content-Type header cannot be changed from its default " +
  645. "value for this request.");
  646. Headers ["Content-Type"] = urlEncodedCType;
  647. WebRequest request = SetupRequest (uri, method, true);
  648. try {
  649. Stream rqStream = request.GetRequestStream ();
  650. MemoryStream tmpStream = new MemoryStream ();
  651. foreach (string key in data) {
  652. byte [] bytes = Encoding.ASCII.GetBytes (key);
  653. UrlEncodeAndWrite (tmpStream, bytes);
  654. tmpStream.WriteByte ((byte) '=');
  655. bytes = Encoding.ASCII.GetBytes (data [key]);
  656. UrlEncodeAndWrite (tmpStream, bytes);
  657. tmpStream.WriteByte ((byte) '&');
  658. }
  659. int length = (int) tmpStream.Length;
  660. if (length > 0)
  661. tmpStream.SetLength (--length); // remove trailing '&'
  662. byte [] buf = tmpStream.GetBuffer ();
  663. rqStream.Write (buf, 0, length);
  664. rqStream.Close ();
  665. tmpStream.Close ();
  666. WebResponse response = request.GetResponse ();
  667. Stream st = ProcessResponse (response);
  668. return ReadAll (st, (int) response.ContentLength, userToken);
  669. } catch (ThreadInterruptedException) {
  670. request.Abort ();
  671. throw;
  672. }
  673. }
  674. #if NET_2_0
  675. public string DownloadString (string address)
  676. {
  677. if (address == null)
  678. throw new ArgumentNullException ("address");
  679. return encoding.GetString (DownloadData (CreateUri (address)));
  680. }
  681. public string DownloadString (Uri address)
  682. {
  683. if (address == null)
  684. throw new ArgumentNullException ("address");
  685. return encoding.GetString (DownloadData (CreateUri (address)));
  686. }
  687. public string UploadString (string address, string data)
  688. {
  689. if (address == null)
  690. throw new ArgumentNullException ("address");
  691. if (data == null)
  692. throw new ArgumentNullException ("data");
  693. byte [] resp = UploadData (address, encoding.GetBytes (data));
  694. return encoding.GetString (resp);
  695. }
  696. public string UploadString (string address, string method, string data)
  697. {
  698. if (address == null)
  699. throw new ArgumentNullException ("address");
  700. if (data == null)
  701. throw new ArgumentNullException ("data");
  702. byte [] resp = UploadData (address, method, encoding.GetBytes (data));
  703. return encoding.GetString (resp);
  704. }
  705. public string UploadString (Uri address, string data)
  706. {
  707. if (address == null)
  708. throw new ArgumentNullException ("address");
  709. if (data == null)
  710. throw new ArgumentNullException ("data");
  711. byte [] resp = UploadData (address, encoding.GetBytes (data));
  712. return encoding.GetString (resp);
  713. }
  714. public string UploadString (Uri address, string method, string data)
  715. {
  716. if (address == null)
  717. throw new ArgumentNullException ("address");
  718. if (data == null)
  719. throw new ArgumentNullException ("data");
  720. byte [] resp = UploadData (address, method, encoding.GetBytes (data));
  721. return encoding.GetString (resp);
  722. }
  723. public event DownloadDataCompletedEventHandler DownloadDataCompleted;
  724. public event AsyncCompletedEventHandler DownloadFileCompleted;
  725. public event DownloadProgressChangedEventHandler DownloadProgressChanged;
  726. public event DownloadStringCompletedEventHandler DownloadStringCompleted;
  727. public event OpenReadCompletedEventHandler OpenReadCompleted;
  728. public event OpenWriteCompletedEventHandler OpenWriteCompleted;
  729. public event UploadDataCompletedEventHandler UploadDataCompleted;
  730. public event UploadFileCompletedEventHandler UploadFileCompleted;
  731. public event UploadProgressChangedEventHandler UploadProgressChanged;
  732. public event UploadStringCompletedEventHandler UploadStringCompleted;
  733. public event UploadValuesCompletedEventHandler UploadValuesCompleted;
  734. #endif
  735. Uri CreateUri (string address)
  736. {
  737. #if ONLY_1_1
  738. try {
  739. return MakeUri (address);
  740. } catch (Exception ex) {
  741. throw new WebException ("An error occurred " +
  742. "performing a WebClient request.", ex);
  743. }
  744. #else
  745. return MakeUri (address);
  746. #endif
  747. }
  748. #if NET_2_0
  749. Uri CreateUri (Uri address)
  750. {
  751. string query = address.Query;
  752. if (String.IsNullOrEmpty (query))
  753. query = GetQueryString (true);
  754. if (baseAddress == null && query == null)
  755. return address;
  756. if (baseAddress == null)
  757. return new Uri (address.ToString () + query, (query != null));
  758. if (query == null)
  759. return new Uri (baseAddress, address.ToString ());
  760. return new Uri (baseAddress, address.ToString () + query, (query != null));
  761. }
  762. #endif
  763. string GetQueryString (bool add_qmark)
  764. {
  765. if (queryString == null || queryString.Count == 0)
  766. return null;
  767. StringBuilder sb = new StringBuilder ();
  768. if (add_qmark)
  769. sb.Append ('?');
  770. foreach (string key in queryString)
  771. sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
  772. if (sb.Length != 0)
  773. sb.Length--; // removes last '&' or the '?' if empty.
  774. if (sb.Length == 0)
  775. return null;
  776. return sb.ToString ();
  777. }
  778. Uri MakeUri (string path)
  779. {
  780. string query = GetQueryString (true);
  781. if (baseAddress == null && query == null) {
  782. try {
  783. return new Uri (path);
  784. #if NET_2_0
  785. } catch (ArgumentNullException) {
  786. path = Path.GetFullPath (path);
  787. return new Uri ("file://" + path);
  788. #endif
  789. } catch (UriFormatException) {
  790. path = Path.GetFullPath (path);
  791. return new Uri ("file://" + path);
  792. }
  793. }
  794. if (baseAddress == null)
  795. return new Uri (path + query, (query != null));
  796. if (query == null)
  797. return new Uri (baseAddress, path);
  798. return new Uri (baseAddress, path + query, (query != null));
  799. }
  800. WebRequest SetupRequest (Uri uri)
  801. {
  802. WebRequest request = WebRequest.Create (uri);
  803. #if NET_2_0
  804. if (Proxy != null)
  805. request.Proxy = Proxy;
  806. #endif
  807. request.Credentials = credentials;
  808. // Special headers. These are properties of HttpWebRequest.
  809. // What do we do with other requests differnt from HttpWebRequest?
  810. if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
  811. HttpWebRequest req = (HttpWebRequest) request;
  812. string expect = headers ["Expect"];
  813. string contentType = headers ["Content-Type"];
  814. string accept = headers ["Accept"];
  815. string connection = headers ["Connection"];
  816. string userAgent = headers ["User-Agent"];
  817. string referer = headers ["Referer"];
  818. headers.RemoveInternal ("Expect");
  819. headers.RemoveInternal ("Content-Type");
  820. headers.RemoveInternal ("Accept");
  821. headers.RemoveInternal ("Connection");
  822. headers.RemoveInternal ("Referer");
  823. headers.RemoveInternal ("User-Agent");
  824. request.Headers = headers;
  825. if (expect != null && expect.Length > 0)
  826. req.Expect = expect;
  827. if (accept != null && accept.Length > 0)
  828. req.Accept = accept;
  829. if (contentType != null && contentType.Length > 0)
  830. req.ContentType = contentType;
  831. if (connection != null && connection.Length > 0)
  832. req.Connection = connection;
  833. if (userAgent != null && userAgent.Length > 0)
  834. req.UserAgent = userAgent;
  835. if (referer != null && referer.Length > 0)
  836. req.Referer = referer;
  837. }
  838. responseHeaders = null;
  839. return request;
  840. }
  841. WebRequest SetupRequest (Uri uri, string method, bool is_upload)
  842. {
  843. WebRequest request = SetupRequest (uri);
  844. request.Method = DetermineMethod (uri, method, is_upload);
  845. return request;
  846. }
  847. Stream ProcessResponse (WebResponse response)
  848. {
  849. responseHeaders = response.Headers;
  850. return response.GetResponseStream ();
  851. }
  852. byte [] ReadAll (Stream stream, int length, object userToken)
  853. {
  854. MemoryStream ms = null;
  855. bool nolength = (length == -1);
  856. int size = ((nolength) ? 8192 : length);
  857. if (nolength)
  858. ms = new MemoryStream ();
  859. // long total = 0;
  860. int nread = 0;
  861. int offset = 0;
  862. byte [] buffer = new byte [size];
  863. while ((nread = stream.Read (buffer, offset, size)) != 0) {
  864. if (nolength) {
  865. ms.Write (buffer, 0, nread);
  866. } else {
  867. offset += nread;
  868. size -= nread;
  869. }
  870. #if NET_2_0
  871. if (async){
  872. // total += nread;
  873. OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (nread, length, userToken));
  874. }
  875. #endif
  876. }
  877. if (nolength)
  878. return ms.ToArray ();
  879. return buffer;
  880. }
  881. string UrlEncode (string str)
  882. {
  883. StringBuilder result = new StringBuilder ();
  884. int len = str.Length;
  885. for (int i = 0; i < len; i++) {
  886. char c = str [i];
  887. if (c == ' ')
  888. result.Append ('+');
  889. else if ((c < '0' && c != '-' && c != '.') ||
  890. (c < 'A' && c > '9') ||
  891. (c > 'Z' && c < 'a' && c != '_') ||
  892. (c > 'z')) {
  893. result.Append ('%');
  894. int idx = ((int) c) >> 4;
  895. result.Append ((char) hexBytes [idx]);
  896. idx = ((int) c) & 0x0F;
  897. result.Append ((char) hexBytes [idx]);
  898. } else {
  899. result.Append (c);
  900. }
  901. }
  902. return result.ToString ();
  903. }
  904. static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
  905. {
  906. if (bytes == null)
  907. return;
  908. int len = bytes.Length;
  909. if (len == 0)
  910. return;
  911. for (int i = 0; i < len; i++) {
  912. char c = (char) bytes [i];
  913. if (c == ' ')
  914. stream.WriteByte ((byte) '+');
  915. else if ((c < '0' && c != '-' && c != '.') ||
  916. (c < 'A' && c > '9') ||
  917. (c > 'Z' && c < 'a' && c != '_') ||
  918. (c > 'z')) {
  919. stream.WriteByte ((byte) '%');
  920. int idx = ((int) c) >> 4;
  921. stream.WriteByte (hexBytes [idx]);
  922. idx = ((int) c) & 0x0F;
  923. stream.WriteByte (hexBytes [idx]);
  924. } else {
  925. stream.WriteByte ((byte) c);
  926. }
  927. }
  928. }
  929. #if NET_2_0
  930. public void CancelAsync ()
  931. {
  932. lock (this){
  933. if (async_thread == null)
  934. return;
  935. //
  936. // We first flag things as done, in case the Interrupt hangs
  937. // or the thread decides to hang in some other way inside the
  938. // event handlers, or if we are stuck somewhere else. This
  939. // ensures that the WebClient object is reusable immediately
  940. //
  941. Thread t = async_thread;
  942. CompleteAsync ();
  943. t.Interrupt ();
  944. }
  945. }
  946. void CompleteAsync ()
  947. {
  948. lock (this){
  949. is_busy = false;
  950. async_thread = null;
  951. }
  952. }
  953. // DownloadDataAsync
  954. public void DownloadDataAsync (Uri address)
  955. {
  956. DownloadDataAsync (address, null);
  957. }
  958. public void DownloadDataAsync (Uri address, object userToken)
  959. {
  960. if (address == null)
  961. throw new ArgumentNullException ("address");
  962. lock (this) {
  963. SetBusy ();
  964. async = true;
  965. async_thread = new Thread (delegate (object state) {
  966. object [] args = (object []) state;
  967. try {
  968. byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
  969. OnDownloadDataCompleted (
  970. new DownloadDataCompletedEventArgs (data, null, false, args [1]));
  971. } catch (ThreadInterruptedException){
  972. OnDownloadDataCompleted (
  973. new DownloadDataCompletedEventArgs (null, null, true, args [1]));
  974. throw;
  975. } catch (Exception e){
  976. OnDownloadDataCompleted (
  977. new DownloadDataCompletedEventArgs (null, e, false, args [1]));
  978. }
  979. });
  980. object [] cb_args = new object [] {address, userToken};
  981. async_thread.Start (cb_args);
  982. }
  983. }
  984. // DownloadFileAsync
  985. public void DownloadFileAsync (Uri address, string fileName)
  986. {
  987. DownloadFileAsync (address, fileName, null);
  988. }
  989. public void DownloadFileAsync (Uri address, string fileName, object userToken)
  990. {
  991. if (address == null)
  992. throw new ArgumentNullException ("address");
  993. if (fileName == null)
  994. throw new ArgumentNullException ("fileName");
  995. lock (this) {
  996. SetBusy ();
  997. async = true;
  998. async_thread = new Thread (delegate (object state) {
  999. object [] args = (object []) state;
  1000. try {
  1001. DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
  1002. OnDownloadFileCompleted (
  1003. new AsyncCompletedEventArgs (null, false, args [2]));
  1004. } catch (ThreadInterruptedException){
  1005. OnDownloadFileCompleted (
  1006. new AsyncCompletedEventArgs (null, true, args [2]));
  1007. } catch (Exception e){
  1008. OnDownloadFileCompleted (
  1009. new AsyncCompletedEventArgs (e, false, args [2]));
  1010. }});
  1011. object [] cb_args = new object [] {address, fileName, userToken};
  1012. async_thread.Start (cb_args);
  1013. }
  1014. }
  1015. // DownloadStringAsync
  1016. public void DownloadStringAsync (Uri address)
  1017. {
  1018. DownloadStringAsync (address, null);
  1019. }
  1020. public void DownloadStringAsync (Uri address, object userToken)
  1021. {
  1022. if (address == null)
  1023. throw new ArgumentNullException ("address");
  1024. lock (this) {
  1025. SetBusy ();
  1026. async = true;
  1027. async_thread = new Thread (delegate (object state) {
  1028. object [] args = (object []) state;
  1029. try {
  1030. string data = encoding.GetString (DownloadDataCore ((Uri) args [0], args [1]));
  1031. OnDownloadStringCompleted (
  1032. new DownloadStringCompletedEventArgs (data, null, false, args [1]));
  1033. } catch (ThreadInterruptedException){
  1034. OnDownloadStringCompleted (
  1035. new DownloadStringCompletedEventArgs (null, null, true, args [1]));
  1036. } catch (Exception e){
  1037. OnDownloadStringCompleted (
  1038. new DownloadStringCompletedEventArgs (null, e, false, args [1]));
  1039. }});
  1040. object [] cb_args = new object [] {address, userToken};
  1041. async_thread.Start (cb_args);
  1042. }
  1043. }
  1044. // OpenReadAsync
  1045. public void OpenReadAsync (Uri address)
  1046. {
  1047. OpenReadAsync (address, null);
  1048. }
  1049. public void OpenReadAsync (Uri address, object userToken)
  1050. {
  1051. if (address == null)
  1052. throw new ArgumentNullException ("address");
  1053. lock (this) {
  1054. SetBusy ();
  1055. async = true;
  1056. async_thread = new Thread (delegate (object state) {
  1057. object [] args = (object []) state;
  1058. WebRequest request = null;
  1059. try {
  1060. request = SetupRequest ((Uri) args [0]);
  1061. WebResponse response = request.GetResponse ();
  1062. Stream stream = ProcessResponse (response);
  1063. OnOpenReadCompleted (
  1064. new OpenReadCompletedEventArgs (stream, null, false, args [1]));
  1065. } catch (ThreadInterruptedException){
  1066. if (request != null)
  1067. request.Abort ();
  1068. OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, args [1]));
  1069. } catch (Exception e){
  1070. OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, e, false, args [1]));
  1071. } });
  1072. object [] cb_args = new object [] {address, userToken};
  1073. async_thread.Start (cb_args);
  1074. }
  1075. }
  1076. // OpenWriteAsync
  1077. public void OpenWriteAsync (Uri address)
  1078. {
  1079. OpenWriteAsync (address, null);
  1080. }
  1081. public void OpenWriteAsync (Uri address, string method)
  1082. {
  1083. OpenWriteAsync (address, method, null);
  1084. }
  1085. public void OpenWriteAsync (Uri address, string method, object userToken)
  1086. {
  1087. if (address == null)
  1088. throw new ArgumentNullException ("address");
  1089. lock (this) {
  1090. SetBusy ();
  1091. async = true;
  1092. async_thread = new Thread (delegate (object state) {
  1093. object [] args = (object []) state;
  1094. WebRequest request = null;
  1095. try {
  1096. request = SetupRequest ((Uri) args [0], (string) args [1], true);
  1097. Stream stream = request.GetRequestStream ();
  1098. OnOpenWriteCompleted (
  1099. new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
  1100. } catch (ThreadInterruptedException){
  1101. if (request != null)
  1102. request.Abort ();
  1103. OnOpenWriteCompleted (
  1104. new OpenWriteCompletedEventArgs (null, null, true, args [2]));
  1105. } catch (Exception e){
  1106. OnOpenWriteCompleted (
  1107. new OpenWriteCompletedEventArgs (null, e, false, args [2]));
  1108. }});
  1109. object [] cb_args = new object [] {address, method, userToken};
  1110. async_thread.Start (cb_args);
  1111. }
  1112. }
  1113. // UploadDataAsync
  1114. public void UploadDataAsync (Uri address, byte [] data)
  1115. {
  1116. UploadDataAsync (address, null, data);
  1117. }
  1118. public void UploadDataAsync (Uri address, string method, byte [] data)
  1119. {
  1120. UploadDataAsync (address, method, data, null);
  1121. }
  1122. public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
  1123. {
  1124. if (address == null)
  1125. throw new ArgumentNullException ("address");
  1126. if (data == null)
  1127. throw new ArgumentNullException ("data");
  1128. lock (this) {
  1129. SetBusy ();
  1130. async = true;
  1131. async_thread = new Thread (delegate (object state) {
  1132. object [] args = (object []) state;
  1133. byte [] data2;
  1134. try {
  1135. data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
  1136. OnUploadDataCompleted (
  1137. new UploadDataCompletedEventArgs (data2, null, false, args [3]));
  1138. } catch (ThreadInterruptedException){
  1139. OnUploadDataCompleted (
  1140. new UploadDataCompletedEventArgs (null, null, true, args [3]));
  1141. } catch (Exception e){
  1142. OnUploadDataCompleted (
  1143. new UploadDataCompletedEventArgs (null, e, false, args [3]));
  1144. }});
  1145. object [] cb_args = new object [] {address, method, data, userToken};
  1146. async_thread.Start (cb_args);
  1147. }
  1148. }
  1149. // UploadFileAsync
  1150. public void UploadFileAsync (Uri address, string fileName)
  1151. {
  1152. UploadFileAsync (address, null, fileName);
  1153. }
  1154. public void UploadFileAsync (Uri address, string method, string fileName)
  1155. {
  1156. UploadFileAsync (address, method, fileName, null);
  1157. }
  1158. public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
  1159. {
  1160. if (address == null)
  1161. throw new ArgumentNullException ("address");
  1162. if (fileName == null)
  1163. throw new ArgumentNullException ("fileName");
  1164. lock (this) {
  1165. SetBusy ();
  1166. async = true;
  1167. async_thread = new Thread (delegate (object state) {
  1168. object [] args = (object []) state;
  1169. byte [] data;
  1170. try {
  1171. data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
  1172. OnUploadFileCompleted (
  1173. new UploadFileCompletedEventArgs (data, null, false, args [3]));
  1174. } catch (ThreadInterruptedException){
  1175. OnUploadFileCompleted (
  1176. new UploadFileCompletedEventArgs (null, null, true, args [3]));
  1177. } catch (Exception e){
  1178. OnUploadFileCompleted (
  1179. new UploadFileCompletedEventArgs (null, e, false, args [3]));
  1180. }});
  1181. object [] cb_args = new object [] {address, method, fileName, userToken};
  1182. async_thread.Start (cb_args);
  1183. }
  1184. }
  1185. // UploadStringAsync
  1186. public void UploadStringAsync (Uri address, string data)
  1187. {
  1188. UploadStringAsync (address, null, data);
  1189. }
  1190. public void UploadStringAsync (Uri address, string method, string data)
  1191. {
  1192. UploadStringAsync (address, method, data, null);
  1193. }
  1194. public void UploadStringAsync (Uri address, string method, string data, object userToken)
  1195. {
  1196. if (address == null)
  1197. throw new ArgumentNullException ("address");
  1198. if (data == null)
  1199. throw new ArgumentNullException ("data");
  1200. lock (this) {
  1201. SetBusy ();
  1202. async = true;
  1203. async_thread = new Thread (delegate (object state) {
  1204. object [] args = (object []) state;
  1205. try {
  1206. string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
  1207. OnUploadStringCompleted (
  1208. new UploadStringCompletedEventArgs (data2, null, false, args [3]));
  1209. } catch (ThreadInterruptedException){
  1210. OnUploadStringCompleted (
  1211. new UploadStringCompletedEventArgs (null, null, true, args [3]));
  1212. } catch (Exception e){
  1213. OnUploadStringCompleted (
  1214. new UploadStringCompletedEventArgs (null, e, false, args [3]));
  1215. }});
  1216. object [] cb_args = new object [] {address, method, data, userToken};
  1217. async_thread.Start (cb_args);
  1218. }
  1219. }
  1220. // UploadValuesAsync
  1221. public void UploadValuesAsync (Uri address, NameValueCollection values)
  1222. {
  1223. UploadValuesAsync (address, null, values);
  1224. }
  1225. public void UploadValuesAsync (Uri address, string method, NameValueCollection values)
  1226. {
  1227. UploadValuesAsync (address, method, values, null);
  1228. }
  1229. public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken)
  1230. {
  1231. if (address == null)
  1232. throw new ArgumentNullException ("address");
  1233. if (values == null)
  1234. throw new ArgumentNullException ("values");
  1235. lock (this) {
  1236. CheckBusy ();
  1237. async = true;
  1238. async_thread = new Thread (delegate (object state) {
  1239. object [] args = (object []) state;
  1240. try {
  1241. byte [] data = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
  1242. OnUploadValuesCompleted (
  1243. new UploadValuesCompletedEventArgs (data, null, false, args [3]));
  1244. } catch (ThreadInterruptedException){
  1245. OnUploadValuesCompleted (
  1246. new UploadValuesCompletedEventArgs (null, null, true, args [3]));
  1247. } catch (Exception e){
  1248. OnUploadValuesCompleted (
  1249. new UploadValuesCompletedEventArgs (null, e, false, args [3]));
  1250. }});
  1251. object [] cb_args = new object [] {address, method, values, userToken};
  1252. async_thread.Start (cb_args);
  1253. }
  1254. }
  1255. protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
  1256. {
  1257. CompleteAsync ();
  1258. if (DownloadDataCompleted != null)
  1259. DownloadDataCompleted (this, args);
  1260. }
  1261. protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
  1262. {
  1263. CompleteAsync ();
  1264. if (DownloadFileCompleted != null)
  1265. DownloadFileCompleted (this, args);
  1266. }
  1267. protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
  1268. {
  1269. if (DownloadProgressChanged != null)
  1270. DownloadProgressChanged (this, e);
  1271. }
  1272. protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
  1273. {
  1274. CompleteAsync ();
  1275. if (DownloadStringCompleted != null)
  1276. DownloadStringCompleted (this, args);
  1277. }
  1278. protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
  1279. {
  1280. CompleteAsync ();
  1281. if (OpenReadCompleted != null)
  1282. OpenReadCompleted (this, args);
  1283. }
  1284. protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
  1285. {
  1286. CompleteAsync ();
  1287. if (OpenWriteCompleted != null)
  1288. OpenWriteCompleted (this, args);
  1289. }
  1290. protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
  1291. {
  1292. CompleteAsync ();
  1293. if (UploadDataCompleted != null)
  1294. UploadDataCompleted (this, args);
  1295. }
  1296. protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
  1297. {
  1298. CompleteAsync ();
  1299. if (UploadFileCompleted != null)
  1300. UploadFileCompleted (this, args);
  1301. }
  1302. protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
  1303. {
  1304. if (UploadProgressChanged != null)
  1305. UploadProgressChanged (this, e);
  1306. }
  1307. protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
  1308. {
  1309. CompleteAsync ();
  1310. if (UploadStringCompleted != null)
  1311. UploadStringCompleted (this, args);
  1312. }
  1313. protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
  1314. {
  1315. CompleteAsync ();
  1316. if (UploadValuesCompleted != null)
  1317. UploadValuesCompleted (this, args);
  1318. }
  1319. [MonoNotSupported("")]
  1320. protected virtual WebRequest GetWebRequest (Uri address)
  1321. {
  1322. throw new NotImplementedException ();
  1323. }
  1324. protected virtual WebResponse GetWebResponse (WebRequest request)
  1325. {
  1326. return request.GetResponse ();
  1327. }
  1328. protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
  1329. {
  1330. return request.EndGetResponse (result);
  1331. }
  1332. #endif
  1333. }
  1334. }