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;
91 bool allow_read_buffering = true;
95 // static WebClient ()
97 // hexBytes = new byte [16];
99 // for (int i = '0'; i <= '9'; i++, index++)
100 // hexBytes [index] = (byte) i;
102 // for (int i = 'A'; i <= 'F'; i++, index++)
103 // hexBytes [index] = (byte) i;
106 // public WebClient ()
112 public string BaseAddress {
114 if (baseString == null) {
115 if (baseAddress == null)
119 baseString = baseAddress.ToString ();
124 if (value == null || value == "") {
127 baseAddress = new Uri (value);
133 // static Exception GetMustImplement ()
135 // return new NotImplementedException ();
139 // public RequestCachePolicy CachePolicy
142 // throw GetMustImplement ();
145 // throw GetMustImplement ();
150 // public bool UseDefaultCredentials
153 // throw GetMustImplement ();
156 // throw GetMustImplement ();
161 // public ICredentials Credentials {
162 // get { return credentials; }
163 // set { credentials = value; }
166 public WebHeaderCollection Headers {
169 headers = new WebHeaderCollection ();
173 set { headers = value; }
176 // public NameValueCollection QueryString {
178 // if (queryString == null)
179 // queryString = new NameValueCollection ();
181 // return queryString;
183 // set { queryString = value; }
186 // public WebHeaderCollection ResponseHeaders {
187 // get { return responseHeaders; }
191 public Encoding Encoding {
192 get { return encoding; }
195 throw new ArgumentNullException ("value");
200 // public IWebProxy Proxy {
201 // get { return proxy; }
202 // set { proxy = value; }
207 get { return is_busy; }
210 [MonoTODO ("value is unused")]
211 public bool AllowReadStreamBuffering {
212 get { return allow_read_buffering; }
213 set { allow_read_buffering = value; }
221 throw new NotSupportedException ("WebClient does not support conccurent I/O operations.");
234 // public byte [] DownloadData (string address)
237 // if (address == null)
238 // throw new ArgumentNullException ("address");
241 // return DownloadData (CreateUri (address));
247 // byte [] DownloadData (Uri address)
250 // if (address == null)
251 // throw new ArgumentNullException ("address");
257 // return DownloadDataCore (address, null);
263 Stream DownloadDataCore (Uri address, object userToken)
265 WebRequest request = null;
268 request = SetupRequest (address, "GET");
269 //WebResponse response = request.GetResponse ();
270 IAsyncResult asyncresult = request.BeginGetResponse (null, userToken);
271 asyncresult.AsyncWaitHandle.WaitOne ();
272 WebResponse response = request.EndGetResponse (asyncresult);
273 Stream st = ProcessResponse (response);
274 return ReadAll (st, (int) st.Length, userToken);
275 } catch (ThreadInterruptedException){
279 } catch (Exception ex) {
280 throw new WebException ("An error occurred " +
281 "performing a WebClient request.", ex);
287 // public void DownloadFile (string address, string fileName)
290 // if (address == null)
291 // throw new ArgumentNullException ("address");
294 // DownloadFile (CreateUri (address), fileName);
300 // void DownloadFile (Uri address, string fileName)
303 // if (address == null)
304 // throw new ArgumentNullException ("address");
305 // if (fileName == null)
306 // throw new ArgumentNullException ("fileName");
312 // DownloadFileCore (address, fileName, null);
313 // } catch (Exception ex) {
314 // throw new WebException ("An error occurred " +
315 // "performing a WebClient request.", ex);
321 // void DownloadFileCore (Uri address, string fileName, object userToken)
323 // WebRequest request = null;
325 // using (FileStream f = new FileStream (fileName, FileMode.Create)) {
327 // request = SetupRequest (address);
328 // WebResponse response = request.GetResponse ();
329 // Stream st = ProcessResponse (response);
331 // int cLength = (int) response.ContentLength;
332 // int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
333 // byte [] buffer = new byte [length];
337 // long notify_total = 0;
339 // while ((nread = st.Read (buffer, 0, length)) != 0){
342 // notify_total += nread;
343 // OnDownloadProgressChanged (
344 // new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken));
348 // f.Write (buffer, 0, nread);
350 // } catch (ThreadInterruptedException){
351 // if (request != null)
360 // public Stream OpenRead (string address)
363 // if (address == null)
364 // throw new ArgumentNullException ("address");
367 // return OpenRead (CreateUri (address));
373 // Stream OpenRead (Uri address)
376 // if (address == null)
377 // throw new ArgumentNullException ("address");
380 // WebRequest request = null;
384 // request = SetupRequest (address);
385 // WebResponse response = request.GetResponse ();
386 // return ProcessResponse (response);
387 // } catch (Exception ex) {
388 // throw new WebException ("An error occurred " +
389 // "performing a WebClient request.", ex);
397 // public Stream OpenWrite (string address)
400 // if (address == null)
401 // throw new ArgumentNullException ("address");
404 // return OpenWrite (CreateUri (address));
407 // public Stream OpenWrite (string address, string method)
410 // if (address == null)
411 // throw new ArgumentNullException ("address");
414 // return OpenWrite (CreateUri (address), method);
420 // Stream OpenWrite (Uri address)
422 // return OpenWrite (address, (string) null);
428 // Stream OpenWrite (Uri address, string method)
431 // if (address == null)
432 // throw new ArgumentNullException ("address");
438 // WebRequest request = SetupRequest (address, method);
439 // return request.GetRequestStream ();
440 // } catch (Exception ex) {
441 // throw new WebException ("An error occurred " +
442 // "performing a WebClient request.", ex);
448 private string DetermineMethod (Uri address, string method)
453 if (address.Scheme == Uri.UriSchemeFtp)
460 // public byte [] UploadData (string address, byte [] data)
463 // if (address == null)
464 // throw new ArgumentNullException ("address");
467 // return UploadData (CreateUri (address), data);
470 // public byte [] UploadData (string address, string method, byte [] data)
473 // if (address == null)
474 // throw new ArgumentNullException ("address");
477 // return UploadData (CreateUri (address), method, data);
483 // byte [] UploadData (Uri address, byte [] data)
485 // return UploadData (address, (string) null, data);
491 // byte [] UploadData (Uri address, string method, byte [] data)
494 // if (address == null)
495 // throw new ArgumentNullException ("address");
497 // throw new ArgumentNullException ("data");
503 // return UploadDataCore (address, method, data, null);
504 // } catch (Exception ex) {
505 // throw new WebException ("An error occurred " +
506 // "performing a WebClient request.", ex);
512 // byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
515 // if (address == null)
516 // throw new ArgumentNullException ("address");
518 // throw new ArgumentNullException ("data");
521 // WebRequest request = SetupRequest (address, method);
523 // int contentLength = data.Length;
524 // request.ContentLength = contentLength;
525 // using (Stream stream = request.GetRequestStream ()) {
526 // stream.Write (data, 0, contentLength);
529 // WebResponse response = request.GetResponse ();
530 // Stream st = ProcessResponse (response);
531 // return ReadAll (st, (int) response.ContentLength, userToken);
532 // } catch (ThreadInterruptedException){
533 // if (request != null)
541 // public byte [] UploadFile (string address, string fileName)
544 // if (address == null)
545 // throw new ArgumentNullException ("address");
548 // return UploadFile (CreateUri (address), fileName);
554 // byte [] UploadFile (Uri address, string fileName)
556 // return UploadFile (address, (string) null, fileName);
559 // public byte [] UploadFile (string address, string method, string fileName)
561 // return UploadFile (CreateUri (address), method, fileName);
567 // byte [] UploadFile (Uri address, string method, string fileName)
570 // if (address == null)
571 // throw new ArgumentNullException ("address");
572 // if (fileName == null)
573 // throw new ArgumentNullException ("fileName");
579 // return UploadFileCore (address, method, fileName, null);
580 // } catch (Exception ex) {
581 // throw new WebException ("An error occurred " +
582 // "performing a WebClient request.", ex);
588 // byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
591 // if (address == null)
592 // throw new ArgumentNullException ("address");
595 // string fileCType = Headers ["Content-Type"];
596 // if (fileCType != null) {
597 // string lower = fileCType.ToLower ();
598 // if (lower.StartsWith ("multipart/"))
599 // throw new WebException ("Content-Type cannot be set to a multipart" +
600 // " type for this request.");
602 // fileCType = "application/octet-stream";
605 // string boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
606 // Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
607 // Stream reqStream = null;
608 // Stream fStream = null;
609 // byte [] resultBytes = null;
611 // fileName = Path.GetFullPath (fileName);
613 // WebRequest request = null;
615 // fStream = File.OpenRead (fileName);
616 // request = SetupRequest (address, method);
617 // reqStream = request.GetRequestStream ();
618 // byte [] realBoundary = Encoding.ASCII.GetBytes ("--" + boundary + "\r\n");
619 // reqStream.Write (realBoundary, 0, realBoundary.Length);
620 // string partHeaders = String.Format ("Content-Disposition: form-data; " +
621 // "name=\"file\"; filename=\"{0}\"\r\n" +
622 // "Content-Type: {1}\r\n\r\n",
623 // Path.GetFileName (fileName), fileCType);
625 // byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
626 // reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
628 // byte [] buffer = new byte [4096];
629 // while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
630 // reqStream.Write (buffer, 0, nread);
632 // reqStream.WriteByte ((byte) '\r');
633 // reqStream.WriteByte ((byte) '\n');
634 // reqStream.Write (realBoundary, 0, realBoundary.Length);
635 // reqStream.Close ();
637 // WebResponse response = request.GetResponse ();
638 // Stream st = ProcessResponse (response);
639 // resultBytes = ReadAll (st, (int) response.ContentLength, userToken);
640 // } catch (ThreadInterruptedException){
641 // if (request != null)
645 // if (fStream != null)
648 // if (reqStream != null)
649 // reqStream.Close ();
652 // return resultBytes;
655 // public byte[] UploadValues (string address, NameValueCollection data)
658 // if (address == null)
659 // throw new ArgumentNullException ("address");
662 // return UploadValues (CreateUri (address), data);
665 // public byte[] UploadValues (string address, string method, NameValueCollection data)
668 // if (address == null)
669 // throw new ArgumentNullException ("address");
672 // return UploadValues (CreateUri (address), method, data);
678 // byte[] UploadValues (Uri address, NameValueCollection data)
680 // return UploadValues (address, (string) null, data);
686 // byte[] UploadValues (Uri address, string method, NameValueCollection data)
689 // if (address == null)
690 // throw new ArgumentNullException ("address");
692 // throw new ArgumentNullException ("data");
698 // return UploadValuesCore (address, method, data, null);
699 // } catch (Exception ex) {
700 // throw new WebException ("An error occurred " +
701 // "performing a WebClient request.", ex);
707 // byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
711 // throw new ArgumentNullException ("data");
714 // string cType = Headers ["Content-Type"];
715 // if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
716 // throw new WebException ("Content-Type header cannot be changed from its default " +
717 // "value for this request.");
719 // Headers ["Content-Type"] = urlEncodedCType;
720 // WebRequest request = SetupRequest (uri, method);
722 // Stream rqStream = request.GetRequestStream ();
723 // MemoryStream tmpStream = new MemoryStream ();
724 // foreach (string key in data) {
725 // byte [] bytes = Encoding.ASCII.GetBytes (key);
726 // UrlEncodeAndWrite (tmpStream, bytes);
727 // tmpStream.WriteByte ((byte) '=');
728 // bytes = Encoding.ASCII.GetBytes (data [key]);
729 // UrlEncodeAndWrite (tmpStream, bytes);
730 // tmpStream.WriteByte ((byte) '&');
733 // int length = (int) tmpStream.Length;
735 // tmpStream.SetLength (--length); // remove trailing '&'
737 // byte [] buf = tmpStream.GetBuffer ();
738 // rqStream.Write (buf, 0, length);
739 // rqStream.Close ();
740 // tmpStream.Close ();
742 // WebResponse response = request.GetResponse ();
743 // Stream st = ProcessResponse (response);
744 // return ReadAll (st, (int) response.ContentLength, userToken);
745 // } catch (ThreadInterruptedException) {
752 // public string DownloadString (string address)
754 // return encoding.GetString (DownloadData (address));
757 // public string DownloadString (Uri address)
759 // return encoding.GetString (DownloadData (address));
762 // public string UploadString (string address, string data)
764 // if (address == null)
765 // throw new ArgumentNullException ("address");
767 // throw new ArgumentNullException ("data");
769 // byte [] resp = UploadData (address, encoding.GetBytes (data));
770 // return encoding.GetString (resp);
773 // public string UploadString (string address, string method, string data)
775 // if (address == null)
776 // throw new ArgumentNullException ("address");
778 // throw new ArgumentNullException ("data");
780 // byte [] resp = UploadData (address, method, encoding.GetBytes (data));
781 // return encoding.GetString (resp);
784 // public string UploadString (Uri address, string data)
786 // if (address == null)
787 // throw new ArgumentNullException ("address");
789 // throw new ArgumentNullException ("data");
791 // byte [] resp = UploadData (address, encoding.GetBytes (data));
792 // return encoding.GetString (resp);
795 // public string UploadString (Uri address, string method, string data)
797 // if (address == null)
798 // throw new ArgumentNullException ("address");
800 // throw new ArgumentNullException ("data");
802 // byte [] resp = UploadData (address, method, encoding.GetBytes (data));
803 // return encoding.GetString (resp);
806 // public event DownloadDataCompletedEventHandler DownloadDataCompleted;
807 // public event AsyncCompletedEventHandler DownloadFileCompleted;
808 public event DownloadProgressChangedEventHandler DownloadProgressChanged;
809 public event DownloadStringCompletedEventHandler DownloadStringCompleted;
810 public event OpenReadCompletedEventHandler OpenReadCompleted;
811 public event OpenWriteCompletedEventHandler OpenWriteCompleted;
812 // public event UploadDataCompletedEventHandler UploadDataCompleted;
813 // public event UploadFileCompletedEventHandler UploadFileCompleted;
814 public event UploadProgressChangedEventHandler UploadProgressChanged;
815 public event UploadStringCompletedEventHandler UploadStringCompleted;
816 // public event UploadValuesCompletedEventHandler UploadValuesCompleted;
817 public event WriteStreamClosedEventHandler WriteStreamClosed;
820 // Uri CreateUri (string address)
824 // return MakeUri (address);
825 // } catch (Exception ex) {
826 // throw new WebException ("An error occurred " +
827 // "performing a WebClient request.", ex);
830 // return MakeUri (address);
834 // Uri MakeUri (string path)
836 // string query = null;
837 // if (queryString != null && queryString.Count != 0) {
838 // // This is not the same as UploadValues, because these 'keys' are not
839 // // urlencoded here.
840 // StringBuilder sb = new StringBuilder ();
842 // foreach (string key in queryString)
843 // sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
845 // if (sb.Length != 0) {
846 // sb.Length--; // remove trailing '&'
847 // query = sb.ToString ();
851 // if (baseAddress == null && query == null) {
853 // return new Uri (path);
855 // } catch (ArgumentNullException) {
856 // path = Path.GetFullPath (path);
857 // return new Uri ("file://" + path);
859 // } catch (UriFormatException) {
860 // path = Path.GetFullPath (path);
861 // return new Uri ("file://" + path);
865 // if (baseAddress == null)
866 // return new Uri (path + query, (query != null));
868 // if (query == null)
869 // return new Uri (baseAddress, path);
871 // return new Uri (baseAddress, path + query, (query != null));
874 WebRequest SetupRequest (Uri uri)
876 WebRequest request = WebRequest.Create (baseAddress != null ? new Uri (baseAddress, uri) : uri);
877 // if (Proxy != null)
878 // request.Proxy = Proxy;
879 // request.Credentials = credentials;
881 // Special headers. These are properties of HttpWebRequest.
882 // What do we do with other requests differnt from HttpWebRequest?
883 // if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
884 // HttpWebRequest req = (HttpWebRequest) request;
885 // string expect = headers ["Expect"];
886 // string contentType = headers ["Content-Type"];
887 // string accept = headers ["Accept"];
888 // string connection = headers ["Connection"];
889 // string userAgent = headers ["User-Agent"];
890 // string referer = headers ["Referer"];
891 // headers.RemoveInternal ("Expect");
892 // headers.RemoveInternal ("Content-Type");
893 // headers.RemoveInternal ("Accept");
894 // headers.RemoveInternal ("Connection");
895 // headers.RemoveInternal ("Referer");
896 // headers.RemoveInternal ("User-Agent");
897 // request.Headers = headers;
899 // if (expect != null && expect.Length > 0)
900 // req.Expect = expect;
902 // if (accept != null && accept.Length > 0)
903 // req.Accept = accept;
905 // if (contentType != null && contentType.Length > 0)
906 // req.ContentType = contentType;
908 // if (connection != null && connection.Length > 0)
909 // req.Connection = connection;
911 // if (userAgent != null && userAgent.Length > 0)
912 // req.UserAgent = userAgent;
914 // if (referer != null && referer.Length > 0)
915 // req.Referer = referer;
918 // responseHeaders = null;
919 request.SetupProgressDelegate ((ProgressChangedDelegate) delegate (long read, long length, object state) {
920 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (read, length, state));
925 WebRequest SetupRequest (Uri uri, string method)
927 WebRequest request = SetupRequest (uri);
928 request.Method = DetermineMethod (uri, method);
932 Stream ProcessResponse (WebResponse response)
934 // responseHeaders = response.Headers;
935 return response.GetResponseStream ();
938 Stream ReadAll (Stream stream, int length, object userToken)
940 MemoryStream ms = null;
942 bool nolength = (length == -1);
943 int size = ((nolength) ? 8192 : length);
944 ms = new MemoryStream (size);
947 byte [] buffer = new byte [size];
948 while ((nread = stream.Read (buffer, 0, buffer.Length)) != 0) {
949 ms.Write (buffer, 0, nread);
951 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (nread, length, userToken));
953 if (!nolength && ms.Length == length) {
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 Stream bdata = DownloadDataCore ((Uri) args [0], args [1]);
1137 using (StreamReader stream = new StreamReader (bdata, encoding, true))
1138 data = stream.ReadToEnd ();
1140 OnDownloadStringCompleted (
1141 new DownloadStringCompletedEventArgs (data, null, false, args [1]));
1142 } catch (ThreadInterruptedException){
1143 OnDownloadStringCompleted (
1144 new DownloadStringCompletedEventArgs (null, null, true, args [1]));
1145 } catch (Exception e){
1146 OnDownloadStringCompleted (
1147 new DownloadStringCompletedEventArgs (null, e, false, args [1]));
1149 object [] cb_args = new object [] {address, userToken};
1150 async_thread.Start (cb_args);
1156 public void OpenReadAsync (Uri address)
1158 OpenReadAsync (address, null);
1161 public void OpenReadAsync (Uri address, object userToken)
1163 if (address == null)
1164 throw new ArgumentNullException ("address");
1170 async_thread = new Thread (delegate (object state) {
1171 object [] args = (object []) state;
1172 WebRequest request = null;
1174 request = SetupRequest ((Uri) args [0]);
1175 //WebResponse response = request.GetResponse ();
1176 IAsyncResult asyncresult = request.BeginGetResponse (null, userToken);
1177 asyncresult.AsyncWaitHandle.WaitOne ();
1178 WebResponse response = request.EndGetResponse (asyncresult);
1179 Stream stream = ProcessResponse (response);
1180 OnOpenReadCompleted (
1181 new OpenReadCompletedEventArgs (stream, address, null, false, args [1]));
1182 } catch (ThreadInterruptedException){
1183 if (request != null)
1186 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, null, true, args [1]));
1187 } catch (Exception e){
1188 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, e, false, args [1]));
1190 object [] cb_args = new object [] {address, userToken};
1191 async_thread.Start (cb_args);
1195 // // OpenWriteAsync
1197 public void OpenWriteAsync (Uri address)
1199 OpenWriteAsync (address, null);
1202 public void OpenWriteAsync (Uri address, string method)
1204 OpenWriteAsync (address, method, null);
1207 public void OpenWriteAsync (Uri address, string method, object userToken)
1209 throw new NotImplementedException ();
1210 // if (address == null)
1211 // throw new ArgumentNullException ("address");
1217 // async_thread = new Thread (delegate (object state) {
1218 // object [] args = (object []) state;
1219 // WebRequest request = null;
1221 // request = SetupRequest ((Uri) args [0], (string) args [1]);
1222 // Stream stream = request.GetRequestStream ();
1223 // OnOpenWriteCompleted (
1224 // new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
1225 // } catch (ThreadInterruptedException){
1226 // if (request != null)
1227 // request.Abort ();
1228 // OnOpenWriteCompleted (
1229 // new OpenWriteCompletedEventArgs (null, null, true, args [2]));
1230 // } catch (Exception e){
1231 // OnOpenWriteCompleted (
1232 // new OpenWriteCompletedEventArgs (null, e, false, args [2]));
1234 // object [] cb_args = new object [] {address, method, userToken};
1235 // async_thread.Start (cb_args);
1239 // // UploadDataAsync
1241 // public void UploadDataAsync (Uri address, byte [] data)
1243 // UploadDataAsync (address, null, data);
1246 // public void UploadDataAsync (Uri address, string method, byte [] data)
1248 // UploadDataAsync (address, method, data, null);
1251 // public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
1253 // if (address == null)
1254 // throw new ArgumentNullException ("address");
1255 // if (data == null)
1256 // throw new ArgumentNullException ("data");
1262 // async_thread = new Thread (delegate (object state) {
1263 // object [] args = (object []) state;
1267 // data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
1269 // OnUploadDataCompleted (
1270 // new UploadDataCompletedEventArgs (data2, null, false, args [3]));
1271 // } catch (ThreadInterruptedException){
1272 // OnUploadDataCompleted (
1273 // new UploadDataCompletedEventArgs (null, null, true, args [3]));
1274 // } catch (Exception e){
1275 // OnUploadDataCompleted (
1276 // new UploadDataCompletedEventArgs (null, e, false, args [3]));
1278 // object [] cb_args = new object [] {address, method, data, userToken};
1279 // async_thread.Start (cb_args);
1283 // // UploadFileAsync
1285 // public void UploadFileAsync (Uri address, string fileName)
1287 // UploadFileAsync (address, null, fileName);
1290 // public void UploadFileAsync (Uri address, string method, string fileName)
1292 // UploadFileAsync (address, method, fileName, null);
1295 // public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
1297 // if (address == null)
1298 // throw new ArgumentNullException ("address");
1299 // if (fileName == null)
1300 // throw new ArgumentNullException ("fileName");
1306 // async_thread = new Thread (delegate (object state) {
1307 // object [] args = (object []) state;
1311 // data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
1312 // OnUploadFileCompleted (
1313 // new UploadFileCompletedEventArgs (data, null, false, args [3]));
1314 // } catch (ThreadInterruptedException){
1315 // OnUploadFileCompleted (
1316 // new UploadFileCompletedEventArgs (null, null, true, args [3]));
1317 // } catch (Exception e){
1318 // OnUploadFileCompleted (
1319 // new UploadFileCompletedEventArgs (null, e, false, args [3]));
1321 // object [] cb_args = new object [] {address, method, fileName, userToken};
1322 // async_thread.Start (cb_args);
1326 // // UploadStringAsync
1328 public void UploadStringAsync (Uri address, string data)
1330 UploadStringAsync (address, null, data);
1333 public void UploadStringAsync (Uri address, string method, string data)
1335 UploadStringAsync (address, method, data, null);
1338 public void UploadStringAsync (Uri address, string method, string data, object userToken)
1340 throw new NotImplementedException ();
1341 // if (address == null)
1342 // throw new ArgumentNullException ("address");
1343 // if (data == null)
1344 // throw new ArgumentNullException ("data");
1350 // async_thread = new Thread (delegate (object state) {
1351 // object [] args = (object []) state;
1354 // string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
1355 // OnUploadStringCompleted (
1356 // new UploadStringCompletedEventArgs (data2, null, false, args [3]));
1357 // } catch (ThreadInterruptedException){
1358 // OnUploadStringCompleted (
1359 // new UploadStringCompletedEventArgs (null, null, true, args [3]));
1360 // } catch (Exception e){
1361 // OnUploadStringCompleted (
1362 // new UploadStringCompletedEventArgs (null, e, false, args [3]));
1364 // object [] cb_args = new object [] {address, method, data, userToken};
1365 // async_thread.Start (cb_args);
1369 // // UploadValuesAsync
1371 // public void UploadValuesAsync (Uri address, NameValueCollection values)
1373 // UploadValuesAsync (address, null, values);
1376 // public void UploadValuesAsync (Uri address, string method, NameValueCollection values)
1378 // UploadValuesAsync (address, method, values, null);
1381 // public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken)
1383 // if (address == null)
1384 // throw new ArgumentNullException ("address");
1385 // if (values == null)
1386 // throw new ArgumentNullException ("values");
1392 // async_thread = new Thread (delegate (object state) {
1393 // object [] args = (object []) state;
1395 // byte [] data = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
1396 // OnUploadValuesCompleted (
1397 // new UploadValuesCompletedEventArgs (data, null, false, args [3]));
1398 // } catch (ThreadInterruptedException){
1399 // OnUploadValuesCompleted (
1400 // new UploadValuesCompletedEventArgs (null, null, true, args [3]));
1401 // } catch (Exception e){
1402 // OnUploadValuesCompleted (
1403 // new UploadValuesCompletedEventArgs (null, e, false, args [3]));
1405 // object [] cb_args = new object [] {address, method, values, userToken};
1406 // async_thread.Start (cb_args);
1410 // protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
1412 // CompleteAsync ();
1413 // if (DownloadDataCompleted != null)
1414 // DownloadDataCompleted (this, args);
1417 // protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
1419 // CompleteAsync ();
1420 // if (DownloadFileCompleted != null)
1421 // DownloadFileCompleted (this, args);
1424 protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
1426 if (DownloadProgressChanged != null) {
1427 DownloadProgressChanged (this, e);
1431 private object callback_args;
1433 protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
1436 if (OpenReadCompleted != null) {
1437 ManualResetEvent wait_event = new ManualResetEvent (false);
1438 GSourceFunc callback = (GSourceFunc) delegate (IntPtr ctx)
1441 OpenReadCompleted (this, (OpenReadCompletedEventArgs) callback_args);
1442 } catch (Exception ex) {
1444 Console.WriteLine ("Unhandled exception: {0}", ex);
1450 } catch (Exception ex) {
1452 Console.WriteLine ("Unhandled exception: {0}", ex);
1458 callback_args = args;
1460 g_timeout_add (0, callback, IntPtr.Zero);
1462 wait_event.WaitOne ();
1463 GC.KeepAlive (callback);
1467 public delegate bool GSourceFunc (IntPtr data);
1469 [DllImport ("moon")]
1470 static extern uint g_timeout_add (uint delay, GSourceFunc callback, IntPtr data);
1472 protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
1475 if (DownloadStringCompleted != null) {
1476 ManualResetEvent wait_event = new ManualResetEvent (false);
1477 GSourceFunc callback = (GSourceFunc) delegate (IntPtr ctx)
1480 DownloadStringCompleted (this, (DownloadStringCompletedEventArgs) callback_args);
1481 } catch (Exception ex) {
1483 Console.WriteLine ("Unhandled exception: {0}", ex);
1489 } catch (Exception ex) {
1491 Console.WriteLine ("Unhandled exception: {0}", ex);
1497 callback_args = args;
1499 g_timeout_add (0, callback, IntPtr.Zero);
1501 wait_event.WaitOne ();
1502 GC.KeepAlive (callback);
1507 protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
1510 if (OpenWriteCompleted != null)
1511 OpenWriteCompleted (this, args);
1514 // protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
1516 // CompleteAsync ();
1517 // if (UploadDataCompleted != null)
1518 // UploadDataCompleted (this, args);
1521 // protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
1523 // CompleteAsync ();
1524 // if (UploadFileCompleted != null)
1525 // UploadFileCompleted (this, args);
1528 protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
1530 if (UploadProgressChanged != null)
1531 UploadProgressChanged (this, e);
1534 protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
1537 if (UploadStringCompleted != null)
1538 UploadStringCompleted (this, args);
1541 // protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
1543 // CompleteAsync ();
1544 // if (UploadValuesCompleted != null)
1545 // UploadValuesCompleted (this, args);
1548 protected virtual void OnWriteStreamClosed (WriteStreamClosedEventArgs e)
1550 throw new NotImplementedException ();
1553 [MonoNotSupported("")]
1554 protected virtual WebRequest GetWebRequest (Uri address)
1556 throw new NotImplementedException ();
1559 // protected virtual WebResponse GetWebResponse (WebRequest request)
1561 // return request.GetResponse ();
1564 protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
1566 return request.EndGetResponse (result);