WebClient.cs 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517
  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);
  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)
  404. {
  405. if (method != null)
  406. return method;
  407. #if NET_2_0
  408. if (address.Scheme == Uri.UriSchemeFtp)
  409. return "RETR";
  410. #endif
  411. return "POST";
  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 (Exception ex) {
  455. throw new WebException ("An error occurred " +
  456. "performing a WebClient request.", ex);
  457. } finally {
  458. is_busy = false;
  459. }
  460. }
  461. byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
  462. {
  463. #if ONLY_1_1
  464. if (address == null)
  465. throw new ArgumentNullException ("address");
  466. if (data == null)
  467. throw new ArgumentNullException ("data");
  468. #endif
  469. WebRequest request = SetupRequest (address, method);
  470. try {
  471. int contentLength = data.Length;
  472. request.ContentLength = contentLength;
  473. using (Stream stream = request.GetRequestStream ()) {
  474. stream.Write (data, 0, contentLength);
  475. }
  476. WebResponse response = request.GetResponse ();
  477. Stream st = ProcessResponse (response);
  478. return ReadAll (st, (int) response.ContentLength, userToken);
  479. } catch (ThreadInterruptedException){
  480. if (request != null)
  481. request.Abort ();
  482. throw;
  483. }
  484. }
  485. // UploadFile
  486. public byte [] UploadFile (string address, string fileName)
  487. {
  488. #if NET_2_0
  489. if (address == null)
  490. throw new ArgumentNullException ("address");
  491. #endif
  492. return UploadFile (CreateUri (address), fileName);
  493. }
  494. #if NET_2_0
  495. public
  496. #endif
  497. byte [] UploadFile (Uri address, string fileName)
  498. {
  499. return UploadFile (address, (string) null, fileName);
  500. }
  501. public byte [] UploadFile (string address, string method, string fileName)
  502. {
  503. return UploadFile (CreateUri (address), method, fileName);
  504. }
  505. #if NET_2_0
  506. public
  507. #endif
  508. byte [] UploadFile (Uri address, string method, string fileName)
  509. {
  510. #if NET_2_0
  511. if (address == null)
  512. throw new ArgumentNullException ("address");
  513. if (fileName == null)
  514. throw new ArgumentNullException ("fileName");
  515. #endif
  516. try {
  517. SetBusy ();
  518. #if NET_2_0
  519. async = false;
  520. #endif
  521. return UploadFileCore (address, method, fileName, null);
  522. } catch (Exception ex) {
  523. throw new WebException ("An error occurred " +
  524. "performing a WebClient request.", ex);
  525. } finally {
  526. is_busy = false;
  527. }
  528. }
  529. byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
  530. {
  531. #if ONLY_1_1
  532. if (address == null)
  533. throw new ArgumentNullException ("address");
  534. #endif
  535. string fileCType = Headers ["Content-Type"];
  536. if (fileCType != null) {
  537. string lower = fileCType.ToLower ();
  538. if (lower.StartsWith ("multipart/"))
  539. throw new WebException ("Content-Type cannot be set to a multipart" +
  540. " type for this request.");
  541. } else {
  542. fileCType = "application/octet-stream";
  543. }
  544. string boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
  545. Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
  546. Stream reqStream = null;
  547. Stream fStream = null;
  548. byte [] resultBytes = null;
  549. fileName = Path.GetFullPath (fileName);
  550. WebRequest request = null;
  551. try {
  552. fStream = File.OpenRead (fileName);
  553. request = SetupRequest (address, method);
  554. reqStream = request.GetRequestStream ();
  555. byte [] realBoundary = Encoding.ASCII.GetBytes ("--" + boundary + "\r\n");
  556. reqStream.Write (realBoundary, 0, realBoundary.Length);
  557. string partHeaders = String.Format ("Content-Disposition: form-data; " +
  558. "name=\"file\"; filename=\"{0}\"\r\n" +
  559. "Content-Type: {1}\r\n\r\n",
  560. Path.GetFileName (fileName), fileCType);
  561. byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
  562. reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
  563. int nread;
  564. byte [] buffer = new byte [4096];
  565. while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
  566. reqStream.Write (buffer, 0, nread);
  567. reqStream.WriteByte ((byte) '\r');
  568. reqStream.WriteByte ((byte) '\n');
  569. reqStream.Write (realBoundary, 0, realBoundary.Length);
  570. reqStream.Close ();
  571. reqStream = null;
  572. WebResponse response = request.GetResponse ();
  573. Stream st = ProcessResponse (response);
  574. resultBytes = ReadAll (st, (int) response.ContentLength, userToken);
  575. } catch (ThreadInterruptedException){
  576. if (request != null)
  577. request.Abort ();
  578. throw;
  579. } finally {
  580. if (fStream != null)
  581. fStream.Close ();
  582. if (reqStream != null)
  583. reqStream.Close ();
  584. }
  585. return resultBytes;
  586. }
  587. public byte[] UploadValues (string address, NameValueCollection data)
  588. {
  589. #if NET_2_0
  590. if (address == null)
  591. throw new ArgumentNullException ("address");
  592. #endif
  593. return UploadValues (CreateUri (address), data);
  594. }
  595. public byte[] UploadValues (string address, string method, NameValueCollection data)
  596. {
  597. #if NET_2_0
  598. if (address == null)
  599. throw new ArgumentNullException ("address");
  600. #endif
  601. return UploadValues (CreateUri (address), method, data);
  602. }
  603. #if NET_2_0
  604. public
  605. #endif
  606. byte[] UploadValues (Uri address, NameValueCollection data)
  607. {
  608. return UploadValues (address, (string) null, data);
  609. }
  610. #if NET_2_0
  611. public
  612. #endif
  613. byte[] UploadValues (Uri address, string method, NameValueCollection data)
  614. {
  615. #if NET_2_0
  616. if (address == null)
  617. throw new ArgumentNullException ("address");
  618. if (data == null)
  619. throw new ArgumentNullException ("data");
  620. #endif
  621. try {
  622. SetBusy ();
  623. #if NET_2_0
  624. async = false;
  625. #endif
  626. return UploadValuesCore (address, method, data, null);
  627. } catch (Exception ex) {
  628. throw new WebException ("An error occurred " +
  629. "performing a WebClient request.", ex);
  630. } finally {
  631. is_busy = false;
  632. }
  633. }
  634. byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
  635. {
  636. #if ONLY_1_1
  637. if (data == null)
  638. throw new ArgumentNullException ("data");
  639. #endif
  640. string cType = Headers ["Content-Type"];
  641. if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
  642. throw new WebException ("Content-Type header cannot be changed from its default " +
  643. "value for this request.");
  644. Headers ["Content-Type"] = urlEncodedCType;
  645. WebRequest request = SetupRequest (uri, method);
  646. try {
  647. Stream rqStream = request.GetRequestStream ();
  648. MemoryStream tmpStream = new MemoryStream ();
  649. foreach (string key in data) {
  650. byte [] bytes = Encoding.ASCII.GetBytes (key);
  651. UrlEncodeAndWrite (tmpStream, bytes);
  652. tmpStream.WriteByte ((byte) '=');
  653. bytes = Encoding.ASCII.GetBytes (data [key]);
  654. UrlEncodeAndWrite (tmpStream, bytes);
  655. tmpStream.WriteByte ((byte) '&');
  656. }
  657. int length = (int) tmpStream.Length;
  658. if (length > 0)
  659. tmpStream.SetLength (--length); // remove trailing '&'
  660. byte [] buf = tmpStream.GetBuffer ();
  661. rqStream.Write (buf, 0, length);
  662. rqStream.Close ();
  663. tmpStream.Close ();
  664. WebResponse response = request.GetResponse ();
  665. Stream st = ProcessResponse (response);
  666. return ReadAll (st, (int) response.ContentLength, userToken);
  667. } catch (ThreadInterruptedException) {
  668. request.Abort ();
  669. throw;
  670. }
  671. }
  672. #if NET_2_0
  673. public string DownloadString (string address)
  674. {
  675. return encoding.GetString (DownloadData (address));
  676. }
  677. public string DownloadString (Uri address)
  678. {
  679. return encoding.GetString (DownloadData (address));
  680. }
  681. public string UploadString (string address, string data)
  682. {
  683. if (address == null)
  684. throw new ArgumentNullException ("address");
  685. if (data == null)
  686. throw new ArgumentNullException ("data");
  687. byte [] resp = UploadData (address, encoding.GetBytes (data));
  688. return encoding.GetString (resp);
  689. }
  690. public string UploadString (string address, string method, string data)
  691. {
  692. if (address == null)
  693. throw new ArgumentNullException ("address");
  694. if (data == null)
  695. throw new ArgumentNullException ("data");
  696. byte [] resp = UploadData (address, method, encoding.GetBytes (data));
  697. return encoding.GetString (resp);
  698. }
  699. public string UploadString (Uri address, string data)
  700. {
  701. if (address == null)
  702. throw new ArgumentNullException ("address");
  703. if (data == null)
  704. throw new ArgumentNullException ("data");
  705. byte [] resp = UploadData (address, encoding.GetBytes (data));
  706. return encoding.GetString (resp);
  707. }
  708. public string UploadString (Uri address, string method, string data)
  709. {
  710. if (address == null)
  711. throw new ArgumentNullException ("address");
  712. if (data == null)
  713. throw new ArgumentNullException ("data");
  714. byte [] resp = UploadData (address, method, encoding.GetBytes (data));
  715. return encoding.GetString (resp);
  716. }
  717. public event DownloadDataCompletedEventHandler DownloadDataCompleted;
  718. public event AsyncCompletedEventHandler DownloadFileCompleted;
  719. public event DownloadProgressChangedEventHandler DownloadProgressChanged;
  720. public event DownloadStringCompletedEventHandler DownloadStringCompleted;
  721. public event OpenReadCompletedEventHandler OpenReadCompleted;
  722. public event OpenWriteCompletedEventHandler OpenWriteCompleted;
  723. public event UploadDataCompletedEventHandler UploadDataCompleted;
  724. public event UploadFileCompletedEventHandler UploadFileCompleted;
  725. public event UploadProgressChangedEventHandler UploadProgressChanged;
  726. public event UploadStringCompletedEventHandler UploadStringCompleted;
  727. public event UploadValuesCompletedEventHandler UploadValuesCompleted;
  728. #endif
  729. Uri CreateUri (string address)
  730. {
  731. #if ONLY_1_1
  732. try {
  733. return MakeUri (address);
  734. } catch (Exception ex) {
  735. throw new WebException ("An error occurred " +
  736. "performing a WebClient request.", ex);
  737. }
  738. #else
  739. return MakeUri (address);
  740. #endif
  741. }
  742. Uri MakeUri (string path)
  743. {
  744. string query = null;
  745. if (queryString != null && queryString.Count != 0) {
  746. // This is not the same as UploadValues, because these 'keys' are not
  747. // urlencoded here.
  748. StringBuilder sb = new StringBuilder ();
  749. sb.Append ('?');
  750. foreach (string key in queryString)
  751. sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
  752. if (sb.Length != 0) {
  753. sb.Length--; // remove trailing '&'
  754. query = sb.ToString ();
  755. }
  756. }
  757. if (baseAddress == null && query == null) {
  758. try {
  759. return new Uri (path);
  760. #if NET_2_0
  761. } catch (ArgumentNullException) {
  762. path = Path.GetFullPath (path);
  763. return new Uri ("file://" + path);
  764. #endif
  765. } catch (UriFormatException) {
  766. path = Path.GetFullPath (path);
  767. return new Uri ("file://" + path);
  768. }
  769. }
  770. if (baseAddress == null)
  771. return new Uri (path + query, (query != null));
  772. if (query == null)
  773. return new Uri (baseAddress, path);
  774. return new Uri (baseAddress, path + query, (query != null));
  775. }
  776. WebRequest SetupRequest (Uri uri)
  777. {
  778. WebRequest request = WebRequest.Create (uri);
  779. #if NET_2_0
  780. if (Proxy != null)
  781. request.Proxy = Proxy;
  782. #endif
  783. request.Credentials = credentials;
  784. // Special headers. These are properties of HttpWebRequest.
  785. // What do we do with other requests differnt from HttpWebRequest?
  786. if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
  787. HttpWebRequest req = (HttpWebRequest) request;
  788. string expect = headers ["Expect"];
  789. string contentType = headers ["Content-Type"];
  790. string accept = headers ["Accept"];
  791. string connection = headers ["Connection"];
  792. string userAgent = headers ["User-Agent"];
  793. string referer = headers ["Referer"];
  794. headers.RemoveInternal ("Expect");
  795. headers.RemoveInternal ("Content-Type");
  796. headers.RemoveInternal ("Accept");
  797. headers.RemoveInternal ("Connection");
  798. headers.RemoveInternal ("Referer");
  799. headers.RemoveInternal ("User-Agent");
  800. request.Headers = headers;
  801. if (expect != null && expect.Length > 0)
  802. req.Expect = expect;
  803. if (accept != null && accept.Length > 0)
  804. req.Accept = accept;
  805. if (contentType != null && contentType.Length > 0)
  806. req.ContentType = contentType;
  807. if (connection != null && connection.Length > 0)
  808. req.Connection = connection;
  809. if (userAgent != null && userAgent.Length > 0)
  810. req.UserAgent = userAgent;
  811. if (referer != null && referer.Length > 0)
  812. req.Referer = referer;
  813. }
  814. responseHeaders = null;
  815. return request;
  816. }
  817. WebRequest SetupRequest (Uri uri, string method)
  818. {
  819. WebRequest request = SetupRequest (uri);
  820. request.Method = DetermineMethod (uri, method);
  821. return request;
  822. }
  823. Stream ProcessResponse (WebResponse response)
  824. {
  825. responseHeaders = response.Headers;
  826. return response.GetResponseStream ();
  827. }
  828. byte [] ReadAll (Stream stream, int length, object userToken)
  829. {
  830. MemoryStream ms = null;
  831. bool nolength = (length == -1);
  832. int size = ((nolength) ? 8192 : length);
  833. if (nolength)
  834. ms = new MemoryStream ();
  835. // long total = 0;
  836. int nread = 0;
  837. int offset = 0;
  838. byte [] buffer = new byte [size];
  839. while ((nread = stream.Read (buffer, offset, size)) != 0) {
  840. if (nolength) {
  841. ms.Write (buffer, 0, nread);
  842. } else {
  843. offset += nread;
  844. size -= nread;
  845. }
  846. #if NET_2_0
  847. if (async){
  848. // total += nread;
  849. OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (nread, length, userToken));
  850. }
  851. #endif
  852. }
  853. if (nolength)
  854. return ms.ToArray ();
  855. return buffer;
  856. }
  857. string UrlEncode (string str)
  858. {
  859. StringBuilder result = new StringBuilder ();
  860. int len = str.Length;
  861. for (int i = 0; i < len; i++) {
  862. char c = str [i];
  863. if (c == ' ')
  864. result.Append ('+');
  865. else if ((c < '0' && c != '-' && c != '.') ||
  866. (c < 'A' && c > '9') ||
  867. (c > 'Z' && c < 'a' && c != '_') ||
  868. (c > 'z')) {
  869. result.Append ('%');
  870. int idx = ((int) c) >> 4;
  871. result.Append ((char) hexBytes [idx]);
  872. idx = ((int) c) & 0x0F;
  873. result.Append ((char) hexBytes [idx]);
  874. } else {
  875. result.Append (c);
  876. }
  877. }
  878. return result.ToString ();
  879. }
  880. static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
  881. {
  882. if (bytes == null)
  883. return;
  884. int len = bytes.Length;
  885. if (len == 0)
  886. return;
  887. for (int i = 0; i < len; i++) {
  888. char c = (char) bytes [i];
  889. if (c == ' ')
  890. stream.WriteByte ((byte) '+');
  891. else if ((c < '0' && c != '-' && c != '.') ||
  892. (c < 'A' && c > '9') ||
  893. (c > 'Z' && c < 'a' && c != '_') ||
  894. (c > 'z')) {
  895. stream.WriteByte ((byte) '%');
  896. int idx = ((int) c) >> 4;
  897. stream.WriteByte (hexBytes [idx]);
  898. idx = ((int) c) & 0x0F;
  899. stream.WriteByte (hexBytes [idx]);
  900. } else {
  901. stream.WriteByte ((byte) c);
  902. }
  903. }
  904. }
  905. #if NET_2_0
  906. public void CancelAsync ()
  907. {
  908. lock (this){
  909. if (async_thread == null)
  910. return;
  911. //
  912. // We first flag things as done, in case the Interrupt hangs
  913. // or the thread decides to hang in some other way inside the
  914. // event handlers, or if we are stuck somewhere else. This
  915. // ensures that the WebClient object is reusable immediately
  916. //
  917. Thread t = async_thread;
  918. CompleteAsync ();
  919. t.Interrupt ();
  920. }
  921. }
  922. void CompleteAsync ()
  923. {
  924. lock (this){
  925. is_busy = false;
  926. async_thread = null;
  927. }
  928. }
  929. // DownloadDataAsync
  930. public void DownloadDataAsync (Uri address)
  931. {
  932. DownloadDataAsync (address, null);
  933. }
  934. public void DownloadDataAsync (Uri address, object userToken)
  935. {
  936. if (address == null)
  937. throw new ArgumentNullException ("address");
  938. lock (this) {
  939. SetBusy ();
  940. async = true;
  941. async_thread = new Thread (delegate (object state) {
  942. object [] args = (object []) state;
  943. try {
  944. byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
  945. OnDownloadDataCompleted (
  946. new DownloadDataCompletedEventArgs (data, null, false, args [1]));
  947. } catch (ThreadInterruptedException){
  948. OnDownloadDataCompleted (
  949. new DownloadDataCompletedEventArgs (null, null, true, args [1]));
  950. throw;
  951. } catch (Exception e){
  952. OnDownloadDataCompleted (
  953. new DownloadDataCompletedEventArgs (null, e, false, args [1]));
  954. }
  955. });
  956. object [] cb_args = new object [] {address, userToken};
  957. async_thread.Start (cb_args);
  958. }
  959. }
  960. // DownloadFileAsync
  961. public void DownloadFileAsync (Uri address, string fileName)
  962. {
  963. DownloadFileAsync (address, fileName, null);
  964. }
  965. public void DownloadFileAsync (Uri address, string fileName, object userToken)
  966. {
  967. if (address == null)
  968. throw new ArgumentNullException ("address");
  969. if (fileName == null)
  970. throw new ArgumentNullException ("fileName");
  971. lock (this) {
  972. SetBusy ();
  973. async = true;
  974. async_thread = new Thread (delegate (object state) {
  975. object [] args = (object []) state;
  976. try {
  977. DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
  978. OnDownloadFileCompleted (
  979. new AsyncCompletedEventArgs (null, false, args [2]));
  980. } catch (ThreadInterruptedException){
  981. OnDownloadFileCompleted (
  982. new AsyncCompletedEventArgs (null, true, args [2]));
  983. } catch (Exception e){
  984. OnDownloadFileCompleted (
  985. new AsyncCompletedEventArgs (e, false, args [2]));
  986. }});
  987. object [] cb_args = new object [] {address, fileName, userToken};
  988. async_thread.Start (cb_args);
  989. }
  990. }
  991. // DownloadStringAsync
  992. public void DownloadStringAsync (Uri address)
  993. {
  994. DownloadStringAsync (address, null);
  995. }
  996. public void DownloadStringAsync (Uri address, object userToken)
  997. {
  998. if (address == null)
  999. throw new ArgumentNullException ("address");
  1000. lock (this) {
  1001. SetBusy ();
  1002. async = true;
  1003. async_thread = new Thread (delegate (object state) {
  1004. object [] args = (object []) state;
  1005. try {
  1006. string data = encoding.GetString (DownloadDataCore ((Uri) args [0], args [1]));
  1007. OnDownloadStringCompleted (
  1008. new DownloadStringCompletedEventArgs (data, null, false, args [1]));
  1009. } catch (ThreadInterruptedException){
  1010. OnDownloadStringCompleted (
  1011. new DownloadStringCompletedEventArgs (null, null, true, args [1]));
  1012. } catch (Exception e){
  1013. OnDownloadStringCompleted (
  1014. new DownloadStringCompletedEventArgs (null, e, false, args [1]));
  1015. }});
  1016. object [] cb_args = new object [] {address, userToken};
  1017. async_thread.Start (cb_args);
  1018. }
  1019. }
  1020. // OpenReadAsync
  1021. public void OpenReadAsync (Uri address)
  1022. {
  1023. OpenReadAsync (address, null);
  1024. }
  1025. public void OpenReadAsync (Uri address, object userToken)
  1026. {
  1027. if (address == null)
  1028. throw new ArgumentNullException ("address");
  1029. lock (this) {
  1030. SetBusy ();
  1031. async = true;
  1032. async_thread = new Thread (delegate (object state) {
  1033. object [] args = (object []) state;
  1034. WebRequest request = null;
  1035. try {
  1036. request = SetupRequest ((Uri) args [0]);
  1037. WebResponse response = request.GetResponse ();
  1038. Stream stream = ProcessResponse (response);
  1039. OnOpenReadCompleted (
  1040. new OpenReadCompletedEventArgs (stream, null, false, args [1]));
  1041. } catch (ThreadInterruptedException){
  1042. if (request != null)
  1043. request.Abort ();
  1044. OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, args [1]));
  1045. } catch (Exception e){
  1046. OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, e, false, args [1]));
  1047. } });
  1048. object [] cb_args = new object [] {address, userToken};
  1049. async_thread.Start (cb_args);
  1050. }
  1051. }
  1052. // OpenWriteAsync
  1053. public void OpenWriteAsync (Uri address)
  1054. {
  1055. OpenWriteAsync (address, null);
  1056. }
  1057. public void OpenWriteAsync (Uri address, string method)
  1058. {
  1059. OpenWriteAsync (address, method, null);
  1060. }
  1061. public void OpenWriteAsync (Uri address, string method, object userToken)
  1062. {
  1063. if (address == null)
  1064. throw new ArgumentNullException ("address");
  1065. lock (this) {
  1066. SetBusy ();
  1067. async = true;
  1068. async_thread = new Thread (delegate (object state) {
  1069. object [] args = (object []) state;
  1070. WebRequest request = null;
  1071. try {
  1072. request = SetupRequest ((Uri) args [0], (string) args [1]);
  1073. Stream stream = request.GetRequestStream ();
  1074. OnOpenWriteCompleted (
  1075. new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
  1076. } catch (ThreadInterruptedException){
  1077. if (request != null)
  1078. request.Abort ();
  1079. OnOpenWriteCompleted (
  1080. new OpenWriteCompletedEventArgs (null, null, true, args [2]));
  1081. } catch (Exception e){
  1082. OnOpenWriteCompleted (
  1083. new OpenWriteCompletedEventArgs (null, e, false, args [2]));
  1084. }});
  1085. object [] cb_args = new object [] {address, method, userToken};
  1086. async_thread.Start (cb_args);
  1087. }
  1088. }
  1089. // UploadDataAsync
  1090. public void UploadDataAsync (Uri address, byte [] data)
  1091. {
  1092. UploadDataAsync (address, null, data);
  1093. }
  1094. public void UploadDataAsync (Uri address, string method, byte [] data)
  1095. {
  1096. UploadDataAsync (address, method, data, null);
  1097. }
  1098. public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
  1099. {
  1100. if (address == null)
  1101. throw new ArgumentNullException ("address");
  1102. if (data == null)
  1103. throw new ArgumentNullException ("data");
  1104. lock (this) {
  1105. SetBusy ();
  1106. async = true;
  1107. async_thread = new Thread (delegate (object state) {
  1108. object [] args = (object []) state;
  1109. byte [] data2;
  1110. try {
  1111. data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
  1112. OnUploadDataCompleted (
  1113. new UploadDataCompletedEventArgs (data2, null, false, args [3]));
  1114. } catch (ThreadInterruptedException){
  1115. OnUploadDataCompleted (
  1116. new UploadDataCompletedEventArgs (null, null, true, args [3]));
  1117. } catch (Exception e){
  1118. OnUploadDataCompleted (
  1119. new UploadDataCompletedEventArgs (null, e, false, args [3]));
  1120. }});
  1121. object [] cb_args = new object [] {address, method, data, userToken};
  1122. async_thread.Start (cb_args);
  1123. }
  1124. }
  1125. // UploadFileAsync
  1126. public void UploadFileAsync (Uri address, string fileName)
  1127. {
  1128. UploadFileAsync (address, null, fileName);
  1129. }
  1130. public void UploadFileAsync (Uri address, string method, string fileName)
  1131. {
  1132. UploadFileAsync (address, method, fileName, null);
  1133. }
  1134. public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
  1135. {
  1136. if (address == null)
  1137. throw new ArgumentNullException ("address");
  1138. if (fileName == null)
  1139. throw new ArgumentNullException ("fileName");
  1140. lock (this) {
  1141. SetBusy ();
  1142. async = true;
  1143. async_thread = new Thread (delegate (object state) {
  1144. object [] args = (object []) state;
  1145. byte [] data;
  1146. try {
  1147. data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
  1148. OnUploadFileCompleted (
  1149. new UploadFileCompletedEventArgs (data, null, false, args [3]));
  1150. } catch (ThreadInterruptedException){
  1151. OnUploadFileCompleted (
  1152. new UploadFileCompletedEventArgs (null, null, true, args [3]));
  1153. } catch (Exception e){
  1154. OnUploadFileCompleted (
  1155. new UploadFileCompletedEventArgs (null, e, false, args [3]));
  1156. }});
  1157. object [] cb_args = new object [] {address, method, fileName, userToken};
  1158. async_thread.Start (cb_args);
  1159. }
  1160. }
  1161. // UploadStringAsync
  1162. public void UploadStringAsync (Uri address, string data)
  1163. {
  1164. UploadStringAsync (address, null, data);
  1165. }
  1166. public void UploadStringAsync (Uri address, string method, string data)
  1167. {
  1168. UploadStringAsync (address, method, data, null);
  1169. }
  1170. public void UploadStringAsync (Uri address, string method, string data, object userToken)
  1171. {
  1172. if (address == null)
  1173. throw new ArgumentNullException ("address");
  1174. if (data == null)
  1175. throw new ArgumentNullException ("data");
  1176. lock (this) {
  1177. SetBusy ();
  1178. async = true;
  1179. async_thread = new Thread (delegate (object state) {
  1180. object [] args = (object []) state;
  1181. try {
  1182. string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
  1183. OnUploadStringCompleted (
  1184. new UploadStringCompletedEventArgs (data2, null, false, args [3]));
  1185. } catch (ThreadInterruptedException){
  1186. OnUploadStringCompleted (
  1187. new UploadStringCompletedEventArgs (null, null, true, args [3]));
  1188. } catch (Exception e){
  1189. OnUploadStringCompleted (
  1190. new UploadStringCompletedEventArgs (null, e, false, args [3]));
  1191. }});
  1192. object [] cb_args = new object [] {address, method, data, userToken};
  1193. async_thread.Start (cb_args);
  1194. }
  1195. }
  1196. // UploadValuesAsync
  1197. public void UploadValuesAsync (Uri address, NameValueCollection values)
  1198. {
  1199. UploadValuesAsync (address, null, values);
  1200. }
  1201. public void UploadValuesAsync (Uri address, string method, NameValueCollection values)
  1202. {
  1203. UploadValuesAsync (address, method, values, null);
  1204. }
  1205. public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken)
  1206. {
  1207. if (address == null)
  1208. throw new ArgumentNullException ("address");
  1209. if (values == null)
  1210. throw new ArgumentNullException ("values");
  1211. lock (this) {
  1212. CheckBusy ();
  1213. async = true;
  1214. async_thread = new Thread (delegate (object state) {
  1215. object [] args = (object []) state;
  1216. try {
  1217. byte [] data = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
  1218. OnUploadValuesCompleted (
  1219. new UploadValuesCompletedEventArgs (data, null, false, args [3]));
  1220. } catch (ThreadInterruptedException){
  1221. OnUploadValuesCompleted (
  1222. new UploadValuesCompletedEventArgs (null, null, true, args [3]));
  1223. } catch (Exception e){
  1224. OnUploadValuesCompleted (
  1225. new UploadValuesCompletedEventArgs (null, e, false, args [3]));
  1226. }});
  1227. object [] cb_args = new object [] {address, method, values, userToken};
  1228. async_thread.Start (cb_args);
  1229. }
  1230. }
  1231. protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
  1232. {
  1233. CompleteAsync ();
  1234. if (DownloadDataCompleted != null)
  1235. DownloadDataCompleted (this, args);
  1236. }
  1237. protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
  1238. {
  1239. CompleteAsync ();
  1240. if (DownloadFileCompleted != null)
  1241. DownloadFileCompleted (this, args);
  1242. }
  1243. protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
  1244. {
  1245. if (DownloadProgressChanged != null)
  1246. DownloadProgressChanged (this, e);
  1247. }
  1248. protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
  1249. {
  1250. CompleteAsync ();
  1251. if (DownloadStringCompleted != null)
  1252. DownloadStringCompleted (this, args);
  1253. }
  1254. protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
  1255. {
  1256. CompleteAsync ();
  1257. if (OpenReadCompleted != null)
  1258. OpenReadCompleted (this, args);
  1259. }
  1260. protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
  1261. {
  1262. CompleteAsync ();
  1263. if (OpenWriteCompleted != null)
  1264. OpenWriteCompleted (this, args);
  1265. }
  1266. protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
  1267. {
  1268. CompleteAsync ();
  1269. if (UploadDataCompleted != null)
  1270. UploadDataCompleted (this, args);
  1271. }
  1272. protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
  1273. {
  1274. CompleteAsync ();
  1275. if (UploadFileCompleted != null)
  1276. UploadFileCompleted (this, args);
  1277. }
  1278. protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
  1279. {
  1280. if (UploadProgressChanged != null)
  1281. UploadProgressChanged (this, e);
  1282. }
  1283. protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
  1284. {
  1285. CompleteAsync ();
  1286. if (UploadStringCompleted != null)
  1287. UploadStringCompleted (this, args);
  1288. }
  1289. protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
  1290. {
  1291. CompleteAsync ();
  1292. if (UploadValuesCompleted != null)
  1293. UploadValuesCompleted (this, args);
  1294. }
  1295. [MonoNotSupported("")]
  1296. protected virtual WebRequest GetWebRequest (Uri address)
  1297. {
  1298. throw new NotImplementedException ();
  1299. }
  1300. protected virtual WebResponse GetWebResponse (WebRequest request)
  1301. {
  1302. return request.GetResponse ();
  1303. }
  1304. protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
  1305. {
  1306. return request.EndGetResponse (result);
  1307. }
  1308. #endif
  1309. }
  1310. }