2009-02-05 Geoff Norton <gnorton@novell.com>
[mono.git] / mcs / class / System.Net / System.Net / WebClient_2_1.cs
1 //
2 // System.Net.WebClient
3 //
4 // Authors:
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)
10 //
11 // Copyright 2003 Ximian, Inc. (http://www.ximian.com)
12 // Copyright 2006, 2008 Novell, Inc. (http://www.novell.com)
13 //
14 //
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:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
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.
33 //
34 //
35 // Notes on CancelAsync and Async methods:
36 //
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.
43 //
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. 
47 //
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.
51 //
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).
61 //
62 using System;
63 using System.Security;
64 using System.Collections.Specialized;
65 using System.ComponentModel;
66 using System.IO;
67 using System.Runtime.InteropServices;
68 using System.Runtime.Serialization;
69 using System.Text;
70 using System.Threading;
71 using System.Net.Cache;
72
73 namespace System.Net 
74 {
75 #if NET_2_1
76         public class WebClient
77         {
78                 private delegate void ProgressChangedDelegate (long read, long length, object state);
79
80 //              static readonly string urlEncodedCType = "application/x-www-form-urlencoded";
81 //              static byte [] hexBytes;
82 //              ICredentials credentials;
83 //              WebHeaderCollection headers;
84 //              WebHeaderCollection responseHeaders;
85                 Uri baseAddress;
86                 string baseString;
87 //              NameValueCollection queryString;
88                 bool is_busy, async;
89                 Thread async_thread;
90                 Encoding encoding = Encoding.UTF8;
91 //              IWebProxy proxy;
92 //
93 //              // Constructors
94 //              static WebClient ()
95 //              {
96 //                      hexBytes = new byte [16];
97 //                      int index = 0;
98 //                      for (int i = '0'; i <= '9'; i++, index++)
99 //                              hexBytes [index] = (byte) i;
100 //
101 //                      for (int i = 'A'; i <= 'F'; i++, index++)
102 //                              hexBytes [index] = (byte) i;
103 //              }
104 //              
105 //              public WebClient ()
106 //              {
107 //              }
108 //              
109 //              // Properties
110 //              
111                 public string BaseAddress {
112                         get {
113                                 if (baseString == null) {
114                                         if (baseAddress == null)
115                                                 return "";
116                                 }
117
118                                 baseString = baseAddress.ToString ();
119                                 return baseString;
120                         }
121                         
122                         set {
123                                 if (value == null || value == "") {
124                                         baseAddress = null;
125                                 } else {
126                                         baseAddress = new Uri (value);
127                                 }
128                         }
129                 }
130 //
131 //#if NET_2_0
132 //              static Exception GetMustImplement ()
133 //              {
134 //                      return new NotImplementedException ();
135 //              }
136 //              
137 //              [MonoTODO]
138 //              public RequestCachePolicy CachePolicy
139 //              {
140 //                      get {
141 //                              throw GetMustImplement ();
142 //                      }
143 //                      set {
144 //                              throw GetMustImplement ();
145 //                      }
146 //              }
147 //
148 //              [MonoTODO]
149 //              public bool UseDefaultCredentials
150 //              {
151 //                      get {
152 //                              throw GetMustImplement ();
153 //                      }
154 //                      set {
155 //                              throw GetMustImplement ();
156 //                      }
157 //              }
158 //#endif
159 //              
160 //              public ICredentials Credentials {
161 //                      get { return credentials; }
162 //                      set { credentials = value; }
163 //              }
164 //
165 //              public WebHeaderCollection Headers {
166 //                      get {
167 //                              if (headers == null)
168 //                                      headers = new WebHeaderCollection ();
169 //
170 //                              return headers;
171 //                      }
172 //                      set { headers = value; }
173 //              }
174 //              
175 //              public NameValueCollection QueryString {
176 //                      get {
177 //                              if (queryString == null)
178 //                                      queryString = new NameValueCollection ();
179 //
180 //                              return queryString;
181 //                      }
182 //                      set { queryString = value; }
183 //              }
184 //              
185 //              public WebHeaderCollection ResponseHeaders {
186 //                      get { return responseHeaders; }
187 //              }
188 //
189 //#if NET_2_0
190 //              public Encoding Encoding {
191 //                      get { return encoding; }
192 //                      set {
193 //                              if (value == null)
194 //                                      throw new ArgumentNullException ("value");
195 //                              encoding = value;
196 //                      }
197 //              }
198 //
199 //              public IWebProxy Proxy {
200 //                      get { return proxy; }
201 //                      set { proxy = value; }
202 //              }
203 //#endif
204 //
205                 public bool IsBusy {
206                         get { return is_busy; }
207                 }
208
209                 // Methods
210
211                 void CheckBusy ()
212                 {
213                         if (IsBusy)
214                                 throw new NotSupportedException ("WebClient does not support conccurent I/O operations.");
215                 }
216
217                 void SetBusy ()
218                 {
219                         lock (this) {
220                                 CheckBusy ();
221                                 is_busy = true;
222                         }
223                 }
224
225 //              //   DownloadData
226 //
227 //              public byte [] DownloadData (string address)
228 //              {
229 //#if NET_2_0
230 //                      if (address == null)
231 //                              throw new ArgumentNullException ("address");
232 //#endif
233 //
234 //                      return DownloadData (CreateUri (address));
235 //              }
236 //
237 //#if NET_2_0
238 //              public
239 //#endif
240 //              byte [] DownloadData (Uri address)
241 //              {
242 //#if NET_2_0
243 //                      if (address == null)
244 //                              throw new ArgumentNullException ("address");
245 //#endif
246 //
247 //                      try {
248 //                              SetBusy ();
249 //                              async = false;
250 //                              return DownloadDataCore (address, null);
251 //                      } finally {
252 //                              is_busy = false;
253 //                      }
254 //              }
255 //
256                 byte [] DownloadDataCore (Uri address, object userToken)
257                 {
258                         WebRequest request = null;
259
260                         try {
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){
269                                 if (request != null)
270                                         request.Abort ();
271                                 throw;
272                         } catch (Exception ex) {
273                                 throw new WebException ("An error occurred " +
274                                         "performing a WebClient request.", ex);
275                         }
276                 }
277
278 //              //   DownloadFile
279 //
280 //              public void DownloadFile (string address, string fileName)
281 //              {
282 //#if NET_2_0
283 //                      if (address == null)
284 //                              throw new ArgumentNullException ("address");
285 //#endif
286 //
287 //                      DownloadFile (CreateUri (address), fileName);
288 //              }
289 //
290 //#if NET_2_0
291 //              public
292 //#endif
293 //              void DownloadFile (Uri address, string fileName)
294 //              {
295 //#if NET_2_0
296 //                      if (address == null)
297 //                              throw new ArgumentNullException ("address");
298 //                      if (fileName == null)
299 //                              throw new ArgumentNullException ("fileName");
300 //#endif
301 //
302 //                      try {
303 //                              SetBusy ();
304 //                              async = false;
305 //                              DownloadFileCore (address, fileName, null);
306 //                      } catch (Exception ex) {
307 //                              throw new WebException ("An error occurred " +
308 //                                      "performing a WebClient request.", ex);
309 //                      } finally {
310 //                              is_busy = false;
311 //                      }
312 //              }
313 //
314 //              void DownloadFileCore (Uri address, string fileName, object userToken)
315 //              {
316 //                      WebRequest request = null;
317 //                      
318 //                      using (FileStream f = new FileStream (fileName, FileMode.Create)) {
319 //                              try {
320 //                                      request = SetupRequest (address);
321 //                                      WebResponse response = request.GetResponse ();
322 //                                      Stream st = ProcessResponse (response);
323 //                                      
324 //                                      int cLength = (int) response.ContentLength;
325 //                                      int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
326 //                                      byte [] buffer = new byte [length];
327 //                                      
328 //                                      int nread = 0;
329 //#if NET_2_0
330 //                                      long notify_total = 0;
331 //#endif                                        
332 //                                      while ((nread = st.Read (buffer, 0, length)) != 0){
333 //#if NET_2_0
334 //                                              if (async){
335 //                                                      notify_total += nread;
336 //                                                      OnDownloadProgressChanged (
337 //                                                              new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken));
338 //                                                                                                    
339 //                                              }
340 //#endif
341 //                                              f.Write (buffer, 0, nread);
342 //                                      }
343 //                              } catch (ThreadInterruptedException){
344 //                                      if (request != null)
345 //                                              request.Abort ();
346 //                                      throw;
347 //                              }
348 //                      }
349 //              }
350 //
351 //              //   OpenRead
352 //
353 //              public Stream OpenRead (string address)
354 //              {
355 //#if NET_2_0
356 //                      if (address == null)
357 //                              throw new ArgumentNullException ("address");
358 //#endif
359 //
360 //                      return OpenRead (CreateUri (address));
361 //              }
362 //
363 //#if NET_2_0
364 //              public
365 //#endif
366 //              Stream OpenRead (Uri address)
367 //              {
368 //#if NET_2_0
369 //                      if (address == null)
370 //                              throw new ArgumentNullException ("address");
371 //#endif
372 //
373 //                      WebRequest request = null;
374 //                      try {
375 //                              SetBusy ();
376 //                              async = false;
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);
383 //                      } finally {
384 //                              is_busy = false;
385 //                      }
386 //              }
387 //
388 //              //   OpenWrite
389 //
390 //              public Stream OpenWrite (string address)
391 //              {
392 //#if NET_2_0
393 //                      if (address == null)
394 //                              throw new ArgumentNullException ("address");
395 //#endif
396 //
397 //                      return OpenWrite (CreateUri (address));
398 //              }
399 //              
400 //              public Stream OpenWrite (string address, string method)
401 //              {
402 //#if NET_2_0
403 //                      if (address == null)
404 //                              throw new ArgumentNullException ("address");
405 //#endif
406 //
407 //                      return OpenWrite (CreateUri (address), method);
408 //              }
409 //
410 //#if NET_2_0
411 //              public
412 //#endif
413 //              Stream OpenWrite (Uri address)
414 //              {
415 //                      return OpenWrite (address, (string) null);
416 //              }
417 //
418 //#if NET_2_0
419 //              public
420 //#endif
421 //              Stream OpenWrite (Uri address, string method)
422 //              {
423 //#if NET_2_0
424 //                      if (address == null)
425 //                              throw new ArgumentNullException ("address");
426 //#endif
427 //
428 //                      try {
429 //                              SetBusy ();
430 //                              async = false;
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);
436 //                      } finally {
437 //                              is_busy = false;
438 //                      }
439 //              }
440 //
441                 private string DetermineMethod (Uri address, string method)
442                 {
443                         if (method != null)
444                                 return method;
445
446                         if (address.Scheme == Uri.UriSchemeFtp)
447                                 return "RETR";
448                         return "POST";
449                 }
450
451 //              //   UploadData
452 //
453 //              public byte [] UploadData (string address, byte [] data)
454 //              {
455 //#if NET_2_0
456 //                      if (address == null)
457 //                              throw new ArgumentNullException ("address");
458 //#endif
459 //
460 //                      return UploadData (CreateUri (address), data);
461 //              }
462 //              
463 //              public byte [] UploadData (string address, string method, byte [] data)
464 //              {
465 //#if NET_2_0
466 //                      if (address == null)
467 //                              throw new ArgumentNullException ("address");
468 //#endif
469 //
470 //                      return UploadData (CreateUri (address), method, data);
471 //              }
472 //
473 //#if NET_2_0
474 //              public
475 //#endif
476 //              byte [] UploadData (Uri address, byte [] data)
477 //              {
478 //                      return UploadData (address, (string) null, data);
479 //              }
480 //
481 //#if NET_2_0
482 //              public
483 //#endif
484 //              byte [] UploadData (Uri address, string method, byte [] data)
485 //              {
486 //#if NET_2_0
487 //                      if (address == null)
488 //                              throw new ArgumentNullException ("address");
489 //                      if (data == null)
490 //                              throw new ArgumentNullException ("data");
491 //#endif
492 //
493 //                      try {
494 //                              SetBusy ();
495 //                              async = false;
496 //                              return UploadDataCore (address, method, data, null);
497 //                      } catch (Exception ex) {
498 //                              throw new WebException ("An error occurred " +
499 //                                      "performing a WebClient request.", ex);
500 //                      } finally {
501 //                              is_busy = false;
502 //                      }
503 //              }
504 //
505 //              byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
506 //              {
507 //#if ONLY_1_1
508 //                      if (address == null)
509 //                              throw new ArgumentNullException ("address");
510 //                      if (data == null)
511 //                              throw new ArgumentNullException ("data");
512 //#endif
513 //
514 //                      WebRequest request = SetupRequest (address, method);
515 //                      try {
516 //                              int contentLength = data.Length;
517 //                              request.ContentLength = contentLength;
518 //                              using (Stream stream = request.GetRequestStream ()) {
519 //                                      stream.Write (data, 0, contentLength);
520 //                              }
521 //                              
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)
527 //                                      request.Abort ();
528 //                              throw;
529 //                      }
530 //              }
531 //
532 //              //   UploadFile
533 //
534 //              public byte [] UploadFile (string address, string fileName)
535 //              {
536 //#if NET_2_0
537 //                      if (address == null)
538 //                              throw new ArgumentNullException ("address");
539 //#endif
540 //
541 //                      return UploadFile (CreateUri (address), fileName);
542 //              }
543 //
544 //#if NET_2_0
545 //              public
546 //#endif
547 //              byte [] UploadFile (Uri address, string fileName)
548 //              {
549 //                      return UploadFile (address, (string) null, fileName);
550 //              }
551 //              
552 //              public byte [] UploadFile (string address, string method, string fileName)
553 //              {
554 //                      return UploadFile (CreateUri (address), method, fileName);
555 //              }
556 //
557 //#if NET_2_0
558 //              public
559 //#endif
560 //              byte [] UploadFile (Uri address, string method, string fileName)
561 //              {
562 //#if NET_2_0
563 //                      if (address == null)
564 //                              throw new ArgumentNullException ("address");
565 //                      if (fileName == null)
566 //                              throw new ArgumentNullException ("fileName");
567 //#endif
568 //
569 //                      try {
570 //                              SetBusy ();
571 //                              async = false;
572 //                              return UploadFileCore (address, method, fileName, null);
573 //                      } catch (Exception ex) {
574 //                              throw new WebException ("An error occurred " +
575 //                                      "performing a WebClient request.", ex);
576 //                      } finally {
577 //                              is_busy = false;
578 //                      }
579 //              }
580 //
581 //              byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
582 //              {
583 //#if ONLY_1_1
584 //                      if (address == null)
585 //                              throw new ArgumentNullException ("address");
586 //#endif
587 //
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.");
594 //                      } else {
595 //                              fileCType = "application/octet-stream";
596 //                      }
597 //
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;
603 //
604 //                      fileName = Path.GetFullPath (fileName);
605 //
606 //                      WebRequest request = null;
607 //                      try {
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);
617 //
618 //                              byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
619 //                              reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
620 //                              int nread;
621 //                              byte [] buffer = new byte [4096];
622 //                              while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
623 //                                      reqStream.Write (buffer, 0, nread);
624 //
625 //                              reqStream.WriteByte ((byte) '\r');
626 //                              reqStream.WriteByte ((byte) '\n');
627 //                              reqStream.Write (realBoundary, 0, realBoundary.Length);
628 //                              reqStream.Close ();
629 //                              reqStream = null;
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)
635 //                                      request.Abort ();
636 //                              throw;
637 //                      } finally {
638 //                              if (fStream != null)
639 //                                      fStream.Close ();
640 //
641 //                              if (reqStream != null)
642 //                                      reqStream.Close ();
643 //                      }
644 //                      
645 //                      return resultBytes;
646 //              }
647 //              
648 //              public byte[] UploadValues (string address, NameValueCollection data)
649 //              {
650 //#if NET_2_0
651 //                      if (address == null)
652 //                              throw new ArgumentNullException ("address");
653 //#endif
654 //
655 //                      return UploadValues (CreateUri (address), data);
656 //              }
657 //              
658 //              public byte[] UploadValues (string address, string method, NameValueCollection data)
659 //              {
660 //#if NET_2_0
661 //                      if (address == null)
662 //                              throw new ArgumentNullException ("address");
663 //#endif
664 //
665 //                      return UploadValues (CreateUri (address), method, data);
666 //              }
667 //
668 //#if NET_2_0
669 //              public
670 //#endif
671 //              byte[] UploadValues (Uri address, NameValueCollection data)
672 //              {
673 //                      return UploadValues (address, (string) null, data);
674 //              }
675 //
676 //#if NET_2_0
677 //              public
678 //#endif
679 //              byte[] UploadValues (Uri address, string method, NameValueCollection data)
680 //              {
681 //#if NET_2_0
682 //                      if (address == null)
683 //                              throw new ArgumentNullException ("address");
684 //                      if (data == null)
685 //                              throw new ArgumentNullException ("data");
686 //#endif
687 //
688 //                      try {
689 //                              SetBusy ();
690 //                              async = false;
691 //                              return UploadValuesCore (address, method, data, null);
692 //                      } catch (Exception ex) {
693 //                              throw new WebException ("An error occurred " +
694 //                                      "performing a WebClient request.", ex);
695 //                      } finally {
696 //                              is_busy = false;
697 //                      }
698 //              }
699 //
700 //              byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
701 //              {
702 //#if ONLY_1_1
703 //                      if (data == null)
704 //                              throw new ArgumentNullException ("data");
705 //#endif
706 //
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.");
711 //
712 //                      Headers ["Content-Type"] = urlEncodedCType;
713 //                      WebRequest request = SetupRequest (uri, method);
714 //                      try {
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) '&');
724 //                              }
725 //                              
726 //                              int length = (int) tmpStream.Length;
727 //                              if (length > 0)
728 //                                      tmpStream.SetLength (--length); // remove trailing '&'
729 //                              
730 //                              byte [] buf = tmpStream.GetBuffer ();
731 //                              rqStream.Write (buf, 0, length);
732 //                              rqStream.Close ();
733 //                              tmpStream.Close ();
734 //                              
735 //                              WebResponse response = request.GetResponse ();
736 //                              Stream st = ProcessResponse (response);
737 //                              return ReadAll (st, (int) response.ContentLength, userToken);
738 //                      } catch (ThreadInterruptedException) {
739 //                              request.Abort ();
740 //                              throw;
741 //                      }
742 //              }
743 //
744 //#if NET_2_0
745 //              public string DownloadString (string address)
746 //              {
747 //                      return encoding.GetString (DownloadData (address));
748 //              }
749 //
750 //              public string DownloadString (Uri address)
751 //              {
752 //                      return encoding.GetString (DownloadData (address));
753 //              }
754 //
755 //              public string UploadString (string address, string data)
756 //              {
757 //                      if (address == null)
758 //                              throw new ArgumentNullException ("address");
759 //                      if (data == null)
760 //                              throw new ArgumentNullException ("data");
761 //
762 //                      byte [] resp = UploadData (address, encoding.GetBytes (data));
763 //                      return encoding.GetString (resp);
764 //              }
765 //
766 //              public string UploadString (string address, string method, string data)
767 //              {
768 //                      if (address == null)
769 //                              throw new ArgumentNullException ("address");
770 //                      if (data == null)
771 //                              throw new ArgumentNullException ("data");
772 //
773 //                      byte [] resp = UploadData (address, method, encoding.GetBytes (data));
774 //                      return encoding.GetString (resp);
775 //              }
776 //
777 //              public string UploadString (Uri address, string data)
778 //              {
779 //                      if (address == null)
780 //                              throw new ArgumentNullException ("address");
781 //                      if (data == null)
782 //                              throw new ArgumentNullException ("data");
783 //
784 //                      byte [] resp = UploadData (address, encoding.GetBytes (data));
785 //                      return encoding.GetString (resp);
786 //              }
787 //
788 //              public string UploadString (Uri address, string method, string data)
789 //              {
790 //                      if (address == null)
791 //                              throw new ArgumentNullException ("address");
792 //                      if (data == null)
793 //                              throw new ArgumentNullException ("data");
794 //
795 //                      byte [] resp = UploadData (address, method, encoding.GetBytes (data));
796 //                      return encoding.GetString (resp);
797 //              }
798 //
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;
810 //#endif
811 //
812 //              Uri CreateUri (string address)
813 //              {
814 //#if ONLY_1_1
815 //                      try {
816 //                              return MakeUri (address);
817 //                      } catch (Exception ex) {
818 //                              throw new WebException ("An error occurred " +
819 //                                      "performing a WebClient request.", ex);
820 //                      }
821 //#else
822 //                      return MakeUri (address);
823 //#endif
824 //              }
825 //
826 //              Uri MakeUri (string path)
827 //              {
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 ();
833 //                              sb.Append ('?');
834 //                              foreach (string key in queryString)
835 //                                      sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
836 //
837 //                              if (sb.Length != 0) {
838 //                                      sb.Length--; // remove trailing '&'
839 //                                      query = sb.ToString ();
840 //                              }
841 //                      }
842 //
843 //                      if (baseAddress == null && query == null) {
844 //                              try {
845 //                                      return new Uri (path);
846 //#if NET_2_0
847 //                              } catch (ArgumentNullException) {
848 //                                      path = Path.GetFullPath (path);
849 //                                      return new Uri ("file://" + path);
850 //#endif
851 //                              } catch (UriFormatException) {
852 //                                      path = Path.GetFullPath (path);
853 //                                      return new Uri ("file://" + path);
854 //                              }
855 //                      }
856 //
857 //                      if (baseAddress == null)
858 //                              return new Uri (path + query, (query != null));
859 //
860 //                      if (query == null)
861 //                              return new Uri (baseAddress, path);
862 //
863 //                      return new Uri (baseAddress, path + query, (query != null));
864 //              }
865 //              
866                 WebRequest SetupRequest (Uri uri)
867                 {
868                         WebRequest request = WebRequest.Create (baseAddress != null ? new Uri (baseAddress, uri) : uri);
869 //                      if (Proxy != null)
870 //                              request.Proxy = Proxy;
871 //                      request.Credentials = credentials;
872
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;
890 //
891 //                              if (expect != null && expect.Length > 0)
892 //                                      req.Expect = expect;
893 //
894 //                              if (accept != null && accept.Length > 0)
895 //                                      req.Accept = accept;
896 //
897 //                              if (contentType != null && contentType.Length > 0)
898 //                                      req.ContentType = contentType;
899 //
900 //                              if (connection != null && connection.Length > 0)
901 //                                      req.Connection = connection;
902 //
903 //                              if (userAgent != null && userAgent.Length > 0)
904 //                                      req.UserAgent = userAgent;
905 //
906 //                              if (referer != null && referer.Length > 0)
907 //                                      req.Referer = referer;
908 //                      }
909 //
910 //                      responseHeaders = null;
911                         request.SetupProgressDelegate ((ProgressChangedDelegate) delegate (long read, long length, object state) {
912                                 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (read, length, state));
913                         });
914                         return request;
915                 }
916
917                 WebRequest SetupRequest (Uri uri, string method)
918                 {
919                         WebRequest request = SetupRequest (uri);
920                         request.Method = DetermineMethod (uri, method);
921                         return request;
922                 }
923
924                 Stream ProcessResponse (WebResponse response)
925                 {
926 //                      responseHeaders = response.Headers;
927                         return response.GetResponseStream ();
928                 }
929
930                 byte [] ReadAll (Stream stream, int length, object userToken)
931                 {
932                         MemoryStream ms = null;
933
934                         bool nolength = (length == -1);
935                         int size = ((nolength) ? 8192 : length);
936                         if (nolength)
937                                 ms = new MemoryStream ();
938
939 //                      long total = 0;
940                         int nread = 0;
941                         int offset = 0;
942                         byte [] buffer = new byte [size];
943                         while ((nread = stream.Read (buffer, offset, size)) != 0) {
944                                 if (nolength) {
945                                         ms.Write (buffer, 0, nread);
946                                 } else {
947                                         offset += nread;
948                                         size -= nread;
949                                 }
950                                 if (async){
951 //                                      total += nread;
952                                         OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (nread, length, userToken));
953                                 }
954                         }
955
956                         if (nolength)
957                                 return ms.ToArray ();
958
959                         return buffer;
960                 }
961
962 //              string UrlEncode (string str)
963 //              {
964 //                      StringBuilder result = new StringBuilder ();
965 //
966 //                      int len = str.Length;
967 //                      for (int i = 0; i < len; i++) {
968 //                              char c = str [i];
969 //                              if (c == ' ')
970 //                                      result.Append ('+');
971 //                              else if ((c < '0' && c != '-' && c != '.') ||
972 //                                       (c < 'A' && c > '9') ||
973 //                                       (c > 'Z' && c < 'a' && c != '_') ||
974 //                                       (c > 'z')) {
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]);
980 //                              } else {
981 //                                      result.Append (c);
982 //                              }
983 //                      }
984 //
985 //                      return result.ToString ();
986 //              }
987 //
988 //              static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
989 //              {
990 //                      if (bytes == null)
991 //                              return;
992 //
993 //                      int len = bytes.Length;
994 //                      if (len == 0)
995 //                              return;
996 //
997 //                      for (int i = 0; i < len; i++) {
998 //                              char c = (char) bytes [i];
999 //                              if (c == ' ')
1000 //                                      stream.WriteByte ((byte) '+');
1001 //                              else if ((c < '0' && c != '-' && c != '.') ||
1002 //                                       (c < 'A' && c > '9') ||
1003 //                                       (c > 'Z' && c < 'a' && c != '_') ||
1004 //                                       (c > 'z')) {
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]);
1010 //                              } else {
1011 //                                      stream.WriteByte ((byte) c);
1012 //                              }
1013 //                      }
1014 //              }
1015 //
1016 //#if NET_2_0
1017                 [SecuritySafeCritical]
1018                 public void CancelAsync ()
1019                 {
1020                         lock (this){
1021                                 if (async_thread == null)
1022                                         return;
1023
1024                                 //
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
1029                                 //
1030                                 Thread t = async_thread;
1031                                 CompleteAsync ();
1032                                 t.Interrupt ();
1033                         }
1034                 }
1035
1036                 void CompleteAsync ()
1037                 {
1038                         lock (this){
1039                                 is_busy = false;
1040                                 async_thread = null;
1041                         }
1042                 }
1043
1044 //              //    DownloadDataAsync
1045 //
1046 //              public void DownloadDataAsync (Uri address)
1047 //              {
1048 //                      DownloadDataAsync (address, null);
1049 //              }
1050 //
1051 //              public void DownloadDataAsync (Uri address, object userToken)
1052 //              {
1053 //                      if (address == null)
1054 //                              throw new ArgumentNullException ("address");
1055 //                      
1056 //                      lock (this) {
1057 //                              SetBusy ();
1058 //                              async = true;
1059 //                              
1060 //                              async_thread = new Thread (delegate (object state) {
1061 //                                      object [] args = (object []) state;
1062 //                                      try {
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]));
1069 //                                              throw;
1070 //                                      } catch (Exception e){
1071 //                                              OnDownloadDataCompleted (
1072 //                                                      new DownloadDataCompletedEventArgs (null, e, false, args [1]));
1073 //                                      }
1074 //                              });
1075 //                              object [] cb_args = new object [] {address, userToken};
1076 //                              async_thread.Start (cb_args);
1077 //                      }
1078 //              }
1079 //
1080 //              //    DownloadFileAsync
1081 //
1082 //              public void DownloadFileAsync (Uri address, string fileName)
1083 //              {
1084 //                      DownloadFileAsync (address, fileName, null);
1085 //              }
1086 //
1087 //              public void DownloadFileAsync (Uri address, string fileName, object userToken)
1088 //              {
1089 //                      if (address == null)
1090 //                              throw new ArgumentNullException ("address");
1091 //                      if (fileName == null)
1092 //                              throw new ArgumentNullException ("fileName");
1093 //                      
1094 //                      lock (this) {
1095 //                              SetBusy ();
1096 //                              async = true;
1097 //
1098 //                              async_thread = new Thread (delegate (object state) {
1099 //                                      object [] args = (object []) state;
1100 //                                      try {
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]));
1110 //                                      }});
1111 //                              object [] cb_args = new object [] {address, fileName, userToken};
1112 //                              async_thread.Start (cb_args);
1113 //                      }
1114 //              }
1115 //
1116 //              //    DownloadStringAsync
1117 //
1118                 public void DownloadStringAsync (Uri address)
1119                 {
1120                         DownloadStringAsync (address, null);
1121                 }
1122
1123                 public void DownloadStringAsync (Uri address, object userToken)
1124                 {
1125                         if (address == null)
1126                                 throw new ArgumentNullException ("address");
1127
1128                         lock (this) {
1129                                 SetBusy ();
1130                                 async = true;
1131
1132                                 async_thread = new Thread (delegate (object state) {
1133                                         object [] args = (object []) state;
1134                                         try {
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]));
1145                                         }});
1146                                 object [] cb_args = new object [] {address, userToken};
1147                                 async_thread.Start (cb_args);
1148                         }
1149                 }
1150
1151                 //    OpenReadAsync
1152
1153                 public void OpenReadAsync (Uri address)
1154                 {
1155                         OpenReadAsync (address, null);
1156                 }
1157
1158                 public void OpenReadAsync (Uri address, object userToken)
1159                 {
1160                         if (address == null)
1161                                 throw new ArgumentNullException ("address");
1162
1163                         lock (this) {
1164                                 SetBusy ();
1165                                 async = true;
1166
1167                                 async_thread = new Thread (delegate (object state) {
1168                                         object [] args = (object []) state;
1169                                         WebRequest request = null;
1170                                         try {
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)
1181                                                         request.Abort ();
1182
1183                                                 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, null, true, args [1]));
1184                                         } catch (Exception e){
1185                                                 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, e, false, args [1]));
1186                                         } });
1187                                 object [] cb_args = new object [] {address, userToken};
1188                                 async_thread.Start (cb_args);
1189                         }
1190                 }
1191
1192 //              //    OpenWriteAsync
1193 //
1194 //              public void OpenWriteAsync (Uri address)
1195 //              {
1196 //                      OpenWriteAsync (address, null);
1197 //              }
1198 //
1199 //              public void OpenWriteAsync (Uri address, string method)
1200 //              {
1201 //                      OpenWriteAsync (address, method, null);
1202 //              }
1203 //
1204 //              public void OpenWriteAsync (Uri address, string method, object userToken)
1205 //              {
1206 //                      if (address == null)
1207 //                              throw new ArgumentNullException ("address");
1208 //
1209 //                      lock (this) {
1210 //                              SetBusy ();
1211 //                              async = true;
1212 //
1213 //                              async_thread = new Thread (delegate (object state) {
1214 //                                      object [] args = (object []) state;
1215 //                                      WebRequest request = null;
1216 //                                      try {
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]));
1229 //                                      }});
1230 //                              object [] cb_args = new object [] {address, method, userToken};
1231 //                              async_thread.Start (cb_args);
1232 //                      }
1233 //              }
1234 //
1235 //              //    UploadDataAsync
1236 //
1237 //              public void UploadDataAsync (Uri address, byte [] data)
1238 //              {
1239 //                      UploadDataAsync (address, null, data);
1240 //              }
1241 //
1242 //              public void UploadDataAsync (Uri address, string method, byte [] data)
1243 //              {
1244 //                      UploadDataAsync (address, method, data, null);
1245 //              }
1246 //
1247 //              public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
1248 //              {
1249 //                      if (address == null)
1250 //                              throw new ArgumentNullException ("address");
1251 //                      if (data == null)
1252 //                              throw new ArgumentNullException ("data");
1253 //                      
1254 //                      lock (this) {
1255 //                              SetBusy ();
1256 //                              async = true;
1257 //
1258 //                              async_thread = new Thread (delegate (object state) {
1259 //                                      object [] args = (object []) state;
1260 //                                      byte [] data2;
1261 //
1262 //                                      try {
1263 //                                              data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
1264 //                                      
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]));
1273 //                                      }});
1274 //                              object [] cb_args = new object [] {address, method, data,  userToken};
1275 //                              async_thread.Start (cb_args);
1276 //                      }
1277 //              }
1278 //
1279 //              //    UploadFileAsync
1280 //
1281 //              public void UploadFileAsync (Uri address, string fileName)
1282 //              {
1283 //                      UploadFileAsync (address, null, fileName);
1284 //              }
1285 //
1286 //              public void UploadFileAsync (Uri address, string method, string fileName)
1287 //              {
1288 //                      UploadFileAsync (address, method, fileName, null);
1289 //              }
1290 //
1291 //              public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
1292 //              {
1293 //                      if (address == null)
1294 //                              throw new ArgumentNullException ("address");
1295 //                      if (fileName == null)
1296 //                              throw new ArgumentNullException ("fileName");
1297 //
1298 //                      lock (this) {
1299 //                              SetBusy ();
1300 //                              async = true;
1301 //
1302 //                              async_thread = new Thread (delegate (object state) {
1303 //                                      object [] args = (object []) state;
1304 //                                      byte [] data;
1305 //
1306 //                                      try {
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]));
1316 //                                      }});
1317 //                              object [] cb_args = new object [] {address, method, fileName,  userToken};
1318 //                              async_thread.Start (cb_args);
1319 //                      }
1320 //              }
1321 //
1322 //              //    UploadStringAsync
1323 //
1324 //              public void UploadStringAsync (Uri address, string data)
1325 //              {
1326 //                      UploadStringAsync (address, null, data);
1327 //              }
1328 //
1329 //              public void UploadStringAsync (Uri address, string method, string data)
1330 //              {
1331 //                      UploadStringAsync (address, method, data, null);
1332 //              }
1333 //
1334 //              public void UploadStringAsync (Uri address, string method, string data, object userToken)
1335 //              {
1336 //                      if (address == null)
1337 //                              throw new ArgumentNullException ("address");
1338 //                      if (data == null)
1339 //                              throw new ArgumentNullException ("data");
1340 //                      
1341 //                      lock (this) {
1342 //                              SetBusy ();
1343 //                              async = true;
1344 //                              
1345 //                              async_thread = new Thread (delegate (object state) {
1346 //                                      object [] args = (object []) state;
1347 //
1348 //                                      try {
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]));
1358 //                                      }});
1359 //                              object [] cb_args = new object [] {address, method, data, userToken};
1360 //                              async_thread.Start (cb_args);
1361 //                      }
1362 //              }
1363 //
1364 //              //    UploadValuesAsync
1365 //
1366 //              public void UploadValuesAsync (Uri address, NameValueCollection values)
1367 //              {
1368 //                      UploadValuesAsync (address, null, values);
1369 //              }
1370 //
1371 //              public void UploadValuesAsync (Uri address, string method, NameValueCollection values)
1372 //              {
1373 //                      UploadValuesAsync (address, method, values, null);
1374 //              }
1375 //
1376 //              public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken)
1377 //              {
1378 //                      if (address == null)
1379 //                              throw new ArgumentNullException ("address");
1380 //                      if (values == null)
1381 //                              throw new ArgumentNullException ("values");
1382 //
1383 //                      lock (this) {
1384 //                              CheckBusy ();
1385 //                              async = true;
1386 //
1387 //                              async_thread = new Thread (delegate (object state) {
1388 //                                      object [] args = (object []) state;
1389 //                                      try {
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]));
1399 //                                      }});
1400 //                              object [] cb_args = new object [] {address, method, values,  userToken};
1401 //                              async_thread.Start (cb_args);
1402 //                      }
1403 //              }
1404 //
1405 //              protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
1406 //              {
1407 //                      CompleteAsync ();
1408 //                      if (DownloadDataCompleted != null)
1409 //                              DownloadDataCompleted (this, args);
1410 //              }
1411 //
1412 //              protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
1413 //              {
1414 //                      CompleteAsync ();
1415 //                      if (DownloadFileCompleted != null)
1416 //                              DownloadFileCompleted (this, args);
1417 //              }
1418 //
1419                 protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
1420                 {
1421                         if (DownloadProgressChanged != null) {
1422                                 DownloadProgressChanged (this, e);
1423                         }
1424                 }
1425                 
1426                 private object callback_args;
1427
1428                 protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
1429                 {
1430                         CompleteAsync ();
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;
1435
1436                                 g_idle_add (callback, IntPtr.Zero);
1437
1438                                 wait_event.WaitOne ();
1439                                 GC.KeepAlive (callback);
1440                         }
1441                 }
1442
1443                 public delegate bool GSourceFunc (IntPtr data);
1444
1445                 [DllImport ("moon")]
1446                 static extern uint g_idle_add (GSourceFunc callback, IntPtr data);
1447
1448                 protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
1449                 {
1450                         CompleteAsync ();
1451                         if (DownloadStringCompleted != null) {
1452                                 ManualResetEvent wait_event = new ManualResetEvent (false);
1453                                 GSourceFunc callback = (GSourceFunc) delegate (IntPtr ctx) 
1454                                 {
1455                                         try {
1456                                                 DownloadStringCompleted (this, (DownloadStringCompletedEventArgs) callback_args);
1457                                                 wait_event.Set ();
1458                                         } catch (Exception ex) {
1459                                                 Console.WriteLine ("Unhandled exception: {0}", ex);
1460                                         } catch {
1461                                                 Console.WriteLine ("Unhandled exception.");
1462                                         }
1463                                         return false;
1464                                 };
1465                                 callback_args = args;
1466
1467                                 g_idle_add (callback, IntPtr.Zero);
1468
1469                                 wait_event.WaitOne ();
1470                                 GC.KeepAlive (callback);
1471                         }
1472                 }
1473
1474
1475 //              protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
1476 //              {
1477 //                      CompleteAsync ();
1478 //                      if (OpenWriteCompleted != null)
1479 //                              OpenWriteCompleted (this, args);
1480 //              }
1481 //
1482 //              protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
1483 //              {
1484 //                      CompleteAsync ();
1485 //                      if (UploadDataCompleted != null)
1486 //                              UploadDataCompleted (this, args);
1487 //              }
1488 //
1489 //              protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
1490 //              {
1491 //                      CompleteAsync ();
1492 //                      if (UploadFileCompleted != null)
1493 //                              UploadFileCompleted (this, args);
1494 //              }
1495 //
1496 //              protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
1497 //              {
1498 //                      if (UploadProgressChanged != null)
1499 //                              UploadProgressChanged (this, e);
1500 //              }
1501 //
1502 //              protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
1503 //              {
1504 //                      CompleteAsync ();
1505 //                      if (UploadStringCompleted != null)
1506 //                              UploadStringCompleted (this, args);
1507 //              }
1508 //
1509 //              protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
1510 //              {
1511 //                      CompleteAsync ();
1512 //                      if (UploadValuesCompleted != null)
1513 //                              UploadValuesCompleted (this, args);
1514 //              }
1515 //
1516 //              [MonoNotSupported("")]
1517 //              protected virtual WebRequest GetWebRequest (Uri address)
1518 //              {
1519 //                      throw new NotImplementedException ();
1520 //              }
1521 //
1522 //              protected virtual WebResponse GetWebResponse (WebRequest request)
1523 //              {
1524 //                      return request.GetResponse ();
1525 //              }
1526 //
1527 //              protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
1528 //              {
1529 //                      return request.EndGetResponse (result);
1530 //              }
1531 //#endif
1532 #endif
1533         }
1534 }
1535
1536