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 // Stephane Delcroix (sdelcroix@novell.com)
11 // Copyright 2003 Ximian, Inc. (http://www.ximian.com)
12 // Copyright 2006, 2008 Novell, Inc. (http://www.novell.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.Security;
64 using System.Collections.Specialized;
65 using System.ComponentModel;
67 using System.Runtime.InteropServices;
68 using System.Runtime.Serialization;
70 using System.Threading;
71 using System.Net.Cache;
76 public class WebClient
78 private delegate void ProgressChangedDelegate (long read, long length, object state);
80 // static readonly string urlEncodedCType = "application/x-www-form-urlencoded";
81 // static byte [] hexBytes;
82 // ICredentials credentials;
83 // WebHeaderCollection headers;
84 // WebHeaderCollection responseHeaders;
87 // NameValueCollection queryString;
90 Encoding encoding = Encoding.UTF8;
94 // static WebClient ()
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;
105 // public WebClient ()
111 public string BaseAddress {
113 if (baseString == null) {
114 if (baseAddress == null)
118 baseString = baseAddress.ToString ();
123 if (value == null || value == "") {
126 baseAddress = new Uri (value);
132 // static Exception GetMustImplement ()
134 // return new NotImplementedException ();
138 // public RequestCachePolicy CachePolicy
141 // throw GetMustImplement ();
144 // throw GetMustImplement ();
149 // public bool UseDefaultCredentials
152 // throw GetMustImplement ();
155 // throw GetMustImplement ();
160 // public ICredentials Credentials {
161 // get { return credentials; }
162 // set { credentials = value; }
165 // public WebHeaderCollection Headers {
167 // if (headers == null)
168 // headers = new WebHeaderCollection ();
172 // set { headers = value; }
175 // public NameValueCollection QueryString {
177 // if (queryString == null)
178 // queryString = new NameValueCollection ();
180 // return queryString;
182 // set { queryString = value; }
185 // public WebHeaderCollection ResponseHeaders {
186 // get { return responseHeaders; }
190 // public Encoding Encoding {
191 // get { return encoding; }
193 // if (value == null)
194 // throw new ArgumentNullException ("value");
199 // public IWebProxy Proxy {
200 // get { return proxy; }
201 // set { proxy = value; }
206 get { return is_busy; }
214 throw new NotSupportedException ("WebClient does not support conccurent I/O operations.");
227 // public byte [] DownloadData (string address)
230 // if (address == null)
231 // throw new ArgumentNullException ("address");
234 // return DownloadData (CreateUri (address));
240 // byte [] DownloadData (Uri address)
243 // if (address == null)
244 // throw new ArgumentNullException ("address");
250 // return DownloadDataCore (address, null);
256 byte [] DownloadDataCore (Uri address, object userToken)
258 WebRequest request = null;
261 request = SetupRequest (address, "GET");
262 //WebResponse response = request.GetResponse ();
263 IAsyncResult asyncresult = request.BeginGetResponse (null, userToken);
264 asyncresult.AsyncWaitHandle.WaitOne ();
265 WebResponse response = request.EndGetResponse (asyncresult);
266 Stream st = ProcessResponse (response);
267 return ReadAll (st, (int) st.Length, userToken);
268 } catch (ThreadInterruptedException){
272 } catch (Exception ex) {
273 throw new WebException ("An error occurred " +
274 "performing a WebClient request.", ex);
280 // public void DownloadFile (string address, string fileName)
283 // if (address == null)
284 // throw new ArgumentNullException ("address");
287 // DownloadFile (CreateUri (address), fileName);
293 // void DownloadFile (Uri address, string fileName)
296 // if (address == null)
297 // throw new ArgumentNullException ("address");
298 // if (fileName == null)
299 // throw new ArgumentNullException ("fileName");
305 // DownloadFileCore (address, fileName, null);
306 // } catch (Exception ex) {
307 // throw new WebException ("An error occurred " +
308 // "performing a WebClient request.", ex);
314 // void DownloadFileCore (Uri address, string fileName, object userToken)
316 // WebRequest request = null;
318 // using (FileStream f = new FileStream (fileName, FileMode.Create)) {
320 // request = SetupRequest (address);
321 // WebResponse response = request.GetResponse ();
322 // Stream st = ProcessResponse (response);
324 // int cLength = (int) response.ContentLength;
325 // int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
326 // byte [] buffer = new byte [length];
330 // long notify_total = 0;
332 // while ((nread = st.Read (buffer, 0, length)) != 0){
335 // notify_total += nread;
336 // OnDownloadProgressChanged (
337 // new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken));
341 // f.Write (buffer, 0, nread);
343 // } catch (ThreadInterruptedException){
344 // if (request != null)
353 // public Stream OpenRead (string address)
356 // if (address == null)
357 // throw new ArgumentNullException ("address");
360 // return OpenRead (CreateUri (address));
366 // Stream OpenRead (Uri address)
369 // if (address == null)
370 // throw new ArgumentNullException ("address");
373 // WebRequest request = null;
377 // request = SetupRequest (address);
378 // WebResponse response = request.GetResponse ();
379 // return ProcessResponse (response);
380 // } catch (Exception ex) {
381 // throw new WebException ("An error occurred " +
382 // "performing a WebClient request.", ex);
390 // public Stream OpenWrite (string address)
393 // if (address == null)
394 // throw new ArgumentNullException ("address");
397 // return OpenWrite (CreateUri (address));
400 // public Stream OpenWrite (string address, string method)
403 // if (address == null)
404 // throw new ArgumentNullException ("address");
407 // return OpenWrite (CreateUri (address), method);
413 // Stream OpenWrite (Uri address)
415 // return OpenWrite (address, (string) null);
421 // Stream OpenWrite (Uri address, string method)
424 // if (address == null)
425 // throw new ArgumentNullException ("address");
431 // WebRequest request = SetupRequest (address, method);
432 // return request.GetRequestStream ();
433 // } catch (Exception ex) {
434 // throw new WebException ("An error occurred " +
435 // "performing a WebClient request.", ex);
441 private string DetermineMethod (Uri address, string method)
446 if (address.Scheme == Uri.UriSchemeFtp)
453 // public byte [] UploadData (string address, byte [] data)
456 // if (address == null)
457 // throw new ArgumentNullException ("address");
460 // return UploadData (CreateUri (address), data);
463 // public byte [] UploadData (string address, string method, byte [] data)
466 // if (address == null)
467 // throw new ArgumentNullException ("address");
470 // return UploadData (CreateUri (address), method, data);
476 // byte [] UploadData (Uri address, byte [] data)
478 // return UploadData (address, (string) null, data);
484 // byte [] UploadData (Uri address, string method, byte [] data)
487 // if (address == null)
488 // throw new ArgumentNullException ("address");
490 // throw new ArgumentNullException ("data");
496 // return UploadDataCore (address, method, data, null);
497 // } catch (Exception ex) {
498 // throw new WebException ("An error occurred " +
499 // "performing a WebClient request.", ex);
505 // byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
508 // if (address == null)
509 // throw new ArgumentNullException ("address");
511 // throw new ArgumentNullException ("data");
514 // WebRequest request = SetupRequest (address, method);
516 // int contentLength = data.Length;
517 // request.ContentLength = contentLength;
518 // using (Stream stream = request.GetRequestStream ()) {
519 // stream.Write (data, 0, contentLength);
522 // WebResponse response = request.GetResponse ();
523 // Stream st = ProcessResponse (response);
524 // return ReadAll (st, (int) response.ContentLength, userToken);
525 // } catch (ThreadInterruptedException){
526 // if (request != null)
534 // public byte [] UploadFile (string address, string fileName)
537 // if (address == null)
538 // throw new ArgumentNullException ("address");
541 // return UploadFile (CreateUri (address), fileName);
547 // byte [] UploadFile (Uri address, string fileName)
549 // return UploadFile (address, (string) null, fileName);
552 // public byte [] UploadFile (string address, string method, string fileName)
554 // return UploadFile (CreateUri (address), method, fileName);
560 // byte [] UploadFile (Uri address, string method, string fileName)
563 // if (address == null)
564 // throw new ArgumentNullException ("address");
565 // if (fileName == null)
566 // throw new ArgumentNullException ("fileName");
572 // return UploadFileCore (address, method, fileName, null);
573 // } catch (Exception ex) {
574 // throw new WebException ("An error occurred " +
575 // "performing a WebClient request.", ex);
581 // byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
584 // if (address == null)
585 // throw new ArgumentNullException ("address");
588 // string fileCType = Headers ["Content-Type"];
589 // if (fileCType != null) {
590 // string lower = fileCType.ToLower ();
591 // if (lower.StartsWith ("multipart/"))
592 // throw new WebException ("Content-Type cannot be set to a multipart" +
593 // " type for this request.");
595 // fileCType = "application/octet-stream";
598 // string boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
599 // Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
600 // Stream reqStream = null;
601 // Stream fStream = null;
602 // byte [] resultBytes = null;
604 // fileName = Path.GetFullPath (fileName);
606 // WebRequest request = null;
608 // fStream = File.OpenRead (fileName);
609 // request = SetupRequest (address, method);
610 // reqStream = request.GetRequestStream ();
611 // byte [] realBoundary = Encoding.ASCII.GetBytes ("--" + boundary + "\r\n");
612 // reqStream.Write (realBoundary, 0, realBoundary.Length);
613 // string partHeaders = String.Format ("Content-Disposition: form-data; " +
614 // "name=\"file\"; filename=\"{0}\"\r\n" +
615 // "Content-Type: {1}\r\n\r\n",
616 // Path.GetFileName (fileName), fileCType);
618 // byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
619 // reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
621 // byte [] buffer = new byte [4096];
622 // while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
623 // reqStream.Write (buffer, 0, nread);
625 // reqStream.WriteByte ((byte) '\r');
626 // reqStream.WriteByte ((byte) '\n');
627 // reqStream.Write (realBoundary, 0, realBoundary.Length);
628 // reqStream.Close ();
630 // WebResponse response = request.GetResponse ();
631 // Stream st = ProcessResponse (response);
632 // resultBytes = ReadAll (st, (int) response.ContentLength, userToken);
633 // } catch (ThreadInterruptedException){
634 // if (request != null)
638 // if (fStream != null)
641 // if (reqStream != null)
642 // reqStream.Close ();
645 // return resultBytes;
648 // public byte[] UploadValues (string address, NameValueCollection data)
651 // if (address == null)
652 // throw new ArgumentNullException ("address");
655 // return UploadValues (CreateUri (address), data);
658 // public byte[] UploadValues (string address, string method, NameValueCollection data)
661 // if (address == null)
662 // throw new ArgumentNullException ("address");
665 // return UploadValues (CreateUri (address), method, data);
671 // byte[] UploadValues (Uri address, NameValueCollection data)
673 // return UploadValues (address, (string) null, data);
679 // byte[] UploadValues (Uri address, string method, NameValueCollection data)
682 // if (address == null)
683 // throw new ArgumentNullException ("address");
685 // throw new ArgumentNullException ("data");
691 // return UploadValuesCore (address, method, data, null);
692 // } catch (Exception ex) {
693 // throw new WebException ("An error occurred " +
694 // "performing a WebClient request.", ex);
700 // byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
704 // throw new ArgumentNullException ("data");
707 // string cType = Headers ["Content-Type"];
708 // if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
709 // throw new WebException ("Content-Type header cannot be changed from its default " +
710 // "value for this request.");
712 // Headers ["Content-Type"] = urlEncodedCType;
713 // WebRequest request = SetupRequest (uri, method);
715 // Stream rqStream = request.GetRequestStream ();
716 // MemoryStream tmpStream = new MemoryStream ();
717 // foreach (string key in data) {
718 // byte [] bytes = Encoding.ASCII.GetBytes (key);
719 // UrlEncodeAndWrite (tmpStream, bytes);
720 // tmpStream.WriteByte ((byte) '=');
721 // bytes = Encoding.ASCII.GetBytes (data [key]);
722 // UrlEncodeAndWrite (tmpStream, bytes);
723 // tmpStream.WriteByte ((byte) '&');
726 // int length = (int) tmpStream.Length;
728 // tmpStream.SetLength (--length); // remove trailing '&'
730 // byte [] buf = tmpStream.GetBuffer ();
731 // rqStream.Write (buf, 0, length);
732 // rqStream.Close ();
733 // tmpStream.Close ();
735 // WebResponse response = request.GetResponse ();
736 // Stream st = ProcessResponse (response);
737 // return ReadAll (st, (int) response.ContentLength, userToken);
738 // } catch (ThreadInterruptedException) {
745 // public string DownloadString (string address)
747 // return encoding.GetString (DownloadData (address));
750 // public string DownloadString (Uri address)
752 // return encoding.GetString (DownloadData (address));
755 // public string UploadString (string address, string data)
757 // if (address == null)
758 // throw new ArgumentNullException ("address");
760 // throw new ArgumentNullException ("data");
762 // byte [] resp = UploadData (address, encoding.GetBytes (data));
763 // return encoding.GetString (resp);
766 // public string UploadString (string address, string method, string data)
768 // if (address == null)
769 // throw new ArgumentNullException ("address");
771 // throw new ArgumentNullException ("data");
773 // byte [] resp = UploadData (address, method, encoding.GetBytes (data));
774 // return encoding.GetString (resp);
777 // public string UploadString (Uri address, string data)
779 // if (address == null)
780 // throw new ArgumentNullException ("address");
782 // throw new ArgumentNullException ("data");
784 // byte [] resp = UploadData (address, encoding.GetBytes (data));
785 // return encoding.GetString (resp);
788 // public string UploadString (Uri address, string method, string data)
790 // if (address == null)
791 // throw new ArgumentNullException ("address");
793 // throw new ArgumentNullException ("data");
795 // byte [] resp = UploadData (address, method, encoding.GetBytes (data));
796 // return encoding.GetString (resp);
799 // public event DownloadDataCompletedEventHandler DownloadDataCompleted;
800 // public event AsyncCompletedEventHandler DownloadFileCompleted;
801 public event DownloadProgressChangedEventHandler DownloadProgressChanged;
802 public event DownloadStringCompletedEventHandler DownloadStringCompleted;
803 public event OpenReadCompletedEventHandler OpenReadCompleted;
804 // public event OpenWriteCompletedEventHandler OpenWriteCompleted;
805 // public event UploadDataCompletedEventHandler UploadDataCompleted;
806 // public event UploadFileCompletedEventHandler UploadFileCompleted;
807 // public event UploadProgressChangedEventHandler UploadProgressChanged;
808 // public event UploadStringCompletedEventHandler UploadStringCompleted;
809 // public event UploadValuesCompletedEventHandler UploadValuesCompleted;
812 // Uri CreateUri (string address)
816 // return MakeUri (address);
817 // } catch (Exception ex) {
818 // throw new WebException ("An error occurred " +
819 // "performing a WebClient request.", ex);
822 // return MakeUri (address);
826 // Uri MakeUri (string path)
828 // string query = null;
829 // if (queryString != null && queryString.Count != 0) {
830 // // This is not the same as UploadValues, because these 'keys' are not
831 // // urlencoded here.
832 // StringBuilder sb = new StringBuilder ();
834 // foreach (string key in queryString)
835 // sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
837 // if (sb.Length != 0) {
838 // sb.Length--; // remove trailing '&'
839 // query = sb.ToString ();
843 // if (baseAddress == null && query == null) {
845 // return new Uri (path);
847 // } catch (ArgumentNullException) {
848 // path = Path.GetFullPath (path);
849 // return new Uri ("file://" + path);
851 // } catch (UriFormatException) {
852 // path = Path.GetFullPath (path);
853 // return new Uri ("file://" + path);
857 // if (baseAddress == null)
858 // return new Uri (path + query, (query != null));
860 // if (query == null)
861 // return new Uri (baseAddress, path);
863 // return new Uri (baseAddress, path + query, (query != null));
866 WebRequest SetupRequest (Uri uri)
868 WebRequest request = WebRequest.Create (baseAddress != null ? new Uri (baseAddress, uri) : uri);
869 // if (Proxy != null)
870 // request.Proxy = Proxy;
871 // request.Credentials = credentials;
873 // Special headers. These are properties of HttpWebRequest.
874 // What do we do with other requests differnt from HttpWebRequest?
875 // if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
876 // HttpWebRequest req = (HttpWebRequest) request;
877 // string expect = headers ["Expect"];
878 // string contentType = headers ["Content-Type"];
879 // string accept = headers ["Accept"];
880 // string connection = headers ["Connection"];
881 // string userAgent = headers ["User-Agent"];
882 // string referer = headers ["Referer"];
883 // headers.RemoveInternal ("Expect");
884 // headers.RemoveInternal ("Content-Type");
885 // headers.RemoveInternal ("Accept");
886 // headers.RemoveInternal ("Connection");
887 // headers.RemoveInternal ("Referer");
888 // headers.RemoveInternal ("User-Agent");
889 // request.Headers = headers;
891 // if (expect != null && expect.Length > 0)
892 // req.Expect = expect;
894 // if (accept != null && accept.Length > 0)
895 // req.Accept = accept;
897 // if (contentType != null && contentType.Length > 0)
898 // req.ContentType = contentType;
900 // if (connection != null && connection.Length > 0)
901 // req.Connection = connection;
903 // if (userAgent != null && userAgent.Length > 0)
904 // req.UserAgent = userAgent;
906 // if (referer != null && referer.Length > 0)
907 // req.Referer = referer;
910 // responseHeaders = null;
911 request.SetupProgressDelegate ((ProgressChangedDelegate) delegate (long read, long length, object state) {
912 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (read, length, state));
917 WebRequest SetupRequest (Uri uri, string method)
919 WebRequest request = SetupRequest (uri);
920 request.Method = DetermineMethod (uri, method);
924 Stream ProcessResponse (WebResponse response)
926 // responseHeaders = response.Headers;
927 return response.GetResponseStream ();
930 byte [] ReadAll (Stream stream, int length, object userToken)
932 MemoryStream ms = null;
934 bool nolength = (length == -1);
935 int size = ((nolength) ? 8192 : length);
937 ms = new MemoryStream ();
942 byte [] buffer = new byte [size];
943 while ((nread = stream.Read (buffer, offset, size)) != 0) {
945 ms.Write (buffer, 0, nread);
952 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (nread, length, userToken));
957 return ms.ToArray ();
962 // string UrlEncode (string str)
964 // StringBuilder result = new StringBuilder ();
966 // int len = str.Length;
967 // for (int i = 0; i < len; i++) {
970 // result.Append ('+');
971 // else if ((c < '0' && c != '-' && c != '.') ||
972 // (c < 'A' && c > '9') ||
973 // (c > 'Z' && c < 'a' && c != '_') ||
975 // result.Append ('%');
976 // int idx = ((int) c) >> 4;
977 // result.Append ((char) hexBytes [idx]);
978 // idx = ((int) c) & 0x0F;
979 // result.Append ((char) hexBytes [idx]);
981 // result.Append (c);
985 // return result.ToString ();
988 // static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
990 // if (bytes == null)
993 // int len = bytes.Length;
997 // for (int i = 0; i < len; i++) {
998 // char c = (char) bytes [i];
1000 // stream.WriteByte ((byte) '+');
1001 // else if ((c < '0' && c != '-' && c != '.') ||
1002 // (c < 'A' && c > '9') ||
1003 // (c > 'Z' && c < 'a' && c != '_') ||
1005 // stream.WriteByte ((byte) '%');
1006 // int idx = ((int) c) >> 4;
1007 // stream.WriteByte (hexBytes [idx]);
1008 // idx = ((int) c) & 0x0F;
1009 // stream.WriteByte (hexBytes [idx]);
1011 // stream.WriteByte ((byte) c);
1017 [SecuritySafeCritical]
1018 public void CancelAsync ()
1021 if (async_thread == null)
1025 // We first flag things as done, in case the Interrupt hangs
1026 // or the thread decides to hang in some other way inside the
1027 // event handlers, or if we are stuck somewhere else. This
1028 // ensures that the WebClient object is reusable immediately
1030 Thread t = async_thread;
1036 void CompleteAsync ()
1040 async_thread = null;
1044 // // DownloadDataAsync
1046 // public void DownloadDataAsync (Uri address)
1048 // DownloadDataAsync (address, null);
1051 // public void DownloadDataAsync (Uri address, object userToken)
1053 // if (address == null)
1054 // throw new ArgumentNullException ("address");
1060 // async_thread = new Thread (delegate (object state) {
1061 // object [] args = (object []) state;
1063 // byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
1064 // OnDownloadDataCompleted (
1065 // new DownloadDataCompletedEventArgs (data, null, false, args [1]));
1066 // } catch (ThreadInterruptedException){
1067 // OnDownloadDataCompleted (
1068 // new DownloadDataCompletedEventArgs (null, null, true, args [1]));
1070 // } catch (Exception e){
1071 // OnDownloadDataCompleted (
1072 // new DownloadDataCompletedEventArgs (null, e, false, args [1]));
1075 // object [] cb_args = new object [] {address, userToken};
1076 // async_thread.Start (cb_args);
1080 // // DownloadFileAsync
1082 // public void DownloadFileAsync (Uri address, string fileName)
1084 // DownloadFileAsync (address, fileName, null);
1087 // public void DownloadFileAsync (Uri address, string fileName, object userToken)
1089 // if (address == null)
1090 // throw new ArgumentNullException ("address");
1091 // if (fileName == null)
1092 // throw new ArgumentNullException ("fileName");
1098 // async_thread = new Thread (delegate (object state) {
1099 // object [] args = (object []) state;
1101 // DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
1102 // OnDownloadFileCompleted (
1103 // new AsyncCompletedEventArgs (null, false, args [2]));
1104 // } catch (ThreadInterruptedException){
1105 // OnDownloadFileCompleted (
1106 // new AsyncCompletedEventArgs (null, true, args [2]));
1107 // } catch (Exception e){
1108 // OnDownloadFileCompleted (
1109 // new AsyncCompletedEventArgs (e, false, args [2]));
1111 // object [] cb_args = new object [] {address, fileName, userToken};
1112 // async_thread.Start (cb_args);
1116 // // DownloadStringAsync
1118 public void DownloadStringAsync (Uri address)
1120 DownloadStringAsync (address, null);
1123 public void DownloadStringAsync (Uri address, object userToken)
1125 if (address == null)
1126 throw new ArgumentNullException ("address");
1132 async_thread = new Thread (delegate (object state) {
1133 object [] args = (object []) state;
1135 byte [] bdata = DownloadDataCore ((Uri) args [0], args [1]);
1136 string data = encoding.GetString (bdata, 0, bdata.Length);
1137 OnDownloadStringCompleted (
1138 new DownloadStringCompletedEventArgs (data, null, false, args [1]));
1139 } catch (ThreadInterruptedException){
1140 OnDownloadStringCompleted (
1141 new DownloadStringCompletedEventArgs (null, null, true, args [1]));
1142 } catch (Exception e){
1143 OnDownloadStringCompleted (
1144 new DownloadStringCompletedEventArgs (null, e, false, args [1]));
1146 object [] cb_args = new object [] {address, userToken};
1147 async_thread.Start (cb_args);
1153 public void OpenReadAsync (Uri address)
1155 OpenReadAsync (address, null);
1158 public void OpenReadAsync (Uri address, object userToken)
1160 if (address == null)
1161 throw new ArgumentNullException ("address");
1167 async_thread = new Thread (delegate (object state) {
1168 object [] args = (object []) state;
1169 WebRequest request = null;
1171 request = SetupRequest ((Uri) args [0]);
1172 //WebResponse response = request.GetResponse ();
1173 IAsyncResult asyncresult = request.BeginGetResponse (null, userToken);
1174 asyncresult.AsyncWaitHandle.WaitOne ();
1175 WebResponse response = request.EndGetResponse (asyncresult);
1176 Stream stream = ProcessResponse (response);
1177 OnOpenReadCompleted (
1178 new OpenReadCompletedEventArgs (stream, address, null, false, args [1]));
1179 } catch (ThreadInterruptedException){
1180 if (request != null)
1183 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, null, true, args [1]));
1184 } catch (Exception e){
1185 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, e, false, args [1]));
1187 object [] cb_args = new object [] {address, userToken};
1188 async_thread.Start (cb_args);
1192 // // OpenWriteAsync
1194 // public void OpenWriteAsync (Uri address)
1196 // OpenWriteAsync (address, null);
1199 // public void OpenWriteAsync (Uri address, string method)
1201 // OpenWriteAsync (address, method, null);
1204 // public void OpenWriteAsync (Uri address, string method, object userToken)
1206 // if (address == null)
1207 // throw new ArgumentNullException ("address");
1213 // async_thread = new Thread (delegate (object state) {
1214 // object [] args = (object []) state;
1215 // WebRequest request = null;
1217 // request = SetupRequest ((Uri) args [0], (string) args [1]);
1218 // Stream stream = request.GetRequestStream ();
1219 // OnOpenWriteCompleted (
1220 // new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
1221 // } catch (ThreadInterruptedException){
1222 // if (request != null)
1223 // request.Abort ();
1224 // OnOpenWriteCompleted (
1225 // new OpenWriteCompletedEventArgs (null, null, true, args [2]));
1226 // } catch (Exception e){
1227 // OnOpenWriteCompleted (
1228 // new OpenWriteCompletedEventArgs (null, e, false, args [2]));
1230 // object [] cb_args = new object [] {address, method, userToken};
1231 // async_thread.Start (cb_args);
1235 // // UploadDataAsync
1237 // public void UploadDataAsync (Uri address, byte [] data)
1239 // UploadDataAsync (address, null, data);
1242 // public void UploadDataAsync (Uri address, string method, byte [] data)
1244 // UploadDataAsync (address, method, data, null);
1247 // public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
1249 // if (address == null)
1250 // throw new ArgumentNullException ("address");
1251 // if (data == null)
1252 // throw new ArgumentNullException ("data");
1258 // async_thread = new Thread (delegate (object state) {
1259 // object [] args = (object []) state;
1263 // data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
1265 // OnUploadDataCompleted (
1266 // new UploadDataCompletedEventArgs (data2, null, false, args [3]));
1267 // } catch (ThreadInterruptedException){
1268 // OnUploadDataCompleted (
1269 // new UploadDataCompletedEventArgs (null, null, true, args [3]));
1270 // } catch (Exception e){
1271 // OnUploadDataCompleted (
1272 // new UploadDataCompletedEventArgs (null, e, false, args [3]));
1274 // object [] cb_args = new object [] {address, method, data, userToken};
1275 // async_thread.Start (cb_args);
1279 // // UploadFileAsync
1281 // public void UploadFileAsync (Uri address, string fileName)
1283 // UploadFileAsync (address, null, fileName);
1286 // public void UploadFileAsync (Uri address, string method, string fileName)
1288 // UploadFileAsync (address, method, fileName, null);
1291 // public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
1293 // if (address == null)
1294 // throw new ArgumentNullException ("address");
1295 // if (fileName == null)
1296 // throw new ArgumentNullException ("fileName");
1302 // async_thread = new Thread (delegate (object state) {
1303 // object [] args = (object []) state;
1307 // data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
1308 // OnUploadFileCompleted (
1309 // new UploadFileCompletedEventArgs (data, null, false, args [3]));
1310 // } catch (ThreadInterruptedException){
1311 // OnUploadFileCompleted (
1312 // new UploadFileCompletedEventArgs (null, null, true, args [3]));
1313 // } catch (Exception e){
1314 // OnUploadFileCompleted (
1315 // new UploadFileCompletedEventArgs (null, e, false, args [3]));
1317 // object [] cb_args = new object [] {address, method, fileName, userToken};
1318 // async_thread.Start (cb_args);
1322 // // UploadStringAsync
1324 // public void UploadStringAsync (Uri address, string data)
1326 // UploadStringAsync (address, null, data);
1329 // public void UploadStringAsync (Uri address, string method, string data)
1331 // UploadStringAsync (address, method, data, null);
1334 // public void UploadStringAsync (Uri address, string method, string data, object userToken)
1336 // if (address == null)
1337 // throw new ArgumentNullException ("address");
1338 // if (data == null)
1339 // throw new ArgumentNullException ("data");
1345 // async_thread = new Thread (delegate (object state) {
1346 // object [] args = (object []) state;
1349 // string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
1350 // OnUploadStringCompleted (
1351 // new UploadStringCompletedEventArgs (data2, null, false, args [3]));
1352 // } catch (ThreadInterruptedException){
1353 // OnUploadStringCompleted (
1354 // new UploadStringCompletedEventArgs (null, null, true, args [3]));
1355 // } catch (Exception e){
1356 // OnUploadStringCompleted (
1357 // new UploadStringCompletedEventArgs (null, e, false, args [3]));
1359 // object [] cb_args = new object [] {address, method, data, userToken};
1360 // async_thread.Start (cb_args);
1364 // // UploadValuesAsync
1366 // public void UploadValuesAsync (Uri address, NameValueCollection values)
1368 // UploadValuesAsync (address, null, values);
1371 // public void UploadValuesAsync (Uri address, string method, NameValueCollection values)
1373 // UploadValuesAsync (address, method, values, null);
1376 // public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken)
1378 // if (address == null)
1379 // throw new ArgumentNullException ("address");
1380 // if (values == null)
1381 // throw new ArgumentNullException ("values");
1387 // async_thread = new Thread (delegate (object state) {
1388 // object [] args = (object []) state;
1390 // byte [] data = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
1391 // OnUploadValuesCompleted (
1392 // new UploadValuesCompletedEventArgs (data, null, false, args [3]));
1393 // } catch (ThreadInterruptedException){
1394 // OnUploadValuesCompleted (
1395 // new UploadValuesCompletedEventArgs (null, null, true, args [3]));
1396 // } catch (Exception e){
1397 // OnUploadValuesCompleted (
1398 // new UploadValuesCompletedEventArgs (null, e, false, args [3]));
1400 // object [] cb_args = new object [] {address, method, values, userToken};
1401 // async_thread.Start (cb_args);
1405 // protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
1407 // CompleteAsync ();
1408 // if (DownloadDataCompleted != null)
1409 // DownloadDataCompleted (this, args);
1412 // protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
1414 // CompleteAsync ();
1415 // if (DownloadFileCompleted != null)
1416 // DownloadFileCompleted (this, args);
1419 protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
1421 if (DownloadProgressChanged != null) {
1422 DownloadProgressChanged (this, e);
1426 private object callback_args;
1428 protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
1431 if (OpenReadCompleted != null) {
1432 ManualResetEvent wait_event = new ManualResetEvent (false);
1433 GSourceFunc callback = (GSourceFunc) delegate (IntPtr ctx) { OpenReadCompleted (this, (OpenReadCompletedEventArgs) callback_args); wait_event.Set (); return false; };
1434 callback_args = args;
1436 g_idle_add (callback, IntPtr.Zero);
1438 wait_event.WaitOne ();
1439 GC.KeepAlive (callback);
1443 public delegate bool GSourceFunc (IntPtr data);
1445 [DllImport ("moon")]
1446 static extern uint g_idle_add (GSourceFunc callback, IntPtr data);
1448 protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
1451 if (DownloadStringCompleted != null) {
1452 ManualResetEvent wait_event = new ManualResetEvent (false);
1453 GSourceFunc callback = (GSourceFunc) delegate (IntPtr ctx)
1456 DownloadStringCompleted (this, (DownloadStringCompletedEventArgs) callback_args);
1458 } catch (Exception ex) {
1459 Console.WriteLine ("Unhandled exception: {0}", ex);
1461 Console.WriteLine ("Unhandled exception.");
1465 callback_args = args;
1467 g_idle_add (callback, IntPtr.Zero);
1469 wait_event.WaitOne ();
1470 GC.KeepAlive (callback);
1475 // protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
1477 // CompleteAsync ();
1478 // if (OpenWriteCompleted != null)
1479 // OpenWriteCompleted (this, args);
1482 // protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
1484 // CompleteAsync ();
1485 // if (UploadDataCompleted != null)
1486 // UploadDataCompleted (this, args);
1489 // protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
1491 // CompleteAsync ();
1492 // if (UploadFileCompleted != null)
1493 // UploadFileCompleted (this, args);
1496 // protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
1498 // if (UploadProgressChanged != null)
1499 // UploadProgressChanged (this, e);
1502 // protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
1504 // CompleteAsync ();
1505 // if (UploadStringCompleted != null)
1506 // UploadStringCompleted (this, args);
1509 // protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
1511 // CompleteAsync ();
1512 // if (UploadValuesCompleted != null)
1513 // UploadValuesCompleted (this, args);
1516 // [MonoNotSupported("")]
1517 // protected virtual WebRequest GetWebRequest (Uri address)
1519 // throw new NotImplementedException ();
1522 // protected virtual WebResponse GetWebResponse (WebRequest request)
1524 // return request.GetResponse ();
1527 // protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
1529 // return request.EndGetResponse (result);