2009-02-24 Alan McGovern <amcgovern@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                 Stream 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                 Stream 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                         ms = new MemoryStream (size);
937
938                         int nread;
939                         byte [] buffer = new byte [size];
940                         while ((nread = stream.Read (buffer, 0, buffer.Length)) != 0) {
941                                 ms.Write (buffer, 0, nread);
942                                 if (async){
943                                         OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (nread, length, userToken));
944                                 }
945                                 if (!nolength && ms.Length == length) {
946                                         break;
947                                 }
948                         }
949
950                         ms.Position = 0;
951                         return ms;
952                 }
953
954 //              string UrlEncode (string str)
955 //              {
956 //                      StringBuilder result = new StringBuilder ();
957 //
958 //                      int len = str.Length;
959 //                      for (int i = 0; i < len; i++) {
960 //                              char c = str [i];
961 //                              if (c == ' ')
962 //                                      result.Append ('+');
963 //                              else if ((c < '0' && c != '-' && c != '.') ||
964 //                                       (c < 'A' && c > '9') ||
965 //                                       (c > 'Z' && c < 'a' && c != '_') ||
966 //                                       (c > 'z')) {
967 //                                      result.Append ('%');
968 //                                      int idx = ((int) c) >> 4;
969 //                                      result.Append ((char) hexBytes [idx]);
970 //                                      idx = ((int) c) & 0x0F;
971 //                                      result.Append ((char) hexBytes [idx]);
972 //                              } else {
973 //                                      result.Append (c);
974 //                              }
975 //                      }
976 //
977 //                      return result.ToString ();
978 //              }
979 //
980 //              static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
981 //              {
982 //                      if (bytes == null)
983 //                              return;
984 //
985 //                      int len = bytes.Length;
986 //                      if (len == 0)
987 //                              return;
988 //
989 //                      for (int i = 0; i < len; i++) {
990 //                              char c = (char) bytes [i];
991 //                              if (c == ' ')
992 //                                      stream.WriteByte ((byte) '+');
993 //                              else if ((c < '0' && c != '-' && c != '.') ||
994 //                                       (c < 'A' && c > '9') ||
995 //                                       (c > 'Z' && c < 'a' && c != '_') ||
996 //                                       (c > 'z')) {
997 //                                      stream.WriteByte ((byte) '%');
998 //                                      int idx = ((int) c) >> 4;
999 //                                      stream.WriteByte (hexBytes [idx]);
1000 //                                      idx = ((int) c) & 0x0F;
1001 //                                      stream.WriteByte (hexBytes [idx]);
1002 //                              } else {
1003 //                                      stream.WriteByte ((byte) c);
1004 //                              }
1005 //                      }
1006 //              }
1007 //
1008 //#if NET_2_0
1009                 [SecuritySafeCritical]
1010                 public void CancelAsync ()
1011                 {
1012                         lock (this){
1013                                 if (async_thread == null)
1014                                         return;
1015
1016                                 //
1017                                 // We first flag things as done, in case the Interrupt hangs
1018                                 // or the thread decides to hang in some other way inside the
1019                                 // event handlers, or if we are stuck somewhere else.  This
1020                                 // ensures that the WebClient object is reusable immediately
1021                                 //
1022                                 Thread t = async_thread;
1023                                 CompleteAsync ();
1024                                 t.Interrupt ();
1025                         }
1026                 }
1027
1028                 void CompleteAsync ()
1029                 {
1030                         lock (this){
1031                                 is_busy = false;
1032                                 async_thread = null;
1033                         }
1034                 }
1035
1036 //              //    DownloadDataAsync
1037 //
1038 //              public void DownloadDataAsync (Uri address)
1039 //              {
1040 //                      DownloadDataAsync (address, null);
1041 //              }
1042 //
1043 //              public void DownloadDataAsync (Uri address, object userToken)
1044 //              {
1045 //                      if (address == null)
1046 //                              throw new ArgumentNullException ("address");
1047 //                      
1048 //                      lock (this) {
1049 //                              SetBusy ();
1050 //                              async = true;
1051 //                              
1052 //                              async_thread = new Thread (delegate (object state) {
1053 //                                      object [] args = (object []) state;
1054 //                                      try {
1055 //                                              byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
1056 //                                              OnDownloadDataCompleted (
1057 //                                                      new DownloadDataCompletedEventArgs (data, null, false, args [1]));
1058 //                                      } catch (ThreadInterruptedException){
1059 //                                              OnDownloadDataCompleted (
1060 //                                                      new DownloadDataCompletedEventArgs (null, null, true, args [1]));
1061 //                                              throw;
1062 //                                      } catch (Exception e){
1063 //                                              OnDownloadDataCompleted (
1064 //                                                      new DownloadDataCompletedEventArgs (null, e, false, args [1]));
1065 //                                      }
1066 //                              });
1067 //                              object [] cb_args = new object [] {address, userToken};
1068 //                              async_thread.Start (cb_args);
1069 //                      }
1070 //              }
1071 //
1072 //              //    DownloadFileAsync
1073 //
1074 //              public void DownloadFileAsync (Uri address, string fileName)
1075 //              {
1076 //                      DownloadFileAsync (address, fileName, null);
1077 //              }
1078 //
1079 //              public void DownloadFileAsync (Uri address, string fileName, object userToken)
1080 //              {
1081 //                      if (address == null)
1082 //                              throw new ArgumentNullException ("address");
1083 //                      if (fileName == null)
1084 //                              throw new ArgumentNullException ("fileName");
1085 //                      
1086 //                      lock (this) {
1087 //                              SetBusy ();
1088 //                              async = true;
1089 //
1090 //                              async_thread = new Thread (delegate (object state) {
1091 //                                      object [] args = (object []) state;
1092 //                                      try {
1093 //                                              DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
1094 //                                              OnDownloadFileCompleted (
1095 //                                                      new AsyncCompletedEventArgs (null, false, args [2]));
1096 //                                      } catch (ThreadInterruptedException){
1097 //                                              OnDownloadFileCompleted (
1098 //                                                      new AsyncCompletedEventArgs (null, true, args [2]));
1099 //                                      } catch (Exception e){
1100 //                                              OnDownloadFileCompleted (
1101 //                                                      new AsyncCompletedEventArgs (e, false, args [2]));
1102 //                                      }});
1103 //                              object [] cb_args = new object [] {address, fileName, userToken};
1104 //                              async_thread.Start (cb_args);
1105 //                      }
1106 //              }
1107 //
1108 //              //    DownloadStringAsync
1109 //
1110                 public void DownloadStringAsync (Uri address)
1111                 {
1112                         DownloadStringAsync (address, null);
1113                 }
1114
1115                 public void DownloadStringAsync (Uri address, object userToken)
1116                 {
1117                         if (address == null)
1118                                 throw new ArgumentNullException ("address");
1119
1120                         lock (this) {
1121                                 SetBusy ();
1122                                 async = true;
1123
1124                                 async_thread = new Thread (delegate (object state) {
1125                                         object [] args = (object []) state;
1126                                         try {
1127                                                 Stream bdata = DownloadDataCore ((Uri) args [0], args [1]);
1128                                                 string data;
1129                                                 using (StreamReader stream = new StreamReader (bdata, encoding, true))
1130                                                         data = stream.ReadToEnd ();
1131
1132                                                 OnDownloadStringCompleted (
1133                                                         new DownloadStringCompletedEventArgs (data, null, false, args [1]));
1134                                         } catch (ThreadInterruptedException){
1135                                                 OnDownloadStringCompleted (
1136                                                         new DownloadStringCompletedEventArgs (null, null, true, args [1]));
1137                                         } catch (Exception e){
1138                                                 OnDownloadStringCompleted (
1139                                                         new DownloadStringCompletedEventArgs (null, e, false, args [1]));
1140                                         }});
1141                                 object [] cb_args = new object [] {address, userToken};
1142                                 async_thread.Start (cb_args);
1143                         }
1144                 }
1145
1146                 //    OpenReadAsync
1147
1148                 public void OpenReadAsync (Uri address)
1149                 {
1150                         OpenReadAsync (address, null);
1151                 }
1152
1153                 public void OpenReadAsync (Uri address, object userToken)
1154                 {
1155                         if (address == null)
1156                                 throw new ArgumentNullException ("address");
1157
1158                         lock (this) {
1159                                 SetBusy ();
1160                                 async = true;
1161
1162                                 async_thread = new Thread (delegate (object state) {
1163                                         object [] args = (object []) state;
1164                                         WebRequest request = null;
1165                                         try {
1166                                                 request = SetupRequest ((Uri) args [0]);
1167                                                 //WebResponse response = request.GetResponse ();
1168                                                 IAsyncResult asyncresult = request.BeginGetResponse (null, userToken);
1169                                                 asyncresult.AsyncWaitHandle.WaitOne ();
1170                                                 WebResponse response = request.EndGetResponse (asyncresult);
1171                                                 Stream stream = ProcessResponse (response);
1172                                                 OnOpenReadCompleted (
1173                                                         new OpenReadCompletedEventArgs (stream, address, null, false, args [1]));
1174                                         } catch (ThreadInterruptedException){
1175                                                 if (request != null)
1176                                                         request.Abort ();
1177
1178                                                 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, null, true, args [1]));
1179                                         } catch (Exception e){
1180                                                 OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, e, false, args [1]));
1181                                         } });
1182                                 object [] cb_args = new object [] {address, userToken};
1183                                 async_thread.Start (cb_args);
1184                         }
1185                 }
1186
1187 //              //    OpenWriteAsync
1188 //
1189 //              public void OpenWriteAsync (Uri address)
1190 //              {
1191 //                      OpenWriteAsync (address, null);
1192 //              }
1193 //
1194 //              public void OpenWriteAsync (Uri address, string method)
1195 //              {
1196 //                      OpenWriteAsync (address, method, null);
1197 //              }
1198 //
1199 //              public void OpenWriteAsync (Uri address, string method, object userToken)
1200 //              {
1201 //                      if (address == null)
1202 //                              throw new ArgumentNullException ("address");
1203 //
1204 //                      lock (this) {
1205 //                              SetBusy ();
1206 //                              async = true;
1207 //
1208 //                              async_thread = new Thread (delegate (object state) {
1209 //                                      object [] args = (object []) state;
1210 //                                      WebRequest request = null;
1211 //                                      try {
1212 //                                              request = SetupRequest ((Uri) args [0], (string) args [1]);
1213 //                                              Stream stream = request.GetRequestStream ();
1214 //                                              OnOpenWriteCompleted (
1215 //                                                      new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
1216 //                                      } catch (ThreadInterruptedException){
1217 //                                              if (request != null)
1218 //                                                      request.Abort ();
1219 //                                              OnOpenWriteCompleted (
1220 //                                                      new OpenWriteCompletedEventArgs (null, null, true, args [2]));
1221 //                                      } catch (Exception e){
1222 //                                              OnOpenWriteCompleted (
1223 //                                                      new OpenWriteCompletedEventArgs (null, e, false, args [2]));
1224 //                                      }});
1225 //                              object [] cb_args = new object [] {address, method, userToken};
1226 //                              async_thread.Start (cb_args);
1227 //                      }
1228 //              }
1229 //
1230 //              //    UploadDataAsync
1231 //
1232 //              public void UploadDataAsync (Uri address, byte [] data)
1233 //              {
1234 //                      UploadDataAsync (address, null, data);
1235 //              }
1236 //
1237 //              public void UploadDataAsync (Uri address, string method, byte [] data)
1238 //              {
1239 //                      UploadDataAsync (address, method, data, null);
1240 //              }
1241 //
1242 //              public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
1243 //              {
1244 //                      if (address == null)
1245 //                              throw new ArgumentNullException ("address");
1246 //                      if (data == null)
1247 //                              throw new ArgumentNullException ("data");
1248 //                      
1249 //                      lock (this) {
1250 //                              SetBusy ();
1251 //                              async = true;
1252 //
1253 //                              async_thread = new Thread (delegate (object state) {
1254 //                                      object [] args = (object []) state;
1255 //                                      byte [] data2;
1256 //
1257 //                                      try {
1258 //                                              data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
1259 //                                      
1260 //                                              OnUploadDataCompleted (
1261 //                                                      new UploadDataCompletedEventArgs (data2, null, false, args [3]));
1262 //                                      } catch (ThreadInterruptedException){
1263 //                                              OnUploadDataCompleted (
1264 //                                                      new UploadDataCompletedEventArgs (null, null, true, args [3]));
1265 //                                      } catch (Exception e){
1266 //                                              OnUploadDataCompleted (
1267 //                                                      new UploadDataCompletedEventArgs (null, e, false, args [3]));
1268 //                                      }});
1269 //                              object [] cb_args = new object [] {address, method, data,  userToken};
1270 //                              async_thread.Start (cb_args);
1271 //                      }
1272 //              }
1273 //
1274 //              //    UploadFileAsync
1275 //
1276 //              public void UploadFileAsync (Uri address, string fileName)
1277 //              {
1278 //                      UploadFileAsync (address, null, fileName);
1279 //              }
1280 //
1281 //              public void UploadFileAsync (Uri address, string method, string fileName)
1282 //              {
1283 //                      UploadFileAsync (address, method, fileName, null);
1284 //              }
1285 //
1286 //              public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
1287 //              {
1288 //                      if (address == null)
1289 //                              throw new ArgumentNullException ("address");
1290 //                      if (fileName == null)
1291 //                              throw new ArgumentNullException ("fileName");
1292 //
1293 //                      lock (this) {
1294 //                              SetBusy ();
1295 //                              async = true;
1296 //
1297 //                              async_thread = new Thread (delegate (object state) {
1298 //                                      object [] args = (object []) state;
1299 //                                      byte [] data;
1300 //
1301 //                                      try {
1302 //                                              data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
1303 //                                              OnUploadFileCompleted (
1304 //                                                      new UploadFileCompletedEventArgs (data, null, false, args [3]));
1305 //                                      } catch (ThreadInterruptedException){
1306 //                                              OnUploadFileCompleted (
1307 //                                                      new UploadFileCompletedEventArgs (null, null, true, args [3]));
1308 //                                      } catch (Exception e){
1309 //                                              OnUploadFileCompleted (
1310 //                                                      new UploadFileCompletedEventArgs (null, e, false, args [3]));
1311 //                                      }});
1312 //                              object [] cb_args = new object [] {address, method, fileName,  userToken};
1313 //                              async_thread.Start (cb_args);
1314 //                      }
1315 //              }
1316 //
1317 //              //    UploadStringAsync
1318 //
1319 //              public void UploadStringAsync (Uri address, string data)
1320 //              {
1321 //                      UploadStringAsync (address, null, data);
1322 //              }
1323 //
1324 //              public void UploadStringAsync (Uri address, string method, string data)
1325 //              {
1326 //                      UploadStringAsync (address, method, data, null);
1327 //              }
1328 //
1329 //              public void UploadStringAsync (Uri address, string method, string data, object userToken)
1330 //              {
1331 //                      if (address == null)
1332 //                              throw new ArgumentNullException ("address");
1333 //                      if (data == null)
1334 //                              throw new ArgumentNullException ("data");
1335 //                      
1336 //                      lock (this) {
1337 //                              SetBusy ();
1338 //                              async = true;
1339 //                              
1340 //                              async_thread = new Thread (delegate (object state) {
1341 //                                      object [] args = (object []) state;
1342 //
1343 //                                      try {
1344 //                                              string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
1345 //                                              OnUploadStringCompleted (
1346 //                                                      new UploadStringCompletedEventArgs (data2, null, false, args [3]));
1347 //                                      } catch (ThreadInterruptedException){
1348 //                                              OnUploadStringCompleted (
1349 //                                                      new UploadStringCompletedEventArgs (null, null, true, args [3]));
1350 //                                      } catch (Exception e){
1351 //                                              OnUploadStringCompleted (
1352 //                                                      new UploadStringCompletedEventArgs (null, e, false, args [3]));
1353 //                                      }});
1354 //                              object [] cb_args = new object [] {address, method, data, userToken};
1355 //                              async_thread.Start (cb_args);
1356 //                      }
1357 //              }
1358 //
1359 //              //    UploadValuesAsync
1360 //
1361 //              public void UploadValuesAsync (Uri address, NameValueCollection values)
1362 //              {
1363 //                      UploadValuesAsync (address, null, values);
1364 //              }
1365 //
1366 //              public void UploadValuesAsync (Uri address, string method, NameValueCollection values)
1367 //              {
1368 //                      UploadValuesAsync (address, method, values, null);
1369 //              }
1370 //
1371 //              public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken)
1372 //              {
1373 //                      if (address == null)
1374 //                              throw new ArgumentNullException ("address");
1375 //                      if (values == null)
1376 //                              throw new ArgumentNullException ("values");
1377 //
1378 //                      lock (this) {
1379 //                              CheckBusy ();
1380 //                              async = true;
1381 //
1382 //                              async_thread = new Thread (delegate (object state) {
1383 //                                      object [] args = (object []) state;
1384 //                                      try {
1385 //                                              byte [] data = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
1386 //                                              OnUploadValuesCompleted (
1387 //                                                      new UploadValuesCompletedEventArgs (data, null, false, args [3]));
1388 //                                      } catch (ThreadInterruptedException){
1389 //                                              OnUploadValuesCompleted (
1390 //                                                      new UploadValuesCompletedEventArgs (null, null, true, args [3]));
1391 //                                      } catch (Exception e){
1392 //                                              OnUploadValuesCompleted (
1393 //                                                      new UploadValuesCompletedEventArgs (null, e, false, args [3]));
1394 //                                      }});
1395 //                              object [] cb_args = new object [] {address, method, values,  userToken};
1396 //                              async_thread.Start (cb_args);
1397 //                      }
1398 //              }
1399 //
1400 //              protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
1401 //              {
1402 //                      CompleteAsync ();
1403 //                      if (DownloadDataCompleted != null)
1404 //                              DownloadDataCompleted (this, args);
1405 //              }
1406 //
1407 //              protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
1408 //              {
1409 //                      CompleteAsync ();
1410 //                      if (DownloadFileCompleted != null)
1411 //                              DownloadFileCompleted (this, args);
1412 //              }
1413 //
1414                 protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
1415                 {
1416                         if (DownloadProgressChanged != null) {
1417                                 DownloadProgressChanged (this, e);
1418                         }
1419                 }
1420                 
1421                 private object callback_args;
1422
1423                 protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
1424                 {
1425                         CompleteAsync ();
1426                         if (OpenReadCompleted != null) {
1427                                 ManualResetEvent wait_event = new ManualResetEvent (false);
1428                                 GSourceFunc callback = (GSourceFunc) delegate (IntPtr ctx) { OpenReadCompleted (this, (OpenReadCompletedEventArgs) callback_args); wait_event.Set (); return false; };
1429                                 callback_args = args;
1430
1431                                 g_timeout_add (0, callback, IntPtr.Zero);
1432
1433                                 wait_event.WaitOne ();
1434                                 GC.KeepAlive (callback);
1435                         }
1436                 }
1437
1438                 public delegate bool GSourceFunc (IntPtr data);
1439
1440                 [DllImport ("moon")]
1441                 static extern uint g_timeout_add (uint delay, GSourceFunc callback, IntPtr data);
1442
1443                 protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
1444                 {
1445                         CompleteAsync ();
1446                         if (DownloadStringCompleted != null) {
1447                                 ManualResetEvent wait_event = new ManualResetEvent (false);
1448                                 GSourceFunc callback = (GSourceFunc) delegate (IntPtr ctx) 
1449                                 {
1450                                         try {
1451                                                 DownloadStringCompleted (this, (DownloadStringCompletedEventArgs) callback_args);
1452                                                 wait_event.Set ();
1453                                         } catch (Exception ex) {
1454                                                 Console.WriteLine ("Unhandled exception: {0}", ex);
1455                                         } catch {
1456                                                 Console.WriteLine ("Unhandled exception.");
1457                                         }
1458                                         return false;
1459                                 };
1460                                 callback_args = args;
1461
1462                                 g_timeout_add (0, callback, IntPtr.Zero);
1463
1464                                 wait_event.WaitOne ();
1465                                 GC.KeepAlive (callback);
1466                         }
1467                 }
1468
1469
1470 //              protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
1471 //              {
1472 //                      CompleteAsync ();
1473 //                      if (OpenWriteCompleted != null)
1474 //                              OpenWriteCompleted (this, args);
1475 //              }
1476 //
1477 //              protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
1478 //              {
1479 //                      CompleteAsync ();
1480 //                      if (UploadDataCompleted != null)
1481 //                              UploadDataCompleted (this, args);
1482 //              }
1483 //
1484 //              protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
1485 //              {
1486 //                      CompleteAsync ();
1487 //                      if (UploadFileCompleted != null)
1488 //                              UploadFileCompleted (this, args);
1489 //              }
1490 //
1491 //              protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
1492 //              {
1493 //                      if (UploadProgressChanged != null)
1494 //                              UploadProgressChanged (this, e);
1495 //              }
1496 //
1497 //              protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
1498 //              {
1499 //                      CompleteAsync ();
1500 //                      if (UploadStringCompleted != null)
1501 //                              UploadStringCompleted (this, args);
1502 //              }
1503 //
1504 //              protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
1505 //              {
1506 //                      CompleteAsync ();
1507 //                      if (UploadValuesCompleted != null)
1508 //                              UploadValuesCompleted (this, args);
1509 //              }
1510 //
1511 //              [MonoNotSupported("")]
1512 //              protected virtual WebRequest GetWebRequest (Uri address)
1513 //              {
1514 //                      throw new NotImplementedException ();
1515 //              }
1516 //
1517 //              protected virtual WebResponse GetWebResponse (WebRequest request)
1518 //              {
1519 //                      return request.GetResponse ();
1520 //              }
1521 //
1522 //              protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
1523 //              {
1524 //                      return request.EndGetResponse (result);
1525 //              }
1526 //#endif
1527 #endif
1528         }
1529 }
1530
1531