2009-05-10 Sebastien Pouliot <sebastien@ximian.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
72 using Mono;
73
74 namespace System.Net 
75 {
76 #if NET_2_1
77         // note: this type is effectively sealed to transparent code since it's default .ctor is marked with [SecuritySafeCritical]
78         public class WebClient
79         {
80                 private delegate void ProgressChangedDelegate (long read, long length, object state);
81
82 //              static readonly string urlEncodedCType = "application/x-www-form-urlencoded";
83 //              static byte [] hexBytes;
84 //              ICredentials credentials;
85                 WebHeaderCollection headers;
86 //              WebHeaderCollection responseHeaders;
87                 Uri baseAddress;
88                 string baseString;
89 //              NameValueCollection queryString;
90                 bool is_busy, async;
91                 Thread async_thread;
92                 Encoding encoding = Encoding.UTF8;
93                 bool allow_read_buffering = true;
94 //              IWebProxy proxy;
95 //
96 //              // Constructors
97 //              static WebClient ()
98 //              {
99 //                      hexBytes = new byte [16];
100 //                      int index = 0;
101 //                      for (int i = '0'; i <= '9'; i++, index++)
102 //                              hexBytes [index] = (byte) i;
103 //
104 //                      for (int i = 'A'; i <= 'F'; i++, index++)
105 //                              hexBytes [index] = (byte) i;
106 //              }
107 //              
108                 public WebClient ()
109                 {
110                         // kind of calling NativeMethods.plugin_instance_get_source_location (PluginHost.Handle)
111                         // but without adding dependency on System.Windows.dll. GetData is [SecurityCritical]
112                         // this makes the default .ctor [SecuritySafeCritical] which would be a problem (inheritance)
113                         // but it happens that MS SL2 also has this default .ctor as SSC :-)
114                         baseAddress = new Uri (AppDomain.CurrentDomain.GetData ("xap_uri") as string);
115                 }
116 //              
117 //              // Properties
118 //              
119                 public string BaseAddress {
120                         get {
121                                 if (baseString == null) {
122                                         if (baseAddress == null)
123                                                 return String.Empty;
124                                         else
125                                                 baseString = baseAddress.ToString ();
126                                 }
127                                 return baseString;
128                         }
129                         
130                         set {
131                                 if (String.IsNullOrEmpty (value)) {
132                                         baseAddress = null;
133                                 } else {
134                                         baseAddress = new Uri (value);
135                                 }
136                         }
137                 }
138 //
139 //#if NET_2_0
140 //              static Exception GetMustImplement ()
141 //              {
142 //                      return new NotImplementedException ();
143 //              }
144 //              
145 //              [MonoTODO]
146 //              public RequestCachePolicy CachePolicy
147 //              {
148 //                      get {
149 //                              throw GetMustImplement ();
150 //                      }
151 //                      set {
152 //                              throw GetMustImplement ();
153 //                      }
154 //              }
155 //
156 //              [MonoTODO]
157 //              public bool UseDefaultCredentials
158 //              {
159 //                      get {
160 //                              throw GetMustImplement ();
161 //                      }
162 //                      set {
163 //                              throw GetMustImplement ();
164 //                      }
165 //              }
166 //#endif
167 //              
168 //              public ICredentials Credentials {
169 //                      get { return credentials; }
170 //                      set { credentials = value; }
171 //              }
172 //
173                 // this is an unvalidated collection, HttpWebRequest is responsable to validate it
174                 public WebHeaderCollection Headers {
175                         get {
176                                 if (headers == null)
177                                         headers = new WebHeaderCollection ();
178
179                                 return headers;
180                         }
181                         set { headers = value; }
182                 }
183 //              
184 //              public NameValueCollection QueryString {
185 //                      get {
186 //                              if (queryString == null)
187 //                                      queryString = new NameValueCollection ();
188 //
189 //                              return queryString;
190 //                      }
191 //                      set { queryString = value; }
192 //              }
193 //              
194 //              public WebHeaderCollection ResponseHeaders {
195 //                      get { return responseHeaders; }
196 //              }
197 //
198 //#if NET_2_0
199                 public Encoding Encoding {
200                         get { return encoding; }
201                         set {
202                                 if (value == null)
203                                         throw new ArgumentNullException ("value");
204                                 encoding = value;
205                         }
206                 }
207 //
208 //              public IWebProxy Proxy {
209 //                      get { return proxy; }
210 //                      set { proxy = value; }
211 //              }
212 //#endif
213 //
214                 public bool IsBusy {
215                         get { return is_busy; }
216                 }
217
218                 [MonoTODO ("value is unused")]
219                 public bool AllowReadStreamBuffering {
220                         get { return allow_read_buffering; }
221                         set { allow_read_buffering = value; }
222                 }
223
224                 // Methods
225
226                 void CheckBusy ()
227                 {
228                         if (IsBusy)
229                                 throw new NotSupportedException ("WebClient does not support conccurent I/O operations.");
230                 }
231
232                 void SetBusy ()
233                 {
234                         lock (this) {
235                                 CheckBusy ();
236                                 is_busy = true;
237                         }
238                 }
239
240 //              //   DownloadData
241 //
242 //              public byte [] DownloadData (string address)
243 //              {
244 //#if NET_2_0
245 //                      if (address == null)
246 //                              throw new ArgumentNullException ("address");
247 //#endif
248 //
249 //                      return DownloadData (CreateUri (address));
250 //              }
251 //
252 //#if NET_2_0
253 //              public
254 //#endif
255 //              byte [] DownloadData (Uri address)
256 //              {
257 //#if NET_2_0
258 //                      if (address == null)
259 //                              throw new ArgumentNullException ("address");
260 //#endif
261 //
262 //                      try {
263 //                              SetBusy ();
264 //                              async = false;
265 //                              return DownloadDataCore (address, null);
266 //                      } finally {
267 //                              is_busy = false;
268 //                      }
269 //              }
270 //
271                 Stream DownloadDataCore (Uri address, object userToken)
272                 {
273                         WebRequest request = null;
274
275                         try {
276                                 request = SetupRequest (address, "GET");
277                                 //WebResponse response = request.GetResponse ();
278                                 IAsyncResult asyncresult = request.BeginGetResponse (null, userToken);
279                                 asyncresult.AsyncWaitHandle.WaitOne ();
280                                 WebResponse response = request.EndGetResponse (asyncresult);
281                                 Stream st = ProcessResponse (response);
282                                 return ReadAll (st, (int) st.Length, userToken);
283                         } catch (ThreadInterruptedException){
284                                 if (request != null)
285                                         request.Abort ();
286                                 throw;
287                         } catch (Exception ex) {
288                                 throw new WebException ("An error occurred " +
289                                         "performing a WebClient request.", ex);
290                         }
291                 }
292
293 //              //   DownloadFile
294 //
295 //              public void DownloadFile (string address, string fileName)
296 //              {
297 //#if NET_2_0
298 //                      if (address == null)
299 //                              throw new ArgumentNullException ("address");
300 //#endif
301 //
302 //                      DownloadFile (CreateUri (address), fileName);
303 //              }
304 //
305 //#if NET_2_0
306 //              public
307 //#endif
308 //              void DownloadFile (Uri address, string fileName)
309 //              {
310 //#if NET_2_0
311 //                      if (address == null)
312 //                              throw new ArgumentNullException ("address");
313 //                      if (fileName == null)
314 //                              throw new ArgumentNullException ("fileName");
315 //#endif
316 //
317 //                      try {
318 //                              SetBusy ();
319 //                              async = false;
320 //                              DownloadFileCore (address, fileName, null);
321 //                      } catch (Exception ex) {
322 //                              throw new WebException ("An error occurred " +
323 //                                      "performing a WebClient request.", ex);
324 //                      } finally {
325 //                              is_busy = false;
326 //                      }
327 //              }
328 //
329 //              void DownloadFileCore (Uri address, string fileName, object userToken)
330 //              {
331 //                      WebRequest request = null;
332 //                      
333 //                      using (FileStream f = new FileStream (fileName, FileMode.Create)) {
334 //                              try {
335 //                                      request = SetupRequest (address);
336 //                                      WebResponse response = request.GetResponse ();
337 //                                      Stream st = ProcessResponse (response);
338 //                                      
339 //                                      int cLength = (int) response.ContentLength;
340 //                                      int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
341 //                                      byte [] buffer = new byte [length];
342 //                                      
343 //                                      int nread = 0;
344 //#if NET_2_0
345 //                                      long notify_total = 0;
346 //#endif                                        
347 //                                      while ((nread = st.Read (buffer, 0, length)) != 0){
348 //#if NET_2_0
349 //                                              if (async){
350 //                                                      notify_total += nread;
351 //                                                      OnDownloadProgressChanged (
352 //                                                              new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken));
353 //                                                                                                    
354 //                                              }
355 //#endif
356 //                                              f.Write (buffer, 0, nread);
357 //                                      }
358 //                              } catch (ThreadInterruptedException){
359 //                                      if (request != null)
360 //                                              request.Abort ();
361 //                                      throw;
362 //                              }
363 //                      }
364 //              }
365 //
366 //              //   OpenRead
367 //
368 //              public Stream OpenRead (string address)
369 //              {
370 //#if NET_2_0
371 //                      if (address == null)
372 //                              throw new ArgumentNullException ("address");
373 //#endif
374 //
375 //                      return OpenRead (CreateUri (address));
376 //              }
377 //
378 //#if NET_2_0
379 //              public
380 //#endif
381 //              Stream OpenRead (Uri address)
382 //              {
383 //#if NET_2_0
384 //                      if (address == null)
385 //                              throw new ArgumentNullException ("address");
386 //#endif
387 //
388 //                      WebRequest request = null;
389 //                      try {
390 //                              SetBusy ();
391 //                              async = false;
392 //                              request = SetupRequest (address);
393 //                              WebResponse response = request.GetResponse ();
394 //                              return ProcessResponse (response);
395 //                      } catch (Exception ex) {
396 //                              throw new WebException ("An error occurred " +
397 //                                      "performing a WebClient request.", ex);
398 //                      } finally {
399 //                              is_busy = false;
400 //                      }
401 //              }
402 //
403 //              //   OpenWrite
404 //
405 //              public Stream OpenWrite (string address)
406 //              {
407 //#if NET_2_0
408 //                      if (address == null)
409 //                              throw new ArgumentNullException ("address");
410 //#endif
411 //
412 //                      return OpenWrite (CreateUri (address));
413 //              }
414 //              
415 //              public Stream OpenWrite (string address, string method)
416 //              {
417 //#if NET_2_0
418 //                      if (address == null)
419 //                              throw new ArgumentNullException ("address");
420 //#endif
421 //
422 //                      return OpenWrite (CreateUri (address), method);
423 //              }
424 //
425 //#if NET_2_0
426 //              public
427 //#endif
428 //              Stream OpenWrite (Uri address)
429 //              {
430 //                      return OpenWrite (address, (string) null);
431 //              }
432 //
433 //#if NET_2_0
434 //              public
435 //#endif
436 //              Stream OpenWrite (Uri address, string method)
437 //              {
438 //#if NET_2_0
439 //                      if (address == null)
440 //                              throw new ArgumentNullException ("address");
441 //#endif
442 //
443 //                      try {
444 //                              SetBusy ();
445 //                              async = false;
446 //                              WebRequest request = SetupRequest (address, method);
447 //                              return request.GetRequestStream ();
448 //                      } catch (Exception ex) {
449 //                              throw new WebException ("An error occurred " +
450 //                                      "performing a WebClient request.", ex);
451 //                      } finally {
452 //                              is_busy = false;
453 //                      }
454 //              }
455 //
456                 private string DetermineMethod (Uri address, string method)
457                 {
458                         if (method != null)
459                                 return method;
460
461                         if (address.Scheme == Uri.UriSchemeFtp)
462                                 return "RETR";
463                         return "POST";
464                 }
465
466 //              //   UploadData
467 //
468 //              public byte [] UploadData (string address, byte [] data)
469 //              {
470 //#if NET_2_0
471 //                      if (address == null)
472 //                              throw new ArgumentNullException ("address");
473 //#endif
474 //
475 //                      return UploadData (CreateUri (address), data);
476 //              }
477 //              
478 //              public byte [] UploadData (string address, string method, byte [] data)
479 //              {
480 //#if NET_2_0
481 //                      if (address == null)
482 //                              throw new ArgumentNullException ("address");
483 //#endif
484 //
485 //                      return UploadData (CreateUri (address), method, data);
486 //              }
487 //
488 //#if NET_2_0
489 //              public
490 //#endif
491 //              byte [] UploadData (Uri address, byte [] data)
492 //              {
493 //                      return UploadData (address, (string) null, data);
494 //              }
495 //
496 //#if NET_2_0
497 //              public
498 //#endif
499 //              byte [] UploadData (Uri address, string method, byte [] data)
500 //              {
501 //#if NET_2_0
502 //                      if (address == null)
503 //                              throw new ArgumentNullException ("address");
504 //                      if (data == null)
505 //                              throw new ArgumentNullException ("data");
506 //#endif
507 //
508 //                      try {
509 //                              SetBusy ();
510 //                              async = false;
511 //                              return UploadDataCore (address, method, data, null);
512 //                      } catch (Exception ex) {
513 //                              throw new WebException ("An error occurred " +
514 //                                      "performing a WebClient request.", ex);
515 //                      } finally {
516 //                              is_busy = false;
517 //                      }
518 //              }
519 //
520 //              byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
521 //              {
522 //#if ONLY_1_1
523 //                      if (address == null)
524 //                              throw new ArgumentNullException ("address");
525 //                      if (data == null)
526 //                              throw new ArgumentNullException ("data");
527 //#endif
528 //
529 //                      WebRequest request = SetupRequest (address, method);
530 //                      try {
531 //                              int contentLength = data.Length;
532 //                              request.ContentLength = contentLength;
533 //                              using (Stream stream = request.GetRequestStream ()) {
534 //                                      stream.Write (data, 0, contentLength);
535 //                              }
536 //                              
537 //                              WebResponse response = request.GetResponse ();
538 //                              Stream st = ProcessResponse (response);
539 //                              return ReadAll (st, (int) response.ContentLength, userToken);
540 //                      } catch (ThreadInterruptedException){
541 //                              if (request != null)
542 //                                      request.Abort ();
543 //                              throw;
544 //                      }
545 //              }
546 //
547 //              //   UploadFile
548 //
549 //              public byte [] UploadFile (string address, string fileName)
550 //              {
551 //#if NET_2_0
552 //                      if (address == null)
553 //                              throw new ArgumentNullException ("address");
554 //#endif
555 //
556 //                      return UploadFile (CreateUri (address), fileName);
557 //              }
558 //
559 //#if NET_2_0
560 //              public
561 //#endif
562 //              byte [] UploadFile (Uri address, string fileName)
563 //              {
564 //                      return UploadFile (address, (string) null, fileName);
565 //              }
566 //              
567 //              public byte [] UploadFile (string address, string method, string fileName)
568 //              {
569 //                      return UploadFile (CreateUri (address), method, fileName);
570 //              }
571 //
572 //#if NET_2_0
573 //              public
574 //#endif
575 //              byte [] UploadFile (Uri address, string method, string fileName)
576 //              {
577 //#if NET_2_0
578 //                      if (address == null)
579 //                              throw new ArgumentNullException ("address");
580 //                      if (fileName == null)
581 //                              throw new ArgumentNullException ("fileName");
582 //#endif
583 //
584 //                      try {
585 //                              SetBusy ();
586 //                              async = false;
587 //                              return UploadFileCore (address, method, fileName, null);
588 //                      } catch (Exception ex) {
589 //                              throw new WebException ("An error occurred " +
590 //                                      "performing a WebClient request.", ex);
591 //                      } finally {
592 //                              is_busy = false;
593 //                      }
594 //              }
595 //
596 //              byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
597 //              {
598 //#if ONLY_1_1
599 //                      if (address == null)
600 //                              throw new ArgumentNullException ("address");
601 //#endif
602 //
603 //                      string fileCType = Headers ["Content-Type"];
604 //                      if (fileCType != null) {
605 //                              string lower = fileCType.ToLower ();
606 //                              if (lower.StartsWith ("multipart/"))
607 //                                      throw new WebException ("Content-Type cannot be set to a multipart" +
608 //                                                              " type for this request.");
609 //                      } else {
610 //                              fileCType = "application/octet-stream";
611 //                      }
612 //
613 //                      string boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
614 //                      Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
615 //                      Stream reqStream = null;
616 //                      Stream fStream = null;
617 //                      byte [] resultBytes = null;
618 //
619 //                      fileName = Path.GetFullPath (fileName);
620 //
621 //                      WebRequest request = null;
622 //                      try {
623 //                              fStream = File.OpenRead (fileName);
624 //                              request = SetupRequest (address, method);
625 //                              reqStream = request.GetRequestStream ();
626 //                              byte [] realBoundary = Encoding.ASCII.GetBytes ("--" + boundary + "\r\n");
627 //                              reqStream.Write (realBoundary, 0, realBoundary.Length);
628 //                              string partHeaders = String.Format ("Content-Disposition: form-data; " +
629 //                                                                  "name=\"file\"; filename=\"{0}\"\r\n" +
630 //                                                                  "Content-Type: {1}\r\n\r\n",
631 //                                                                  Path.GetFileName (fileName), fileCType);
632 //
633 //                              byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
634 //                              reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
635 //                              int nread;
636 //                              byte [] buffer = new byte [4096];
637 //                              while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
638 //                                      reqStream.Write (buffer, 0, nread);
639 //
640 //                              reqStream.WriteByte ((byte) '\r');
641 //                              reqStream.WriteByte ((byte) '\n');
642 //                              reqStream.Write (realBoundary, 0, realBoundary.Length);
643 //                              reqStream.Close ();
644 //                              reqStream = null;
645 //                              WebResponse response = request.GetResponse ();
646 //                              Stream st = ProcessResponse (response);
647 //                              resultBytes = ReadAll (st, (int) response.ContentLength, userToken);
648 //                      } catch (ThreadInterruptedException){
649 //                              if (request != null)
650 //                                      request.Abort ();
651 //                              throw;
652 //                      } finally {
653 //                              if (fStream != null)
654 //                                      fStream.Close ();
655 //
656 //                              if (reqStream != null)
657 //                                      reqStream.Close ();
658 //                      }
659 //                      
660 //                      return resultBytes;
661 //              }
662 //              
663 //              public byte[] UploadValues (string address, NameValueCollection data)
664 //              {
665 //#if NET_2_0
666 //                      if (address == null)
667 //                              throw new ArgumentNullException ("address");
668 //#endif
669 //
670 //                      return UploadValues (CreateUri (address), data);
671 //              }
672 //              
673 //              public byte[] UploadValues (string address, string method, NameValueCollection data)
674 //              {
675 //#if NET_2_0
676 //                      if (address == null)
677 //                              throw new ArgumentNullException ("address");
678 //#endif
679 //
680 //                      return UploadValues (CreateUri (address), method, data);
681 //              }
682 //
683 //#if NET_2_0
684 //              public
685 //#endif
686 //              byte[] UploadValues (Uri address, NameValueCollection data)
687 //              {
688 //                      return UploadValues (address, (string) null, data);
689 //              }
690 //
691 //#if NET_2_0
692 //              public
693 //#endif
694 //              byte[] UploadValues (Uri address, string method, NameValueCollection data)
695 //              {
696 //#if NET_2_0
697 //                      if (address == null)
698 //                              throw new ArgumentNullException ("address");
699 //                      if (data == null)
700 //                              throw new ArgumentNullException ("data");
701 //#endif
702 //
703 //                      try {
704 //                              SetBusy ();
705 //                              async = false;
706 //                              return UploadValuesCore (address, method, data, null);
707 //                      } catch (Exception ex) {
708 //                              throw new WebException ("An error occurred " +
709 //                                      "performing a WebClient request.", ex);
710 //                      } finally {
711 //                              is_busy = false;
712 //                      }
713 //              }
714 //
715 //              byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
716 //              {
717 //#if ONLY_1_1
718 //                      if (data == null)
719 //                              throw new ArgumentNullException ("data");
720 //#endif
721 //
722 //                      string cType = Headers ["Content-Type"];
723 //                      if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
724 //                              throw new WebException ("Content-Type header cannot be changed from its default " +
725 //                                                      "value for this request.");
726 //
727 //                      Headers ["Content-Type"] = urlEncodedCType;
728 //                      WebRequest request = SetupRequest (uri, method);
729 //                      try {
730 //                              Stream rqStream = request.GetRequestStream ();
731 //                              MemoryStream tmpStream = new MemoryStream ();
732 //                              foreach (string key in data) {
733 //                                      byte [] bytes = Encoding.ASCII.GetBytes (key);
734 //                                      UrlEncodeAndWrite (tmpStream, bytes);
735 //                                      tmpStream.WriteByte ((byte) '=');
736 //                                      bytes = Encoding.ASCII.GetBytes (data [key]);
737 //                                      UrlEncodeAndWrite (tmpStream, bytes);
738 //                                      tmpStream.WriteByte ((byte) '&');
739 //                              }
740 //                              
741 //                              int length = (int) tmpStream.Length;
742 //                              if (length > 0)
743 //                                      tmpStream.SetLength (--length); // remove trailing '&'
744 //                              
745 //                              byte [] buf = tmpStream.GetBuffer ();
746 //                              rqStream.Write (buf, 0, length);
747 //                              rqStream.Close ();
748 //                              tmpStream.Close ();
749 //                              
750 //                              WebResponse response = request.GetResponse ();
751 //                              Stream st = ProcessResponse (response);
752 //                              return ReadAll (st, (int) response.ContentLength, userToken);
753 //                      } catch (ThreadInterruptedException) {
754 //                              request.Abort ();
755 //                              throw;
756 //                      }
757 //              }
758 //
759 //#if NET_2_0
760 //              public string DownloadString (string address)
761 //              {
762 //                      return encoding.GetString (DownloadData (address));
763 //              }
764 //
765 //              public string DownloadString (Uri address)
766 //              {
767 //                      return encoding.GetString (DownloadData (address));
768 //              }
769 //
770 //              public string UploadString (string address, string data)
771 //              {
772 //                      if (address == null)
773 //                              throw new ArgumentNullException ("address");
774 //                      if (data == null)
775 //                              throw new ArgumentNullException ("data");
776 //
777 //                      byte [] resp = UploadData (address, encoding.GetBytes (data));
778 //                      return encoding.GetString (resp);
779 //              }
780 //
781 //              public string UploadString (string address, string method, string data)
782 //              {
783 //                      if (address == null)
784 //                              throw new ArgumentNullException ("address");
785 //                      if (data == null)
786 //                              throw new ArgumentNullException ("data");
787 //
788 //                      byte [] resp = UploadData (address, method, encoding.GetBytes (data));
789 //                      return encoding.GetString (resp);
790 //              }
791 //
792 //              public string UploadString (Uri address, string data)
793 //              {
794 //                      if (address == null)
795 //                              throw new ArgumentNullException ("address");
796 //                      if (data == null)
797 //                              throw new ArgumentNullException ("data");
798 //
799 //                      byte [] resp = UploadData (address, encoding.GetBytes (data));
800 //                      return encoding.GetString (resp);
801 //              }
802 //
803 //              public string UploadString (Uri address, string method, string data)
804 //              {
805 //                      if (address == null)
806 //                              throw new ArgumentNullException ("address");
807 //                      if (data == null)
808 //                              throw new ArgumentNullException ("data");
809 //
810 //                      byte [] resp = UploadData (address, method, encoding.GetBytes (data));
811 //                      return encoding.GetString (resp);
812 //              }
813 //
814 //              public event DownloadDataCompletedEventHandler DownloadDataCompleted;
815 //              public event AsyncCompletedEventHandler DownloadFileCompleted;
816                 public event DownloadProgressChangedEventHandler DownloadProgressChanged;
817                 public event DownloadStringCompletedEventHandler DownloadStringCompleted;
818                 public event OpenReadCompletedEventHandler OpenReadCompleted;
819                 public event OpenWriteCompletedEventHandler OpenWriteCompleted;
820 //              public event UploadDataCompletedEventHandler UploadDataCompleted;
821 //              public event UploadFileCompletedEventHandler UploadFileCompleted;
822                 public event UploadProgressChangedEventHandler UploadProgressChanged;
823                 public event UploadStringCompletedEventHandler UploadStringCompleted;
824 //              public event UploadValuesCompletedEventHandler UploadValuesCompleted;
825                 public event WriteStreamClosedEventHandler WriteStreamClosed;
826 //#endif
827 //
828 //              Uri CreateUri (string address)
829 //              {
830 //#if ONLY_1_1
831 //                      try {
832 //                              return MakeUri (address);
833 //                      } catch (Exception ex) {
834 //                              throw new WebException ("An error occurred " +
835 //                                      "performing a WebClient request.", ex);
836 //                      }
837 //#else
838 //                      return MakeUri (address);
839 //#endif
840 //              }
841 //
842 //              Uri MakeUri (string path)
843 //              {
844 //                      string query = null;
845 //                      if (queryString != null && queryString.Count != 0) {
846 //                              // This is not the same as UploadValues, because these 'keys' are not
847 //                              // urlencoded here.
848 //                              StringBuilder sb = new StringBuilder ();
849 //                              sb.Append ('?');
850 //                              foreach (string key in queryString)
851 //                                      sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
852 //
853 //                              if (sb.Length != 0) {
854 //                                      sb.Length--; // remove trailing '&'
855 //                                      query = sb.ToString ();
856 //                              }
857 //                      }
858 //
859 //                      if (baseAddress == null && query == null) {
860 //                              try {
861 //                                      return new Uri (path);
862 //#if NET_2_0
863 //                              } catch (ArgumentNullException) {
864 //                                      path = Path.GetFullPath (path);
865 //                                      return new Uri ("file://" + path);
866 //#endif
867 //                              } catch (UriFormatException) {
868 //                                      path = Path.GetFullPath (path);
869 //                                      return new Uri ("file://" + path);
870 //                              }
871 //                      }
872 //
873 //                      if (baseAddress == null)
874 //                              return new Uri (path + query, (query != null));
875 //
876 //                      if (query == null)
877 //                              return new Uri (baseAddress, path);
878 //
879 //                      return new Uri (baseAddress, path + query, (query != null));
880 //              }
881 //              
882 //              WebRequest SetupRequest (Uri uri)
883 //              {
884 //                      WebRequest request = WebRequest.CreateInternal (baseAddress != null ? new Uri (baseAddress, uri) : uri, true);
885 //                      if (Proxy != null)
886 //                              request.Proxy = Proxy;
887 //                      request.Credentials = credentials;
888
889                         // Special headers. These are properties of HttpWebRequest.
890                         // What do we do with other requests differnt from HttpWebRequest?
891 //                      if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
892 //                              HttpWebRequest req = (HttpWebRequest) request;
893 //                              string expect = headers ["Expect"];
894 //                              string contentType = headers ["Content-Type"];
895 //                              string accept = headers ["Accept"];
896 //                              string connection = headers ["Connection"];
897 //                              string userAgent = headers ["User-Agent"];
898 //                              string referer = headers ["Referer"];
899 //                              headers.RemoveInternal ("Expect");
900 //                              headers.RemoveInternal ("Content-Type");
901 //                              headers.RemoveInternal ("Accept");
902 //                              headers.RemoveInternal ("Connection");
903 //                              headers.RemoveInternal ("Referer");
904 //                              headers.RemoveInternal ("User-Agent");
905 //                              request.Headers = headers;
906 //
907 //                              if (expect != null && expect.Length > 0)
908 //                                      req.Expect = expect;
909 //
910 //                              if (accept != null && accept.Length > 0)
911 //                                      req.Accept = accept;
912 //
913 //                              if (contentType != null && contentType.Length > 0)
914 //                                      req.ContentType = contentType;
915 //
916 //                              if (connection != null && connection.Length > 0)
917 //                                      req.Connection = connection;
918 //
919 //                              if (userAgent != null && userAgent.Length > 0)
920 //                                      req.UserAgent = userAgent;
921 //
922 //                              if (referer != null && referer.Length > 0)
923 //                                      req.Referer = referer;
924 //                      }
925 //
926 //                      responseHeaders = null;
927 //                      return request;
928 //              }
929
930                 WebRequest SetupRequest (Uri uri, string method)
931                 {
932                         WebRequest request = GetWebRequest (uri);
933                         request.Method = DetermineMethod (uri, method);
934                         return request;
935                 }
936
937                 Stream ProcessResponse (WebResponse response)
938                 {
939 //                      responseHeaders = response.Headers;
940                         return response.GetResponseStream ();
941                 }
942
943                 Stream ReadAll (Stream stream, int length, object userToken)
944                 {
945                         MemoryStream ms = null;
946
947                         bool nolength = (length == -1);
948                         int size = ((nolength) ? 8192 : length);
949                         ms = new MemoryStream (size);
950
951                         int nread;
952                         byte [] buffer = new byte [size];
953                         while ((nread = stream.Read (buffer, 0, buffer.Length)) != 0) {
954                                 ms.Write (buffer, 0, nread);
955                                 if (async){
956                                         OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (nread, length, userToken));
957                                 }
958                                 if (!nolength && ms.Length == length) {
959                                         break;
960                                 }
961                         }
962
963                         ms.Position = 0;
964                         return ms;
965                 }
966
967 //              string UrlEncode (string str)
968 //              {
969 //                      StringBuilder result = new StringBuilder ();
970 //
971 //                      int len = str.Length;
972 //                      for (int i = 0; i < len; i++) {
973 //                              char c = str [i];
974 //                              if (c == ' ')
975 //                                      result.Append ('+');
976 //                              else if ((c < '0' && c != '-' && c != '.') ||
977 //                                       (c < 'A' && c > '9') ||
978 //                                       (c > 'Z' && c < 'a' && c != '_') ||
979 //                                       (c > 'z')) {
980 //                                      result.Append ('%');
981 //                                      int idx = ((int) c) >> 4;
982 //                                      result.Append ((char) hexBytes [idx]);
983 //                                      idx = ((int) c) & 0x0F;
984 //                                      result.Append ((char) hexBytes [idx]);
985 //                              } else {
986 //                                      result.Append (c);
987 //                              }
988 //                      }
989 //
990 //                      return result.ToString ();
991 //              }
992 //
993 //              static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
994 //              {
995 //                      if (bytes == null)
996 //                              return;
997 //
998 //                      int len = bytes.Length;
999 //                      if (len == 0)
1000 //                              return;
1001 //
1002 //                      for (int i = 0; i < len; i++) {
1003 //                              char c = (char) bytes [i];
1004 //                              if (c == ' ')
1005 //                                      stream.WriteByte ((byte) '+');
1006 //                              else if ((c < '0' && c != '-' && c != '.') ||
1007 //                                       (c < 'A' && c > '9') ||
1008 //                                       (c > 'Z' && c < 'a' && c != '_') ||
1009 //                                       (c > 'z')) {
1010 //                                      stream.WriteByte ((byte) '%');
1011 //                                      int idx = ((int) c) >> 4;
1012 //                                      stream.WriteByte (hexBytes [idx]);
1013 //                                      idx = ((int) c) & 0x0F;
1014 //                                      stream.WriteByte (hexBytes [idx]);
1015 //                              } else {
1016 //                                      stream.WriteByte ((byte) c);
1017 //                              }
1018 //                      }
1019 //              }
1020 //
1021 //#if NET_2_0
1022                 [SecuritySafeCritical]
1023                 public void CancelAsync ()
1024                 {
1025                         lock (this){
1026                                 if (async_thread == null)
1027                                         return;
1028
1029                                 //
1030                                 // We first flag things as done, in case the Interrupt hangs
1031                                 // or the thread decides to hang in some other way inside the
1032                                 // event handlers, or if we are stuck somewhere else.  This
1033                                 // ensures that the WebClient object is reusable immediately
1034                                 //
1035                                 Thread t = async_thread;
1036                                 CompleteAsync ();
1037                                 t.Interrupt ();
1038                         }
1039                 }
1040
1041                 void CompleteAsync ()
1042                 {
1043                         lock (this){
1044                                 is_busy = false;
1045                                 async_thread = null;
1046                         }
1047                 }
1048
1049 //              //    DownloadDataAsync
1050 //
1051 //              public void DownloadDataAsync (Uri address)
1052 //              {
1053 //                      DownloadDataAsync (address, null);
1054 //              }
1055 //
1056 //              public void DownloadDataAsync (Uri address, object userToken)
1057 //              {
1058 //                      if (address == null)
1059 //                              throw new ArgumentNullException ("address");
1060 //                      
1061 //                      lock (this) {
1062 //                              SetBusy ();
1063 //                              async = true;
1064 //                              
1065 //                              async_thread = new Thread (delegate (object state) {
1066 //                                      object [] args = (object []) state;
1067 //                                      try {
1068 //                                              byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
1069 //                                              OnDownloadDataCompleted (
1070 //                                                      new DownloadDataCompletedEventArgs (data, null, false, args [1]));
1071 //                                      } catch (ThreadInterruptedException){
1072 //                                              OnDownloadDataCompleted (
1073 //                                                      new DownloadDataCompletedEventArgs (null, null, true, args [1]));
1074 //                                              throw;
1075 //                                      } catch (Exception e){
1076 //                                              OnDownloadDataCompleted (
1077 //                                                      new DownloadDataCompletedEventArgs (null, e, false, args [1]));
1078 //                                      }
1079 //                              });
1080 //                              object [] cb_args = new object [] {address, userToken};
1081 //                              async_thread.Start (cb_args);
1082 //                      }
1083 //              }
1084 //
1085 //              //    DownloadFileAsync
1086 //
1087 //              public void DownloadFileAsync (Uri address, string fileName)
1088 //              {
1089 //                      DownloadFileAsync (address, fileName, null);
1090 //              }
1091 //
1092 //              public void DownloadFileAsync (Uri address, string fileName, object userToken)
1093 //              {
1094 //                      if (address == null)
1095 //                              throw new ArgumentNullException ("address");
1096 //                      if (fileName == null)
1097 //                              throw new ArgumentNullException ("fileName");
1098 //                      
1099 //                      lock (this) {
1100 //                              SetBusy ();
1101 //                              async = true;
1102 //
1103 //                              async_thread = new Thread (delegate (object state) {
1104 //                                      object [] args = (object []) state;
1105 //                                      try {
1106 //                                              DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
1107 //                                              OnDownloadFileCompleted (
1108 //                                                      new AsyncCompletedEventArgs (null, false, args [2]));
1109 //                                      } catch (ThreadInterruptedException){
1110 //                                              OnDownloadFileCompleted (
1111 //                                                      new AsyncCompletedEventArgs (null, true, args [2]));
1112 //                                      } catch (Exception e){
1113 //                                              OnDownloadFileCompleted (
1114 //                                                      new AsyncCompletedEventArgs (e, false, args [2]));
1115 //                                      }});
1116 //                              object [] cb_args = new object [] {address, fileName, userToken};
1117 //                              async_thread.Start (cb_args);
1118 //                      }
1119 //              }
1120 //
1121 //              //    DownloadStringAsync
1122 //
1123                 public void DownloadStringAsync (Uri address)
1124                 {
1125                         DownloadStringAsync (address, null);
1126                 }
1127
1128                 public void DownloadStringAsync (Uri address, object userToken)
1129                 {
1130                         if (address == null)
1131                                 throw new ArgumentNullException ("address");
1132
1133                         lock (this) {
1134                                 SetBusy ();
1135                                 async = true;
1136
1137                                 async_thread = new Thread (delegate (object state) {
1138                                         object [] args = (object []) state;
1139                                         try {
1140                                                 Stream bdata = DownloadDataCore ((Uri) args [0], args [1]);
1141                                                 string data;
1142                                                 using (StreamReader stream = new StreamReader (bdata, encoding, true))
1143                                                         data = stream.ReadToEnd ();
1144
1145                                                 OnDownloadStringCompleted (
1146                                                         new DownloadStringCompletedEventArgs (data, null, false, args [1]));
1147                                         } catch (ThreadInterruptedException){
1148                                                 OnDownloadStringCompleted (
1149                                                         new DownloadStringCompletedEventArgs (null, null, true, args [1]));
1150                                         } catch (Exception e){
1151                                                 OnDownloadStringCompleted (
1152                                                         new DownloadStringCompletedEventArgs (null, e, false, args [1]));
1153                                         }});
1154                                 object [] cb_args = new object [] {address, userToken};
1155                                 async_thread.Start (cb_args);
1156                         }
1157                 }
1158
1159                 //    OpenReadAsync
1160
1161                 public void OpenReadAsync (Uri address)
1162                 {
1163                         OpenReadAsync (address, null);
1164                 }
1165
1166                 public void OpenReadAsync (Uri address, object userToken)
1167                 {
1168                         if (address == null)
1169                                 throw new ArgumentNullException ("address");
1170
1171                         lock (this) {
1172                                 SetBusy ();
1173                                 async = true;
1174
1175                                 async_thread = new Thread (delegate (object state) {
1176                                         object [] args = (object []) state;
1177                                         WebRequest request = null;
1178                                         try {
1179                                                 request = SetupRequest ((Uri) args [0], "GET");
1180                                                 //WebResponse response = request.GetResponse ();
1181                                                 IAsyncResult asyncresult = request.BeginGetResponse (null, userToken);
1182                                                 asyncresult.AsyncWaitHandle.WaitOne ();
1183                                                 WebResponse response = request.EndGetResponse (asyncresult);
1184                                                 Stream stream = ProcessResponse (response);
1185                                                 OnOpenReadCompleted (
1186                                                         new OpenReadCompletedEventArgs (stream, address, null, false, args [1]));
1187                                         } catch (ThreadInterruptedException){
1188                                                 if (request != null)
1189                                                         request.Abort ();
1190
1191                                                 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, null, true, args [1]));
1192                                         } catch (Exception e){
1193                                                 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, e, false, args [1]));
1194                                         } });
1195                                 object [] cb_args = new object [] {address, userToken};
1196                                 async_thread.Start (cb_args);
1197                         }
1198                 }
1199
1200 //              //    OpenWriteAsync
1201 //
1202                 public void OpenWriteAsync (Uri address)
1203                 {
1204                         OpenWriteAsync (address, null);
1205                 }
1206
1207                 public void OpenWriteAsync (Uri address, string method)
1208                 {
1209                         OpenWriteAsync (address, method, null);
1210                 }
1211
1212                 public void OpenWriteAsync (Uri address, string method, object userToken)
1213                 {
1214                         if (address == null)
1215                                 throw new ArgumentNullException ("address");
1216
1217                         throw new NotImplementedException ();
1218 //
1219 //                      lock (this) {
1220 //                              SetBusy ();
1221 //                              async = true;
1222 //
1223 //                              async_thread = new Thread (delegate (object state) {
1224 //                                      object [] args = (object []) state;
1225 //                                      WebRequest request = null;
1226 //                                      try {
1227 //                                              request = SetupRequest ((Uri) args [0], (string) args [1]);
1228 //                                              Stream stream = request.GetRequestStream ();
1229 //                                              OnOpenWriteCompleted (
1230 //                                                      new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
1231 //                                      } catch (ThreadInterruptedException){
1232 //                                              if (request != null)
1233 //                                                      request.Abort ();
1234 //                                              OnOpenWriteCompleted (
1235 //                                                      new OpenWriteCompletedEventArgs (null, null, true, args [2]));
1236 //                                      } catch (Exception e){
1237 //                                              OnOpenWriteCompleted (
1238 //                                                      new OpenWriteCompletedEventArgs (null, e, false, args [2]));
1239 //                                      }});
1240 //                              object [] cb_args = new object [] {address, method, userToken};
1241 //                              async_thread.Start (cb_args);
1242 //                      }
1243                 }
1244 //
1245 //              //    UploadDataAsync
1246 //
1247 //              public void UploadDataAsync (Uri address, byte [] data)
1248 //              {
1249 //                      UploadDataAsync (address, null, data);
1250 //              }
1251 //
1252 //              public void UploadDataAsync (Uri address, string method, byte [] data)
1253 //              {
1254 //                      UploadDataAsync (address, method, data, null);
1255 //              }
1256 //
1257 //              public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
1258 //              {
1259 //                      if (address == null)
1260 //                              throw new ArgumentNullException ("address");
1261 //                      if (data == null)
1262 //                              throw new ArgumentNullException ("data");
1263 //                      
1264 //                      lock (this) {
1265 //                              SetBusy ();
1266 //                              async = true;
1267 //
1268 //                              async_thread = new Thread (delegate (object state) {
1269 //                                      object [] args = (object []) state;
1270 //                                      byte [] data2;
1271 //
1272 //                                      try {
1273 //                                              data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
1274 //                                      
1275 //                                              OnUploadDataCompleted (
1276 //                                                      new UploadDataCompletedEventArgs (data2, null, false, args [3]));
1277 //                                      } catch (ThreadInterruptedException){
1278 //                                              OnUploadDataCompleted (
1279 //                                                      new UploadDataCompletedEventArgs (null, null, true, args [3]));
1280 //                                      } catch (Exception e){
1281 //                                              OnUploadDataCompleted (
1282 //                                                      new UploadDataCompletedEventArgs (null, e, false, args [3]));
1283 //                                      }});
1284 //                              object [] cb_args = new object [] {address, method, data,  userToken};
1285 //                              async_thread.Start (cb_args);
1286 //                      }
1287 //              }
1288 //
1289 //              //    UploadFileAsync
1290 //
1291 //              public void UploadFileAsync (Uri address, string fileName)
1292 //              {
1293 //                      UploadFileAsync (address, null, fileName);
1294 //              }
1295 //
1296 //              public void UploadFileAsync (Uri address, string method, string fileName)
1297 //              {
1298 //                      UploadFileAsync (address, method, fileName, null);
1299 //              }
1300 //
1301 //              public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
1302 //              {
1303 //                      if (address == null)
1304 //                              throw new ArgumentNullException ("address");
1305 //                      if (fileName == null)
1306 //                              throw new ArgumentNullException ("fileName");
1307 //
1308 //                      lock (this) {
1309 //                              SetBusy ();
1310 //                              async = true;
1311 //
1312 //                              async_thread = new Thread (delegate (object state) {
1313 //                                      object [] args = (object []) state;
1314 //                                      byte [] data;
1315 //
1316 //                                      try {
1317 //                                              data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
1318 //                                              OnUploadFileCompleted (
1319 //                                                      new UploadFileCompletedEventArgs (data, null, false, args [3]));
1320 //                                      } catch (ThreadInterruptedException){
1321 //                                              OnUploadFileCompleted (
1322 //                                                      new UploadFileCompletedEventArgs (null, null, true, args [3]));
1323 //                                      } catch (Exception e){
1324 //                                              OnUploadFileCompleted (
1325 //                                                      new UploadFileCompletedEventArgs (null, e, false, args [3]));
1326 //                                      }});
1327 //                              object [] cb_args = new object [] {address, method, fileName,  userToken};
1328 //                              async_thread.Start (cb_args);
1329 //                      }
1330 //              }
1331 //
1332 //              //    UploadStringAsync
1333 //
1334                 public void UploadStringAsync (Uri address, string data)
1335                 {
1336                         UploadStringAsync (address, null, data);
1337                 }
1338
1339                 public void UploadStringAsync (Uri address, string method, string data)
1340                 {
1341                         UploadStringAsync (address, method, data, null);
1342                 }
1343
1344                 public void UploadStringAsync (Uri address, string method, string data, object userToken)
1345                 {
1346                         if (address == null)
1347                                 throw new ArgumentNullException ("address");
1348                         if (data == null)
1349                                 throw new ArgumentNullException ("data");
1350
1351                         throw new NotImplementedException ();
1352 //                      lock (this) {
1353 //                              SetBusy ();
1354 //                              async = true;
1355 //                              
1356 //                              async_thread = new Thread (delegate (object state) {
1357 //                                      object [] args = (object []) state;
1358 //
1359 //                                      try {
1360 //                                              string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
1361 //                                              OnUploadStringCompleted (
1362 //                                                      new UploadStringCompletedEventArgs (data2, null, false, args [3]));
1363 //                                      } catch (ThreadInterruptedException){
1364 //                                              OnUploadStringCompleted (
1365 //                                                      new UploadStringCompletedEventArgs (null, null, true, args [3]));
1366 //                                      } catch (Exception e){
1367 //                                              OnUploadStringCompleted (
1368 //                                                      new UploadStringCompletedEventArgs (null, e, false, args [3]));
1369 //                                      }});
1370 //                              object [] cb_args = new object [] {address, method, data, userToken};
1371 //                              async_thread.Start (cb_args);
1372 //                      }
1373                 }
1374 //
1375 //              //    UploadValuesAsync
1376 //
1377 //              public void UploadValuesAsync (Uri address, NameValueCollection values)
1378 //              {
1379 //                      UploadValuesAsync (address, null, values);
1380 //              }
1381 //
1382 //              public void UploadValuesAsync (Uri address, string method, NameValueCollection values)
1383 //              {
1384 //                      UploadValuesAsync (address, method, values, null);
1385 //              }
1386 //
1387 //              public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken)
1388 //              {
1389 //                      if (address == null)
1390 //                              throw new ArgumentNullException ("address");
1391 //                      if (values == null)
1392 //                              throw new ArgumentNullException ("values");
1393 //
1394 //                      lock (this) {
1395 //                              CheckBusy ();
1396 //                              async = true;
1397 //
1398 //                              async_thread = new Thread (delegate (object state) {
1399 //                                      object [] args = (object []) state;
1400 //                                      try {
1401 //                                              byte [] data = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
1402 //                                              OnUploadValuesCompleted (
1403 //                                                      new UploadValuesCompletedEventArgs (data, null, false, args [3]));
1404 //                                      } catch (ThreadInterruptedException){
1405 //                                              OnUploadValuesCompleted (
1406 //                                                      new UploadValuesCompletedEventArgs (null, null, true, args [3]));
1407 //                                      } catch (Exception e){
1408 //                                              OnUploadValuesCompleted (
1409 //                                                      new UploadValuesCompletedEventArgs (null, e, false, args [3]));
1410 //                                      }});
1411 //                              object [] cb_args = new object [] {address, method, values,  userToken};
1412 //                              async_thread.Start (cb_args);
1413 //                      }
1414 //              }
1415 //
1416 //              protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
1417 //              {
1418 //                      CompleteAsync ();
1419 //                      if (DownloadDataCompleted != null)
1420 //                              DownloadDataCompleted (this, args);
1421 //              }
1422 //
1423 //              protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
1424 //              {
1425 //                      CompleteAsync ();
1426 //                      if (DownloadFileCompleted != null)
1427 //                              DownloadFileCompleted (this, args);
1428 //              }
1429 //
1430                 protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
1431                 {
1432                         if (DownloadProgressChanged != null) {
1433                                 DownloadProgressChanged (this, e);
1434                         }
1435                 }
1436                 
1437                 private object callback_args;
1438
1439                 protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
1440                 {
1441                         CompleteAsync ();
1442                         if (OpenReadCompleted != null) {
1443                                 ManualResetEvent wait_event = new ManualResetEvent (false);
1444                                 GSourceFunc callback = (GSourceFunc) delegate (IntPtr ctx)
1445                                 {
1446                                         try {
1447                                                 OpenReadCompleted (this, (OpenReadCompletedEventArgs) callback_args);
1448                                         } catch (Exception ex) {
1449                                                 try {
1450                                                         Console.WriteLine ("Unhandled exception: {0}", ex);
1451                                                 } catch {
1452                                                 }
1453                                         }
1454                                         try {
1455                                                 wait_event.Set ();
1456                                         } catch (Exception ex) {
1457                                                 try {
1458                                                         Console.WriteLine ("Unhandled exception: {0}", ex);
1459                                                 } catch {
1460                                                 }
1461                                         }
1462                                         return false;
1463                                 };
1464                                 callback_args = args;
1465
1466                                 g_timeout_add (0, callback, IntPtr.Zero);
1467
1468                                 wait_event.WaitOne ();
1469                                 GC.KeepAlive (callback);
1470                         }
1471                 }
1472
1473                 public delegate bool GSourceFunc (IntPtr data);
1474
1475                 [DllImport ("moon")]
1476                 static extern uint g_timeout_add (uint delay, GSourceFunc callback, IntPtr data);
1477
1478                 protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
1479                 {
1480                         CompleteAsync ();
1481                         if (DownloadStringCompleted != null) {
1482                                 ManualResetEvent wait_event = new ManualResetEvent (false);
1483                                 GSourceFunc callback = (GSourceFunc) delegate (IntPtr ctx) 
1484                                 {
1485                                         try {
1486                                                 DownloadStringCompleted (this, (DownloadStringCompletedEventArgs) callback_args);
1487                                         } catch (Exception ex) {
1488                                                 try {
1489                                                         Console.WriteLine ("Unhandled exception: {0}", ex);
1490                                                 } catch {
1491                                                 }
1492                                         }
1493                                         try {
1494                                                 wait_event.Set ();
1495                                         } catch (Exception ex) {
1496                                                 try {
1497                                                         Console.WriteLine ("Unhandled exception: {0}", ex);
1498                                                 } catch {
1499                                                 }
1500                                         }
1501                                         return false;
1502                                 };
1503                                 callback_args = args;
1504
1505                                 g_timeout_add (0, callback, IntPtr.Zero);
1506
1507                                 wait_event.WaitOne ();
1508                                 GC.KeepAlive (callback);
1509                         }
1510                 }
1511
1512
1513                 protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
1514                 {
1515                         CompleteAsync ();
1516                         if (OpenWriteCompleted != null)
1517                                 OpenWriteCompleted (this, args);
1518                 }
1519 //
1520 //              protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
1521 //              {
1522 //                      CompleteAsync ();
1523 //                      if (UploadDataCompleted != null)
1524 //                              UploadDataCompleted (this, args);
1525 //              }
1526 //
1527 //              protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
1528 //              {
1529 //                      CompleteAsync ();
1530 //                      if (UploadFileCompleted != null)
1531 //                              UploadFileCompleted (this, args);
1532 //              }
1533 //
1534                 protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
1535                 {
1536                         if (UploadProgressChanged != null)
1537                                 UploadProgressChanged (this, e);
1538                 }
1539
1540                 protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
1541                 {
1542                         CompleteAsync ();
1543                         if (UploadStringCompleted != null)
1544                                 UploadStringCompleted (this, args);
1545                 }
1546 //
1547 //              protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
1548 //              {
1549 //                      CompleteAsync ();
1550 //                      if (UploadValuesCompleted != null)
1551 //                              UploadValuesCompleted (this, args);
1552 //              }
1553 //
1554                 protected virtual void OnWriteStreamClosed (WriteStreamClosedEventArgs e)
1555                 {
1556                         throw new NotImplementedException ();
1557                 }
1558
1559                 protected virtual WebRequest GetWebRequest (Uri address)
1560                 {
1561                         if (address == null)
1562                                 throw new ArgumentNullException ("address");
1563
1564                         // if the URI is relative then we use our base address URI to make an absolute one
1565                         Uri uri = address.IsAbsoluteUri ? address : new Uri (baseAddress, address);
1566
1567                         WebRequest request = WebRequest.Create (uri);
1568
1569                         request.SetupProgressDelegate ((ProgressChangedDelegate) delegate (long read, long length, object state) {
1570                                 OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (read, length, state));
1571                         });
1572                         return request;
1573                 }
1574 //
1575 //              protected virtual WebResponse GetWebResponse (WebRequest request)
1576 //              {
1577 //                      return request.GetResponse ();
1578 //              }
1579 //
1580                 protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
1581                 {
1582                         return request.EndGetResponse (result);
1583                 }
1584 //#endif
1585 #endif
1586         }
1587 }
1588
1589