2 // System.Net.WebClient
5 // Lawrence Pit (loz@cable.a2000.nl)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Atsushi Enomoto (atsushi@ximian.com)
8 // Miguel de Icaza (miguel@ximian.com)
9 // Martin Baulig (martin.baulig@googlemail.com)
10 // Marek Safar (marek.safar@gmail.com)
12 // Copyright 2003 Ximian, Inc. (http://www.ximian.com)
13 // Copyright 2006, 2010 Novell, Inc. (http://www.novell.com)
14 // Copyright 2012 Xamarin Inc. (http://www.xamarin.com)
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 // Notes on CancelAsync and Async methods:
39 // WebClient.CancelAsync is implemented by calling Thread.Interrupt
40 // in our helper thread. The various async methods have to cancel
41 // any ongoing requests by calling request.Abort () at that point.
42 // In a few places (UploadDataCore, UploadValuesCore,
43 // UploadFileCore) we catch the ThreadInterruptedException and
44 // abort the request there.
46 // Higher level routines (the async callbacks) also need to catch
47 // the exception and raise the OnXXXXCompleted events there with
48 // the "canceled" flag set to true.
50 // In a few other places where these helper routines are not used
51 // (OpenReadAsync for example) catching the ThreadAbortException
52 // also must abort the request.
54 // The Async methods currently differ in their implementation from
55 // the .NET implementation in that we manually catch any other
56 // exceptions and correctly raise the OnXXXXCompleted passing the
57 // Exception that caused the problem. The .NET implementation
58 // does not seem to have a mechanism to flag errors that happen
59 // during downloads though. We do this because we still need to
60 // catch the exception on these helper threads, or we would
61 // otherwise kill the application (on the 2.x profile, uncaught
62 // exceptions in threads terminate the application).
65 using System.Collections.Specialized;
66 using System.ComponentModel;
68 using System.Runtime.InteropServices;
69 using System.Runtime.Serialization;
71 using System.Threading;
72 using System.Net.Cache;
74 using System.Threading.Tasks;
80 public class WebClient : Component
82 static readonly string urlEncodedCType = "application/x-www-form-urlencoded";
83 static byte [] hexBytes;
84 ICredentials credentials;
85 WebHeaderCollection headers;
86 WebHeaderCollection responseHeaders;
89 NameValueCollection queryString;
92 bool proxySet = false;
94 Encoding encoding = Encoding.Default;
96 // RequestCachePolicy cache_policy;
98 CancellationTokenSource cts;
104 hexBytes = new byte [16];
106 for (int i = '0'; i <= '9'; i++, index++)
107 hexBytes [index] = (byte) i;
109 for (int i = 'a'; i <= 'f'; i++, index++)
110 hexBytes [index] = (byte) i;
119 public string BaseAddress {
121 if (baseString == null) {
122 if (baseAddress == null)
126 baseString = baseAddress.ToString ();
131 if (value == null || value.Length == 0) {
134 baseAddress = new Uri (value);
139 static Exception GetMustImplement ()
141 return new NotImplementedException ();
144 [MonoTODO ("Value can be set but is currently ignored")]
145 public RequestCachePolicy CachePolicy
148 throw GetMustImplement ();
150 set { /*cache_policy = value;*/ }
153 [MonoTODO ("Value can be set but is ignored")]
154 public bool UseDefaultCredentials
157 throw GetMustImplement ();
160 // This makes no sense in mono
164 public ICredentials Credentials {
165 get { return credentials; }
166 set { credentials = value; }
169 public WebHeaderCollection Headers {
172 headers = new WebHeaderCollection ();
176 set { headers = value; }
179 public NameValueCollection QueryString {
181 if (queryString == null)
182 queryString = new NameValueCollection ();
186 set { queryString = value; }
189 public WebHeaderCollection ResponseHeaders {
190 get { return responseHeaders; }
193 public Encoding Encoding {
194 get { return encoding; }
197 throw new ArgumentNullException ("Encoding");
202 public IWebProxy Proxy {
205 return WebRequest.DefaultWebProxy;
218 return is_busy || (cts != null);
229 throw new NotSupportedException ("WebClient does not support concurrent I/O operations.");
242 public byte [] DownloadData (string address)
245 throw new ArgumentNullException ("address");
247 return DownloadData (CreateUri (address));
250 public byte [] DownloadData (Uri address)
253 throw new ArgumentNullException ("address");
258 return DownloadDataCore (address, null);
264 byte [] DownloadDataCore (Uri address, object userToken)
266 WebRequest request = null;
269 request = SetupRequest (address);
270 return ReadAll (request, userToken);
271 } catch (ThreadInterruptedException){
274 throw new WebException ("User canceled the request", WebExceptionStatus.RequestCanceled);
275 } catch (WebException) {
277 } catch (Exception ex) {
278 throw new WebException ("An error occurred performing a WebClient request.", ex);
284 public void DownloadFile (string address, string fileName)
287 throw new ArgumentNullException ("address");
289 DownloadFile (CreateUri (address), fileName);
292 public void DownloadFile (Uri address, string fileName)
295 throw new ArgumentNullException ("address");
296 if (fileName == null)
297 throw new ArgumentNullException ("fileName");
302 DownloadFileCore (address, fileName, null);
303 } catch (WebException) {
305 } catch (Exception ex) {
306 throw new WebException ("An error occurred " +
307 "performing a WebClient request.", ex);
313 void DownloadFileCore (Uri address, string fileName, object userToken)
315 WebRequest request = null;
317 using (FileStream f = new FileStream (fileName, FileMode.Create)) {
319 request = SetupRequest (address);
320 WebResponse response = GetWebResponse (request);
321 Stream st = response.GetResponseStream ();
323 int cLength = (int) response.ContentLength;
324 int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
325 byte [] buffer = new byte [length];
328 long notify_total = 0;
329 while ((nread = st.Read (buffer, 0, length)) != 0) {
330 notify_total += nread;
332 OnDownloadProgressChanged (
333 new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken));
334 f.Write (buffer, 0, nread);
337 if (cLength > 0 && notify_total < cLength)
338 throw new WebException ("Download aborted prematurely.", WebExceptionStatus.ReceiveFailure);
339 } catch (ThreadInterruptedException){
349 public Stream OpenRead (string address)
352 throw new ArgumentNullException ("address");
353 return OpenRead (CreateUri (address));
356 public Stream OpenRead (Uri address)
359 throw new ArgumentNullException ("address");
361 WebRequest request = null;
365 request = SetupRequest (address);
366 WebResponse response = GetWebResponse (request);
367 return response.GetResponseStream ();
368 } catch (WebException) {
370 } catch (Exception ex) {
371 throw new WebException ("An error occurred " +
372 "performing a WebClient request.", ex);
380 public Stream OpenWrite (string address)
383 throw new ArgumentNullException ("address");
385 return OpenWrite (CreateUri (address));
388 public Stream OpenWrite (string address, string method)
391 throw new ArgumentNullException ("address");
393 return OpenWrite (CreateUri (address), method);
396 public Stream OpenWrite (Uri address)
398 return OpenWrite (address, (string) null);
401 public Stream OpenWrite (Uri address, string method)
404 throw new ArgumentNullException ("address");
409 WebRequest request = SetupRequest (address, method, true);
410 return request.GetRequestStream ();
411 } catch (WebException) {
413 } catch (Exception ex) {
414 throw new WebException ("An error occurred " +
415 "performing a WebClient request.", ex);
421 private string DetermineMethod (Uri address, string method, bool is_upload)
426 if (address.Scheme == Uri.UriSchemeFtp)
427 return (is_upload) ? "STOR" : "RETR";
429 return (is_upload) ? "POST" : "GET";
434 public byte [] UploadData (string address, byte [] data)
437 throw new ArgumentNullException ("address");
439 return UploadData (CreateUri (address), data);
442 public byte [] UploadData (string address, string method, byte [] data)
445 throw new ArgumentNullException ("address");
447 return UploadData (CreateUri (address), method, data);
450 public byte [] UploadData (Uri address, byte [] data)
452 return UploadData (address, (string) null, data);
455 public byte [] UploadData (Uri address, string method, byte [] data)
458 throw new ArgumentNullException ("address");
460 throw new ArgumentNullException ("data");
465 return UploadDataCore (address, method, data, null);
466 } catch (WebException) {
468 } catch (Exception ex) {
469 throw new WebException ("An error occurred " +
470 "performing a WebClient request.", ex);
476 byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
478 WebRequest request = SetupRequest (address, method, true);
480 int contentLength = data.Length;
481 request.ContentLength = contentLength;
482 using (Stream stream = request.GetRequestStream ()) {
483 stream.Write (data, 0, contentLength);
486 return ReadAll (request, userToken);
487 } catch (ThreadInterruptedException){
496 public byte [] UploadFile (string address, string fileName)
499 throw new ArgumentNullException ("address");
501 return UploadFile (CreateUri (address), fileName);
504 public byte [] UploadFile (Uri address, string fileName)
506 return UploadFile (address, (string) null, fileName);
509 public byte [] UploadFile (string address, string method, string fileName)
511 return UploadFile (CreateUri (address), method, fileName);
514 public byte [] UploadFile (Uri address, string method, string fileName)
517 throw new ArgumentNullException ("address");
518 if (fileName == null)
519 throw new ArgumentNullException ("fileName");
524 return UploadFileCore (address, method, fileName, null);
525 } catch (WebException) {
527 } catch (Exception ex) {
528 throw new WebException ("An error occurred " +
529 "performing a WebClient request.", ex);
535 byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
537 string fileCType = Headers ["Content-Type"];
538 if (fileCType != null) {
539 string lower = fileCType.ToLower ();
540 if (lower.StartsWith ("multipart/"))
541 throw new WebException ("Content-Type cannot be set to a multipart" +
542 " type for this request.");
544 fileCType = "application/octet-stream";
547 bool needs_boundary = (method != "PUT"); // only verified case so far
548 string boundary = null;
549 if (needs_boundary) {
550 boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
551 Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
553 Stream reqStream = null;
554 Stream fStream = null;
555 byte [] resultBytes = null;
557 fileName = Path.GetFullPath (fileName);
559 WebRequest request = null;
561 fStream = File.OpenRead (fileName);
562 request = SetupRequest (address, method, true);
563 reqStream = request.GetRequestStream ();
564 byte [] bytes_boundary = null;
565 if (needs_boundary) {
566 bytes_boundary = Encoding.ASCII.GetBytes (boundary);
567 reqStream.WriteByte ((byte) '-');
568 reqStream.WriteByte ((byte) '-');
569 reqStream.Write (bytes_boundary, 0, bytes_boundary.Length);
570 reqStream.WriteByte ((byte) '\r');
571 reqStream.WriteByte ((byte) '\n');
572 string partHeaders = String.Format ("Content-Disposition: form-data; " +
573 "name=\"file\"; filename=\"{0}\"\r\n" +
574 "Content-Type: {1}\r\n\r\n",
575 Path.GetFileName (fileName), fileCType);
577 byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
578 reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
583 long step = 16384; // every 16kB
584 if (fStream.CanSeek) {
585 file_size = fStream.Length;
586 step = file_size / 100;
588 var upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, 0, userToken);
589 OnUploadProgressChanged (upload_args);
590 byte [] buffer = new byte [4096];
592 while ((nread = fStream.Read (buffer, 0, 4096)) > 0) {
593 reqStream.Write (buffer, 0, nread);
596 if (sum >= step || nread < 4096) {
599 percent = (int) (bytes_sent * 100 / file_size);
600 upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, percent, userToken);
601 OnUploadProgressChanged (upload_args);
606 if (needs_boundary) {
607 reqStream.WriteByte ((byte) '\r');
608 reqStream.WriteByte ((byte) '\n');
609 reqStream.WriteByte ((byte) '-');
610 reqStream.WriteByte ((byte) '-');
611 reqStream.Write (bytes_boundary, 0, bytes_boundary.Length);
612 reqStream.WriteByte ((byte) '-');
613 reqStream.WriteByte ((byte) '-');
614 reqStream.WriteByte ((byte) '\r');
615 reqStream.WriteByte ((byte) '\n');
619 resultBytes = ReadAll (request, userToken);
620 } catch (ThreadInterruptedException){
628 if (reqStream != null)
635 public byte[] UploadValues (string address, NameValueCollection data)
638 throw new ArgumentNullException ("address");
640 return UploadValues (CreateUri (address), data);
643 public byte[] UploadValues (string address, string method, NameValueCollection data)
646 throw new ArgumentNullException ("address");
647 return UploadValues (CreateUri (address), method, data);
650 public byte[] UploadValues (Uri address, NameValueCollection data)
652 return UploadValues (address, (string) null, data);
655 public byte[] UploadValues (Uri address, string method, NameValueCollection data)
658 throw new ArgumentNullException ("address");
660 throw new ArgumentNullException ("data");
665 return UploadValuesCore (address, method, data, null);
666 } catch (WebException) {
668 } catch (Exception ex) {
669 throw new WebException ("An error occurred " +
670 "performing a WebClient request.", ex);
676 byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
678 string cType = Headers ["Content-Type"];
679 if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
680 throw new WebException ("Content-Type header cannot be changed from its default " +
681 "value for this request.");
683 Headers ["Content-Type"] = urlEncodedCType;
684 WebRequest request = SetupRequest (uri, method, true);
686 MemoryStream tmpStream = new MemoryStream ();
687 foreach (string key in data) {
688 byte [] bytes = Encoding.UTF8.GetBytes (key);
689 UrlEncodeAndWrite (tmpStream, bytes);
690 tmpStream.WriteByte ((byte) '=');
691 bytes = Encoding.UTF8.GetBytes (data [key]);
692 UrlEncodeAndWrite (tmpStream, bytes);
693 tmpStream.WriteByte ((byte) '&');
696 int length = (int) tmpStream.Length;
698 tmpStream.SetLength (--length); // remove trailing '&'
700 byte [] buf = tmpStream.GetBuffer ();
701 request.ContentLength = length;
702 using (Stream rqStream = request.GetRequestStream ()) {
703 rqStream.Write (buf, 0, length);
707 return ReadAll (request, userToken);
708 } catch (ThreadInterruptedException) {
714 public string DownloadString (string address)
717 throw new ArgumentNullException ("address");
719 return encoding.GetString (DownloadData (CreateUri (address)));
722 public string DownloadString (Uri address)
725 throw new ArgumentNullException ("address");
727 return encoding.GetString (DownloadData (CreateUri (address)));
730 public string UploadString (string address, string data)
733 throw new ArgumentNullException ("address");
735 throw new ArgumentNullException ("data");
737 byte [] resp = UploadData (address, encoding.GetBytes (data));
738 return encoding.GetString (resp);
741 public string UploadString (string address, string method, string data)
744 throw new ArgumentNullException ("address");
746 throw new ArgumentNullException ("data");
748 byte [] resp = UploadData (address, method, encoding.GetBytes (data));
749 return encoding.GetString (resp);
752 public string UploadString (Uri address, string data)
755 throw new ArgumentNullException ("address");
757 throw new ArgumentNullException ("data");
759 byte [] resp = UploadData (address, encoding.GetBytes (data));
760 return encoding.GetString (resp);
763 public string UploadString (Uri address, string method, string data)
766 throw new ArgumentNullException ("address");
768 throw new ArgumentNullException ("data");
770 byte [] resp = UploadData (address, method, encoding.GetBytes (data));
771 return encoding.GetString (resp);
774 public event DownloadDataCompletedEventHandler DownloadDataCompleted;
775 public event AsyncCompletedEventHandler DownloadFileCompleted;
776 public event DownloadProgressChangedEventHandler DownloadProgressChanged;
777 public event DownloadStringCompletedEventHandler DownloadStringCompleted;
778 public event OpenReadCompletedEventHandler OpenReadCompleted;
779 public event OpenWriteCompletedEventHandler OpenWriteCompleted;
780 public event UploadDataCompletedEventHandler UploadDataCompleted;
781 public event UploadFileCompletedEventHandler UploadFileCompleted;
782 public event UploadProgressChangedEventHandler UploadProgressChanged;
783 public event UploadStringCompletedEventHandler UploadStringCompleted;
784 public event UploadValuesCompletedEventHandler UploadValuesCompleted;
786 Uri CreateUri (string address)
790 if (baseAddress == null)
791 uri = new Uri (address);
793 uri = new Uri (baseAddress, address);
794 return CreateUri (uri);
797 return new Uri (Path.GetFullPath (address));
800 Uri CreateUri (Uri address)
802 Uri result = address;
803 if (baseAddress != null && !result.IsAbsoluteUri) {
805 result = new Uri (baseAddress, result.OriginalString);
807 return result; // Not much we can do here.
811 string query = result.Query;
812 if (String.IsNullOrEmpty (query))
813 query = GetQueryString (true);
814 UriBuilder builder = new UriBuilder (address);
815 if (!String.IsNullOrEmpty (query))
816 builder.Query = query.Substring (1);
820 string GetQueryString (bool add_qmark)
822 if (queryString == null || queryString.Count == 0)
825 StringBuilder sb = new StringBuilder ();
829 foreach (string key in queryString)
830 sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
833 sb.Length--; // removes last '&' or the '?' if empty.
838 return sb.ToString ();
841 WebRequest SetupRequest (Uri uri)
843 WebRequest request = GetWebRequest (uri);
845 request.Proxy = Proxy;
846 if (credentials != null)
847 request.Credentials = credentials;
848 else if (!String.IsNullOrEmpty (uri.UserInfo)) {
849 // Perhaps this should be done by the underlying URI handler?
850 ICredentials creds = GetCredentials (uri.UserInfo);
852 request.Credentials = creds;
855 // Special headers. These are properties of HttpWebRequest.
856 // What do we do with other requests differnt from HttpWebRequest?
857 if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
858 HttpWebRequest req = (HttpWebRequest) request;
859 string expect = headers ["Expect"];
860 string contentType = headers ["Content-Type"];
861 string accept = headers ["Accept"];
862 string connection = headers ["Connection"];
863 string userAgent = headers ["User-Agent"];
864 string referer = headers ["Referer"];
865 headers.RemoveInternal ("Expect");
866 headers.RemoveInternal ("Content-Type");
867 headers.RemoveInternal ("Accept");
868 headers.RemoveInternal ("Connection");
869 headers.RemoveInternal ("Referer");
870 headers.RemoveInternal ("User-Agent");
871 request.Headers = headers;
873 if (expect != null && expect.Length > 0)
876 if (accept != null && accept.Length > 0)
879 if (contentType != null && contentType.Length > 0)
880 req.ContentType = contentType;
882 if (connection != null && connection.Length > 0)
883 req.Connection = connection;
885 if (userAgent != null && userAgent.Length > 0)
886 req.UserAgent = userAgent;
888 if (referer != null && referer.Length > 0)
889 req.Referer = referer;
892 responseHeaders = null;
896 WebRequest SetupRequest (Uri uri, string method, bool is_upload)
898 WebRequest request = SetupRequest (uri);
899 request.Method = DetermineMethod (uri, method, is_upload);
903 static NetworkCredential GetCredentials (string user_info)
905 string [] creds = user_info.Split (':');
906 if (creds.Length != 2)
909 if (creds [0].IndexOf ('\\') != -1) {
910 string [] user = creds [0].Split ('\\');
911 if (user.Length != 2)
913 return new NetworkCredential (user [1], creds [1], user [0]);
915 return new NetworkCredential (creds [0], creds [1]);
918 byte [] ReadAll (WebRequest request, object userToken)
920 WebResponse response = GetWebResponse (request);
921 Stream stream = response.GetResponseStream ();
922 int length = (int) response.ContentLength;
923 HttpWebRequest wreq = request as HttpWebRequest;
925 if (length > -1 && wreq != null && (int) wreq.AutomaticDecompression != 0) {
926 string content_encoding = ((HttpWebResponse) response).ContentEncoding;
927 if (((content_encoding == "gzip" && (wreq.AutomaticDecompression & DecompressionMethods.GZip) != 0)) ||
928 ((content_encoding == "deflate" && (wreq.AutomaticDecompression & DecompressionMethods.Deflate) != 0)))
932 MemoryStream ms = null;
933 bool nolength = (length == -1);
934 int size = ((nolength) ? 8192 : length);
936 ms = new MemoryStream ();
941 byte [] buffer = new byte [size];
942 while ((nread = stream.Read (buffer, offset, size)) != 0) {
944 ms.Write (buffer, 0, nread);
951 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (total, length, userToken));
956 return ms.ToArray ();
961 string UrlEncode (string str)
963 StringBuilder result = new StringBuilder ();
965 int len = str.Length;
966 for (int i = 0; i < len; i++) {
970 else if ((c < '0' && c != '-' && c != '.') ||
971 (c < 'A' && c > '9') ||
972 (c > 'Z' && c < 'a' && c != '_') ||
975 int idx = ((int) c) >> 4;
976 result.Append ((char) hexBytes [idx]);
977 idx = ((int) c) & 0x0F;
978 result.Append ((char) hexBytes [idx]);
984 return result.ToString ();
987 static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
992 int len = bytes.Length;
996 for (int i = 0; i < len; i++) {
997 char c = (char) bytes [i];
999 stream.WriteByte ((byte) '+');
1000 else if ((c < '0' && c != '-' && c != '.') ||
1001 (c < 'A' && c > '9') ||
1002 (c > 'Z' && c < 'a' && c != '_') ||
1004 stream.WriteByte ((byte) '%');
1005 int idx = ((int) c) >> 4;
1006 stream.WriteByte (hexBytes [idx]);
1007 idx = ((int) c) & 0x0F;
1008 stream.WriteByte (hexBytes [idx]);
1010 stream.WriteByte ((byte) c);
1015 public void CancelAsync ()
1025 if (async_thread == null)
1029 // We first flag things as done, in case the Interrupt hangs
1030 // or the thread decides to hang in some other way inside the
1031 // event handlers, or if we are stuck somewhere else. This
1032 // ensures that the WebClient object is reusable immediately
1034 Thread t = async_thread;
1040 void CompleteAsync ()
1044 async_thread = null;
1053 // DownloadDataAsync
1055 public void DownloadDataAsync (Uri address)
1057 DownloadDataAsync (address, null);
1060 public void DownloadDataAsync (Uri address, object userToken)
1062 if (address == null)
1063 throw new ArgumentNullException ("address");
1069 async_thread = new Thread (delegate (object state) {
1070 object [] args = (object []) state;
1072 byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
1073 OnDownloadDataCompleted (
1074 new DownloadDataCompletedEventArgs (data, null, false, args [1]));
1075 } catch (Exception e){
1076 bool canceled = false;
1077 WebException we = e as WebException;
1079 canceled = we.Status == WebExceptionStatus.RequestCanceled;
1080 OnDownloadDataCompleted (
1081 new DownloadDataCompletedEventArgs (null, e, canceled, args [1]));
1084 object [] cb_args = new object [] { CreateUri (address), userToken };
1085 async_thread.IsBackground = true;
1086 async_thread.Start (cb_args);
1090 // DownloadFileAsync
1092 public void DownloadFileAsync (Uri address, string fileName)
1094 DownloadFileAsync (address, fileName, null);
1097 public void DownloadFileAsync (Uri address, string fileName, object userToken)
1099 if (address == null)
1100 throw new ArgumentNullException ("address");
1101 if (fileName == null)
1102 throw new ArgumentNullException ("fileName");
1108 async_thread = new Thread (delegate (object state) {
1109 object [] args = (object []) state;
1111 DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
1112 OnDownloadFileCompleted (
1113 new AsyncCompletedEventArgs (null, false, args [2]));
1114 } catch (ThreadInterruptedException){
1115 OnDownloadFileCompleted (
1116 new AsyncCompletedEventArgs (null, true, args [2]));
1117 } catch (Exception e){
1118 OnDownloadFileCompleted (
1119 new AsyncCompletedEventArgs (e, false, args [2]));
1121 object [] cb_args = new object [] { CreateUri (address), fileName, userToken };
1122 async_thread.IsBackground = true;
1123 async_thread.Start (cb_args);
1127 // DownloadStringAsync
1129 public void DownloadStringAsync (Uri address)
1131 DownloadStringAsync (address, null);
1134 public void DownloadStringAsync (Uri address, object userToken)
1136 if (address == null)
1137 throw new ArgumentNullException ("address");
1143 async_thread = new Thread (delegate (object state) {
1144 object [] args = (object []) state;
1146 string data = encoding.GetString (DownloadDataCore ((Uri) args [0], args [1]));
1147 OnDownloadStringCompleted (
1148 new DownloadStringCompletedEventArgs (data, null, false, args [1]));
1149 } catch (Exception e){
1150 bool canceled = false;
1151 WebException we = e as WebException;
1153 canceled = we.Status == WebExceptionStatus.RequestCanceled;
1154 OnDownloadStringCompleted (
1155 new DownloadStringCompletedEventArgs (null, e, canceled, args [1]));
1157 object [] cb_args = new object [] { CreateUri (address), userToken };
1158 async_thread.IsBackground = true;
1159 async_thread.Start (cb_args);
1165 public void OpenReadAsync (Uri address)
1167 OpenReadAsync (address, null);
1170 public void OpenReadAsync (Uri address, object userToken)
1172 if (address == null)
1173 throw new ArgumentNullException ("address");
1179 async_thread = new Thread (delegate (object state) {
1180 object [] args = (object []) state;
1181 WebRequest request = null;
1183 request = SetupRequest ((Uri) args [0]);
1184 WebResponse response = GetWebResponse (request);
1185 Stream stream = response.GetResponseStream ();
1186 OnOpenReadCompleted (
1187 new OpenReadCompletedEventArgs (stream, null, false, args [1]));
1188 } catch (ThreadInterruptedException){
1189 if (request != null)
1192 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, args [1]));
1193 } catch (Exception e){
1194 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, e, false, args [1]));
1196 object [] cb_args = new object [] { CreateUri (address), userToken };
1197 async_thread.IsBackground = true;
1198 async_thread.Start (cb_args);
1204 public void OpenWriteAsync (Uri address)
1206 OpenWriteAsync (address, null);
1209 public void OpenWriteAsync (Uri address, string method)
1211 OpenWriteAsync (address, method, null);
1214 public void OpenWriteAsync (Uri address, string method, object userToken)
1216 if (address == null)
1217 throw new ArgumentNullException ("address");
1223 async_thread = new Thread (delegate (object state) {
1224 object [] args = (object []) state;
1225 WebRequest request = null;
1227 request = SetupRequest ((Uri) args [0], (string) args [1], true);
1228 Stream stream = request.GetRequestStream ();
1229 OnOpenWriteCompleted (
1230 new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
1231 } catch (ThreadInterruptedException){
1232 if (request != null)
1234 OnOpenWriteCompleted (
1235 new OpenWriteCompletedEventArgs (null, null, true, args [2]));
1236 } catch (Exception e){
1237 OnOpenWriteCompleted (
1238 new OpenWriteCompletedEventArgs (null, e, false, args [2]));
1240 object [] cb_args = new object [] { CreateUri (address), method, userToken };
1241 async_thread.IsBackground = true;
1242 async_thread.Start (cb_args);
1248 public void UploadDataAsync (Uri address, byte [] data)
1250 UploadDataAsync (address, null, data);
1253 public void UploadDataAsync (Uri address, string method, byte [] data)
1255 UploadDataAsync (address, method, data, null);
1258 public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
1260 if (address == null)
1261 throw new ArgumentNullException ("address");
1263 throw new ArgumentNullException ("data");
1269 async_thread = new Thread (delegate (object state) {
1270 object [] args = (object []) state;
1274 data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
1276 OnUploadDataCompleted (
1277 new UploadDataCompletedEventArgs (data2, null, false, args [3]));
1278 } catch (ThreadInterruptedException){
1279 OnUploadDataCompleted (
1280 new UploadDataCompletedEventArgs (null, null, true, args [3]));
1281 } catch (Exception e){
1282 OnUploadDataCompleted (
1283 new UploadDataCompletedEventArgs (null, e, false, args [3]));
1285 object [] cb_args = new object [] { CreateUri (address), method, data, userToken };
1286 async_thread.IsBackground = true;
1287 async_thread.Start (cb_args);
1293 public void UploadFileAsync (Uri address, string fileName)
1295 UploadFileAsync (address, null, fileName);
1298 public void UploadFileAsync (Uri address, string method, string fileName)
1300 UploadFileAsync (address, method, fileName, null);
1303 public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
1305 if (address == null)
1306 throw new ArgumentNullException ("address");
1307 if (fileName == null)
1308 throw new ArgumentNullException ("fileName");
1314 async_thread = new Thread (delegate (object state) {
1315 object [] args = (object []) state;
1319 data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
1320 OnUploadFileCompleted (
1321 new UploadFileCompletedEventArgs (data, null, false, args [3]));
1322 } catch (ThreadInterruptedException){
1323 OnUploadFileCompleted (
1324 new UploadFileCompletedEventArgs (null, null, true, args [3]));
1325 } catch (Exception e){
1326 OnUploadFileCompleted (
1327 new UploadFileCompletedEventArgs (null, e, false, args [3]));
1329 object [] cb_args = new object [] { CreateUri (address), method, fileName, userToken };
1330 async_thread.IsBackground = true;
1331 async_thread.Start (cb_args);
1335 // UploadStringAsync
1337 public void UploadStringAsync (Uri address, string data)
1339 UploadStringAsync (address, null, data);
1342 public void UploadStringAsync (Uri address, string method, string data)
1344 UploadStringAsync (address, method, data, null);
1347 public void UploadStringAsync (Uri address, string method, string data, object userToken)
1349 if (address == null)
1350 throw new ArgumentNullException ("address");
1352 throw new ArgumentNullException ("data");
1358 async_thread = new Thread (delegate (object state) {
1359 object [] args = (object []) state;
1362 string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
1363 OnUploadStringCompleted (
1364 new UploadStringCompletedEventArgs (data2, null, false, args [3]));
1365 } catch (ThreadInterruptedException){
1366 OnUploadStringCompleted (
1367 new UploadStringCompletedEventArgs (null, null, true, args [3]));
1368 } catch (Exception e){
1369 OnUploadStringCompleted (
1370 new UploadStringCompletedEventArgs (null, e, false, args [3]));
1372 object [] cb_args = new object [] { CreateUri (address), method, data, userToken };
1373 async_thread.IsBackground = true;
1374 async_thread.Start (cb_args);
1378 // UploadValuesAsync
1380 public void UploadValuesAsync (Uri address, NameValueCollection data)
1382 UploadValuesAsync (address, null, data);
1385 public void UploadValuesAsync (Uri address, string method, NameValueCollection data)
1387 UploadValuesAsync (address, method, data, null);
1390 public void UploadValuesAsync (Uri address, string method, NameValueCollection data, object userToken)
1392 if (address == null)
1393 throw new ArgumentNullException ("address");
1395 throw new ArgumentNullException ("data");
1401 async_thread = new Thread (delegate (object state) {
1402 object [] args = (object []) state;
1404 byte [] values = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
1405 OnUploadValuesCompleted (
1406 new UploadValuesCompletedEventArgs (values, null, false, args [3]));
1407 } catch (ThreadInterruptedException){
1408 OnUploadValuesCompleted (
1409 new UploadValuesCompletedEventArgs (null, null, true, args [3]));
1410 } catch (Exception e){
1411 OnUploadValuesCompleted (
1412 new UploadValuesCompletedEventArgs (null, e, false, args [3]));
1414 object [] cb_args = new object [] { CreateUri (address), method, data, userToken };
1415 async_thread.IsBackground = true;
1416 async_thread.Start (cb_args);
1420 protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs e)
1423 if (DownloadDataCompleted != null)
1424 DownloadDataCompleted (this, e);
1427 protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs e)
1430 if (DownloadFileCompleted != null)
1431 DownloadFileCompleted (this, e);
1434 protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
1436 if (DownloadProgressChanged != null)
1437 DownloadProgressChanged (this, e);
1440 protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs e)
1443 if (DownloadStringCompleted != null)
1444 DownloadStringCompleted (this, e);
1447 protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs e)
1450 if (OpenReadCompleted != null)
1451 OpenReadCompleted (this, e);
1454 protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs e)
1457 if (OpenWriteCompleted != null)
1458 OpenWriteCompleted (this, e);
1461 protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs e)
1464 if (UploadDataCompleted != null)
1465 UploadDataCompleted (this, e);
1468 protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs e)
1471 if (UploadFileCompleted != null)
1472 UploadFileCompleted (this, e);
1475 protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
1477 if (UploadProgressChanged != null)
1478 UploadProgressChanged (this, e);
1481 protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs e)
1484 if (UploadStringCompleted != null)
1485 UploadStringCompleted (this, e);
1488 protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs e)
1491 if (UploadValuesCompleted != null)
1492 UploadValuesCompleted (this, e);
1495 protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
1497 WebResponse response = request.EndGetResponse (result);
1498 responseHeaders = response.Headers;
1502 protected virtual WebRequest GetWebRequest (Uri address)
1504 return WebRequest.Create (address);
1507 protected virtual WebResponse GetWebResponse (WebRequest request)
1509 WebResponse response = request.GetResponse ();
1510 responseHeaders = response.Headers;
1516 // DownloadDataTaskAsync
1518 public Task<byte[]> DownloadDataTaskAsync (string address)
1520 return DownloadDataTaskAsync (CreateUri (address));
1523 public async Task<byte[]> DownloadDataTaskAsync (Uri address)
1525 WebRequest request = null;
1526 WebResponse response = null;
1529 cts = new CancellationTokenSource ();
1530 request = await SetupRequestAsync (address);
1531 response = await GetWebResponseTaskAsync (request, cts.Token);
1532 var result = await ReadAllTaskAsync (request, response, cts.Token);
1534 // Has to run on original context
1535 OnDownloadDataCompleted (new DownloadDataCompletedEventArgs (result, null, false, null));
1537 } catch (WebException ex) {
1538 OnDownloadDataCompleted (new DownloadDataCompletedEventArgs (null, ex, false, null));
1540 } catch (OperationCanceledException) {
1541 if (request != null)
1543 OnDownloadDataCompleted (new DownloadDataCompletedEventArgs (null, null, true, null));
1545 } catch (Exception ex) {
1546 OnDownloadDataCompleted (new DownloadDataCompletedEventArgs (null, ex, true, null));
1547 throw new WebException ("An error occurred performing a WebClient request.", ex);
1549 if (response != null)
1554 Task<WebRequest> SetupRequestAsync (Uri address)
1556 return Task.Factory.StartNew (() => SetupRequest (address));
1559 async Task<WebRequest> SetupRequestAsync (Uri address, string method, bool is_upload)
1561 WebRequest request = await SetupRequestAsync (address).ConfigureAwait (false);
1562 request.Method = DetermineMethod (address, method, is_upload);
1566 async Task<WebResponse> GetWebResponseTaskAsync (WebRequest request, CancellationToken token)
1568 token.ThrowIfCancellationRequested ();
1569 WebResponse response = await request.GetResponseAsync ().ConfigureAwait (false);
1570 token.ThrowIfCancellationRequested ();
1571 responseHeaders = response.Headers;
1575 async Task<byte[]> ReadAllTaskAsync (WebRequest request, WebResponse response, CancellationToken token)
1577 Stream stream = response.GetResponseStream ();
1578 int length = (int)response.ContentLength;
1579 HttpWebRequest wreq = request as HttpWebRequest;
1581 if (length > -1 && wreq != null && (int)wreq.AutomaticDecompression != 0) {
1582 string content_encoding = ((HttpWebResponse)response).ContentEncoding;
1583 if (((content_encoding == "gzip" && (wreq.AutomaticDecompression & DecompressionMethods.GZip) != 0)) ||
1584 ((content_encoding == "deflate" && (wreq.AutomaticDecompression & DecompressionMethods.Deflate) != 0)))
1588 MemoryStream ms = null;
1589 bool nolength = (length == -1);
1590 int size = ((nolength) ? 8192 : length);
1592 ms = new MemoryStream ();
1597 byte [] buffer = new byte [size];
1598 token.ThrowIfCancellationRequested ();
1599 while ((nread = await stream.ReadAsync (buffer, offset, size, token)) != 0) {
1601 ms.Write (buffer, 0, nread);
1607 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (total, length, null));
1608 token.ThrowIfCancellationRequested ();
1611 return nolength ? ms.ToArray () : buffer;
1614 // DownloadFileTaskAsync
1616 public Task DownloadFileTaskAsync (string address, string fileName)
1618 if (address == null)
1619 throw new ArgumentNullException ("address");
1621 return DownloadFileTaskAsync (CreateUri (address), fileName);
1624 public async Task DownloadFileTaskAsync (Uri address, string fileName)
1626 if (address == null)
1627 throw new ArgumentNullException ("address");
1628 if (fileName == null)
1629 throw new ArgumentNullException ("fileName");
1631 WebRequest request = null;
1632 WebResponse response = null;
1636 cts = new CancellationTokenSource ();
1637 request = await SetupRequestAsync (address);
1638 response = await GetWebResponseTaskAsync (request, cts.Token);
1639 await DownloadFileTaskAsyncCore (request, response, fileName, cts.Token);
1640 OnDownloadFileCompleted (new AsyncCompletedEventArgs (null, false, null));
1641 } catch (WebException ex) {
1642 OnDownloadFileCompleted (new AsyncCompletedEventArgs (ex, false, null));
1644 } catch (OperationCanceledException) {
1645 if (request != null)
1647 OnDownloadFileCompleted (new AsyncCompletedEventArgs (null, true, null));
1649 } catch (Exception ex) {
1650 OnDownloadFileCompleted (new AsyncCompletedEventArgs (ex, false, null));
1651 throw new WebException ("An error occurred " +
1652 "performing a WebClient request.", ex);
1654 if (response != null)
1659 async Task DownloadFileTaskAsyncCore (WebRequest request, WebResponse response,
1660 string fileName, CancellationToken token)
1662 using (FileStream f = new FileStream (fileName, FileMode.Create)) {
1663 Stream st = response.GetResponseStream ();
1665 int cLength = (int)response.ContentLength;
1666 int length = (cLength <= -1 || cLength > 32 * 1024) ? 32 * 1024 : cLength;
1667 byte [] buffer = new byte [length];
1670 long notify_total = 0;
1671 token.ThrowIfCancellationRequested ();
1672 while ((nread = await st.ReadAsync (buffer, 0, length, token)) != 0) {
1673 notify_total += nread;
1674 OnDownloadProgressChanged (
1675 new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, null));
1676 token.ThrowIfCancellationRequested ();
1677 await f.WriteAsync (buffer, 0, nread, token);
1678 token.ThrowIfCancellationRequested ();
1683 // OpenReadTaskAsync
1685 public Task<Stream> OpenReadTaskAsync (string address)
1687 if (address == null)
1688 throw new ArgumentNullException ("address");
1689 return OpenReadTaskAsync (CreateUri (address));
1692 public async Task<Stream> OpenReadTaskAsync (Uri address)
1694 if (address == null)
1695 throw new ArgumentNullException ("address");
1697 WebRequest request = null;
1700 cts = new CancellationTokenSource ();
1701 request = await SetupRequestAsync (address);
1702 WebResponse response = await GetWebResponseTaskAsync (request, cts.Token);
1703 var result = response.GetResponseStream ();
1704 cts.Token.ThrowIfCancellationRequested ();
1705 OnOpenReadCompleted (new OpenReadCompletedEventArgs (result, null, false, null));
1707 } catch (WebException ex) {
1708 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, ex, false, null));
1710 } catch (OperationCanceledException) {
1711 if (request != null)
1713 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, null));
1715 } catch (Exception ex) {
1716 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, ex, false, null));
1717 throw new WebException ("An error occurred " +
1718 "performing a WebClient request.", ex);
1722 // DownloadStringTaskAsync
1724 public Task<string> DownloadStringTaskAsync (string address)
1726 if (address == null)
1727 throw new ArgumentNullException ("address");
1729 return DownloadStringTaskAsync (CreateUri (address));
1732 public async Task<string> DownloadStringTaskAsync (Uri address)
1734 if (address == null)
1735 throw new ArgumentNullException ("address");
1737 WebRequest request = null;
1738 WebResponse response = null;
1742 cts = new CancellationTokenSource ();
1743 request = await SetupRequestAsync (address);
1744 response = await GetWebResponseTaskAsync (request, cts.Token);
1745 var data = await ReadAllTaskAsync (request, response, cts.Token);
1746 cts.Token.ThrowIfCancellationRequested ();
1747 var text = encoding.GetString (data);
1748 OnDownloadStringCompleted (new DownloadStringCompletedEventArgs (text, null, false, null));
1750 } catch (WebException ex) {
1751 OnDownloadStringCompleted (new DownloadStringCompletedEventArgs (null, ex, false, null));
1753 } catch (OperationCanceledException) {
1754 if (request != null)
1756 OnDownloadStringCompleted (new DownloadStringCompletedEventArgs (null, null, true, null));
1758 } catch (Exception ex) {
1759 OnDownloadStringCompleted (new DownloadStringCompletedEventArgs (null, ex, true, null));
1760 throw new WebException ("An error occurred performing a WebClient request.", ex);
1762 if (response != null)
1767 // OpenWriteTaskAsync
1769 public Task<Stream> OpenWriteTaskAsync (string address)
1771 if (address == null)
1772 throw new ArgumentNullException ("address");
1774 return OpenWriteTaskAsync (CreateUri (address));
1777 public Task<Stream> OpenWriteTaskAsync (string address, string method)
1779 if (address == null)
1780 throw new ArgumentNullException ("address");
1782 return OpenWriteTaskAsync (CreateUri (address), method);
1785 public Task<Stream> OpenWriteTaskAsync (Uri address)
1787 return OpenWriteTaskAsync (address, (string) null);
1790 public async Task<Stream> OpenWriteTaskAsync (Uri address, string method)
1792 if (address == null)
1793 throw new ArgumentNullException ("address");
1795 WebRequest request = null;
1798 cts = new CancellationTokenSource ();
1799 request = SetupRequest (address);
1800 return await request.GetRequestStreamAsync ().ConfigureAwait (false);
1801 } catch (WebException) {
1803 } catch (OperationCanceledException) {
1804 if (request != null)
1807 } catch (Exception ex) {
1808 throw new WebException ("An error occurred " +
1809 "performing a WebClient request.", ex);
1815 // UploadDataTaskAsync
1817 public Task<byte[]> UploadDataTaskAsync (string address, byte [] data)
1819 if (address == null)
1820 throw new ArgumentNullException ("address");
1822 return UploadDataTaskAsync (CreateUri (address), data);
1825 public Task<byte[]> UploadDataTaskAsync (string address, string method, byte [] data)
1827 if (address == null)
1828 throw new ArgumentNullException ("address");
1830 return UploadDataTaskAsync (CreateUri (address), method, data);
1833 public Task<byte[]> UploadDataTaskAsync (Uri address, byte [] data)
1835 return UploadDataTaskAsync (address, (string) null, data);
1838 public async Task<byte[]> UploadDataTaskAsync (Uri address, string method, byte [] data)
1840 if (address == null)
1841 throw new ArgumentNullException ("address");
1843 throw new ArgumentNullException ("data");
1845 WebRequest request = null;
1848 cts = new CancellationTokenSource ();
1849 request = await SetupRequestAsync (address, method, true).ConfigureAwait (false);
1850 var result = await UploadDataTaskAsyncCore (request, data, cts.Token).ConfigureAwait (false);
1851 OnUploadDataCompleted (new UploadDataCompletedEventArgs (result, null, false, null));
1853 } catch (WebException ex) {
1854 OnUploadDataCompleted (new UploadDataCompletedEventArgs (null, ex, false, null));
1856 } catch (OperationCanceledException) {
1857 if (request != null)
1859 OnUploadDataCompleted (new UploadDataCompletedEventArgs (null, null, true, null));
1861 } catch (Exception ex) {
1862 OnUploadDataCompleted (new UploadDataCompletedEventArgs (null, ex, true, null));
1863 throw new WebException ("An error occurred performing a WebClient request.", ex);
1867 async Task<byte[]> UploadDataTaskAsyncCore (WebRequest request, byte[] data, CancellationToken token)
1869 token.ThrowIfCancellationRequested ();
1871 int contentLength = data.Length;
1872 request.ContentLength = contentLength;
1873 using (Stream stream = await request.GetRequestStreamAsync ().ConfigureAwait (false)) {
1874 token.ThrowIfCancellationRequested ();
1875 await stream.WriteAsync (data, 0, contentLength, token).ConfigureAwait (false);
1876 token.ThrowIfCancellationRequested ();
1879 WebResponse response = null;
1882 response = await GetWebResponseTaskAsync (request, token).ConfigureAwait (false);
1883 return await ReadAllTaskAsync (request, response, token).ConfigureAwait (false);
1885 if (response != null)
1890 // UploadFileTaskAsync
1892 public Task<byte[]> UploadFileTaskAsync (string address, string fileName)
1894 if (address == null)
1895 throw new ArgumentNullException ("address");
1897 return UploadFileTaskAsync (CreateUri (address), fileName);
1900 public Task<byte[]> UploadFileTaskAsync (Uri address, string fileName)
1902 return UploadFileTaskAsync (address, (string) null, fileName);
1905 public Task<byte[]> UploadFileTaskAsync (string address, string method, string fileName)
1907 return UploadFileTaskAsync (CreateUri (address), method, fileName);
1910 public async Task<byte[]> UploadFileTaskAsync (Uri address, string method, string fileName)
1912 if (address == null)
1913 throw new ArgumentNullException ("address");
1914 if (fileName == null)
1915 throw new ArgumentNullException ("fileName");
1917 WebRequest request = null;
1920 cts = new CancellationTokenSource ();
1921 request = await SetupRequestAsync (address, method, true).ConfigureAwait (false);
1922 var result = await UploadFileTaskAsyncCore (request, method, fileName, cts.Token).ConfigureAwait (false);
1923 OnUploadFileCompleted (new UploadFileCompletedEventArgs (result, null, false, null));
1925 } catch (WebException ex) {
1926 OnUploadFileCompleted (new UploadFileCompletedEventArgs (null, ex, false, null));
1928 } catch (OperationCanceledException) {
1929 if (request != null)
1931 OnUploadFileCompleted (new UploadFileCompletedEventArgs (null, null, true, null));
1933 } catch (Exception ex) {
1934 OnUploadFileCompleted (new UploadFileCompletedEventArgs (null, ex, true, null));
1935 throw new WebException ("An error occurred performing a WebClient request.", ex);
1939 async Task<byte[]> UploadFileTaskAsyncCore (WebRequest request, string method,
1940 string fileName, CancellationToken token)
1942 token.ThrowIfCancellationRequested ();
1944 string fileCType = Headers ["Content-Type"];
1945 if (fileCType != null) {
1946 string lower = fileCType.ToLower ();
1947 if (lower.StartsWith ("multipart/"))
1948 throw new WebException ("Content-Type cannot be set to a multipart" +
1949 " type for this request.");
1951 fileCType = "application/octet-stream";
1954 bool needs_boundary = (method != "PUT"); // only verified case so far
1955 string boundary = null;
1956 if (needs_boundary) {
1957 boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
1958 Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
1960 Stream reqStream = null;
1961 Stream fStream = null;
1962 WebResponse response = null;
1964 fileName = Path.GetFullPath (fileName);
1967 fStream = File.OpenRead (fileName);
1968 token.ThrowIfCancellationRequested ();
1969 reqStream = await request.GetRequestStreamAsync ().ConfigureAwait (false);
1970 token.ThrowIfCancellationRequested ();
1971 byte [] bytes_boundary = null;
1972 if (needs_boundary) {
1973 bytes_boundary = Encoding.ASCII.GetBytes (boundary);
1974 using (MemoryStream ms = new MemoryStream ()) {
1975 ms.WriteByte ((byte) '-');
1976 ms.WriteByte ((byte) '-');
1977 ms.Write (bytes_boundary, 0, bytes_boundary.Length);
1978 ms.WriteByte ((byte) '\r');
1979 ms.WriteByte ((byte) '\n');
1980 string partHeaders = String.Format (
1981 "Content-Disposition: form-data; " +
1982 "name=\"file\"; filename=\"{0}\"\r\n" +
1983 "Content-Type: {1}\r\n\r\n",
1984 Path.GetFileName (fileName), fileCType);
1985 byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
1986 ms.Write (partHeadersBytes, 0, partHeadersBytes.Length);
1987 await ms.CopyToAsync (reqStream, (int)ms.Position, token).ConfigureAwait (false);
1991 long bytes_sent = 0;
1992 long file_size = -1;
1993 long step = 16384; // every 16kB
1994 if (fStream.CanSeek) {
1995 file_size = fStream.Length;
1996 step = file_size / 100;
1998 var upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, 0, null);
1999 OnUploadProgressChanged (upload_args);
2000 byte [] buffer = new byte [4096];
2002 token.ThrowIfCancellationRequested ();
2003 while ((nread = await fStream.ReadAsync (buffer, 0, 4096, token).ConfigureAwait (false)) > 0) {
2004 token.ThrowIfCancellationRequested ();
2005 await reqStream.WriteAsync (buffer, 0, nread, token).ConfigureAwait (false);
2006 bytes_sent += nread;
2008 if (sum >= step || nread < 4096) {
2011 percent = (int) (bytes_sent * 100 / file_size);
2012 upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, percent, null);
2013 OnUploadProgressChanged (upload_args);
2018 if (needs_boundary) {
2019 using (MemoryStream ms = new MemoryStream ()) {
2020 ms.WriteByte ((byte) '\r');
2021 ms.WriteByte ((byte) '\n');
2022 ms.WriteByte ((byte) '-');
2023 ms.WriteByte ((byte) '-');
2024 ms.Write (bytes_boundary, 0, bytes_boundary.Length);
2025 ms.WriteByte ((byte) '-');
2026 ms.WriteByte ((byte) '-');
2027 ms.WriteByte ((byte) '\r');
2028 ms.WriteByte ((byte) '\n');
2029 await ms.CopyToAsync (reqStream, (int)ms.Position, token).ConfigureAwait (false);
2035 response = await GetWebResponseTaskAsync (request, token).ConfigureAwait (false);
2036 return await ReadAllTaskAsync (request, response, token).ConfigureAwait (false);
2038 if (fStream != null)
2041 if (reqStream != null)
2044 if (response != null)
2049 // UploadStringTaskAsync
2051 public Task<string> UploadStringTaskAsync (string address, string data)
2053 if (address == null)
2054 throw new ArgumentNullException ("address");
2056 throw new ArgumentNullException ("data");
2058 return UploadStringTaskAsync (CreateUri (address), null, data);
2061 public Task<string> UploadStringTaskAsync (string address, string method, string data)
2063 if (address == null)
2064 throw new ArgumentNullException ("address");
2066 throw new ArgumentNullException ("data");
2068 return UploadStringTaskAsync (CreateUri (address), method, data);
2071 public Task<string> UploadStringTaskAsync (Uri address, string data)
2073 if (address == null)
2074 throw new ArgumentNullException ("address");
2076 throw new ArgumentNullException ("data");
2078 return UploadStringTaskAsync (address, null, data);
2081 public async Task<string> UploadStringTaskAsync (Uri address, string method, string data)
2083 if (address == null)
2084 throw new ArgumentNullException ("address");
2086 throw new ArgumentNullException ("data");
2088 WebRequest request = null;
2091 cts = new CancellationTokenSource ();
2092 request = await SetupRequestAsync (address, method, true).ConfigureAwait (false);
2093 var result = await UploadDataTaskAsyncCore (request, encoding.GetBytes (data), cts.Token).ConfigureAwait (false);
2094 var result_str = encoding.GetString (result);
2095 OnUploadStringCompleted (new UploadStringCompletedEventArgs (result_str, null, false, null));
2097 } catch (WebException ex) {
2098 OnUploadStringCompleted (new UploadStringCompletedEventArgs (null, ex, false, null));
2100 } catch (OperationCanceledException) {
2101 if (request != null)
2103 OnUploadStringCompleted (new UploadStringCompletedEventArgs (null, null, true, null));
2105 } catch (Exception ex) {
2106 OnUploadStringCompleted (new UploadStringCompletedEventArgs (null, ex, true, null));
2107 throw new WebException ("An error occurred performing a WebClient request.", ex);
2111 // UploadValuesTaskAsync
2113 public Task<byte[]> UploadValuesTaskAsync (string address, NameValueCollection data)
2115 if (address == null)
2116 throw new ArgumentNullException ("address");
2118 return UploadValuesTaskAsync (CreateUri (address), data);
2121 public Task<byte[]> UploadValuesTaskAsync (string address, string method, NameValueCollection data)
2123 if (address == null)
2124 throw new ArgumentNullException ("address");
2126 return UploadValuesTaskAsync (CreateUri (address), method, data);
2129 public Task<byte[]> UploadValuesTaskAsync (Uri address, NameValueCollection data)
2131 return UploadValuesTaskAsync (address, (string) null, data);
2134 public async Task<byte[]> UploadValuesTaskAsync (Uri address, string method, NameValueCollection data)
2136 if (address == null)
2137 throw new ArgumentNullException ("address");
2139 throw new ArgumentNullException ("data");
2141 WebRequest request = null;
2144 cts = new CancellationTokenSource ();
2145 request = await SetupRequestAsync (address, method, true).ConfigureAwait (false);
2146 var result = await UploadValuesTaskAsyncCore (request, data, cts.Token).ConfigureAwait (false);
2147 OnUploadValuesCompleted (new UploadValuesCompletedEventArgs (result, null, false, null));
2149 } catch (WebException ex) {
2150 OnUploadValuesCompleted (new UploadValuesCompletedEventArgs (null, ex, false, null));
2152 } catch (OperationCanceledException) {
2153 if (request != null)
2155 OnUploadValuesCompleted (new UploadValuesCompletedEventArgs (null, null, true, null));
2157 } catch (Exception ex) {
2158 OnUploadValuesCompleted (new UploadValuesCompletedEventArgs (null, ex, true, null));
2159 throw new WebException ("An error occurred performing a WebClient request.", ex);
2163 async Task<byte[]> UploadValuesTaskAsyncCore (WebRequest request, NameValueCollection data,
2164 CancellationToken token)
2166 token.ThrowIfCancellationRequested ();
2167 string cType = Headers ["Content-Type"];
2168 if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
2169 throw new WebException ("Content-Type header cannot be changed from its default " +
2170 "value for this request.");
2172 WebResponse response = null;
2174 Headers ["Content-Type"] = urlEncodedCType;
2176 MemoryStream tmpStream = new MemoryStream ();
2177 foreach (string key in data) {
2178 byte [] bytes = Encoding.UTF8.GetBytes (key);
2179 UrlEncodeAndWrite (tmpStream, bytes);
2180 tmpStream.WriteByte ((byte) '=');
2181 bytes = Encoding.UTF8.GetBytes (data [key]);
2182 UrlEncodeAndWrite (tmpStream, bytes);
2183 tmpStream.WriteByte ((byte) '&');
2186 token.ThrowIfCancellationRequested ();
2188 int length = (int) tmpStream.Length;
2190 tmpStream.SetLength (--length); // remove trailing '&'
2192 byte [] buf = tmpStream.GetBuffer ();
2193 request.ContentLength = length;
2194 using (Stream rqStream = await request.GetRequestStreamAsync ().ConfigureAwait (false)) {
2195 await rqStream.WriteAsync (buf, 0, length, token).ConfigureAwait (false);
2199 response = await GetWebResponseTaskAsync (request, token).ConfigureAwait (false);
2200 return await ReadAllTaskAsync (request, response, token).ConfigureAwait (false);
2202 if (response != null)