WebClient.cs 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198
  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. // Martin Baulig ([email protected])
  10. //
  11. // Copyright 2003 Ximian, Inc. (http://www.ximian.com)
  12. // Copyright 2006, 2010 Novell, Inc. (http://www.novell.com)
  13. // Copyright 2012 Xamarin Inc. (http://www.xamarin.com)
  14. //
  15. //
  16. // Permission is hereby granted, free of charge, to any person obtaining
  17. // a copy of this software and associated documentation files (the
  18. // "Software"), to deal in the Software without restriction, including
  19. // without limitation the rights to use, copy, modify, merge, publish,
  20. // distribute, sublicense, and/or sell copies of the Software, and to
  21. // permit persons to whom the Software is furnished to do so, subject to
  22. // the following conditions:
  23. //
  24. // The above copyright notice and this permission notice shall be
  25. // included in all copies or substantial portions of the Software.
  26. //
  27. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  28. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  29. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  30. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  31. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  32. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  33. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  34. //
  35. //
  36. // Notes on CancelAsync and Async methods:
  37. //
  38. // WebClient.CancelAsync is implemented by calling Thread.Interrupt
  39. // in our helper thread. The various async methods have to cancel
  40. // any ongoing requests by calling request.Abort () at that point.
  41. // In a few places (UploadDataCore, UploadValuesCore,
  42. // UploadFileCore) we catch the ThreadInterruptedException and
  43. // abort the request there.
  44. //
  45. // Higher level routines (the async callbacks) also need to catch
  46. // the exception and raise the OnXXXXCompleted events there with
  47. // the "canceled" flag set to true.
  48. //
  49. // In a few other places where these helper routines are not used
  50. // (OpenReadAsync for example) catching the ThreadAbortException
  51. // also must abort the request.
  52. //
  53. // The Async methods currently differ in their implementation from
  54. // the .NET implementation in that we manually catch any other
  55. // exceptions and correctly raise the OnXXXXCompleted passing the
  56. // Exception that caused the problem. The .NET implementation
  57. // does not seem to have a mechanism to flag errors that happen
  58. // during downloads though. We do this because we still need to
  59. // catch the exception on these helper threads, or we would
  60. // otherwise kill the application (on the 2.x profile, uncaught
  61. // exceptions in threads terminate the application).
  62. //
  63. using System;
  64. using System.Collections.Specialized;
  65. using System.ComponentModel;
  66. using System.IO;
  67. using System.Runtime.InteropServices;
  68. using System.Runtime.Serialization;
  69. using System.Text;
  70. using System.Threading;
  71. using System.Net.Cache;
  72. #if NET_4_5
  73. using System.Threading.Tasks;
  74. #endif
  75. namespace System.Net
  76. {
  77. [ComVisible(true)]
  78. public class WebClient : Component
  79. {
  80. static readonly string urlEncodedCType = "application/x-www-form-urlencoded";
  81. static byte [] hexBytes;
  82. ICredentials credentials;
  83. WebHeaderCollection headers;
  84. WebHeaderCollection responseHeaders;
  85. Uri baseAddress;
  86. string baseString;
  87. NameValueCollection queryString;
  88. bool is_busy;
  89. bool async;
  90. bool proxySet = false;
  91. Thread async_thread;
  92. Encoding encoding = Encoding.Default;
  93. IWebProxy proxy;
  94. // RequestCachePolicy cache_policy;
  95. #if NET_4_5
  96. CancellationTokenSource cts;
  97. #endif
  98. // Constructors
  99. static WebClient ()
  100. {
  101. hexBytes = new byte [16];
  102. int index = 0;
  103. for (int i = '0'; i <= '9'; i++, index++)
  104. hexBytes [index] = (byte) i;
  105. for (int i = 'a'; i <= 'f'; i++, index++)
  106. hexBytes [index] = (byte) i;
  107. }
  108. public WebClient ()
  109. {
  110. }
  111. // Properties
  112. public string BaseAddress {
  113. get {
  114. if (baseString == null) {
  115. if (baseAddress == null)
  116. return string.Empty;
  117. }
  118. baseString = baseAddress.ToString ();
  119. return baseString;
  120. }
  121. set {
  122. if (value == null || value.Length == 0) {
  123. baseAddress = null;
  124. } else {
  125. baseAddress = new Uri (value);
  126. }
  127. }
  128. }
  129. static Exception GetMustImplement ()
  130. {
  131. return new NotImplementedException ();
  132. }
  133. [MonoTODO ("Value can be set but is currently ignored")]
  134. public RequestCachePolicy CachePolicy
  135. {
  136. get {
  137. throw GetMustImplement ();
  138. }
  139. set { /*cache_policy = value;*/ }
  140. }
  141. [MonoTODO ("Value can be set but is ignored")]
  142. public bool UseDefaultCredentials
  143. {
  144. get {
  145. throw GetMustImplement ();
  146. }
  147. set {
  148. // This makes no sense in mono
  149. }
  150. }
  151. public ICredentials Credentials {
  152. get { return credentials; }
  153. set { credentials = value; }
  154. }
  155. public WebHeaderCollection Headers {
  156. get {
  157. if (headers == null)
  158. headers = new WebHeaderCollection ();
  159. return headers;
  160. }
  161. set { headers = value; }
  162. }
  163. public NameValueCollection QueryString {
  164. get {
  165. if (queryString == null)
  166. queryString = new NameValueCollection ();
  167. return queryString;
  168. }
  169. set { queryString = value; }
  170. }
  171. public WebHeaderCollection ResponseHeaders {
  172. get { return responseHeaders; }
  173. }
  174. public Encoding Encoding {
  175. get { return encoding; }
  176. set {
  177. if (value == null)
  178. throw new ArgumentNullException ("Encoding");
  179. encoding = value;
  180. }
  181. }
  182. public IWebProxy Proxy {
  183. get {
  184. if (!proxySet)
  185. return WebRequest.DefaultWebProxy;
  186. return proxy;
  187. }
  188. set {
  189. proxy = value;
  190. proxySet = true;
  191. }
  192. }
  193. public bool IsBusy {
  194. get {
  195. #if NET_4_5
  196. return is_busy || (cts != null);
  197. #else
  198. return is_busy;
  199. #endif
  200. }
  201. }
  202. // Methods
  203. void CheckBusy ()
  204. {
  205. if (IsBusy)
  206. throw new NotSupportedException ("WebClient does not support concurrent I/O operations.");
  207. }
  208. void SetBusy ()
  209. {
  210. lock (this) {
  211. CheckBusy ();
  212. is_busy = true;
  213. }
  214. }
  215. // DownloadData
  216. public byte [] DownloadData (string address)
  217. {
  218. if (address == null)
  219. throw new ArgumentNullException ("address");
  220. return DownloadData (CreateUri (address));
  221. }
  222. public byte [] DownloadData (Uri address)
  223. {
  224. if (address == null)
  225. throw new ArgumentNullException ("address");
  226. try {
  227. SetBusy ();
  228. async = false;
  229. return DownloadDataCore (address, null);
  230. } finally {
  231. is_busy = false;
  232. }
  233. }
  234. byte [] DownloadDataCore (Uri address, object userToken)
  235. {
  236. WebRequest request = null;
  237. try {
  238. request = SetupRequest (address);
  239. return ReadAll (request, userToken);
  240. } catch (ThreadInterruptedException){
  241. if (request != null)
  242. request.Abort ();
  243. throw new WebException ("User canceled the request", WebExceptionStatus.RequestCanceled);
  244. } catch (WebException) {
  245. throw;
  246. } catch (Exception ex) {
  247. throw new WebException ("An error occurred performing a WebClient request.", ex);
  248. }
  249. }
  250. // DownloadFile
  251. public void DownloadFile (string address, string fileName)
  252. {
  253. if (address == null)
  254. throw new ArgumentNullException ("address");
  255. DownloadFile (CreateUri (address), fileName);
  256. }
  257. public void DownloadFile (Uri address, string fileName)
  258. {
  259. if (address == null)
  260. throw new ArgumentNullException ("address");
  261. if (fileName == null)
  262. throw new ArgumentNullException ("fileName");
  263. try {
  264. SetBusy ();
  265. async = false;
  266. DownloadFileCore (address, fileName, null);
  267. } catch (WebException) {
  268. throw;
  269. } catch (Exception ex) {
  270. throw new WebException ("An error occurred " +
  271. "performing a WebClient request.", ex);
  272. } finally {
  273. is_busy = false;
  274. }
  275. }
  276. void DownloadFileCore (Uri address, string fileName, object userToken)
  277. {
  278. WebRequest request = null;
  279. using (FileStream f = new FileStream (fileName, FileMode.Create)) {
  280. try {
  281. request = SetupRequest (address);
  282. WebResponse response = GetWebResponse (request);
  283. Stream st = response.GetResponseStream ();
  284. int cLength = (int) response.ContentLength;
  285. int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
  286. byte [] buffer = new byte [length];
  287. int nread = 0;
  288. long notify_total = 0;
  289. while ((nread = st.Read (buffer, 0, length)) != 0){
  290. if (async){
  291. notify_total += nread;
  292. OnDownloadProgressChanged (
  293. new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken));
  294. }
  295. f.Write (buffer, 0, nread);
  296. }
  297. } catch (ThreadInterruptedException){
  298. if (request != null)
  299. request.Abort ();
  300. throw;
  301. }
  302. }
  303. }
  304. // OpenRead
  305. public Stream OpenRead (string address)
  306. {
  307. if (address == null)
  308. throw new ArgumentNullException ("address");
  309. return OpenRead (CreateUri (address));
  310. }
  311. public Stream OpenRead (Uri address)
  312. {
  313. if (address == null)
  314. throw new ArgumentNullException ("address");
  315. WebRequest request = null;
  316. try {
  317. SetBusy ();
  318. async = false;
  319. request = SetupRequest (address);
  320. WebResponse response = GetWebResponse (request);
  321. return response.GetResponseStream ();
  322. } catch (WebException) {
  323. throw;
  324. } catch (Exception ex) {
  325. throw new WebException ("An error occurred " +
  326. "performing a WebClient request.", ex);
  327. } finally {
  328. is_busy = false;
  329. }
  330. }
  331. // OpenWrite
  332. public Stream OpenWrite (string address)
  333. {
  334. if (address == null)
  335. throw new ArgumentNullException ("address");
  336. return OpenWrite (CreateUri (address));
  337. }
  338. public Stream OpenWrite (string address, string method)
  339. {
  340. if (address == null)
  341. throw new ArgumentNullException ("address");
  342. return OpenWrite (CreateUri (address), method);
  343. }
  344. public Stream OpenWrite (Uri address)
  345. {
  346. return OpenWrite (address, (string) null);
  347. }
  348. public Stream OpenWrite (Uri address, string method)
  349. {
  350. if (address == null)
  351. throw new ArgumentNullException ("address");
  352. try {
  353. SetBusy ();
  354. async = false;
  355. WebRequest request = SetupRequest (address, method, true);
  356. return request.GetRequestStream ();
  357. } catch (WebException) {
  358. throw;
  359. } catch (Exception ex) {
  360. throw new WebException ("An error occurred " +
  361. "performing a WebClient request.", ex);
  362. } finally {
  363. is_busy = false;
  364. }
  365. }
  366. private string DetermineMethod (Uri address, string method, bool is_upload)
  367. {
  368. if (method != null)
  369. return method;
  370. if (address.Scheme == Uri.UriSchemeFtp)
  371. return (is_upload) ? "STOR" : "RETR";
  372. return (is_upload) ? "POST" : "GET";
  373. }
  374. // UploadData
  375. public byte [] UploadData (string address, byte [] data)
  376. {
  377. if (address == null)
  378. throw new ArgumentNullException ("address");
  379. return UploadData (CreateUri (address), data);
  380. }
  381. public byte [] UploadData (string address, string method, byte [] data)
  382. {
  383. if (address == null)
  384. throw new ArgumentNullException ("address");
  385. return UploadData (CreateUri (address), method, data);
  386. }
  387. public byte [] UploadData (Uri address, byte [] data)
  388. {
  389. return UploadData (address, (string) null, data);
  390. }
  391. public byte [] UploadData (Uri address, string method, byte [] data)
  392. {
  393. if (address == null)
  394. throw new ArgumentNullException ("address");
  395. if (data == null)
  396. throw new ArgumentNullException ("data");
  397. try {
  398. SetBusy ();
  399. async = false;
  400. return UploadDataCore (address, method, data, null);
  401. } catch (WebException) {
  402. throw;
  403. } catch (Exception ex) {
  404. throw new WebException ("An error occurred " +
  405. "performing a WebClient request.", ex);
  406. } finally {
  407. is_busy = false;
  408. }
  409. }
  410. byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
  411. {
  412. WebRequest request = SetupRequest (address, method, true);
  413. try {
  414. int contentLength = data.Length;
  415. request.ContentLength = contentLength;
  416. using (Stream stream = request.GetRequestStream ()) {
  417. stream.Write (data, 0, contentLength);
  418. }
  419. return ReadAll (request, userToken);
  420. } catch (ThreadInterruptedException){
  421. if (request != null)
  422. request.Abort ();
  423. throw;
  424. }
  425. }
  426. // UploadFile
  427. public byte [] UploadFile (string address, string fileName)
  428. {
  429. if (address == null)
  430. throw new ArgumentNullException ("address");
  431. return UploadFile (CreateUri (address), fileName);
  432. }
  433. public byte [] UploadFile (Uri address, string fileName)
  434. {
  435. return UploadFile (address, (string) null, fileName);
  436. }
  437. public byte [] UploadFile (string address, string method, string fileName)
  438. {
  439. return UploadFile (CreateUri (address), method, fileName);
  440. }
  441. public byte [] UploadFile (Uri address, string method, string fileName)
  442. {
  443. if (address == null)
  444. throw new ArgumentNullException ("address");
  445. if (fileName == null)
  446. throw new ArgumentNullException ("fileName");
  447. try {
  448. SetBusy ();
  449. async = false;
  450. return UploadFileCore (address, method, fileName, null);
  451. } catch (WebException) {
  452. throw;
  453. } catch (Exception ex) {
  454. throw new WebException ("An error occurred " +
  455. "performing a WebClient request.", ex);
  456. } finally {
  457. is_busy = false;
  458. }
  459. }
  460. byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
  461. {
  462. string fileCType = Headers ["Content-Type"];
  463. if (fileCType != null) {
  464. string lower = fileCType.ToLower ();
  465. if (lower.StartsWith ("multipart/"))
  466. throw new WebException ("Content-Type cannot be set to a multipart" +
  467. " type for this request.");
  468. } else {
  469. fileCType = "application/octet-stream";
  470. }
  471. bool needs_boundary = (method != "PUT"); // only verified case so far
  472. string boundary = null;
  473. if (needs_boundary) {
  474. boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
  475. Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
  476. }
  477. Stream reqStream = null;
  478. Stream fStream = null;
  479. byte [] resultBytes = null;
  480. fileName = Path.GetFullPath (fileName);
  481. WebRequest request = null;
  482. try {
  483. fStream = File.OpenRead (fileName);
  484. request = SetupRequest (address, method, true);
  485. reqStream = request.GetRequestStream ();
  486. byte [] bytes_boundary = null;
  487. if (needs_boundary) {
  488. bytes_boundary = Encoding.ASCII.GetBytes (boundary);
  489. reqStream.WriteByte ((byte) '-');
  490. reqStream.WriteByte ((byte) '-');
  491. reqStream.Write (bytes_boundary, 0, bytes_boundary.Length);
  492. reqStream.WriteByte ((byte) '\r');
  493. reqStream.WriteByte ((byte) '\n');
  494. string partHeaders = String.Format ("Content-Disposition: form-data; " +
  495. "name=\"file\"; filename=\"{0}\"\r\n" +
  496. "Content-Type: {1}\r\n\r\n",
  497. Path.GetFileName (fileName), fileCType);
  498. byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
  499. reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
  500. }
  501. int nread;
  502. long bytes_sent = 0;
  503. long file_size = -1;
  504. long step = 16384; // every 16kB
  505. if (fStream.CanSeek) {
  506. file_size = fStream.Length;
  507. step = file_size / 100;
  508. }
  509. var upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, 0, userToken);
  510. OnUploadProgressChanged (upload_args);
  511. byte [] buffer = new byte [4096];
  512. long sum = 0;
  513. while ((nread = fStream.Read (buffer, 0, 4096)) > 0) {
  514. reqStream.Write (buffer, 0, nread);
  515. bytes_sent += nread;
  516. sum += nread;
  517. if (sum >= step || nread < 4096) {
  518. int percent = 0;
  519. if (file_size > 0)
  520. percent = (int) (bytes_sent * 100 / file_size);
  521. upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, percent, userToken);
  522. OnUploadProgressChanged (upload_args);
  523. sum = 0;
  524. }
  525. }
  526. if (needs_boundary) {
  527. reqStream.WriteByte ((byte) '\r');
  528. reqStream.WriteByte ((byte) '\n');
  529. reqStream.WriteByte ((byte) '-');
  530. reqStream.WriteByte ((byte) '-');
  531. reqStream.Write (bytes_boundary, 0, bytes_boundary.Length);
  532. reqStream.WriteByte ((byte) '-');
  533. reqStream.WriteByte ((byte) '-');
  534. reqStream.WriteByte ((byte) '\r');
  535. reqStream.WriteByte ((byte) '\n');
  536. }
  537. reqStream.Close ();
  538. reqStream = null;
  539. resultBytes = ReadAll (request, userToken);
  540. } catch (ThreadInterruptedException){
  541. if (request != null)
  542. request.Abort ();
  543. throw;
  544. } finally {
  545. if (fStream != null)
  546. fStream.Close ();
  547. if (reqStream != null)
  548. reqStream.Close ();
  549. }
  550. return resultBytes;
  551. }
  552. public byte[] UploadValues (string address, NameValueCollection data)
  553. {
  554. if (address == null)
  555. throw new ArgumentNullException ("address");
  556. return UploadValues (CreateUri (address), data);
  557. }
  558. public byte[] UploadValues (string address, string method, NameValueCollection data)
  559. {
  560. if (address == null)
  561. throw new ArgumentNullException ("address");
  562. return UploadValues (CreateUri (address), method, data);
  563. }
  564. public byte[] UploadValues (Uri address, NameValueCollection data)
  565. {
  566. return UploadValues (address, (string) null, data);
  567. }
  568. public byte[] UploadValues (Uri address, string method, NameValueCollection data)
  569. {
  570. if (address == null)
  571. throw new ArgumentNullException ("address");
  572. if (data == null)
  573. throw new ArgumentNullException ("data");
  574. try {
  575. SetBusy ();
  576. async = false;
  577. return UploadValuesCore (address, method, data, null);
  578. } catch (WebException) {
  579. throw;
  580. } catch (Exception ex) {
  581. throw new WebException ("An error occurred " +
  582. "performing a WebClient request.", ex);
  583. } finally {
  584. is_busy = false;
  585. }
  586. }
  587. byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
  588. {
  589. string cType = Headers ["Content-Type"];
  590. if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
  591. throw new WebException ("Content-Type header cannot be changed from its default " +
  592. "value for this request.");
  593. Headers ["Content-Type"] = urlEncodedCType;
  594. WebRequest request = SetupRequest (uri, method, true);
  595. try {
  596. MemoryStream tmpStream = new MemoryStream ();
  597. foreach (string key in data) {
  598. byte [] bytes = Encoding.UTF8.GetBytes (key);
  599. UrlEncodeAndWrite (tmpStream, bytes);
  600. tmpStream.WriteByte ((byte) '=');
  601. bytes = Encoding.UTF8.GetBytes (data [key]);
  602. UrlEncodeAndWrite (tmpStream, bytes);
  603. tmpStream.WriteByte ((byte) '&');
  604. }
  605. int length = (int) tmpStream.Length;
  606. if (length > 0)
  607. tmpStream.SetLength (--length); // remove trailing '&'
  608. byte [] buf = tmpStream.GetBuffer ();
  609. request.ContentLength = length;
  610. using (Stream rqStream = request.GetRequestStream ()) {
  611. rqStream.Write (buf, 0, length);
  612. }
  613. tmpStream.Close ();
  614. return ReadAll (request, userToken);
  615. } catch (ThreadInterruptedException) {
  616. request.Abort ();
  617. throw;
  618. }
  619. }
  620. public string DownloadString (string address)
  621. {
  622. if (address == null)
  623. throw new ArgumentNullException ("address");
  624. return encoding.GetString (DownloadData (CreateUri (address)));
  625. }
  626. public string DownloadString (Uri address)
  627. {
  628. if (address == null)
  629. throw new ArgumentNullException ("address");
  630. return encoding.GetString (DownloadData (CreateUri (address)));
  631. }
  632. public string UploadString (string address, string data)
  633. {
  634. if (address == null)
  635. throw new ArgumentNullException ("address");
  636. if (data == null)
  637. throw new ArgumentNullException ("data");
  638. byte [] resp = UploadData (address, encoding.GetBytes (data));
  639. return encoding.GetString (resp);
  640. }
  641. public string UploadString (string address, string method, string data)
  642. {
  643. if (address == null)
  644. throw new ArgumentNullException ("address");
  645. if (data == null)
  646. throw new ArgumentNullException ("data");
  647. byte [] resp = UploadData (address, method, encoding.GetBytes (data));
  648. return encoding.GetString (resp);
  649. }
  650. public string UploadString (Uri address, string data)
  651. {
  652. if (address == null)
  653. throw new ArgumentNullException ("address");
  654. if (data == null)
  655. throw new ArgumentNullException ("data");
  656. byte [] resp = UploadData (address, encoding.GetBytes (data));
  657. return encoding.GetString (resp);
  658. }
  659. public string UploadString (Uri address, string method, string data)
  660. {
  661. if (address == null)
  662. throw new ArgumentNullException ("address");
  663. if (data == null)
  664. throw new ArgumentNullException ("data");
  665. byte [] resp = UploadData (address, method, encoding.GetBytes (data));
  666. return encoding.GetString (resp);
  667. }
  668. public event DownloadDataCompletedEventHandler DownloadDataCompleted;
  669. public event AsyncCompletedEventHandler DownloadFileCompleted;
  670. public event DownloadProgressChangedEventHandler DownloadProgressChanged;
  671. public event DownloadStringCompletedEventHandler DownloadStringCompleted;
  672. public event OpenReadCompletedEventHandler OpenReadCompleted;
  673. public event OpenWriteCompletedEventHandler OpenWriteCompleted;
  674. public event UploadDataCompletedEventHandler UploadDataCompleted;
  675. public event UploadFileCompletedEventHandler UploadFileCompleted;
  676. public event UploadProgressChangedEventHandler UploadProgressChanged;
  677. public event UploadStringCompletedEventHandler UploadStringCompleted;
  678. public event UploadValuesCompletedEventHandler UploadValuesCompleted;
  679. Uri CreateUri (string address)
  680. {
  681. Uri uri;
  682. try {
  683. if (baseAddress == null)
  684. uri = new Uri (address);
  685. else
  686. uri = new Uri (baseAddress, address);
  687. return CreateUri (uri);
  688. } catch {
  689. }
  690. return new Uri (Path.GetFullPath (address));
  691. }
  692. Uri CreateUri (Uri address)
  693. {
  694. Uri result = address;
  695. if (baseAddress != null && !result.IsAbsoluteUri) {
  696. try {
  697. result = new Uri (baseAddress, result.OriginalString);
  698. } catch {
  699. return result; // Not much we can do here.
  700. }
  701. }
  702. string query = result.Query;
  703. if (String.IsNullOrEmpty (query))
  704. query = GetQueryString (true);
  705. UriBuilder builder = new UriBuilder (address);
  706. if (!String.IsNullOrEmpty (query))
  707. builder.Query = query.Substring (1);
  708. return builder.Uri;
  709. }
  710. string GetQueryString (bool add_qmark)
  711. {
  712. if (queryString == null || queryString.Count == 0)
  713. return null;
  714. StringBuilder sb = new StringBuilder ();
  715. if (add_qmark)
  716. sb.Append ('?');
  717. foreach (string key in queryString)
  718. sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
  719. if (sb.Length != 0)
  720. sb.Length--; // removes last '&' or the '?' if empty.
  721. if (sb.Length == 0)
  722. return null;
  723. return sb.ToString ();
  724. }
  725. WebRequest SetupRequest (Uri uri)
  726. {
  727. WebRequest request = GetWebRequest (uri);
  728. if (proxySet)
  729. request.Proxy = Proxy;
  730. if (credentials != null)
  731. request.Credentials = credentials;
  732. else if (!String.IsNullOrEmpty (uri.UserInfo)) {
  733. // Perhaps this should be done by the underlying URI handler?
  734. ICredentials creds = GetCredentials (uri.UserInfo);
  735. if (creds != null)
  736. request.Credentials = creds;
  737. }
  738. // Special headers. These are properties of HttpWebRequest.
  739. // What do we do with other requests differnt from HttpWebRequest?
  740. if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
  741. HttpWebRequest req = (HttpWebRequest) request;
  742. string expect = headers ["Expect"];
  743. string contentType = headers ["Content-Type"];
  744. string accept = headers ["Accept"];
  745. string connection = headers ["Connection"];
  746. string userAgent = headers ["User-Agent"];
  747. string referer = headers ["Referer"];
  748. headers.RemoveInternal ("Expect");
  749. headers.RemoveInternal ("Content-Type");
  750. headers.RemoveInternal ("Accept");
  751. headers.RemoveInternal ("Connection");
  752. headers.RemoveInternal ("Referer");
  753. headers.RemoveInternal ("User-Agent");
  754. request.Headers = headers;
  755. if (expect != null && expect.Length > 0)
  756. req.Expect = expect;
  757. if (accept != null && accept.Length > 0)
  758. req.Accept = accept;
  759. if (contentType != null && contentType.Length > 0)
  760. req.ContentType = contentType;
  761. if (connection != null && connection.Length > 0)
  762. req.Connection = connection;
  763. if (userAgent != null && userAgent.Length > 0)
  764. req.UserAgent = userAgent;
  765. if (referer != null && referer.Length > 0)
  766. req.Referer = referer;
  767. }
  768. responseHeaders = null;
  769. return request;
  770. }
  771. WebRequest SetupRequest (Uri uri, string method, bool is_upload)
  772. {
  773. WebRequest request = SetupRequest (uri);
  774. request.Method = DetermineMethod (uri, method, is_upload);
  775. return request;
  776. }
  777. static NetworkCredential GetCredentials (string user_info)
  778. {
  779. string [] creds = user_info.Split (':');
  780. if (creds.Length != 2)
  781. return null;
  782. if (creds [0].IndexOf ('\\') != -1) {
  783. string [] user = creds [0].Split ('\\');
  784. if (user.Length != 2)
  785. return null;
  786. return new NetworkCredential (user [1], creds [1], user [0]);
  787. }
  788. return new NetworkCredential (creds [0], creds [1]);
  789. }
  790. byte [] ReadAll (WebRequest request, object userToken)
  791. {
  792. WebResponse response = GetWebResponse (request);
  793. Stream stream = response.GetResponseStream ();
  794. int length = (int) response.ContentLength;
  795. HttpWebRequest wreq = request as HttpWebRequest;
  796. if (length > -1 && wreq != null && (int) wreq.AutomaticDecompression != 0) {
  797. string content_encoding = ((HttpWebResponse) response).ContentEncoding;
  798. if (((content_encoding == "gzip" && (wreq.AutomaticDecompression & DecompressionMethods.GZip) != 0)) ||
  799. ((content_encoding == "deflate" && (wreq.AutomaticDecompression & DecompressionMethods.Deflate) != 0)))
  800. length = -1;
  801. }
  802. MemoryStream ms = null;
  803. bool nolength = (length == -1);
  804. int size = ((nolength) ? 8192 : length);
  805. if (nolength)
  806. ms = new MemoryStream ();
  807. long total = 0;
  808. int nread = 0;
  809. int offset = 0;
  810. byte [] buffer = new byte [size];
  811. while ((nread = stream.Read (buffer, offset, size)) != 0) {
  812. if (nolength) {
  813. ms.Write (buffer, 0, nread);
  814. } else {
  815. offset += nread;
  816. size -= nread;
  817. }
  818. if (async){
  819. total += nread;
  820. OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (total, length, userToken));
  821. }
  822. }
  823. if (nolength)
  824. return ms.ToArray ();
  825. return buffer;
  826. }
  827. string UrlEncode (string str)
  828. {
  829. StringBuilder result = new StringBuilder ();
  830. int len = str.Length;
  831. for (int i = 0; i < len; i++) {
  832. char c = str [i];
  833. if (c == ' ')
  834. result.Append ('+');
  835. else if ((c < '0' && c != '-' && c != '.') ||
  836. (c < 'A' && c > '9') ||
  837. (c > 'Z' && c < 'a' && c != '_') ||
  838. (c > 'z')) {
  839. result.Append ('%');
  840. int idx = ((int) c) >> 4;
  841. result.Append ((char) hexBytes [idx]);
  842. idx = ((int) c) & 0x0F;
  843. result.Append ((char) hexBytes [idx]);
  844. } else {
  845. result.Append (c);
  846. }
  847. }
  848. return result.ToString ();
  849. }
  850. static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
  851. {
  852. if (bytes == null)
  853. return;
  854. int len = bytes.Length;
  855. if (len == 0)
  856. return;
  857. for (int i = 0; i < len; i++) {
  858. char c = (char) bytes [i];
  859. if (c == ' ')
  860. stream.WriteByte ((byte) '+');
  861. else if ((c < '0' && c != '-' && c != '.') ||
  862. (c < 'A' && c > '9') ||
  863. (c > 'Z' && c < 'a' && c != '_') ||
  864. (c > 'z')) {
  865. stream.WriteByte ((byte) '%');
  866. int idx = ((int) c) >> 4;
  867. stream.WriteByte (hexBytes [idx]);
  868. idx = ((int) c) & 0x0F;
  869. stream.WriteByte (hexBytes [idx]);
  870. } else {
  871. stream.WriteByte ((byte) c);
  872. }
  873. }
  874. }
  875. public void CancelAsync ()
  876. {
  877. lock (this){
  878. #if NET_4_5
  879. if (cts != null) {
  880. cts.Cancel ();
  881. return;
  882. }
  883. #endif
  884. if (async_thread == null)
  885. return;
  886. //
  887. // We first flag things as done, in case the Interrupt hangs
  888. // or the thread decides to hang in some other way inside the
  889. // event handlers, or if we are stuck somewhere else. This
  890. // ensures that the WebClient object is reusable immediately
  891. //
  892. Thread t = async_thread;
  893. CompleteAsync ();
  894. t.Interrupt ();
  895. }
  896. }
  897. void CompleteAsync ()
  898. {
  899. lock (this) {
  900. is_busy = false;
  901. async_thread = null;
  902. #if NET_4_5
  903. if (cts != null)
  904. cts.Dispose ();
  905. cts = null;
  906. #endif
  907. }
  908. }
  909. // DownloadDataAsync
  910. public void DownloadDataAsync (Uri address)
  911. {
  912. DownloadDataAsync (address, null);
  913. }
  914. public void DownloadDataAsync (Uri address, object userToken)
  915. {
  916. if (address == null)
  917. throw new ArgumentNullException ("address");
  918. lock (this) {
  919. SetBusy ();
  920. async = true;
  921. async_thread = new Thread (delegate (object state) {
  922. object [] args = (object []) state;
  923. try {
  924. byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
  925. OnDownloadDataCompleted (
  926. new DownloadDataCompletedEventArgs (data, null, false, args [1]));
  927. } catch (Exception e){
  928. bool canceled = false;
  929. WebException we = e as WebException;
  930. if (we != null)
  931. canceled = we.Status == WebExceptionStatus.RequestCanceled;
  932. OnDownloadDataCompleted (
  933. new DownloadDataCompletedEventArgs (null, e, canceled, args [1]));
  934. }
  935. });
  936. object [] cb_args = new object [] {address, userToken};
  937. async_thread.Start (cb_args);
  938. }
  939. }
  940. // DownloadFileAsync
  941. public void DownloadFileAsync (Uri address, string fileName)
  942. {
  943. DownloadFileAsync (address, fileName, null);
  944. }
  945. public void DownloadFileAsync (Uri address, string fileName, object userToken)
  946. {
  947. if (address == null)
  948. throw new ArgumentNullException ("address");
  949. if (fileName == null)
  950. throw new ArgumentNullException ("fileName");
  951. lock (this) {
  952. SetBusy ();
  953. async = true;
  954. async_thread = new Thread (delegate (object state) {
  955. object [] args = (object []) state;
  956. try {
  957. DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
  958. OnDownloadFileCompleted (
  959. new AsyncCompletedEventArgs (null, false, args [2]));
  960. } catch (ThreadInterruptedException){
  961. OnDownloadFileCompleted (
  962. new AsyncCompletedEventArgs (null, true, args [2]));
  963. } catch (Exception e){
  964. OnDownloadFileCompleted (
  965. new AsyncCompletedEventArgs (e, false, args [2]));
  966. }});
  967. object [] cb_args = new object [] {address, fileName, userToken};
  968. async_thread.Start (cb_args);
  969. }
  970. }
  971. // DownloadStringAsync
  972. public void DownloadStringAsync (Uri address)
  973. {
  974. DownloadStringAsync (address, null);
  975. }
  976. public void DownloadStringAsync (Uri address, object userToken)
  977. {
  978. if (address == null)
  979. throw new ArgumentNullException ("address");
  980. lock (this) {
  981. SetBusy ();
  982. async = true;
  983. async_thread = new Thread (delegate (object state) {
  984. object [] args = (object []) state;
  985. try {
  986. string data = encoding.GetString (DownloadDataCore ((Uri) args [0], args [1]));
  987. OnDownloadStringCompleted (
  988. new DownloadStringCompletedEventArgs (data, null, false, args [1]));
  989. } catch (Exception e){
  990. bool canceled = false;
  991. WebException we = e as WebException;
  992. if (we != null)
  993. canceled = we.Status == WebExceptionStatus.RequestCanceled;
  994. OnDownloadStringCompleted (
  995. new DownloadStringCompletedEventArgs (null, e, canceled, args [1]));
  996. }});
  997. object [] cb_args = new object [] {address, userToken};
  998. async_thread.Start (cb_args);
  999. }
  1000. }
  1001. // OpenReadAsync
  1002. public void OpenReadAsync (Uri address)
  1003. {
  1004. OpenReadAsync (address, null);
  1005. }
  1006. public void OpenReadAsync (Uri address, object userToken)
  1007. {
  1008. if (address == null)
  1009. throw new ArgumentNullException ("address");
  1010. lock (this) {
  1011. SetBusy ();
  1012. async = true;
  1013. async_thread = new Thread (delegate (object state) {
  1014. object [] args = (object []) state;
  1015. WebRequest request = null;
  1016. try {
  1017. request = SetupRequest ((Uri) args [0]);
  1018. WebResponse response = GetWebResponse (request);
  1019. Stream stream = response.GetResponseStream ();
  1020. OnOpenReadCompleted (
  1021. new OpenReadCompletedEventArgs (stream, null, false, args [1]));
  1022. } catch (ThreadInterruptedException){
  1023. if (request != null)
  1024. request.Abort ();
  1025. OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, args [1]));
  1026. } catch (Exception e){
  1027. OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, e, false, args [1]));
  1028. } });
  1029. object [] cb_args = new object [] {address, userToken};
  1030. async_thread.Start (cb_args);
  1031. }
  1032. }
  1033. // OpenWriteAsync
  1034. public void OpenWriteAsync (Uri address)
  1035. {
  1036. OpenWriteAsync (address, null);
  1037. }
  1038. public void OpenWriteAsync (Uri address, string method)
  1039. {
  1040. OpenWriteAsync (address, method, null);
  1041. }
  1042. public void OpenWriteAsync (Uri address, string method, object userToken)
  1043. {
  1044. if (address == null)
  1045. throw new ArgumentNullException ("address");
  1046. lock (this) {
  1047. SetBusy ();
  1048. async = true;
  1049. async_thread = new Thread (delegate (object state) {
  1050. object [] args = (object []) state;
  1051. WebRequest request = null;
  1052. try {
  1053. request = SetupRequest ((Uri) args [0], (string) args [1], true);
  1054. Stream stream = request.GetRequestStream ();
  1055. OnOpenWriteCompleted (
  1056. new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
  1057. } catch (ThreadInterruptedException){
  1058. if (request != null)
  1059. request.Abort ();
  1060. OnOpenWriteCompleted (
  1061. new OpenWriteCompletedEventArgs (null, null, true, args [2]));
  1062. } catch (Exception e){
  1063. OnOpenWriteCompleted (
  1064. new OpenWriteCompletedEventArgs (null, e, false, args [2]));
  1065. }});
  1066. object [] cb_args = new object [] {address, method, userToken};
  1067. async_thread.Start (cb_args);
  1068. }
  1069. }
  1070. // UploadDataAsync
  1071. public void UploadDataAsync (Uri address, byte [] data)
  1072. {
  1073. UploadDataAsync (address, null, data);
  1074. }
  1075. public void UploadDataAsync (Uri address, string method, byte [] data)
  1076. {
  1077. UploadDataAsync (address, method, data, null);
  1078. }
  1079. public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
  1080. {
  1081. if (address == null)
  1082. throw new ArgumentNullException ("address");
  1083. if (data == null)
  1084. throw new ArgumentNullException ("data");
  1085. lock (this) {
  1086. SetBusy ();
  1087. async = true;
  1088. async_thread = new Thread (delegate (object state) {
  1089. object [] args = (object []) state;
  1090. byte [] data2;
  1091. try {
  1092. data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
  1093. OnUploadDataCompleted (
  1094. new UploadDataCompletedEventArgs (data2, null, false, args [3]));
  1095. } catch (ThreadInterruptedException){
  1096. OnUploadDataCompleted (
  1097. new UploadDataCompletedEventArgs (null, null, true, args [3]));
  1098. } catch (Exception e){
  1099. OnUploadDataCompleted (
  1100. new UploadDataCompletedEventArgs (null, e, false, args [3]));
  1101. }});
  1102. object [] cb_args = new object [] {address, method, data, userToken};
  1103. async_thread.Start (cb_args);
  1104. }
  1105. }
  1106. // UploadFileAsync
  1107. public void UploadFileAsync (Uri address, string fileName)
  1108. {
  1109. UploadFileAsync (address, null, fileName);
  1110. }
  1111. public void UploadFileAsync (Uri address, string method, string fileName)
  1112. {
  1113. UploadFileAsync (address, method, fileName, null);
  1114. }
  1115. public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
  1116. {
  1117. if (address == null)
  1118. throw new ArgumentNullException ("address");
  1119. if (fileName == null)
  1120. throw new ArgumentNullException ("fileName");
  1121. lock (this) {
  1122. SetBusy ();
  1123. async = true;
  1124. async_thread = new Thread (delegate (object state) {
  1125. object [] args = (object []) state;
  1126. byte [] data;
  1127. try {
  1128. data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
  1129. OnUploadFileCompleted (
  1130. new UploadFileCompletedEventArgs (data, null, false, args [3]));
  1131. } catch (ThreadInterruptedException){
  1132. OnUploadFileCompleted (
  1133. new UploadFileCompletedEventArgs (null, null, true, args [3]));
  1134. } catch (Exception e){
  1135. OnUploadFileCompleted (
  1136. new UploadFileCompletedEventArgs (null, e, false, args [3]));
  1137. }});
  1138. object [] cb_args = new object [] {address, method, fileName, userToken};
  1139. async_thread.Start (cb_args);
  1140. }
  1141. }
  1142. // UploadStringAsync
  1143. public void UploadStringAsync (Uri address, string data)
  1144. {
  1145. UploadStringAsync (address, null, data);
  1146. }
  1147. public void UploadStringAsync (Uri address, string method, string data)
  1148. {
  1149. UploadStringAsync (address, method, data, null);
  1150. }
  1151. public void UploadStringAsync (Uri address, string method, string data, object userToken)
  1152. {
  1153. if (address == null)
  1154. throw new ArgumentNullException ("address");
  1155. if (data == null)
  1156. throw new ArgumentNullException ("data");
  1157. lock (this) {
  1158. CheckBusy ();
  1159. async = true;
  1160. async_thread = new Thread (delegate (object state) {
  1161. object [] args = (object []) state;
  1162. try {
  1163. string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
  1164. OnUploadStringCompleted (
  1165. new UploadStringCompletedEventArgs (data2, null, false, args [3]));
  1166. } catch (ThreadInterruptedException){
  1167. OnUploadStringCompleted (
  1168. new UploadStringCompletedEventArgs (null, null, true, args [3]));
  1169. } catch (Exception e){
  1170. OnUploadStringCompleted (
  1171. new UploadStringCompletedEventArgs (null, e, false, args [3]));
  1172. }});
  1173. object [] cb_args = new object [] {address, method, data, userToken};
  1174. async_thread.Start (cb_args);
  1175. }
  1176. }
  1177. // UploadValuesAsync
  1178. public void UploadValuesAsync (Uri address, NameValueCollection data)
  1179. {
  1180. UploadValuesAsync (address, null, data);
  1181. }
  1182. public void UploadValuesAsync (Uri address, string method, NameValueCollection data)
  1183. {
  1184. UploadValuesAsync (address, method, data, null);
  1185. }
  1186. public void UploadValuesAsync (Uri address, string method, NameValueCollection data, object userToken)
  1187. {
  1188. if (address == null)
  1189. throw new ArgumentNullException ("address");
  1190. if (data == null)
  1191. throw new ArgumentNullException ("data");
  1192. lock (this) {
  1193. CheckBusy ();
  1194. async = true;
  1195. async_thread = new Thread (delegate (object state) {
  1196. object [] args = (object []) state;
  1197. try {
  1198. byte [] values = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
  1199. OnUploadValuesCompleted (
  1200. new UploadValuesCompletedEventArgs (values, null, false, args [3]));
  1201. } catch (ThreadInterruptedException){
  1202. OnUploadValuesCompleted (
  1203. new UploadValuesCompletedEventArgs (null, null, true, args [3]));
  1204. } catch (Exception e){
  1205. OnUploadValuesCompleted (
  1206. new UploadValuesCompletedEventArgs (null, e, false, args [3]));
  1207. }});
  1208. object [] cb_args = new object [] {address, method, data, userToken};
  1209. async_thread.Start (cb_args);
  1210. }
  1211. }
  1212. protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs e)
  1213. {
  1214. CompleteAsync ();
  1215. if (DownloadDataCompleted != null)
  1216. DownloadDataCompleted (this, e);
  1217. }
  1218. protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs e)
  1219. {
  1220. CompleteAsync ();
  1221. if (DownloadFileCompleted != null)
  1222. DownloadFileCompleted (this, e);
  1223. }
  1224. protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
  1225. {
  1226. if (DownloadProgressChanged != null)
  1227. DownloadProgressChanged (this, e);
  1228. }
  1229. protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs e)
  1230. {
  1231. CompleteAsync ();
  1232. if (DownloadStringCompleted != null)
  1233. DownloadStringCompleted (this, e);
  1234. }
  1235. protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs e)
  1236. {
  1237. CompleteAsync ();
  1238. if (OpenReadCompleted != null)
  1239. OpenReadCompleted (this, e);
  1240. }
  1241. protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs e)
  1242. {
  1243. CompleteAsync ();
  1244. if (OpenWriteCompleted != null)
  1245. OpenWriteCompleted (this, e);
  1246. }
  1247. protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs e)
  1248. {
  1249. CompleteAsync ();
  1250. if (UploadDataCompleted != null)
  1251. UploadDataCompleted (this, e);
  1252. }
  1253. protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs e)
  1254. {
  1255. CompleteAsync ();
  1256. if (UploadFileCompleted != null)
  1257. UploadFileCompleted (this, e);
  1258. }
  1259. protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
  1260. {
  1261. if (UploadProgressChanged != null)
  1262. UploadProgressChanged (this, e);
  1263. }
  1264. protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs e)
  1265. {
  1266. CompleteAsync ();
  1267. if (UploadStringCompleted != null)
  1268. UploadStringCompleted (this, e);
  1269. }
  1270. protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs e)
  1271. {
  1272. CompleteAsync ();
  1273. if (UploadValuesCompleted != null)
  1274. UploadValuesCompleted (this, e);
  1275. }
  1276. protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
  1277. {
  1278. WebResponse response = request.EndGetResponse (result);
  1279. responseHeaders = response.Headers;
  1280. return response;
  1281. }
  1282. protected virtual WebRequest GetWebRequest (Uri address)
  1283. {
  1284. return WebRequest.Create (address);
  1285. }
  1286. protected virtual WebResponse GetWebResponse (WebRequest request)
  1287. {
  1288. WebResponse response = request.GetResponse ();
  1289. responseHeaders = response.Headers;
  1290. return response;
  1291. }
  1292. #if NET_4_5
  1293. // DownloadDataTaskAsync
  1294. public Task<byte[]> DownloadDataTaskAsync (string address)
  1295. {
  1296. return DownloadDataTaskAsync (CreateUri (address));
  1297. }
  1298. public async Task<byte[]> DownloadDataTaskAsync (Uri address)
  1299. {
  1300. WebRequest request = null;
  1301. WebResponse response = null;
  1302. try {
  1303. SetBusy ();
  1304. cts = new CancellationTokenSource ();
  1305. request = await SetupRequestAsync (address);
  1306. response = await GetWebResponseTaskAsync (request, cts.Token);
  1307. var result = await ReadAllTaskAsync (request, response, cts.Token);
  1308. OnDownloadDataCompleted (new DownloadDataCompletedEventArgs (result, null, false, null));
  1309. return result;
  1310. } catch (WebException ex) {
  1311. OnDownloadDataCompleted (new DownloadDataCompletedEventArgs (null, ex, false, null));
  1312. throw;
  1313. } catch (OperationCanceledException) {
  1314. if (request != null)
  1315. request.Abort ();
  1316. OnDownloadDataCompleted (new DownloadDataCompletedEventArgs (null, null, true, null));
  1317. throw;
  1318. } catch (Exception ex) {
  1319. OnDownloadDataCompleted (new DownloadDataCompletedEventArgs (null, ex, true, null));
  1320. throw new WebException ("An error occurred performing a WebClient request.", ex);
  1321. } finally {
  1322. if (response != null)
  1323. response.Close ();
  1324. }
  1325. }
  1326. Task<WebRequest> SetupRequestAsync (Uri address)
  1327. {
  1328. return Task.Factory.StartNew (() => SetupRequest (address));
  1329. }
  1330. async Task<WebRequest> SetupRequestAsync (Uri address, string method, bool is_upload)
  1331. {
  1332. WebRequest request = await SetupRequestAsync (address);
  1333. request.Method = DetermineMethod (address, method, is_upload);
  1334. return request;
  1335. }
  1336. async Task<WebResponse> GetWebResponseTaskAsync (WebRequest request, CancellationToken token)
  1337. {
  1338. token.ThrowIfCancellationRequested ();
  1339. WebResponse response = await request.GetResponseAsync ();
  1340. token.ThrowIfCancellationRequested ();
  1341. responseHeaders = response.Headers;
  1342. return response;
  1343. }
  1344. async Task<byte[]> ReadAllTaskAsync (WebRequest request, WebResponse response, CancellationToken token)
  1345. {
  1346. Stream stream = response.GetResponseStream ();
  1347. int length = (int)response.ContentLength;
  1348. HttpWebRequest wreq = request as HttpWebRequest;
  1349. if (length > -1 && wreq != null && (int)wreq.AutomaticDecompression != 0) {
  1350. string content_encoding = ((HttpWebResponse)response).ContentEncoding;
  1351. if (((content_encoding == "gzip" && (wreq.AutomaticDecompression & DecompressionMethods.GZip) != 0)) ||
  1352. ((content_encoding == "deflate" && (wreq.AutomaticDecompression & DecompressionMethods.Deflate) != 0)))
  1353. length = -1;
  1354. }
  1355. MemoryStream ms = null;
  1356. bool nolength = (length == -1);
  1357. int size = ((nolength) ? 8192 : length);
  1358. if (nolength)
  1359. ms = new MemoryStream ();
  1360. long total = 0;
  1361. int nread = 0;
  1362. int offset = 0;
  1363. byte [] buffer = new byte [size];
  1364. token.ThrowIfCancellationRequested ();
  1365. while ((nread = await stream.ReadAsync (buffer, offset, size, token)) != 0) {
  1366. if (nolength) {
  1367. ms.Write (buffer, 0, nread);
  1368. } else {
  1369. offset += nread;
  1370. size -= nread;
  1371. }
  1372. total += nread;
  1373. OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (total, length, null));
  1374. token.ThrowIfCancellationRequested ();
  1375. }
  1376. return nolength ? ms.ToArray () : buffer;
  1377. }
  1378. // DownloadFileTaskAsync
  1379. public Task DownloadFileTaskAsync (string address, string fileName)
  1380. {
  1381. if (address == null)
  1382. throw new ArgumentNullException ("address");
  1383. return DownloadFileTaskAsync (CreateUri (address), fileName);
  1384. }
  1385. public async Task DownloadFileTaskAsync (Uri address, string fileName)
  1386. {
  1387. if (address == null)
  1388. throw new ArgumentNullException ("address");
  1389. if (fileName == null)
  1390. throw new ArgumentNullException ("fileName");
  1391. WebRequest request = null;
  1392. WebResponse response = null;
  1393. try {
  1394. SetBusy ();
  1395. cts = new CancellationTokenSource ();
  1396. request = await SetupRequestAsync (address);
  1397. response = await GetWebResponseTaskAsync (request, cts.Token);
  1398. await DownloadFileTaskAsyncCore (request, response, fileName, cts.Token);
  1399. OnDownloadFileCompleted (new AsyncCompletedEventArgs (null, false, null));
  1400. } catch (WebException ex) {
  1401. OnDownloadFileCompleted (new AsyncCompletedEventArgs (ex, false, null));
  1402. throw;
  1403. } catch (OperationCanceledException) {
  1404. if (request != null)
  1405. request.Abort ();
  1406. OnDownloadFileCompleted (new AsyncCompletedEventArgs (null, true, null));
  1407. throw;
  1408. } catch (Exception ex) {
  1409. OnDownloadFileCompleted (new AsyncCompletedEventArgs (ex, false, null));
  1410. throw new WebException ("An error occurred " +
  1411. "performing a WebClient request.", ex);
  1412. } finally {
  1413. if (response != null)
  1414. response.Close ();
  1415. }
  1416. }
  1417. async Task DownloadFileTaskAsyncCore (WebRequest request, WebResponse response,
  1418. string fileName, CancellationToken token)
  1419. {
  1420. using (FileStream f = new FileStream (fileName, FileMode.Create)) {
  1421. Stream st = response.GetResponseStream ();
  1422. int cLength = (int)response.ContentLength;
  1423. int length = (cLength <= -1 || cLength > 32 * 1024) ? 32 * 1024 : cLength;
  1424. byte [] buffer = new byte [length];
  1425. int nread = 0;
  1426. long notify_total = 0;
  1427. token.ThrowIfCancellationRequested ();
  1428. while ((nread = await st.ReadAsync (buffer, 0, length, token)) != 0) {
  1429. notify_total += nread;
  1430. OnDownloadProgressChanged (
  1431. new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, null));
  1432. token.ThrowIfCancellationRequested ();
  1433. await f.WriteAsync (buffer, 0, nread, token);
  1434. token.ThrowIfCancellationRequested ();
  1435. }
  1436. }
  1437. }
  1438. // OpenReadTaskAsync
  1439. public Task<Stream> OpenReadTaskAsync (string address)
  1440. {
  1441. if (address == null)
  1442. throw new ArgumentNullException ("address");
  1443. return OpenReadTaskAsync (CreateUri (address));
  1444. }
  1445. public async Task<Stream> OpenReadTaskAsync (Uri address)
  1446. {
  1447. if (address == null)
  1448. throw new ArgumentNullException ("address");
  1449. WebRequest request = null;
  1450. try {
  1451. SetBusy ();
  1452. cts = new CancellationTokenSource ();
  1453. request = await SetupRequestAsync (address);
  1454. WebResponse response = await GetWebResponseTaskAsync (request, cts.Token);
  1455. var result = response.GetResponseStream ();
  1456. cts.Token.ThrowIfCancellationRequested ();
  1457. OnOpenReadCompleted (new OpenReadCompletedEventArgs (result, null, false, null));
  1458. return result;
  1459. } catch (WebException ex) {
  1460. OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, ex, false, null));
  1461. throw;
  1462. } catch (OperationCanceledException) {
  1463. if (request != null)
  1464. request.Abort ();
  1465. OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, null));
  1466. throw;
  1467. } catch (Exception ex) {
  1468. OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, ex, false, null));
  1469. throw new WebException ("An error occurred " +
  1470. "performing a WebClient request.", ex);
  1471. }
  1472. }
  1473. // DownloadStringTaskAsync
  1474. public Task<string> DownloadStringTaskAsync (string address)
  1475. {
  1476. if (address == null)
  1477. throw new ArgumentNullException ("address");
  1478. return DownloadStringTaskAsync (CreateUri (address));
  1479. }
  1480. public async Task<string> DownloadStringTaskAsync (Uri address)
  1481. {
  1482. if (address == null)
  1483. throw new ArgumentNullException ("address");
  1484. WebRequest request = null;
  1485. WebResponse response = null;
  1486. try {
  1487. SetBusy ();
  1488. cts = new CancellationTokenSource ();
  1489. request = await SetupRequestAsync (address);
  1490. response = await GetWebResponseTaskAsync (request, cts.Token);
  1491. var data = await ReadAllTaskAsync (request, response, cts.Token);
  1492. cts.Token.ThrowIfCancellationRequested ();
  1493. var text = encoding.GetString (data);
  1494. OnDownloadStringCompleted (new DownloadStringCompletedEventArgs (text, null, false, null));
  1495. return text;
  1496. } catch (WebException ex) {
  1497. OnDownloadStringCompleted (new DownloadStringCompletedEventArgs (null, ex, false, null));
  1498. throw;
  1499. } catch (OperationCanceledException) {
  1500. if (request != null)
  1501. request.Abort ();
  1502. OnDownloadStringCompleted (new DownloadStringCompletedEventArgs (null, null, true, null));
  1503. throw;
  1504. } catch (Exception ex) {
  1505. OnDownloadStringCompleted (new DownloadStringCompletedEventArgs (null, ex, true, null));
  1506. throw new WebException ("An error occurred performing a WebClient request.", ex);
  1507. } finally {
  1508. if (response != null)
  1509. response.Close ();
  1510. }
  1511. }
  1512. // OpenWriteTaskAsync
  1513. public Task<Stream> OpenWriteTaskAsync (string address)
  1514. {
  1515. if (address == null)
  1516. throw new ArgumentNullException ("address");
  1517. return OpenWriteTaskAsync (CreateUri (address));
  1518. }
  1519. public Task<Stream> OpenWriteTaskAsync (string address, string method)
  1520. {
  1521. if (address == null)
  1522. throw new ArgumentNullException ("address");
  1523. return OpenWriteTaskAsync (CreateUri (address), method);
  1524. }
  1525. public Task<Stream> OpenWriteTaskAsync (Uri address)
  1526. {
  1527. return OpenWriteTaskAsync (address, (string) null);
  1528. }
  1529. public async Task<Stream> OpenWriteTaskAsync (Uri address, string method)
  1530. {
  1531. if (address == null)
  1532. throw new ArgumentNullException ("address");
  1533. WebRequest request = null;
  1534. try {
  1535. SetBusy ();
  1536. cts = new CancellationTokenSource ();
  1537. request = SetupRequest (address);
  1538. return await request.GetRequestStreamAsync ();
  1539. } catch (WebException) {
  1540. throw;
  1541. } catch (OperationCanceledException) {
  1542. if (request != null)
  1543. request.Abort ();
  1544. throw;
  1545. } catch (Exception ex) {
  1546. throw new WebException ("An error occurred " +
  1547. "performing a WebClient request.", ex);
  1548. } finally {
  1549. CompleteAsync ();
  1550. }
  1551. }
  1552. // UploadDataTaskAsync
  1553. public Task<byte[]> UploadDataTaskAsync (string address, byte [] data)
  1554. {
  1555. if (address == null)
  1556. throw new ArgumentNullException ("address");
  1557. return UploadDataTaskAsync (CreateUri (address), data);
  1558. }
  1559. public Task<byte[]> UploadDataTaskAsync (string address, string method, byte [] data)
  1560. {
  1561. if (address == null)
  1562. throw new ArgumentNullException ("address");
  1563. return UploadDataTaskAsync (CreateUri (address), method, data);
  1564. }
  1565. public Task<byte[]> UploadDataTaskAsync (Uri address, byte [] data)
  1566. {
  1567. return UploadDataTaskAsync (address, (string) null, data);
  1568. }
  1569. public async Task<byte[]> UploadDataTaskAsync (Uri address, string method, byte [] data)
  1570. {
  1571. if (address == null)
  1572. throw new ArgumentNullException ("address");
  1573. if (data == null)
  1574. throw new ArgumentNullException ("data");
  1575. WebRequest request = null;
  1576. try {
  1577. SetBusy ();
  1578. cts = new CancellationTokenSource ();
  1579. request = await SetupRequestAsync (address, method, true);
  1580. var result = await UploadDataTaskAsyncCore (request, data, cts.Token);
  1581. OnUploadDataCompleted (new UploadDataCompletedEventArgs (result, null, false, null));
  1582. return result;
  1583. } catch (WebException ex) {
  1584. OnUploadDataCompleted (new UploadDataCompletedEventArgs (null, ex, false, null));
  1585. throw;
  1586. } catch (OperationCanceledException) {
  1587. if (request != null)
  1588. request.Abort ();
  1589. OnUploadDataCompleted (new UploadDataCompletedEventArgs (null, null, true, null));
  1590. throw;
  1591. } catch (Exception ex) {
  1592. OnUploadDataCompleted (new UploadDataCompletedEventArgs (null, ex, true, null));
  1593. throw new WebException ("An error occurred performing a WebClient request.", ex);
  1594. }
  1595. }
  1596. async Task<byte[]> UploadDataTaskAsyncCore (WebRequest request, byte[] data, CancellationToken token)
  1597. {
  1598. token.ThrowIfCancellationRequested ();
  1599. int contentLength = data.Length;
  1600. request.ContentLength = contentLength;
  1601. using (Stream stream = await request.GetRequestStreamAsync ()) {
  1602. token.ThrowIfCancellationRequested ();
  1603. await stream.WriteAsync (data, 0, contentLength, token);
  1604. token.ThrowIfCancellationRequested ();
  1605. }
  1606. WebResponse response = null;
  1607. try {
  1608. response = await GetWebResponseTaskAsync (request, token);
  1609. return await ReadAllTaskAsync (request, response, token);
  1610. } finally {
  1611. if (response != null)
  1612. response.Close ();
  1613. }
  1614. }
  1615. // UploadFileTaskAsync
  1616. public Task<byte[]> UploadFileTaskAsync (string address, string fileName)
  1617. {
  1618. if (address == null)
  1619. throw new ArgumentNullException ("address");
  1620. return UploadFileTaskAsync (CreateUri (address), fileName);
  1621. }
  1622. public Task<byte[]> UploadFileTaskAsync (Uri address, string fileName)
  1623. {
  1624. return UploadFileTaskAsync (address, (string) null, fileName);
  1625. }
  1626. public Task<byte[]> UploadFileTaskAsync (string address, string method, string fileName)
  1627. {
  1628. return UploadFileTaskAsync (CreateUri (address), method, fileName);
  1629. }
  1630. public async Task<byte[]> UploadFileTaskAsync (Uri address, string method, string fileName)
  1631. {
  1632. if (address == null)
  1633. throw new ArgumentNullException ("address");
  1634. if (fileName == null)
  1635. throw new ArgumentNullException ("fileName");
  1636. WebRequest request = null;
  1637. try {
  1638. SetBusy ();
  1639. cts = new CancellationTokenSource ();
  1640. request = await SetupRequestAsync (address, method, true);
  1641. var result = await UploadFileTaskAsyncCore (request, method, fileName, cts.Token);
  1642. OnUploadFileCompleted (new UploadFileCompletedEventArgs (result, null, false, null));
  1643. return result;
  1644. } catch (WebException ex) {
  1645. OnUploadFileCompleted (new UploadFileCompletedEventArgs (null, ex, false, null));
  1646. throw;
  1647. } catch (OperationCanceledException) {
  1648. if (request != null)
  1649. request.Abort ();
  1650. OnUploadFileCompleted (new UploadFileCompletedEventArgs (null, null, true, null));
  1651. throw;
  1652. } catch (Exception ex) {
  1653. OnUploadFileCompleted (new UploadFileCompletedEventArgs (null, ex, true, null));
  1654. throw new WebException ("An error occurred performing a WebClient request.", ex);
  1655. }
  1656. }
  1657. async Task<byte[]> UploadFileTaskAsyncCore (WebRequest request, string method,
  1658. string fileName, CancellationToken token)
  1659. {
  1660. token.ThrowIfCancellationRequested ();
  1661. string fileCType = Headers ["Content-Type"];
  1662. if (fileCType != null) {
  1663. string lower = fileCType.ToLower ();
  1664. if (lower.StartsWith ("multipart/"))
  1665. throw new WebException ("Content-Type cannot be set to a multipart" +
  1666. " type for this request.");
  1667. } else {
  1668. fileCType = "application/octet-stream";
  1669. }
  1670. bool needs_boundary = (method != "PUT"); // only verified case so far
  1671. string boundary = null;
  1672. if (needs_boundary) {
  1673. boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
  1674. Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
  1675. }
  1676. Stream reqStream = null;
  1677. Stream fStream = null;
  1678. WebResponse response = null;
  1679. fileName = Path.GetFullPath (fileName);
  1680. try {
  1681. fStream = File.OpenRead (fileName);
  1682. token.ThrowIfCancellationRequested ();
  1683. reqStream = await request.GetRequestStreamAsync ();
  1684. token.ThrowIfCancellationRequested ();
  1685. byte [] bytes_boundary = null;
  1686. if (needs_boundary) {
  1687. bytes_boundary = Encoding.ASCII.GetBytes (boundary);
  1688. using (MemoryStream ms = new MemoryStream ()) {
  1689. ms.WriteByte ((byte) '-');
  1690. ms.WriteByte ((byte) '-');
  1691. ms.Write (bytes_boundary, 0, bytes_boundary.Length);
  1692. ms.WriteByte ((byte) '\r');
  1693. ms.WriteByte ((byte) '\n');
  1694. string partHeaders = String.Format (
  1695. "Content-Disposition: form-data; " +
  1696. "name=\"file\"; filename=\"{0}\"\r\n" +
  1697. "Content-Type: {1}\r\n\r\n",
  1698. Path.GetFileName (fileName), fileCType);
  1699. byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
  1700. ms.Write (partHeadersBytes, 0, partHeadersBytes.Length);
  1701. await ms.CopyToAsync (reqStream, (int)ms.Position, token);
  1702. }
  1703. }
  1704. int nread;
  1705. long bytes_sent = 0;
  1706. long file_size = -1;
  1707. long step = 16384; // every 16kB
  1708. if (fStream.CanSeek) {
  1709. file_size = fStream.Length;
  1710. step = file_size / 100;
  1711. }
  1712. var upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, 0, null);
  1713. OnUploadProgressChanged (upload_args);
  1714. byte [] buffer = new byte [4096];
  1715. long sum = 0;
  1716. token.ThrowIfCancellationRequested ();
  1717. while ((nread = await fStream.ReadAsync (buffer, 0, 4096, token)) > 0) {
  1718. token.ThrowIfCancellationRequested ();
  1719. await reqStream.WriteAsync (buffer, 0, nread, token);
  1720. bytes_sent += nread;
  1721. sum += nread;
  1722. if (sum >= step || nread < 4096) {
  1723. int percent = 0;
  1724. if (file_size > 0)
  1725. percent = (int) (bytes_sent * 100 / file_size);
  1726. upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, percent, null);
  1727. OnUploadProgressChanged (upload_args);
  1728. sum = 0;
  1729. }
  1730. }
  1731. if (needs_boundary) {
  1732. using (MemoryStream ms = new MemoryStream ()) {
  1733. ms.WriteByte ((byte) '\r');
  1734. ms.WriteByte ((byte) '\n');
  1735. ms.WriteByte ((byte) '-');
  1736. ms.WriteByte ((byte) '-');
  1737. ms.Write (bytes_boundary, 0, bytes_boundary.Length);
  1738. ms.WriteByte ((byte) '-');
  1739. ms.WriteByte ((byte) '-');
  1740. ms.WriteByte ((byte) '\r');
  1741. ms.WriteByte ((byte) '\n');
  1742. await ms.CopyToAsync (reqStream, (int)ms.Position, token);
  1743. }
  1744. }
  1745. reqStream.Close ();
  1746. reqStream = null;
  1747. response = await GetWebResponseTaskAsync (request, token);
  1748. return await ReadAllTaskAsync (request, response, token);
  1749. } finally {
  1750. if (fStream != null)
  1751. fStream.Close ();
  1752. if (reqStream != null)
  1753. reqStream.Close ();
  1754. if (response != null)
  1755. response.Close ();
  1756. }
  1757. }
  1758. // UploadStringTaskAsync
  1759. public Task<string> UploadStringTaskAsync (string address, string data)
  1760. {
  1761. if (address == null)
  1762. throw new ArgumentNullException ("address");
  1763. if (data == null)
  1764. throw new ArgumentNullException ("data");
  1765. return UploadStringTaskAsync (CreateUri (address), null, data);
  1766. }
  1767. public Task<string> UploadStringTaskAsync (string address, string method, string data)
  1768. {
  1769. if (address == null)
  1770. throw new ArgumentNullException ("address");
  1771. if (data == null)
  1772. throw new ArgumentNullException ("data");
  1773. return UploadStringTaskAsync (CreateUri (address), method, data);
  1774. }
  1775. public Task<string> UploadStringTaskAsync (Uri address, string data)
  1776. {
  1777. if (address == null)
  1778. throw new ArgumentNullException ("address");
  1779. if (data == null)
  1780. throw new ArgumentNullException ("data");
  1781. return UploadStringTaskAsync (address, null, data);
  1782. }
  1783. public async Task<string> UploadStringTaskAsync (Uri address, string method, string data)
  1784. {
  1785. if (address == null)
  1786. throw new ArgumentNullException ("address");
  1787. if (data == null)
  1788. throw new ArgumentNullException ("data");
  1789. WebRequest request = null;
  1790. try {
  1791. SetBusy ();
  1792. cts = new CancellationTokenSource ();
  1793. request = await SetupRequestAsync (address, method, true);
  1794. var result = await UploadDataTaskAsyncCore (request, encoding.GetBytes (data), cts.Token);
  1795. var result_str = encoding.GetString (result);
  1796. OnUploadStringCompleted (new UploadStringCompletedEventArgs (result_str, null, false, null));
  1797. return result_str;
  1798. } catch (WebException ex) {
  1799. OnUploadStringCompleted (new UploadStringCompletedEventArgs (null, ex, false, null));
  1800. throw;
  1801. } catch (OperationCanceledException) {
  1802. if (request != null)
  1803. request.Abort ();
  1804. OnUploadStringCompleted (new UploadStringCompletedEventArgs (null, null, true, null));
  1805. throw;
  1806. } catch (Exception ex) {
  1807. OnUploadStringCompleted (new UploadStringCompletedEventArgs (null, ex, true, null));
  1808. throw new WebException ("An error occurred performing a WebClient request.", ex);
  1809. }
  1810. }
  1811. // UploadValuesTaskAsync
  1812. public Task<byte[]> UploadValuesTaskAsync (string address, NameValueCollection data)
  1813. {
  1814. if (address == null)
  1815. throw new ArgumentNullException ("address");
  1816. return UploadValuesTaskAsync (CreateUri (address), data);
  1817. }
  1818. public Task<byte[]> UploadValuesTaskAsync (string address, string method, NameValueCollection data)
  1819. {
  1820. if (address == null)
  1821. throw new ArgumentNullException ("address");
  1822. return UploadValuesTaskAsync (CreateUri (address), method, data);
  1823. }
  1824. public Task<byte[]> UploadValuesTaskAsync (Uri address, NameValueCollection data)
  1825. {
  1826. return UploadValuesTaskAsync (address, (string) null, data);
  1827. }
  1828. public async Task<byte[]> UploadValuesTaskAsync (Uri address, string method, NameValueCollection data)
  1829. {
  1830. if (address == null)
  1831. throw new ArgumentNullException ("address");
  1832. if (data == null)
  1833. throw new ArgumentNullException ("data");
  1834. WebRequest request = null;
  1835. try {
  1836. SetBusy ();
  1837. cts = new CancellationTokenSource ();
  1838. request = await SetupRequestAsync (address, method, true);
  1839. var result = await UploadValuesTaskAsyncCore (request, data, cts.Token);
  1840. OnUploadValuesCompleted (new UploadValuesCompletedEventArgs (result, null, false, null));
  1841. return result;
  1842. } catch (WebException ex) {
  1843. OnUploadValuesCompleted (new UploadValuesCompletedEventArgs (null, ex, false, null));
  1844. throw;
  1845. } catch (OperationCanceledException) {
  1846. if (request != null)
  1847. request.Abort ();
  1848. OnUploadValuesCompleted (new UploadValuesCompletedEventArgs (null, null, true, null));
  1849. throw;
  1850. } catch (Exception ex) {
  1851. OnUploadValuesCompleted (new UploadValuesCompletedEventArgs (null, ex, true, null));
  1852. throw new WebException ("An error occurred performing a WebClient request.", ex);
  1853. }
  1854. }
  1855. async Task<byte[]> UploadValuesTaskAsyncCore (WebRequest request, NameValueCollection data,
  1856. CancellationToken token)
  1857. {
  1858. token.ThrowIfCancellationRequested ();
  1859. string cType = Headers ["Content-Type"];
  1860. if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
  1861. throw new WebException ("Content-Type header cannot be changed from its default " +
  1862. "value for this request.");
  1863. WebResponse response = null;
  1864. Headers ["Content-Type"] = urlEncodedCType;
  1865. try {
  1866. MemoryStream tmpStream = new MemoryStream ();
  1867. foreach (string key in data) {
  1868. byte [] bytes = Encoding.UTF8.GetBytes (key);
  1869. UrlEncodeAndWrite (tmpStream, bytes);
  1870. tmpStream.WriteByte ((byte) '=');
  1871. bytes = Encoding.UTF8.GetBytes (data [key]);
  1872. UrlEncodeAndWrite (tmpStream, bytes);
  1873. tmpStream.WriteByte ((byte) '&');
  1874. }
  1875. token.ThrowIfCancellationRequested ();
  1876. int length = (int) tmpStream.Length;
  1877. if (length > 0)
  1878. tmpStream.SetLength (--length); // remove trailing '&'
  1879. byte [] buf = tmpStream.GetBuffer ();
  1880. request.ContentLength = length;
  1881. using (Stream rqStream = await request.GetRequestStreamAsync ()) {
  1882. await rqStream.WriteAsync (buf, 0, length, token);
  1883. }
  1884. tmpStream.Close ();
  1885. response = await GetWebResponseTaskAsync (request, token);
  1886. return await ReadAllTaskAsync (request, response, token);
  1887. } finally {
  1888. if (response != null)
  1889. response.Close ();
  1890. }
  1891. }
  1892. #endif
  1893. }
  1894. }