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)
10 // Copyright 2003 Ximian, Inc. (http://www.ximian.com)
11 // Copyright 2006, 2010 Novell, Inc. (http://www.novell.com)
12 // Copyright 2012 Xamarin Inc. (http://www.xamarin.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 // Notes on CancelAsync and Async methods:
37 // WebClient.CancelAsync is implemented by calling Thread.Interrupt
38 // in our helper thread. The various async methods have to cancel
39 // any ongoing requests by calling request.Abort () at that point.
40 // In a few places (UploadDataCore, UploadValuesCore,
41 // UploadFileCore) we catch the ThreadInterruptedException and
42 // abort the request there.
44 // Higher level routines (the async callbacks) also need to catch
45 // the exception and raise the OnXXXXCompleted events there with
46 // the "canceled" flag set to true.
48 // In a few other places where these helper routines are not used
49 // (OpenReadAsync for example) catching the ThreadAbortException
50 // also must abort the request.
52 // The Async methods currently differ in their implementation from
53 // the .NET implementation in that we manually catch any other
54 // exceptions and correctly raise the OnXXXXCompleted passing the
55 // Exception that caused the problem. The .NET implementation
56 // does not seem to have a mechanism to flag errors that happen
57 // during downloads though. We do this because we still need to
58 // catch the exception on these helper threads, or we would
59 // otherwise kill the application (on the 2.x profile, uncaught
60 // exceptions in threads terminate the application).
63 using System.Collections.Specialized;
64 using System.ComponentModel;
66 using System.Runtime.InteropServices;
67 using System.Runtime.Serialization;
69 using System.Threading;
70 using System.Net.Cache;
75 public class WebClient : Component
77 static readonly string urlEncodedCType = "application/x-www-form-urlencoded";
78 static byte [] hexBytes;
79 ICredentials credentials;
80 WebHeaderCollection headers;
81 WebHeaderCollection responseHeaders;
84 NameValueCollection queryString;
87 bool proxySet = false;
89 Encoding encoding = Encoding.Default;
91 // RequestCachePolicy cache_policy;
96 hexBytes = new byte [16];
98 for (int i = '0'; i <= '9'; i++, index++)
99 hexBytes [index] = (byte) i;
101 for (int i = 'a'; i <= 'f'; i++, index++)
102 hexBytes [index] = (byte) i;
111 public string BaseAddress {
113 if (baseString == null) {
114 if (baseAddress == null)
118 baseString = baseAddress.ToString ();
123 if (value == null || value.Length == 0) {
126 baseAddress = new Uri (value);
131 static Exception GetMustImplement ()
133 return new NotImplementedException ();
136 [MonoTODO ("Value can be set but is currently ignored")]
137 public RequestCachePolicy CachePolicy
140 throw GetMustImplement ();
142 set { /*cache_policy = value;*/ }
145 [MonoTODO ("Value can be set but is ignored")]
146 public bool UseDefaultCredentials
149 throw GetMustImplement ();
152 // This makes no sense in mono
156 public ICredentials Credentials {
157 get { return credentials; }
158 set { credentials = value; }
161 public WebHeaderCollection Headers {
164 headers = new WebHeaderCollection ();
168 set { headers = value; }
171 public NameValueCollection QueryString {
173 if (queryString == null)
174 queryString = new NameValueCollection ();
178 set { queryString = value; }
181 public WebHeaderCollection ResponseHeaders {
182 get { return responseHeaders; }
185 public Encoding Encoding {
186 get { return encoding; }
189 throw new ArgumentNullException ("Encoding");
194 public IWebProxy Proxy {
197 return WebRequest.DefaultWebProxy;
208 get { return is_busy; }
215 throw new NotSupportedException ("WebClient does not support concurrent I/O operations.");
228 public byte [] DownloadData (string address)
231 throw new ArgumentNullException ("address");
233 return DownloadData (CreateUri (address));
236 public byte [] DownloadData (Uri address)
239 throw new ArgumentNullException ("address");
244 return DownloadDataCore (address, null);
250 byte [] DownloadDataCore (Uri address, object userToken)
252 WebRequest request = null;
255 request = SetupRequest (address);
256 return ReadAll (request, userToken);
257 } catch (ThreadInterruptedException){
260 throw new WebException ("User canceled the request", WebExceptionStatus.RequestCanceled);
261 } catch (WebException) {
263 } catch (Exception ex) {
264 throw new WebException ("An error occurred performing a WebClient request.", ex);
270 public void DownloadFile (string address, string fileName)
273 throw new ArgumentNullException ("address");
275 DownloadFile (CreateUri (address), fileName);
278 public void DownloadFile (Uri address, string fileName)
281 throw new ArgumentNullException ("address");
282 if (fileName == null)
283 throw new ArgumentNullException ("fileName");
288 DownloadFileCore (address, fileName, null);
289 } catch (WebException) {
291 } catch (Exception ex) {
292 throw new WebException ("An error occurred " +
293 "performing a WebClient request.", ex);
299 void DownloadFileCore (Uri address, string fileName, object userToken)
301 WebRequest request = null;
303 using (FileStream f = new FileStream (fileName, FileMode.Create)) {
305 request = SetupRequest (address);
306 WebResponse response = GetWebResponse (request);
307 Stream st = response.GetResponseStream ();
309 int cLength = (int) response.ContentLength;
310 int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
311 byte [] buffer = new byte [length];
314 long notify_total = 0;
315 while ((nread = st.Read (buffer, 0, length)) != 0){
317 notify_total += nread;
318 OnDownloadProgressChanged (
319 new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken));
322 f.Write (buffer, 0, nread);
324 } catch (ThreadInterruptedException){
334 public Stream OpenRead (string address)
337 throw new ArgumentNullException ("address");
338 return OpenRead (CreateUri (address));
341 public Stream OpenRead (Uri address)
344 throw new ArgumentNullException ("address");
346 WebRequest request = null;
350 request = SetupRequest (address);
351 WebResponse response = GetWebResponse (request);
352 return response.GetResponseStream ();
353 } catch (WebException) {
355 } catch (Exception ex) {
356 throw new WebException ("An error occurred " +
357 "performing a WebClient request.", ex);
365 public Stream OpenWrite (string address)
368 throw new ArgumentNullException ("address");
370 return OpenWrite (CreateUri (address));
373 public Stream OpenWrite (string address, string method)
376 throw new ArgumentNullException ("address");
378 return OpenWrite (CreateUri (address), method);
381 public Stream OpenWrite (Uri address)
383 return OpenWrite (address, (string) null);
386 public Stream OpenWrite (Uri address, string method)
389 throw new ArgumentNullException ("address");
394 WebRequest request = SetupRequest (address, method, true);
395 return request.GetRequestStream ();
396 } catch (WebException) {
398 } catch (Exception ex) {
399 throw new WebException ("An error occurred " +
400 "performing a WebClient request.", ex);
406 private string DetermineMethod (Uri address, string method, bool is_upload)
411 if (address.Scheme == Uri.UriSchemeFtp)
412 return (is_upload) ? "STOR" : "RETR";
414 return (is_upload) ? "POST" : "GET";
419 public byte [] UploadData (string address, byte [] data)
422 throw new ArgumentNullException ("address");
424 return UploadData (CreateUri (address), data);
427 public byte [] UploadData (string address, string method, byte [] data)
430 throw new ArgumentNullException ("address");
432 return UploadData (CreateUri (address), method, data);
435 public byte [] UploadData (Uri address, byte [] data)
437 return UploadData (address, (string) null, data);
440 public byte [] UploadData (Uri address, string method, byte [] data)
443 throw new ArgumentNullException ("address");
445 throw new ArgumentNullException ("data");
450 return UploadDataCore (address, method, data, null);
451 } catch (WebException) {
453 } catch (Exception ex) {
454 throw new WebException ("An error occurred " +
455 "performing a WebClient request.", ex);
461 byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
463 WebRequest request = SetupRequest (address, method, true);
465 int contentLength = data.Length;
466 request.ContentLength = contentLength;
467 using (Stream stream = request.GetRequestStream ()) {
468 stream.Write (data, 0, contentLength);
471 return ReadAll (request, userToken);
472 } catch (ThreadInterruptedException){
481 public byte [] UploadFile (string address, string fileName)
484 throw new ArgumentNullException ("address");
486 return UploadFile (CreateUri (address), fileName);
489 public byte [] UploadFile (Uri address, string fileName)
491 return UploadFile (address, (string) null, fileName);
494 public byte [] UploadFile (string address, string method, string fileName)
496 return UploadFile (CreateUri (address), method, fileName);
499 public byte [] UploadFile (Uri address, string method, string fileName)
502 throw new ArgumentNullException ("address");
503 if (fileName == null)
504 throw new ArgumentNullException ("fileName");
509 return UploadFileCore (address, method, fileName, null);
510 } catch (WebException) {
512 } catch (Exception ex) {
513 throw new WebException ("An error occurred " +
514 "performing a WebClient request.", ex);
520 byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
522 string fileCType = Headers ["Content-Type"];
523 if (fileCType != null) {
524 string lower = fileCType.ToLower ();
525 if (lower.StartsWith ("multipart/"))
526 throw new WebException ("Content-Type cannot be set to a multipart" +
527 " type for this request.");
529 fileCType = "application/octet-stream";
532 bool needs_boundary = (method != "PUT"); // only verified case so far
533 string boundary = null;
534 if (needs_boundary) {
535 boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
536 Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
538 Stream reqStream = null;
539 Stream fStream = null;
540 byte [] resultBytes = null;
542 fileName = Path.GetFullPath (fileName);
544 WebRequest request = null;
546 fStream = File.OpenRead (fileName);
547 request = SetupRequest (address, method, true);
548 reqStream = request.GetRequestStream ();
549 byte [] bytes_boundary = null;
550 if (needs_boundary) {
551 bytes_boundary = Encoding.ASCII.GetBytes (boundary);
552 reqStream.WriteByte ((byte) '-');
553 reqStream.WriteByte ((byte) '-');
554 reqStream.Write (bytes_boundary, 0, bytes_boundary.Length);
555 reqStream.WriteByte ((byte) '\r');
556 reqStream.WriteByte ((byte) '\n');
557 string partHeaders = String.Format ("Content-Disposition: form-data; " +
558 "name=\"file\"; filename=\"{0}\"\r\n" +
559 "Content-Type: {1}\r\n\r\n",
560 Path.GetFileName (fileName), fileCType);
562 byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
563 reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
566 byte [] buffer = new byte [4096];
567 while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
568 reqStream.Write (buffer, 0, nread);
570 if (needs_boundary) {
571 reqStream.WriteByte ((byte) '\r');
572 reqStream.WriteByte ((byte) '\n');
573 reqStream.WriteByte ((byte) '-');
574 reqStream.WriteByte ((byte) '-');
575 reqStream.Write (bytes_boundary, 0, bytes_boundary.Length);
576 reqStream.WriteByte ((byte) '-');
577 reqStream.WriteByte ((byte) '-');
578 reqStream.WriteByte ((byte) '\r');
579 reqStream.WriteByte ((byte) '\n');
583 resultBytes = ReadAll (request, userToken);
584 } catch (ThreadInterruptedException){
592 if (reqStream != null)
599 public byte[] UploadValues (string address, NameValueCollection data)
602 throw new ArgumentNullException ("address");
604 return UploadValues (CreateUri (address), data);
607 public byte[] UploadValues (string address, string method, NameValueCollection data)
610 throw new ArgumentNullException ("address");
611 return UploadValues (CreateUri (address), method, data);
614 public byte[] UploadValues (Uri address, NameValueCollection data)
616 return UploadValues (address, (string) null, data);
619 public byte[] UploadValues (Uri address, string method, NameValueCollection data)
622 throw new ArgumentNullException ("address");
624 throw new ArgumentNullException ("data");
629 return UploadValuesCore (address, method, data, null);
630 } catch (WebException) {
632 } catch (Exception ex) {
633 throw new WebException ("An error occurred " +
634 "performing a WebClient request.", ex);
640 byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
642 string cType = Headers ["Content-Type"];
643 if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
644 throw new WebException ("Content-Type header cannot be changed from its default " +
645 "value for this request.");
647 Headers ["Content-Type"] = urlEncodedCType;
648 WebRequest request = SetupRequest (uri, method, true);
650 MemoryStream tmpStream = new MemoryStream ();
651 foreach (string key in data) {
652 byte [] bytes = Encoding.UTF8.GetBytes (key);
653 UrlEncodeAndWrite (tmpStream, bytes);
654 tmpStream.WriteByte ((byte) '=');
655 bytes = Encoding.UTF8.GetBytes (data [key]);
656 UrlEncodeAndWrite (tmpStream, bytes);
657 tmpStream.WriteByte ((byte) '&');
660 int length = (int) tmpStream.Length;
662 tmpStream.SetLength (--length); // remove trailing '&'
664 byte [] buf = tmpStream.GetBuffer ();
665 request.ContentLength = length;
666 using (Stream rqStream = request.GetRequestStream ()) {
667 rqStream.Write (buf, 0, length);
671 return ReadAll (request, userToken);
672 } catch (ThreadInterruptedException) {
678 public string DownloadString (string address)
681 throw new ArgumentNullException ("address");
683 return encoding.GetString (DownloadData (CreateUri (address)));
686 public string DownloadString (Uri address)
689 throw new ArgumentNullException ("address");
691 return encoding.GetString (DownloadData (CreateUri (address)));
694 public string UploadString (string address, string data)
697 throw new ArgumentNullException ("address");
699 throw new ArgumentNullException ("data");
701 byte [] resp = UploadData (address, encoding.GetBytes (data));
702 return encoding.GetString (resp);
705 public string UploadString (string address, string method, string data)
708 throw new ArgumentNullException ("address");
710 throw new ArgumentNullException ("data");
712 byte [] resp = UploadData (address, method, encoding.GetBytes (data));
713 return encoding.GetString (resp);
716 public string UploadString (Uri address, string data)
719 throw new ArgumentNullException ("address");
721 throw new ArgumentNullException ("data");
723 byte [] resp = UploadData (address, encoding.GetBytes (data));
724 return encoding.GetString (resp);
727 public string UploadString (Uri address, string method, string data)
730 throw new ArgumentNullException ("address");
732 throw new ArgumentNullException ("data");
734 byte [] resp = UploadData (address, method, encoding.GetBytes (data));
735 return encoding.GetString (resp);
738 public event DownloadDataCompletedEventHandler DownloadDataCompleted;
739 public event AsyncCompletedEventHandler DownloadFileCompleted;
740 public event DownloadProgressChangedEventHandler DownloadProgressChanged;
741 public event DownloadStringCompletedEventHandler DownloadStringCompleted;
742 public event OpenReadCompletedEventHandler OpenReadCompleted;
743 public event OpenWriteCompletedEventHandler OpenWriteCompleted;
744 public event UploadDataCompletedEventHandler UploadDataCompleted;
745 public event UploadFileCompletedEventHandler UploadFileCompleted;
746 public event UploadProgressChangedEventHandler UploadProgressChanged;
747 public event UploadStringCompletedEventHandler UploadStringCompleted;
748 public event UploadValuesCompletedEventHandler UploadValuesCompleted;
750 Uri CreateUri (string address)
754 if (baseAddress == null)
755 uri = new Uri (address);
757 uri = new Uri (baseAddress, address);
758 return CreateUri (uri);
761 return new Uri (Path.GetFullPath (address));
764 Uri CreateUri (Uri address)
766 Uri result = address;
767 if (baseAddress != null && !result.IsAbsoluteUri) {
769 result = new Uri (baseAddress, result.OriginalString);
771 return result; // Not much we can do here.
775 string query = result.Query;
776 if (String.IsNullOrEmpty (query))
777 query = GetQueryString (true);
778 UriBuilder builder = new UriBuilder (address);
779 if (!String.IsNullOrEmpty (query))
780 builder.Query = query.Substring (1);
784 string GetQueryString (bool add_qmark)
786 if (queryString == null || queryString.Count == 0)
789 StringBuilder sb = new StringBuilder ();
793 foreach (string key in queryString)
794 sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
797 sb.Length--; // removes last '&' or the '?' if empty.
802 return sb.ToString ();
805 WebRequest SetupRequest (Uri uri)
807 WebRequest request = GetWebRequest (uri);
809 request.Proxy = Proxy;
810 if (credentials != null)
811 request.Credentials = credentials;
812 else if (!String.IsNullOrEmpty (uri.UserInfo)) {
813 // Perhaps this should be done by the underlying URI handler?
814 ICredentials creds = GetCredentials (uri.UserInfo);
816 request.Credentials = creds;
819 // Special headers. These are properties of HttpWebRequest.
820 // What do we do with other requests differnt from HttpWebRequest?
821 if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
822 HttpWebRequest req = (HttpWebRequest) request;
823 string expect = headers ["Expect"];
824 string contentType = headers ["Content-Type"];
825 string accept = headers ["Accept"];
826 string connection = headers ["Connection"];
827 string userAgent = headers ["User-Agent"];
828 string referer = headers ["Referer"];
829 headers.RemoveInternal ("Expect");
830 headers.RemoveInternal ("Content-Type");
831 headers.RemoveInternal ("Accept");
832 headers.RemoveInternal ("Connection");
833 headers.RemoveInternal ("Referer");
834 headers.RemoveInternal ("User-Agent");
835 request.Headers = headers;
837 if (expect != null && expect.Length > 0)
840 if (accept != null && accept.Length > 0)
843 if (contentType != null && contentType.Length > 0)
844 req.ContentType = contentType;
846 if (connection != null && connection.Length > 0)
847 req.Connection = connection;
849 if (userAgent != null && userAgent.Length > 0)
850 req.UserAgent = userAgent;
852 if (referer != null && referer.Length > 0)
853 req.Referer = referer;
856 responseHeaders = null;
860 WebRequest SetupRequest (Uri uri, string method, bool is_upload)
862 WebRequest request = SetupRequest (uri);
863 request.Method = DetermineMethod (uri, method, is_upload);
867 static NetworkCredential GetCredentials (string user_info)
869 string [] creds = user_info.Split (':');
870 if (creds.Length != 2)
873 if (creds [0].IndexOf ('\\') != -1) {
874 string [] user = creds [0].Split ('\\');
875 if (user.Length != 2)
877 return new NetworkCredential (user [1], creds [1], user [0]);
879 return new NetworkCredential (creds [0], creds [1]);
882 byte [] ReadAll (WebRequest request, object userToken)
884 WebResponse response = GetWebResponse (request);
885 Stream stream = response.GetResponseStream ();
886 int length = (int) response.ContentLength;
887 HttpWebRequest wreq = request as HttpWebRequest;
889 if (length > -1 && wreq != null && (int) wreq.AutomaticDecompression != 0) {
890 string content_encoding = ((HttpWebResponse) response).ContentEncoding;
891 if (((content_encoding == "gzip" && (wreq.AutomaticDecompression & DecompressionMethods.GZip) != 0)) ||
892 ((content_encoding == "deflate" && (wreq.AutomaticDecompression & DecompressionMethods.Deflate) != 0)))
896 MemoryStream ms = null;
897 bool nolength = (length == -1);
898 int size = ((nolength) ? 8192 : length);
900 ms = new MemoryStream ();
905 byte [] buffer = new byte [size];
906 while ((nread = stream.Read (buffer, offset, size)) != 0) {
908 ms.Write (buffer, 0, nread);
915 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (total, length, userToken));
920 return ms.ToArray ();
925 string UrlEncode (string str)
927 StringBuilder result = new StringBuilder ();
929 int len = str.Length;
930 for (int i = 0; i < len; i++) {
934 else if ((c < '0' && c != '-' && c != '.') ||
935 (c < 'A' && c > '9') ||
936 (c > 'Z' && c < 'a' && c != '_') ||
939 int idx = ((int) c) >> 4;
940 result.Append ((char) hexBytes [idx]);
941 idx = ((int) c) & 0x0F;
942 result.Append ((char) hexBytes [idx]);
948 return result.ToString ();
951 static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
956 int len = bytes.Length;
960 for (int i = 0; i < len; i++) {
961 char c = (char) bytes [i];
963 stream.WriteByte ((byte) '+');
964 else if ((c < '0' && c != '-' && c != '.') ||
965 (c < 'A' && c > '9') ||
966 (c > 'Z' && c < 'a' && c != '_') ||
968 stream.WriteByte ((byte) '%');
969 int idx = ((int) c) >> 4;
970 stream.WriteByte (hexBytes [idx]);
971 idx = ((int) c) & 0x0F;
972 stream.WriteByte (hexBytes [idx]);
974 stream.WriteByte ((byte) c);
979 public void CancelAsync ()
982 if (async_thread == null)
986 // We first flag things as done, in case the Interrupt hangs
987 // or the thread decides to hang in some other way inside the
988 // event handlers, or if we are stuck somewhere else. This
989 // ensures that the WebClient object is reusable immediately
991 Thread t = async_thread;
997 void CompleteAsync ()
1001 async_thread = null;
1005 // DownloadDataAsync
1007 public void DownloadDataAsync (Uri address)
1009 DownloadDataAsync (address, null);
1012 public void DownloadDataAsync (Uri address, object userToken)
1014 if (address == null)
1015 throw new ArgumentNullException ("address");
1021 async_thread = new Thread (delegate (object state) {
1022 object [] args = (object []) state;
1024 byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
1025 OnDownloadDataCompleted (
1026 new DownloadDataCompletedEventArgs (data, null, false, args [1]));
1027 } catch (Exception e){
1028 bool canceled = false;
1029 WebException we = e as WebException;
1031 canceled = we.Status == WebExceptionStatus.RequestCanceled;
1032 OnDownloadDataCompleted (
1033 new DownloadDataCompletedEventArgs (null, e, canceled, args [1]));
1036 object [] cb_args = new object [] {address, userToken};
1037 async_thread.Start (cb_args);
1041 // DownloadFileAsync
1043 public void DownloadFileAsync (Uri address, string fileName)
1045 DownloadFileAsync (address, fileName, null);
1048 public void DownloadFileAsync (Uri address, string fileName, object userToken)
1050 if (address == null)
1051 throw new ArgumentNullException ("address");
1052 if (fileName == null)
1053 throw new ArgumentNullException ("fileName");
1059 async_thread = new Thread (delegate (object state) {
1060 object [] args = (object []) state;
1062 DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
1063 OnDownloadFileCompleted (
1064 new AsyncCompletedEventArgs (null, false, args [2]));
1065 } catch (ThreadInterruptedException){
1066 OnDownloadFileCompleted (
1067 new AsyncCompletedEventArgs (null, true, args [2]));
1068 } catch (Exception e){
1069 OnDownloadFileCompleted (
1070 new AsyncCompletedEventArgs (e, false, args [2]));
1072 object [] cb_args = new object [] {address, fileName, userToken};
1073 async_thread.Start (cb_args);
1077 // DownloadStringAsync
1079 public void DownloadStringAsync (Uri address)
1081 DownloadStringAsync (address, null);
1084 public void DownloadStringAsync (Uri address, object userToken)
1086 if (address == null)
1087 throw new ArgumentNullException ("address");
1093 async_thread = new Thread (delegate (object state) {
1094 object [] args = (object []) state;
1096 string data = encoding.GetString (DownloadDataCore ((Uri) args [0], args [1]));
1097 OnDownloadStringCompleted (
1098 new DownloadStringCompletedEventArgs (data, null, false, args [1]));
1099 } catch (Exception e){
1100 bool canceled = false;
1101 WebException we = e as WebException;
1103 canceled = we.Status == WebExceptionStatus.RequestCanceled;
1104 OnDownloadStringCompleted (
1105 new DownloadStringCompletedEventArgs (null, e, canceled, args [1]));
1107 object [] cb_args = new object [] {address, userToken};
1108 async_thread.Start (cb_args);
1114 public void OpenReadAsync (Uri address)
1116 OpenReadAsync (address, null);
1119 public void OpenReadAsync (Uri address, object userToken)
1121 if (address == null)
1122 throw new ArgumentNullException ("address");
1128 async_thread = new Thread (delegate (object state) {
1129 object [] args = (object []) state;
1130 WebRequest request = null;
1132 request = SetupRequest ((Uri) args [0]);
1133 WebResponse response = GetWebResponse (request);
1134 Stream stream = response.GetResponseStream ();
1135 OnOpenReadCompleted (
1136 new OpenReadCompletedEventArgs (stream, null, false, args [1]));
1137 } catch (ThreadInterruptedException){
1138 if (request != null)
1141 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, args [1]));
1142 } catch (Exception e){
1143 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, e, false, args [1]));
1145 object [] cb_args = new object [] {address, userToken};
1146 async_thread.Start (cb_args);
1152 public void OpenWriteAsync (Uri address)
1154 OpenWriteAsync (address, null);
1157 public void OpenWriteAsync (Uri address, string method)
1159 OpenWriteAsync (address, method, null);
1162 public void OpenWriteAsync (Uri address, string method, object userToken)
1164 if (address == null)
1165 throw new ArgumentNullException ("address");
1171 async_thread = new Thread (delegate (object state) {
1172 object [] args = (object []) state;
1173 WebRequest request = null;
1175 request = SetupRequest ((Uri) args [0], (string) args [1], true);
1176 Stream stream = request.GetRequestStream ();
1177 OnOpenWriteCompleted (
1178 new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
1179 } catch (ThreadInterruptedException){
1180 if (request != null)
1182 OnOpenWriteCompleted (
1183 new OpenWriteCompletedEventArgs (null, null, true, args [2]));
1184 } catch (Exception e){
1185 OnOpenWriteCompleted (
1186 new OpenWriteCompletedEventArgs (null, e, false, args [2]));
1188 object [] cb_args = new object [] {address, method, userToken};
1189 async_thread.Start (cb_args);
1195 public void UploadDataAsync (Uri address, byte [] data)
1197 UploadDataAsync (address, null, data);
1200 public void UploadDataAsync (Uri address, string method, byte [] data)
1202 UploadDataAsync (address, method, data, null);
1205 public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
1207 if (address == null)
1208 throw new ArgumentNullException ("address");
1210 throw new ArgumentNullException ("data");
1216 async_thread = new Thread (delegate (object state) {
1217 object [] args = (object []) state;
1221 data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
1223 OnUploadDataCompleted (
1224 new UploadDataCompletedEventArgs (data2, null, false, args [3]));
1225 } catch (ThreadInterruptedException){
1226 OnUploadDataCompleted (
1227 new UploadDataCompletedEventArgs (null, null, true, args [3]));
1228 } catch (Exception e){
1229 OnUploadDataCompleted (
1230 new UploadDataCompletedEventArgs (null, e, false, args [3]));
1232 object [] cb_args = new object [] {address, method, data, userToken};
1233 async_thread.Start (cb_args);
1239 public void UploadFileAsync (Uri address, string fileName)
1241 UploadFileAsync (address, null, fileName);
1244 public void UploadFileAsync (Uri address, string method, string fileName)
1246 UploadFileAsync (address, method, fileName, null);
1249 public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
1251 if (address == null)
1252 throw new ArgumentNullException ("address");
1253 if (fileName == null)
1254 throw new ArgumentNullException ("fileName");
1260 async_thread = new Thread (delegate (object state) {
1261 object [] args = (object []) state;
1265 data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
1266 OnUploadFileCompleted (
1267 new UploadFileCompletedEventArgs (data, null, false, args [3]));
1268 } catch (ThreadInterruptedException){
1269 OnUploadFileCompleted (
1270 new UploadFileCompletedEventArgs (null, null, true, args [3]));
1271 } catch (Exception e){
1272 OnUploadFileCompleted (
1273 new UploadFileCompletedEventArgs (null, e, false, args [3]));
1275 object [] cb_args = new object [] {address, method, fileName, userToken};
1276 async_thread.Start (cb_args);
1280 // UploadStringAsync
1282 public void UploadStringAsync (Uri address, string data)
1284 UploadStringAsync (address, null, data);
1287 public void UploadStringAsync (Uri address, string method, string data)
1289 UploadStringAsync (address, method, data, null);
1292 public void UploadStringAsync (Uri address, string method, string data, object userToken)
1294 if (address == null)
1295 throw new ArgumentNullException ("address");
1297 throw new ArgumentNullException ("data");
1303 async_thread = new Thread (delegate (object state) {
1304 object [] args = (object []) state;
1307 string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
1308 OnUploadStringCompleted (
1309 new UploadStringCompletedEventArgs (data2, null, false, args [3]));
1310 } catch (ThreadInterruptedException){
1311 OnUploadStringCompleted (
1312 new UploadStringCompletedEventArgs (null, null, true, args [3]));
1313 } catch (Exception e){
1314 OnUploadStringCompleted (
1315 new UploadStringCompletedEventArgs (null, e, false, args [3]));
1317 object [] cb_args = new object [] {address, method, data, userToken};
1318 async_thread.Start (cb_args);
1322 // UploadValuesAsync
1324 public void UploadValuesAsync (Uri address, NameValueCollection data)
1326 UploadValuesAsync (address, null, data);
1329 public void UploadValuesAsync (Uri address, string method, NameValueCollection data)
1331 UploadValuesAsync (address, method, data, null);
1334 public void UploadValuesAsync (Uri address, string method, NameValueCollection data, object userToken)
1336 if (address == null)
1337 throw new ArgumentNullException ("address");
1339 throw new ArgumentNullException ("data");
1345 async_thread = new Thread (delegate (object state) {
1346 object [] args = (object []) state;
1348 byte [] values = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
1349 OnUploadValuesCompleted (
1350 new UploadValuesCompletedEventArgs (values, null, false, args [3]));
1351 } catch (ThreadInterruptedException){
1352 OnUploadValuesCompleted (
1353 new UploadValuesCompletedEventArgs (null, null, true, args [3]));
1354 } catch (Exception e){
1355 OnUploadValuesCompleted (
1356 new UploadValuesCompletedEventArgs (null, e, false, args [3]));
1358 object [] cb_args = new object [] {address, method, data, userToken};
1359 async_thread.Start (cb_args);
1363 protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs e)
1366 if (DownloadDataCompleted != null)
1367 DownloadDataCompleted (this, e);
1370 protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs e)
1373 if (DownloadFileCompleted != null)
1374 DownloadFileCompleted (this, e);
1377 protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
1379 if (DownloadProgressChanged != null)
1380 DownloadProgressChanged (this, e);
1383 protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs e)
1386 if (DownloadStringCompleted != null)
1387 DownloadStringCompleted (this, e);
1390 protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs e)
1393 if (OpenReadCompleted != null)
1394 OpenReadCompleted (this, e);
1397 protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs e)
1400 if (OpenWriteCompleted != null)
1401 OpenWriteCompleted (this, e);
1404 protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs e)
1407 if (UploadDataCompleted != null)
1408 UploadDataCompleted (this, e);
1411 protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs e)
1414 if (UploadFileCompleted != null)
1415 UploadFileCompleted (this, e);
1418 protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
1420 if (UploadProgressChanged != null)
1421 UploadProgressChanged (this, e);
1424 protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs e)
1427 if (UploadStringCompleted != null)
1428 UploadStringCompleted (this, e);
1431 protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs e)
1434 if (UploadValuesCompleted != null)
1435 UploadValuesCompleted (this, e);
1438 protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
1440 WebResponse response = request.EndGetResponse (result);
1441 responseHeaders = response.Headers;
1445 protected virtual WebRequest GetWebRequest (Uri address)
1447 return WebRequest.Create (address);
1450 protected virtual WebResponse GetWebResponse (WebRequest request)
1452 WebResponse response = request.GetResponse ();
1453 responseHeaders = response.Headers;