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)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 // Notes on CancelAsync and Async methods:
36 // WebClient.CancelAsync is implemented by calling Thread.Interrupt
37 // in our helper thread. The various async methods have to cancel
38 // any ongoing requests by calling request.Abort () at that point.
39 // In a few places (UploadDataCore, UploadValuesCore,
40 // UploadFileCore) we catch the ThreadInterruptedException and
41 // abort the request there.
43 // Higher level routines (the async callbacks) also need to catch
44 // the exception and raise the OnXXXXCompleted events there with
45 // the "canceled" flag set to true.
47 // In a few other places where these helper routines are not used
48 // (OpenReadAsync for example) catching the ThreadAbortException
49 // also must abort the request.
51 // The Async methods currently differ in their implementation from
52 // the .NET implementation in that we manually catch any other
53 // exceptions and correctly raise the OnXXXXCompleted passing the
54 // Exception that caused the problem. The .NET implementation
55 // does not seem to have a mechanism to flag errors that happen
56 // during downloads though. We do this because we still need to
57 // catch the exception on these helper threads, or we would
58 // otherwise kill the application (on the 2.x profile, uncaught
59 // exceptions in threads terminate the application).
62 using System.Collections.Specialized;
63 using System.ComponentModel;
65 using System.Runtime.InteropServices;
66 using System.Runtime.Serialization;
68 using System.Threading;
69 using System.Net.Cache;
74 public class WebClient : Component
76 static readonly string urlEncodedCType = "application/x-www-form-urlencoded";
77 static byte [] hexBytes;
78 ICredentials credentials;
79 WebHeaderCollection headers;
80 WebHeaderCollection responseHeaders;
83 NameValueCollection queryString;
87 Encoding encoding = Encoding.Default;
89 RequestCachePolicy cache_policy;
94 hexBytes = new byte [16];
96 for (int i = '0'; i <= '9'; i++, index++)
97 hexBytes [index] = (byte) i;
99 for (int i = 'a'; i <= 'f'; i++, index++)
100 hexBytes [index] = (byte) i;
109 public string BaseAddress {
111 if (baseString == null) {
112 if (baseAddress == null)
116 baseString = baseAddress.ToString ();
121 if (value == null || value.Length == 0) {
124 baseAddress = new Uri (value);
129 static Exception GetMustImplement ()
131 return new NotImplementedException ();
134 [MonoTODO ("Value can be set but is currently ignored")]
135 public RequestCachePolicy CachePolicy
138 throw GetMustImplement ();
140 set { cache_policy = value; }
143 [MonoTODO ("Value can be set but is ignored")]
144 public bool UseDefaultCredentials
147 throw GetMustImplement ();
150 // This makes no sense in mono
154 public ICredentials Credentials {
155 get { return credentials; }
156 set { credentials = value; }
159 public WebHeaderCollection Headers {
162 headers = new WebHeaderCollection ();
166 set { headers = value; }
169 public NameValueCollection QueryString {
171 if (queryString == null)
172 queryString = new NameValueCollection ();
176 set { queryString = value; }
179 public WebHeaderCollection ResponseHeaders {
180 get { return responseHeaders; }
183 public Encoding Encoding {
184 get { return encoding; }
187 throw new ArgumentNullException ("Encoding");
192 public IWebProxy Proxy {
193 get { return proxy; }
194 set { proxy = value; }
198 get { return is_busy; }
205 throw new NotSupportedException ("WebClient does not support conccurent I/O operations.");
218 public byte [] DownloadData (string address)
221 throw new ArgumentNullException ("address");
223 return DownloadData (CreateUri (address));
226 public byte [] DownloadData (Uri address)
229 throw new ArgumentNullException ("address");
234 return DownloadDataCore (address, null);
240 byte [] DownloadDataCore (Uri address, object userToken)
242 WebRequest request = null;
245 request = SetupRequest (address);
246 return ReadAll (request, userToken);
247 } catch (ThreadInterruptedException){
251 } catch (WebException) {
253 } catch (Exception ex) {
254 throw new WebException ("An error occurred " +
255 "performing a WebClient request.", ex);
261 public void DownloadFile (string address, string fileName)
264 throw new ArgumentNullException ("address");
266 DownloadFile (CreateUri (address), fileName);
269 public void DownloadFile (Uri address, string fileName)
272 throw new ArgumentNullException ("address");
273 if (fileName == null)
274 throw new ArgumentNullException ("fileName");
279 DownloadFileCore (address, fileName, null);
280 } catch (WebException) {
282 } catch (Exception ex) {
283 throw new WebException ("An error occurred " +
284 "performing a WebClient request.", ex);
290 void DownloadFileCore (Uri address, string fileName, object userToken)
292 WebRequest request = null;
294 using (FileStream f = new FileStream (fileName, FileMode.Create)) {
296 request = SetupRequest (address);
297 WebResponse response = GetWebResponse (request);
298 Stream st = response.GetResponseStream ();
300 int cLength = (int) response.ContentLength;
301 int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
302 byte [] buffer = new byte [length];
305 long notify_total = 0;
306 while ((nread = st.Read (buffer, 0, length)) != 0){
308 notify_total += nread;
309 OnDownloadProgressChanged (
310 new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken));
313 f.Write (buffer, 0, nread);
315 } catch (ThreadInterruptedException){
325 public Stream OpenRead (string address)
328 throw new ArgumentNullException ("address");
329 return OpenRead (CreateUri (address));
332 public Stream OpenRead (Uri address)
335 throw new ArgumentNullException ("address");
337 WebRequest request = null;
341 request = SetupRequest (address);
342 WebResponse response = GetWebResponse (request);
343 return response.GetResponseStream ();
344 } catch (WebException) {
346 } catch (Exception ex) {
347 throw new WebException ("An error occurred " +
348 "performing a WebClient request.", ex);
356 public Stream OpenWrite (string address)
359 throw new ArgumentNullException ("address");
361 return OpenWrite (CreateUri (address));
364 public Stream OpenWrite (string address, string method)
367 throw new ArgumentNullException ("address");
369 return OpenWrite (CreateUri (address), method);
372 public Stream OpenWrite (Uri address)
374 return OpenWrite (address, (string) null);
377 public Stream OpenWrite (Uri address, string method)
380 throw new ArgumentNullException ("address");
385 WebRequest request = SetupRequest (address, method, true);
386 return request.GetRequestStream ();
387 } catch (WebException) {
389 } catch (Exception ex) {
390 throw new WebException ("An error occurred " +
391 "performing a WebClient request.", ex);
397 private string DetermineMethod (Uri address, string method, bool is_upload)
402 if (address.Scheme == Uri.UriSchemeFtp)
403 return (is_upload) ? "STOR" : "RETR";
405 return (is_upload) ? "POST" : "GET";
410 public byte [] UploadData (string address, byte [] data)
413 throw new ArgumentNullException ("address");
415 return UploadData (CreateUri (address), data);
418 public byte [] UploadData (string address, string method, byte [] data)
421 throw new ArgumentNullException ("address");
423 return UploadData (CreateUri (address), method, data);
426 public byte [] UploadData (Uri address, byte [] data)
428 return UploadData (address, (string) null, data);
431 public byte [] UploadData (Uri address, string method, byte [] data)
434 throw new ArgumentNullException ("address");
436 throw new ArgumentNullException ("data");
441 return UploadDataCore (address, method, data, null);
442 } catch (WebException) {
444 } catch (Exception ex) {
445 throw new WebException ("An error occurred " +
446 "performing a WebClient request.", ex);
452 byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
454 WebRequest request = SetupRequest (address, method, true);
456 int contentLength = data.Length;
457 request.ContentLength = contentLength;
458 using (Stream stream = request.GetRequestStream ()) {
459 stream.Write (data, 0, contentLength);
462 return ReadAll (request, userToken);
463 } catch (ThreadInterruptedException){
472 public byte [] UploadFile (string address, string fileName)
475 throw new ArgumentNullException ("address");
477 return UploadFile (CreateUri (address), fileName);
480 public byte [] UploadFile (Uri address, string fileName)
482 return UploadFile (address, (string) null, fileName);
485 public byte [] UploadFile (string address, string method, string fileName)
487 return UploadFile (CreateUri (address), method, fileName);
490 public byte [] UploadFile (Uri address, string method, string fileName)
493 throw new ArgumentNullException ("address");
494 if (fileName == null)
495 throw new ArgumentNullException ("fileName");
500 return UploadFileCore (address, method, fileName, null);
501 } catch (WebException) {
503 } catch (Exception ex) {
504 throw new WebException ("An error occurred " +
505 "performing a WebClient request.", ex);
511 byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
513 string fileCType = Headers ["Content-Type"];
514 if (fileCType != null) {
515 string lower = fileCType.ToLower ();
516 if (lower.StartsWith ("multipart/"))
517 throw new WebException ("Content-Type cannot be set to a multipart" +
518 " type for this request.");
520 fileCType = "application/octet-stream";
523 string boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
524 Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
525 Stream reqStream = null;
526 Stream fStream = null;
527 byte [] resultBytes = null;
529 fileName = Path.GetFullPath (fileName);
531 WebRequest request = null;
533 fStream = File.OpenRead (fileName);
534 request = SetupRequest (address, method, true);
535 reqStream = request.GetRequestStream ();
536 byte [] bytes_boundary = Encoding.ASCII.GetBytes (boundary);
537 reqStream.WriteByte ((byte) '-');
538 reqStream.WriteByte ((byte) '-');
539 reqStream.Write (bytes_boundary, 0, bytes_boundary.Length);
540 reqStream.WriteByte ((byte) '\r');
541 reqStream.WriteByte ((byte) '\n');
542 string partHeaders = String.Format ("Content-Disposition: form-data; " +
543 "name=\"file\"; filename=\"{0}\"\r\n" +
544 "Content-Type: {1}\r\n\r\n",
545 Path.GetFileName (fileName), fileCType);
547 byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
548 reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
550 byte [] buffer = new byte [4096];
551 while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
552 reqStream.Write (buffer, 0, nread);
554 reqStream.WriteByte ((byte) '\r');
555 reqStream.WriteByte ((byte) '\n');
556 reqStream.WriteByte ((byte) '-');
557 reqStream.WriteByte ((byte) '-');
558 reqStream.Write (bytes_boundary, 0, bytes_boundary.Length);
559 reqStream.WriteByte ((byte) '-');
560 reqStream.WriteByte ((byte) '-');
561 reqStream.WriteByte ((byte) '\r');
562 reqStream.WriteByte ((byte) '\n');
565 resultBytes = ReadAll (request, userToken);
566 } catch (ThreadInterruptedException){
574 if (reqStream != null)
581 public byte[] UploadValues (string address, NameValueCollection data)
584 throw new ArgumentNullException ("address");
586 return UploadValues (CreateUri (address), data);
589 public byte[] UploadValues (string address, string method, NameValueCollection data)
592 throw new ArgumentNullException ("address");
593 return UploadValues (CreateUri (address), method, data);
596 public byte[] UploadValues (Uri address, NameValueCollection data)
598 return UploadValues (address, (string) null, data);
601 public byte[] UploadValues (Uri address, string method, NameValueCollection data)
604 throw new ArgumentNullException ("address");
606 throw new ArgumentNullException ("data");
611 return UploadValuesCore (address, method, data, null);
612 } catch (WebException) {
614 } catch (Exception ex) {
615 throw new WebException ("An error occurred " +
616 "performing a WebClient request.", ex);
622 byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
624 string cType = Headers ["Content-Type"];
625 if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
626 throw new WebException ("Content-Type header cannot be changed from its default " +
627 "value for this request.");
629 Headers ["Content-Type"] = urlEncodedCType;
630 WebRequest request = SetupRequest (uri, method, true);
632 MemoryStream tmpStream = new MemoryStream ();
633 foreach (string key in data) {
634 byte [] bytes = Encoding.UTF8.GetBytes (key);
635 UrlEncodeAndWrite (tmpStream, bytes);
636 tmpStream.WriteByte ((byte) '=');
637 bytes = Encoding.UTF8.GetBytes (data [key]);
638 UrlEncodeAndWrite (tmpStream, bytes);
639 tmpStream.WriteByte ((byte) '&');
642 int length = (int) tmpStream.Length;
644 tmpStream.SetLength (--length); // remove trailing '&'
646 byte [] buf = tmpStream.GetBuffer ();
647 request.ContentLength = length;
648 using (Stream rqStream = request.GetRequestStream ()) {
649 rqStream.Write (buf, 0, length);
653 return ReadAll (request, userToken);
654 } catch (ThreadInterruptedException) {
660 public string DownloadString (string address)
663 throw new ArgumentNullException ("address");
665 return encoding.GetString (DownloadData (CreateUri (address)));
668 public string DownloadString (Uri address)
671 throw new ArgumentNullException ("address");
673 return encoding.GetString (DownloadData (CreateUri (address)));
676 public string UploadString (string address, string data)
679 throw new ArgumentNullException ("address");
681 throw new ArgumentNullException ("data");
683 byte [] resp = UploadData (address, encoding.GetBytes (data));
684 return encoding.GetString (resp);
687 public string UploadString (string address, string method, string data)
690 throw new ArgumentNullException ("address");
692 throw new ArgumentNullException ("data");
694 byte [] resp = UploadData (address, method, encoding.GetBytes (data));
695 return encoding.GetString (resp);
698 public string UploadString (Uri address, string data)
701 throw new ArgumentNullException ("address");
703 throw new ArgumentNullException ("data");
705 byte [] resp = UploadData (address, encoding.GetBytes (data));
706 return encoding.GetString (resp);
709 public string UploadString (Uri address, string method, string data)
712 throw new ArgumentNullException ("address");
714 throw new ArgumentNullException ("data");
716 byte [] resp = UploadData (address, method, encoding.GetBytes (data));
717 return encoding.GetString (resp);
720 public event DownloadDataCompletedEventHandler DownloadDataCompleted;
721 public event AsyncCompletedEventHandler DownloadFileCompleted;
722 public event DownloadProgressChangedEventHandler DownloadProgressChanged;
723 public event DownloadStringCompletedEventHandler DownloadStringCompleted;
724 public event OpenReadCompletedEventHandler OpenReadCompleted;
725 public event OpenWriteCompletedEventHandler OpenWriteCompleted;
726 public event UploadDataCompletedEventHandler UploadDataCompleted;
727 public event UploadFileCompletedEventHandler UploadFileCompleted;
728 public event UploadProgressChangedEventHandler UploadProgressChanged;
729 public event UploadStringCompletedEventHandler UploadStringCompleted;
730 public event UploadValuesCompletedEventHandler UploadValuesCompleted;
732 Uri CreateUri (string address)
736 if (baseAddress == null)
737 uri = new Uri (address);
739 uri = new Uri (baseAddress, address);
740 return CreateUri (uri);
743 return new Uri (Path.GetFullPath (address));
746 Uri CreateUri (Uri address)
748 Uri result = address;
749 if (baseAddress != null && !result.IsAbsoluteUri) {
751 result = new Uri (baseAddress, result.OriginalString);
753 return result; // Not much we can do here.
757 string query = result.Query;
758 if (String.IsNullOrEmpty (query))
759 query = GetQueryString (true);
760 UriBuilder builder = new UriBuilder (address);
761 if (!String.IsNullOrEmpty (query))
762 builder.Query = query.Substring (1);
766 string GetQueryString (bool add_qmark)
768 if (queryString == null || queryString.Count == 0)
771 StringBuilder sb = new StringBuilder ();
775 foreach (string key in queryString)
776 sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
779 sb.Length--; // removes last '&' or the '?' if empty.
784 return sb.ToString ();
787 WebRequest SetupRequest (Uri uri)
789 WebRequest request = GetWebRequest (uri);
791 request.Proxy = Proxy;
792 request.Credentials = credentials;
794 // Special headers. These are properties of HttpWebRequest.
795 // What do we do with other requests differnt from HttpWebRequest?
796 if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
797 HttpWebRequest req = (HttpWebRequest) request;
798 string expect = headers ["Expect"];
799 string contentType = headers ["Content-Type"];
800 string accept = headers ["Accept"];
801 string connection = headers ["Connection"];
802 string userAgent = headers ["User-Agent"];
803 string referer = headers ["Referer"];
804 headers.RemoveInternal ("Expect");
805 headers.RemoveInternal ("Content-Type");
806 headers.RemoveInternal ("Accept");
807 headers.RemoveInternal ("Connection");
808 headers.RemoveInternal ("Referer");
809 headers.RemoveInternal ("User-Agent");
810 request.Headers = headers;
812 if (expect != null && expect.Length > 0)
815 if (accept != null && accept.Length > 0)
818 if (contentType != null && contentType.Length > 0)
819 req.ContentType = contentType;
821 if (connection != null && connection.Length > 0)
822 req.Connection = connection;
824 if (userAgent != null && userAgent.Length > 0)
825 req.UserAgent = userAgent;
827 if (referer != null && referer.Length > 0)
828 req.Referer = referer;
831 responseHeaders = null;
835 WebRequest SetupRequest (Uri uri, string method, bool is_upload)
837 WebRequest request = SetupRequest (uri);
838 request.Method = DetermineMethod (uri, method, is_upload);
842 byte [] ReadAll (WebRequest request, object userToken)
844 WebResponse response = GetWebResponse (request);
845 Stream stream = response.GetResponseStream ();
846 int length = (int) response.ContentLength;
847 HttpWebRequest wreq = request as HttpWebRequest;
849 if (length > -1 && wreq != null && (int) wreq.AutomaticDecompression != 0) {
850 string content_encoding = ((HttpWebResponse) response).ContentEncoding;
851 if (((content_encoding == "gzip" && (wreq.AutomaticDecompression & DecompressionMethods.GZip) != 0)) ||
852 ((content_encoding == "deflate" && (wreq.AutomaticDecompression & DecompressionMethods.Deflate) != 0)))
856 MemoryStream ms = null;
857 bool nolength = (length == -1);
858 int size = ((nolength) ? 8192 : length);
860 ms = new MemoryStream ();
865 byte [] buffer = new byte [size];
866 while ((nread = stream.Read (buffer, offset, size)) != 0) {
868 ms.Write (buffer, 0, nread);
875 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (nread, length, userToken));
880 return ms.ToArray ();
885 string UrlEncode (string str)
887 StringBuilder result = new StringBuilder ();
889 int len = str.Length;
890 for (int i = 0; i < len; i++) {
894 else if ((c < '0' && c != '-' && c != '.') ||
895 (c < 'A' && c > '9') ||
896 (c > 'Z' && c < 'a' && c != '_') ||
899 int idx = ((int) c) >> 4;
900 result.Append ((char) hexBytes [idx]);
901 idx = ((int) c) & 0x0F;
902 result.Append ((char) hexBytes [idx]);
908 return result.ToString ();
911 static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
916 int len = bytes.Length;
920 for (int i = 0; i < len; i++) {
921 char c = (char) bytes [i];
923 stream.WriteByte ((byte) '+');
924 else if ((c < '0' && c != '-' && c != '.') ||
925 (c < 'A' && c > '9') ||
926 (c > 'Z' && c < 'a' && c != '_') ||
928 stream.WriteByte ((byte) '%');
929 int idx = ((int) c) >> 4;
930 stream.WriteByte (hexBytes [idx]);
931 idx = ((int) c) & 0x0F;
932 stream.WriteByte (hexBytes [idx]);
934 stream.WriteByte ((byte) c);
939 public void CancelAsync ()
942 if (async_thread == null)
946 // We first flag things as done, in case the Interrupt hangs
947 // or the thread decides to hang in some other way inside the
948 // event handlers, or if we are stuck somewhere else. This
949 // ensures that the WebClient object is reusable immediately
951 Thread t = async_thread;
957 void CompleteAsync ()
967 public void DownloadDataAsync (Uri address)
969 DownloadDataAsync (address, null);
972 public void DownloadDataAsync (Uri address, object userToken)
975 throw new ArgumentNullException ("address");
981 async_thread = new Thread (delegate (object state) {
982 object [] args = (object []) state;
984 byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
985 OnDownloadDataCompleted (
986 new DownloadDataCompletedEventArgs (data, null, false, args [1]));
987 } catch (ThreadInterruptedException){
988 OnDownloadDataCompleted (
989 new DownloadDataCompletedEventArgs (null, null, true, args [1]));
991 } catch (Exception e){
992 OnDownloadDataCompleted (
993 new DownloadDataCompletedEventArgs (null, e, false, args [1]));
996 object [] cb_args = new object [] {address, userToken};
997 async_thread.Start (cb_args);
1001 // DownloadFileAsync
1003 public void DownloadFileAsync (Uri address, string fileName)
1005 DownloadFileAsync (address, fileName, null);
1008 public void DownloadFileAsync (Uri address, string fileName, object userToken)
1010 if (address == null)
1011 throw new ArgumentNullException ("address");
1012 if (fileName == null)
1013 throw new ArgumentNullException ("fileName");
1019 async_thread = new Thread (delegate (object state) {
1020 object [] args = (object []) state;
1022 DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
1023 OnDownloadFileCompleted (
1024 new AsyncCompletedEventArgs (null, false, args [2]));
1025 } catch (ThreadInterruptedException){
1026 OnDownloadFileCompleted (
1027 new AsyncCompletedEventArgs (null, true, args [2]));
1028 } catch (Exception e){
1029 OnDownloadFileCompleted (
1030 new AsyncCompletedEventArgs (e, false, args [2]));
1032 object [] cb_args = new object [] {address, fileName, userToken};
1033 async_thread.Start (cb_args);
1037 // DownloadStringAsync
1039 public void DownloadStringAsync (Uri address)
1041 DownloadStringAsync (address, null);
1044 public void DownloadStringAsync (Uri address, object userToken)
1046 if (address == null)
1047 throw new ArgumentNullException ("address");
1053 async_thread = new Thread (delegate (object state) {
1054 object [] args = (object []) state;
1056 string data = encoding.GetString (DownloadDataCore ((Uri) args [0], args [1]));
1057 OnDownloadStringCompleted (
1058 new DownloadStringCompletedEventArgs (data, null, false, args [1]));
1059 } catch (ThreadInterruptedException){
1060 OnDownloadStringCompleted (
1061 new DownloadStringCompletedEventArgs (null, null, true, args [1]));
1062 } catch (Exception e){
1063 OnDownloadStringCompleted (
1064 new DownloadStringCompletedEventArgs (null, e, false, args [1]));
1066 object [] cb_args = new object [] {address, userToken};
1067 async_thread.Start (cb_args);
1073 public void OpenReadAsync (Uri address)
1075 OpenReadAsync (address, null);
1078 public void OpenReadAsync (Uri address, object userToken)
1080 if (address == null)
1081 throw new ArgumentNullException ("address");
1087 async_thread = new Thread (delegate (object state) {
1088 object [] args = (object []) state;
1089 WebRequest request = null;
1091 request = SetupRequest ((Uri) args [0]);
1092 WebResponse response = GetWebResponse (request);
1093 Stream stream = response.GetResponseStream ();
1094 OnOpenReadCompleted (
1095 new OpenReadCompletedEventArgs (stream, null, false, args [1]));
1096 } catch (ThreadInterruptedException){
1097 if (request != null)
1100 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, args [1]));
1101 } catch (Exception e){
1102 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, e, false, args [1]));
1104 object [] cb_args = new object [] {address, userToken};
1105 async_thread.Start (cb_args);
1111 public void OpenWriteAsync (Uri address)
1113 OpenWriteAsync (address, null);
1116 public void OpenWriteAsync (Uri address, string method)
1118 OpenWriteAsync (address, method, null);
1121 public void OpenWriteAsync (Uri address, string method, object userToken)
1123 if (address == null)
1124 throw new ArgumentNullException ("address");
1130 async_thread = new Thread (delegate (object state) {
1131 object [] args = (object []) state;
1132 WebRequest request = null;
1134 request = SetupRequest ((Uri) args [0], (string) args [1], true);
1135 Stream stream = request.GetRequestStream ();
1136 OnOpenWriteCompleted (
1137 new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
1138 } catch (ThreadInterruptedException){
1139 if (request != null)
1141 OnOpenWriteCompleted (
1142 new OpenWriteCompletedEventArgs (null, null, true, args [2]));
1143 } catch (Exception e){
1144 OnOpenWriteCompleted (
1145 new OpenWriteCompletedEventArgs (null, e, false, args [2]));
1147 object [] cb_args = new object [] {address, method, userToken};
1148 async_thread.Start (cb_args);
1154 public void UploadDataAsync (Uri address, byte [] data)
1156 UploadDataAsync (address, null, data);
1159 public void UploadDataAsync (Uri address, string method, byte [] data)
1161 UploadDataAsync (address, method, data, null);
1164 public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
1166 if (address == null)
1167 throw new ArgumentNullException ("address");
1169 throw new ArgumentNullException ("data");
1175 async_thread = new Thread (delegate (object state) {
1176 object [] args = (object []) state;
1180 data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
1182 OnUploadDataCompleted (
1183 new UploadDataCompletedEventArgs (data2, null, false, args [3]));
1184 } catch (ThreadInterruptedException){
1185 OnUploadDataCompleted (
1186 new UploadDataCompletedEventArgs (null, null, true, args [3]));
1187 } catch (Exception e){
1188 OnUploadDataCompleted (
1189 new UploadDataCompletedEventArgs (null, e, false, args [3]));
1191 object [] cb_args = new object [] {address, method, data, userToken};
1192 async_thread.Start (cb_args);
1198 public void UploadFileAsync (Uri address, string fileName)
1200 UploadFileAsync (address, null, fileName);
1203 public void UploadFileAsync (Uri address, string method, string fileName)
1205 UploadFileAsync (address, method, fileName, null);
1208 public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
1210 if (address == null)
1211 throw new ArgumentNullException ("address");
1212 if (fileName == null)
1213 throw new ArgumentNullException ("fileName");
1219 async_thread = new Thread (delegate (object state) {
1220 object [] args = (object []) state;
1224 data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
1225 OnUploadFileCompleted (
1226 new UploadFileCompletedEventArgs (data, null, false, args [3]));
1227 } catch (ThreadInterruptedException){
1228 OnUploadFileCompleted (
1229 new UploadFileCompletedEventArgs (null, null, true, args [3]));
1230 } catch (Exception e){
1231 OnUploadFileCompleted (
1232 new UploadFileCompletedEventArgs (null, e, false, args [3]));
1234 object [] cb_args = new object [] {address, method, fileName, userToken};
1235 async_thread.Start (cb_args);
1239 // UploadStringAsync
1241 public void UploadStringAsync (Uri address, string data)
1243 UploadStringAsync (address, null, data);
1246 public void UploadStringAsync (Uri address, string method, string data)
1248 UploadStringAsync (address, method, data, null);
1251 public void UploadStringAsync (Uri address, string method, string data, object userToken)
1253 if (address == null)
1254 throw new ArgumentNullException ("address");
1256 throw new ArgumentNullException ("data");
1262 async_thread = new Thread (delegate (object state) {
1263 object [] args = (object []) state;
1266 string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
1267 OnUploadStringCompleted (
1268 new UploadStringCompletedEventArgs (data2, null, false, args [3]));
1269 } catch (ThreadInterruptedException){
1270 OnUploadStringCompleted (
1271 new UploadStringCompletedEventArgs (null, null, true, args [3]));
1272 } catch (Exception e){
1273 OnUploadStringCompleted (
1274 new UploadStringCompletedEventArgs (null, e, false, args [3]));
1276 object [] cb_args = new object [] {address, method, data, userToken};
1277 async_thread.Start (cb_args);
1281 // UploadValuesAsync
1283 public void UploadValuesAsync (Uri address, NameValueCollection values)
1285 UploadValuesAsync (address, null, values);
1288 public void UploadValuesAsync (Uri address, string method, NameValueCollection values)
1290 UploadValuesAsync (address, method, values, null);
1293 public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken)
1295 if (address == null)
1296 throw new ArgumentNullException ("address");
1298 throw new ArgumentNullException ("values");
1304 async_thread = new Thread (delegate (object state) {
1305 object [] args = (object []) state;
1307 byte [] data = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
1308 OnUploadValuesCompleted (
1309 new UploadValuesCompletedEventArgs (data, null, false, args [3]));
1310 } catch (ThreadInterruptedException){
1311 OnUploadValuesCompleted (
1312 new UploadValuesCompletedEventArgs (null, null, true, args [3]));
1313 } catch (Exception e){
1314 OnUploadValuesCompleted (
1315 new UploadValuesCompletedEventArgs (null, e, false, args [3]));
1317 object [] cb_args = new object [] {address, method, values, userToken};
1318 async_thread.Start (cb_args);
1322 protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
1325 if (DownloadDataCompleted != null)
1326 DownloadDataCompleted (this, args);
1329 protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
1332 if (DownloadFileCompleted != null)
1333 DownloadFileCompleted (this, args);
1336 protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
1338 if (DownloadProgressChanged != null)
1339 DownloadProgressChanged (this, e);
1342 protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
1345 if (DownloadStringCompleted != null)
1346 DownloadStringCompleted (this, args);
1349 protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
1352 if (OpenReadCompleted != null)
1353 OpenReadCompleted (this, args);
1356 protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
1359 if (OpenWriteCompleted != null)
1360 OpenWriteCompleted (this, args);
1363 protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
1366 if (UploadDataCompleted != null)
1367 UploadDataCompleted (this, args);
1370 protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
1373 if (UploadFileCompleted != null)
1374 UploadFileCompleted (this, args);
1377 protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
1379 if (UploadProgressChanged != null)
1380 UploadProgressChanged (this, e);
1383 protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
1386 if (UploadStringCompleted != null)
1387 UploadStringCompleted (this, args);
1390 protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
1393 if (UploadValuesCompleted != null)
1394 UploadValuesCompleted (this, args);
1397 protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
1399 WebResponse response = request.EndGetResponse (result);
1400 responseHeaders = response.Headers;
1404 protected virtual WebRequest GetWebRequest (Uri address)
1406 return WebRequest.Create (address);
1409 protected virtual WebResponse GetWebResponse (WebRequest request)
1411 WebResponse response = request.GetResponse ();
1412 responseHeaders = response.Headers;