X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Net%2FSystem.Net%2FWebClient_2_1.cs;h=1487adc40b62382f791f2bfd94b73d82e2829099;hb=2d23bfcbce7a3f7e54dcd5911adb88b244baca35;hp=699bd42509bf60f71077e8bf5a40e39d00ae7051;hpb=92c325300716cc92b97b504d746028736ec54ff5;p=mono.git diff --git a/mcs/class/System.Net/System.Net/WebClient_2_1.cs b/mcs/class/System.Net/System.Net/WebClient_2_1.cs index 699bd42509b..1487adc40b6 100644 --- a/mcs/class/System.Net/System.Net/WebClient_2_1.cs +++ b/mcs/class/System.Net/System.Net/WebClient_2_1.cs @@ -9,7 +9,7 @@ // Stephane Delcroix (sdelcroix@novell.com) // // Copyright 2003 Ximian, Inc. (http://www.ximian.com) -// Copyright 2006, 2008 Novell, Inc. (http://www.novell.com) +// Copyright 2006, 2008, 2009-2010 Novell, Inc. (http://www.novell.com) // // // Permission is hereby granted, free of charge, to any person obtaining @@ -31,178 +31,103 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -// -// Notes on CancelAsync and Async methods: -// -// WebClient.CancelAsync is implemented by calling Thread.Interrupt -// in our helper thread. The various async methods have to cancel -// any ongoing requests by calling request.Abort () at that point. -// In a few places (UploadDataCore, UploadValuesCore, -// UploadFileCore) we catch the ThreadInterruptedException and -// abort the request there. -// -// Higher level routines (the async callbacks) also need to catch -// the exception and raise the OnXXXXCompleted events there with -// the "canceled" flag set to true. -// -// In a few other places where these helper routines are not used -// (OpenReadAsync for example) catching the ThreadAbortException -// also must abort the request. -// -// The Async methods currently differ in their implementation from -// the .NET implementation in that we manually catch any other -// exceptions and correctly raise the OnXXXXCompleted passing the -// Exception that caused the problem. The .NET implementation -// does not seem to have a mechanism to flag errors that happen -// during downloads though. We do this because we still need to -// catch the exception on these helper threads, or we would -// otherwise kill the application (on the 2.x profile, uncaught -// exceptions in threads terminate the application). -// -using System; -using System.Collections.Specialized; -using System.ComponentModel; + using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; using System.Text; using System.Threading; -using System.Net.Cache; - -namespace System.Net -{ -#if NET_2_1 - public class WebClient - { -// static readonly string urlEncodedCType = "application/x-www-form-urlencoded"; -// static byte [] hexBytes; -// ICredentials credentials; -// WebHeaderCollection headers; -// WebHeaderCollection responseHeaders; -// Uri baseAddress; -// string baseString; -// NameValueCollection queryString; - bool is_busy, async; - Thread async_thread; -// Encoding encoding = Encoding.Default; -// IWebProxy proxy; -// -// // Constructors -// static WebClient () -// { -// hexBytes = new byte [16]; -// int index = 0; -// for (int i = '0'; i <= '9'; i++, index++) -// hexBytes [index] = (byte) i; -// -// for (int i = 'A'; i <= 'F'; i++, index++) -// hexBytes [index] = (byte) i; -// } -// -// public WebClient () -// { -// } -// -// // Properties -// -// public string BaseAddress { -// get { -// if (baseString == null) { -// if (baseAddress == null) -// return ""; -// } -// -// baseString = baseAddress.ToString (); -// return baseString; -// } -// -// set { -// if (value == null || value == "") { -// baseAddress = null; -// } else { -// baseAddress = new Uri (value); -// } -// } -// } -// -//#if NET_2_0 -// static Exception GetMustImplement () -// { -// return new NotImplementedException (); -// } -// -// [MonoTODO] -// public RequestCachePolicy CachePolicy -// { -// get { -// throw GetMustImplement (); -// } -// set { -// throw GetMustImplement (); -// } -// } -// -// [MonoTODO] -// public bool UseDefaultCredentials -// { -// get { -// throw GetMustImplement (); -// } -// set { -// throw GetMustImplement (); -// } -// } -//#endif -// -// public ICredentials Credentials { -// get { return credentials; } -// set { credentials = value; } -// } -// -// public WebHeaderCollection Headers { -// get { -// if (headers == null) -// headers = new WebHeaderCollection (); -// -// return headers; -// } -// set { headers = value; } -// } -// -// public NameValueCollection QueryString { -// get { -// if (queryString == null) -// queryString = new NameValueCollection (); -// -// return queryString; -// } -// set { queryString = value; } -// } -// -// public WebHeaderCollection ResponseHeaders { -// get { return responseHeaders; } -// } -// -//#if NET_2_0 -// public Encoding Encoding { -// get { return encoding; } -// set { -// if (value == null) -// throw new ArgumentNullException ("value"); -// encoding = value; -// } -// } -// -// public IWebProxy Proxy { -// get { return proxy; } -// set { proxy = value; } -// } -//#endif -// + +namespace System.Net { + + // note: this type is effectively sealed to transparent code since it's default .ctor is marked with [SecuritySafeCritical] + public class WebClient { + + WebHeaderCollection headers; + WebHeaderCollection responseHeaders; + string baseAddress; + bool is_busy; + Encoding encoding = Encoding.UTF8; + bool allow_read_buffering = true; + bool allow_write_buffering = true; + WebRequest request; + object locker; + CallbackData callback_data; + + public WebClient () + { + // kind of calling NativeMethods.plugin_instance_get_source_location (PluginHost.Handle) + // but without adding dependency on System.Windows.dll. GetData is [SecurityCritical] + // this makes the default .ctor [SecuritySafeCritical] which would be a problem (inheritance) + // but it happens that MS SL2 also has this default .ctor as SSC :-) + baseAddress = (AppDomain.CurrentDomain.GetData ("xap_uri") as string); + locker = new object (); + UseDefaultCredentials = true; + } + + // Properties + + public string BaseAddress { + get { return baseAddress; } + set { + if (String.IsNullOrEmpty (value)) { + baseAddress = String.Empty; + } else { + Uri uri = null; + if (!Uri.TryCreate (value, UriKind.Absolute, out uri)) + throw new ArgumentException ("Invalid URI"); + + baseAddress = Uri.UnescapeDataString (uri.AbsoluteUri); + } + } + } + + [MonoTODO ("provide credentials to the client stack")] + public ICredentials Credentials { get; set; } + + // this is an unvalidated collection, HttpWebRequest is responsable to validate it + public WebHeaderCollection Headers { + get { + if (headers == null) + headers = new WebHeaderCollection (); + + return headers; + } + set { headers = value; } + } + + public WebHeaderCollection ResponseHeaders { + get { return responseHeaders; } + } + + public Encoding Encoding { + get { return encoding; } + set { + if (value == null) + throw new ArgumentNullException ("value"); + encoding = value; + } + } + public bool IsBusy { get { return is_busy; } } + [MonoTODO ("value is unused, current implementation always works like it's true (default)")] + public bool AllowReadStreamBuffering { + get { return allow_read_buffering; } + set { allow_read_buffering = value; } + } + + // new in SL4 RC + [MonoTODO ("value is unused, current implementation always works like it's true (default)")] + public bool AllowWriteStreamBuffering { + get { return allow_write_buffering; } + set { allow_write_buffering = value; } + } + + public bool UseDefaultCredentials { + get; set; + } + // Methods void CheckBusy () @@ -213,934 +138,144 @@ namespace System.Net void SetBusy () { - lock (this) { + lock (locker) { CheckBusy (); is_busy = true; } } -// // DownloadData -// -// public byte [] DownloadData (string address) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// return DownloadData (CreateUri (address)); -// } -// -//#if NET_2_0 -// public -//#endif -// byte [] DownloadData (Uri address) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// try { -// SetBusy (); -// async = false; -// return DownloadDataCore (address, null); -// } finally { -// is_busy = false; -// } -// } -// -// byte [] DownloadDataCore (Uri address, object userToken) -// { -// WebRequest request = null; -// -// try { -// request = SetupRequest (address, "GET"); -// WebResponse response = request.GetResponse (); -// Stream st = ProcessResponse (response); -// return ReadAll (st, (int) response.ContentLength, userToken); -// } catch (ThreadInterruptedException){ -// if (request != null) -// request.Abort (); -// throw; -// } catch (Exception ex) { -// throw new WebException ("An error occurred " + -// "performing a WebClient request.", ex); -// } -// } -// -// // DownloadFile -// -// public void DownloadFile (string address, string fileName) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// DownloadFile (CreateUri (address), fileName); -// } -// -//#if NET_2_0 -// public -//#endif -// void DownloadFile (Uri address, string fileName) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (fileName == null) -// throw new ArgumentNullException ("fileName"); -//#endif -// -// try { -// SetBusy (); -// async = false; -// DownloadFileCore (address, fileName, null); -// } catch (Exception ex) { -// throw new WebException ("An error occurred " + -// "performing a WebClient request.", ex); -// } finally { -// is_busy = false; -// } -// } -// -// void DownloadFileCore (Uri address, string fileName, object userToken) -// { -// WebRequest request = null; -// -// using (FileStream f = new FileStream (fileName, FileMode.Create)) { -// try { -// request = SetupRequest (address); -// WebResponse response = request.GetResponse (); -// Stream st = ProcessResponse (response); -// -// int cLength = (int) response.ContentLength; -// int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength; -// byte [] buffer = new byte [length]; -// -// int nread = 0; -//#if NET_2_0 -// long notify_total = 0; -//#endif -// while ((nread = st.Read (buffer, 0, length)) != 0){ -//#if NET_2_0 -// if (async){ -// notify_total += nread; -// OnDownloadProgressChanged ( -// new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, userToken)); -// -// } -//#endif -// f.Write (buffer, 0, nread); -// } -// } catch (ThreadInterruptedException){ -// if (request != null) -// request.Abort (); -// throw; -// } -// } -// } -// -// // OpenRead -// -// public Stream OpenRead (string address) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// return OpenRead (CreateUri (address)); -// } -// -//#if NET_2_0 -// public -//#endif -// Stream OpenRead (Uri address) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// WebRequest request = null; -// try { -// SetBusy (); -// async = false; -// request = SetupRequest (address); -// WebResponse response = request.GetResponse (); -// return ProcessResponse (response); -// } catch (Exception ex) { -// throw new WebException ("An error occurred " + -// "performing a WebClient request.", ex); -// } finally { -// is_busy = false; -// } -// } -// -// // OpenWrite -// -// public Stream OpenWrite (string address) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// return OpenWrite (CreateUri (address)); -// } -// -// public Stream OpenWrite (string address, string method) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// return OpenWrite (CreateUri (address), method); -// } -// -//#if NET_2_0 -// public -//#endif -// Stream OpenWrite (Uri address) -// { -// return OpenWrite (address, (string) null); -// } -// -//#if NET_2_0 -// public -//#endif -// Stream OpenWrite (Uri address, string method) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// try { -// SetBusy (); -// async = false; -// WebRequest request = SetupRequest (address, method); -// return request.GetRequestStream (); -// } catch (Exception ex) { -// throw new WebException ("An error occurred " + -// "performing a WebClient request.", ex); -// } finally { -// is_busy = false; -// } -// } -// -// private string DetermineMethod (Uri address, string method) -// { -// if (method != null) -// return method; -// -//#if NET_2_0 -// if (address.Scheme == Uri.UriSchemeFtp) -// return "RETR"; -//#endif -// return "POST"; -// } -// -// // UploadData -// -// public byte [] UploadData (string address, byte [] data) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// return UploadData (CreateUri (address), data); -// } -// -// public byte [] UploadData (string address, string method, byte [] data) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// return UploadData (CreateUri (address), method, data); -// } -// -//#if NET_2_0 -// public -//#endif -// byte [] UploadData (Uri address, byte [] data) -// { -// return UploadData (address, (string) null, data); -// } -// -//#if NET_2_0 -// public -//#endif -// byte [] UploadData (Uri address, string method, byte [] data) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (data == null) -// throw new ArgumentNullException ("data"); -//#endif -// -// try { -// SetBusy (); -// async = false; -// return UploadDataCore (address, method, data, null); -// } catch (Exception ex) { -// throw new WebException ("An error occurred " + -// "performing a WebClient request.", ex); -// } finally { -// is_busy = false; -// } -// } -// -// byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken) -// { -//#if ONLY_1_1 -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (data == null) -// throw new ArgumentNullException ("data"); -//#endif -// -// WebRequest request = SetupRequest (address, method); -// try { -// int contentLength = data.Length; -// request.ContentLength = contentLength; -// using (Stream stream = request.GetRequestStream ()) { -// stream.Write (data, 0, contentLength); -// } -// -// WebResponse response = request.GetResponse (); -// Stream st = ProcessResponse (response); -// return ReadAll (st, (int) response.ContentLength, userToken); -// } catch (ThreadInterruptedException){ -// if (request != null) -// request.Abort (); -// throw; -// } -// } -// -// // UploadFile -// -// public byte [] UploadFile (string address, string fileName) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// return UploadFile (CreateUri (address), fileName); -// } -// -//#if NET_2_0 -// public -//#endif -// byte [] UploadFile (Uri address, string fileName) -// { -// return UploadFile (address, (string) null, fileName); -// } -// -// public byte [] UploadFile (string address, string method, string fileName) -// { -// return UploadFile (CreateUri (address), method, fileName); -// } -// -//#if NET_2_0 -// public -//#endif -// byte [] UploadFile (Uri address, string method, string fileName) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (fileName == null) -// throw new ArgumentNullException ("fileName"); -//#endif -// -// try { -// SetBusy (); -// async = false; -// return UploadFileCore (address, method, fileName, null); -// } catch (Exception ex) { -// throw new WebException ("An error occurred " + -// "performing a WebClient request.", ex); -// } finally { -// is_busy = false; -// } -// } -// -// byte [] UploadFileCore (Uri address, string method, string fileName, object userToken) -// { -//#if ONLY_1_1 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// string fileCType = Headers ["Content-Type"]; -// if (fileCType != null) { -// string lower = fileCType.ToLower (); -// if (lower.StartsWith ("multipart/")) -// throw new WebException ("Content-Type cannot be set to a multipart" + -// " type for this request."); -// } else { -// fileCType = "application/octet-stream"; -// } -// -// string boundary = "------------" + DateTime.Now.Ticks.ToString ("x"); -// Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary); -// Stream reqStream = null; -// Stream fStream = null; -// byte [] resultBytes = null; -// -// fileName = Path.GetFullPath (fileName); -// -// WebRequest request = null; -// try { -// fStream = File.OpenRead (fileName); -// request = SetupRequest (address, method); -// reqStream = request.GetRequestStream (); -// byte [] realBoundary = Encoding.ASCII.GetBytes ("--" + boundary + "\r\n"); -// reqStream.Write (realBoundary, 0, realBoundary.Length); -// string partHeaders = String.Format ("Content-Disposition: form-data; " + -// "name=\"file\"; filename=\"{0}\"\r\n" + -// "Content-Type: {1}\r\n\r\n", -// Path.GetFileName (fileName), fileCType); -// -// byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders); -// reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length); -// int nread; -// byte [] buffer = new byte [4096]; -// while ((nread = fStream.Read (buffer, 0, 4096)) != 0) -// reqStream.Write (buffer, 0, nread); -// -// reqStream.WriteByte ((byte) '\r'); -// reqStream.WriteByte ((byte) '\n'); -// reqStream.Write (realBoundary, 0, realBoundary.Length); -// reqStream.Close (); -// reqStream = null; -// WebResponse response = request.GetResponse (); -// Stream st = ProcessResponse (response); -// resultBytes = ReadAll (st, (int) response.ContentLength, userToken); -// } catch (ThreadInterruptedException){ -// if (request != null) -// request.Abort (); -// throw; -// } finally { -// if (fStream != null) -// fStream.Close (); -// -// if (reqStream != null) -// reqStream.Close (); -// } -// -// return resultBytes; -// } -// -// public byte[] UploadValues (string address, NameValueCollection data) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// return UploadValues (CreateUri (address), data); -// } -// -// public byte[] UploadValues (string address, string method, NameValueCollection data) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -//#endif -// -// return UploadValues (CreateUri (address), method, data); -// } -// -//#if NET_2_0 -// public -//#endif -// byte[] UploadValues (Uri address, NameValueCollection data) -// { -// return UploadValues (address, (string) null, data); -// } -// -//#if NET_2_0 -// public -//#endif -// byte[] UploadValues (Uri address, string method, NameValueCollection data) -// { -//#if NET_2_0 -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (data == null) -// throw new ArgumentNullException ("data"); -//#endif -// -// try { -// SetBusy (); -// async = false; -// return UploadValuesCore (address, method, data, null); -// } catch (Exception ex) { -// throw new WebException ("An error occurred " + -// "performing a WebClient request.", ex); -// } finally { -// is_busy = false; -// } -// } -// -// byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken) -// { -//#if ONLY_1_1 -// if (data == null) -// throw new ArgumentNullException ("data"); -//#endif -// -// string cType = Headers ["Content-Type"]; -// if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0) -// throw new WebException ("Content-Type header cannot be changed from its default " + -// "value for this request."); -// -// Headers ["Content-Type"] = urlEncodedCType; -// WebRequest request = SetupRequest (uri, method); -// try { -// Stream rqStream = request.GetRequestStream (); -// MemoryStream tmpStream = new MemoryStream (); -// foreach (string key in data) { -// byte [] bytes = Encoding.ASCII.GetBytes (key); -// UrlEncodeAndWrite (tmpStream, bytes); -// tmpStream.WriteByte ((byte) '='); -// bytes = Encoding.ASCII.GetBytes (data [key]); -// UrlEncodeAndWrite (tmpStream, bytes); -// tmpStream.WriteByte ((byte) '&'); -// } -// -// int length = (int) tmpStream.Length; -// if (length > 0) -// tmpStream.SetLength (--length); // remove trailing '&' -// -// byte [] buf = tmpStream.GetBuffer (); -// rqStream.Write (buf, 0, length); -// rqStream.Close (); -// tmpStream.Close (); -// -// WebResponse response = request.GetResponse (); -// Stream st = ProcessResponse (response); -// return ReadAll (st, (int) response.ContentLength, userToken); -// } catch (ThreadInterruptedException) { -// request.Abort (); -// throw; -// } -// } -// -//#if NET_2_0 -// public string DownloadString (string address) -// { -// return encoding.GetString (DownloadData (address)); -// } -// -// public string DownloadString (Uri address) -// { -// return encoding.GetString (DownloadData (address)); -// } -// -// public string UploadString (string address, string data) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (data == null) -// throw new ArgumentNullException ("data"); -// -// byte [] resp = UploadData (address, encoding.GetBytes (data)); -// return encoding.GetString (resp); -// } -// -// public string UploadString (string address, string method, string data) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (data == null) -// throw new ArgumentNullException ("data"); -// -// byte [] resp = UploadData (address, method, encoding.GetBytes (data)); -// return encoding.GetString (resp); -// } -// -// public string UploadString (Uri address, string data) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (data == null) -// throw new ArgumentNullException ("data"); -// -// byte [] resp = UploadData (address, encoding.GetBytes (data)); -// return encoding.GetString (resp); -// } -// -// public string UploadString (Uri address, string method, string data) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (data == null) -// throw new ArgumentNullException ("data"); -// -// byte [] resp = UploadData (address, method, encoding.GetBytes (data)); -// return encoding.GetString (resp); -// } -// -// public event DownloadDataCompletedEventHandler DownloadDataCompleted; -// public event AsyncCompletedEventHandler DownloadFileCompleted; + private string DetermineMethod (Uri address, string method) + { + if (method != null) + return method; + + if (address.Scheme == Uri.UriSchemeFtp) + return "RETR"; + return "POST"; + } + public event DownloadProgressChangedEventHandler DownloadProgressChanged; -// public event DownloadStringCompletedEventHandler DownloadStringCompleted; + public event DownloadStringCompletedEventHandler DownloadStringCompleted; public event OpenReadCompletedEventHandler OpenReadCompleted; -// public event OpenWriteCompletedEventHandler OpenWriteCompleted; -// public event UploadDataCompletedEventHandler UploadDataCompleted; -// public event UploadFileCompletedEventHandler UploadFileCompleted; -// public event UploadProgressChangedEventHandler UploadProgressChanged; -// public event UploadStringCompletedEventHandler UploadStringCompleted; -// public event UploadValuesCompletedEventHandler UploadValuesCompleted; -//#endif -// -// Uri CreateUri (string address) -// { -//#if ONLY_1_1 -// try { -// return MakeUri (address); -// } catch (Exception ex) { -// throw new WebException ("An error occurred " + -// "performing a WebClient request.", ex); -// } -//#else -// return MakeUri (address); -//#endif -// } -// -// Uri MakeUri (string path) -// { -// string query = null; -// if (queryString != null && queryString.Count != 0) { -// // This is not the same as UploadValues, because these 'keys' are not -// // urlencoded here. -// StringBuilder sb = new StringBuilder (); -// sb.Append ('?'); -// foreach (string key in queryString) -// sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key])); -// -// if (sb.Length != 0) { -// sb.Length--; // remove trailing '&' -// query = sb.ToString (); -// } -// } -// -// if (baseAddress == null && query == null) { -// try { -// return new Uri (path); -//#if NET_2_0 -// } catch (ArgumentNullException) { -// path = Path.GetFullPath (path); -// return new Uri ("file://" + path); -//#endif -// } catch (UriFormatException) { -// path = Path.GetFullPath (path); -// return new Uri ("file://" + path); -// } -// } -// -// if (baseAddress == null) -// return new Uri (path + query, (query != null)); -// -// if (query == null) -// return new Uri (baseAddress, path); -// -// return new Uri (baseAddress, path + query, (query != null)); -// } -// - WebRequest SetupRequest (Uri uri) + public event OpenWriteCompletedEventHandler OpenWriteCompleted; + public event UploadProgressChangedEventHandler UploadProgressChanged; + public event UploadStringCompletedEventHandler UploadStringCompleted; + public event WriteStreamClosedEventHandler WriteStreamClosed; + + WebRequest SetupRequest (Uri uri, string method, CallbackData callbackData) { - WebRequest request = WebRequest.Create (uri); -// if (Proxy != null) -// request.Proxy = Proxy; -// request.Credentials = credentials; - - // Special headers. These are properties of HttpWebRequest. - // What do we do with other requests differnt from HttpWebRequest? -// if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) { -// HttpWebRequest req = (HttpWebRequest) request; -// string expect = headers ["Expect"]; -// string contentType = headers ["Content-Type"]; -// string accept = headers ["Accept"]; -// string connection = headers ["Connection"]; -// string userAgent = headers ["User-Agent"]; -// string referer = headers ["Referer"]; -// headers.RemoveInternal ("Expect"); -// headers.RemoveInternal ("Content-Type"); -// headers.RemoveInternal ("Accept"); -// headers.RemoveInternal ("Connection"); -// headers.RemoveInternal ("Referer"); -// headers.RemoveInternal ("User-Agent"); -// request.Headers = headers; -// -// if (expect != null && expect.Length > 0) -// req.Expect = expect; -// -// if (accept != null && accept.Length > 0) -// req.Accept = accept; -// -// if (contentType != null && contentType.Length > 0) -// req.ContentType = contentType; -// -// if (connection != null && connection.Length > 0) -// req.Connection = connection; -// -// if (userAgent != null && userAgent.Length > 0) -// req.UserAgent = userAgent; -// -// if (referer != null && referer.Length > 0) -// req.Referer = referer; -// } -// -// responseHeaders = null; + callback_data = callbackData; + WebRequest request = GetWebRequest (uri); + request.Method = DetermineMethod (uri, method); + foreach (string header in Headers.AllKeys) + request.Headers.SetHeader (header, Headers [header]); return request; } -// WebRequest SetupRequest (Uri uri, string method) -// { -// WebRequest request = SetupRequest (uri); -// request.Method = DetermineMethod (uri, method); -// return request; -// } - Stream ProcessResponse (WebResponse response) { -// responseHeaders = response.Headers; - return response.GetResponseStream (); + responseHeaders = response.Headers; + HttpWebResponse hwr = (response as HttpWebResponse); + if (hwr == null) + throw new NotSupportedException (); + + HttpStatusCode status_code = HttpStatusCode.NotFound; + Stream s = null; + try { + status_code = hwr.StatusCode; + if (status_code == HttpStatusCode.OK) + s = response.GetResponseStream (); + } + catch (Exception e) { + throw new WebException ("NotFound", e, WebExceptionStatus.UnknownError, response); + } + finally { + if (status_code != HttpStatusCode.OK) + throw new WebException ("NotFound", null, WebExceptionStatus.UnknownError, response); + } + return s; + } + + public void CancelAsync () + { + if (request != null) + request.Abort (); } -// byte [] ReadAll (Stream stream, int length, object userToken) -// { -// MemoryStream ms = null; -// -// bool nolength = (length == -1); -// int size = ((nolength) ? 8192 : length); -// if (nolength) -// ms = new MemoryStream (); -// -//// long total = 0; -// int nread = 0; -// int offset = 0; -// byte [] buffer = new byte [size]; -// while ((nread = stream.Read (buffer, offset, size)) != 0) { -// if (nolength) { -// ms.Write (buffer, 0, nread); -// } else { -// offset += nread; -// size -= nread; -// } -//#if NET_2_0 -// if (async){ -//// total += nread; -// OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (nread, length, userToken)); -// } -//#endif -// } -// -// if (nolength) -// return ms.ToArray (); -// -// return buffer; -// } -// -// string UrlEncode (string str) -// { -// StringBuilder result = new StringBuilder (); -// -// int len = str.Length; -// for (int i = 0; i < len; i++) { -// char c = str [i]; -// if (c == ' ') -// result.Append ('+'); -// else if ((c < '0' && c != '-' && c != '.') || -// (c < 'A' && c > '9') || -// (c > 'Z' && c < 'a' && c != '_') || -// (c > 'z')) { -// result.Append ('%'); -// int idx = ((int) c) >> 4; -// result.Append ((char) hexBytes [idx]); -// idx = ((int) c) & 0x0F; -// result.Append ((char) hexBytes [idx]); -// } else { -// result.Append (c); -// } -// } -// -// return result.ToString (); -// } -// -// static void UrlEncodeAndWrite (Stream stream, byte [] bytes) -// { -// if (bytes == null) -// return; -// -// int len = bytes.Length; -// if (len == 0) -// return; -// -// for (int i = 0; i < len; i++) { -// char c = (char) bytes [i]; -// if (c == ' ') -// stream.WriteByte ((byte) '+'); -// else if ((c < '0' && c != '-' && c != '.') || -// (c < 'A' && c > '9') || -// (c > 'Z' && c < 'a' && c != '_') || -// (c > 'z')) { -// stream.WriteByte ((byte) '%'); -// int idx = ((int) c) >> 4; -// stream.WriteByte (hexBytes [idx]); -// idx = ((int) c) & 0x0F; -// stream.WriteByte (hexBytes [idx]); -// } else { -// stream.WriteByte ((byte) c); -// } -// } -// } -// -//#if NET_2_0 -// public void CancelAsync () -// { -// lock (this){ -// if (async_thread == null) -// return; -// -// // -// // We first flag things as done, in case the Interrupt hangs -// // or the thread decides to hang in some other way inside the -// // event handlers, or if we are stuck somewhere else. This -// // ensures that the WebClient object is reusable immediately -// // -// Thread t = async_thread; -// CompleteAsync (); -// t.Interrupt (); -// } -// } -// void CompleteAsync () { - lock (this){ - is_busy = false; - async_thread = null; + is_busy = false; + } + + class CallbackData { + public object user_token; + public SynchronizationContext sync_context; + public byte [] data; + public CallbackData (object user_token, byte [] data) + { + this.user_token = user_token; + this.data = data; + this.sync_context = SynchronizationContext.Current ?? new SynchronizationContext (); + } + public CallbackData (object user_token) : this (user_token, null) + { + } + } + + // DownloadStringAsync + + public void DownloadStringAsync (Uri address) + { + DownloadStringAsync (address, null); + } + + public void DownloadStringAsync (Uri address, object userToken) + { + if (address == null) + throw new ArgumentNullException ("address"); + + lock (locker) { + SetBusy (); + + try { + request = SetupRequest (address, "GET", new CallbackData (userToken)); + request.BeginGetResponse (new AsyncCallback (DownloadStringAsyncCallback), null); + } + catch (Exception e) { + WebException wex = new WebException ("Could not start operation.", e); + OnDownloadStringCompleted ( + new DownloadStringCompletedEventArgs (null, wex, false, userToken)); + } + } + } + + private void DownloadStringAsyncCallback (IAsyncResult result) + { + string data = null; + Exception ex = null; + bool cancel = false; + try { + WebResponse response = request.EndGetResponse (result); + Stream stream = ProcessResponse (response); + + using (StreamReader sr = new StreamReader (stream, encoding, true)) { + data = sr.ReadToEnd (); + } + } + catch (WebException web) { + cancel = (web.Status == WebExceptionStatus.RequestCanceled); + ex = web; + } + catch (Exception e) { + ex = e; + } + finally { + callback_data.sync_context.Post (delegate (object sender) { + OnDownloadStringCompleted (new DownloadStringCompletedEventArgs (data, ex, cancel, callback_data.user_token)); + }, null); } } -// // DownloadDataAsync -// -// public void DownloadDataAsync (Uri address) -// { -// DownloadDataAsync (address, null); -// } -// -// public void DownloadDataAsync (Uri address, object userToken) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// -// lock (this) { -// SetBusy (); -// async = true; -// -// async_thread = new Thread (delegate (object state) { -// object [] args = (object []) state; -// try { -// byte [] data = DownloadDataCore ((Uri) args [0], args [1]); -// OnDownloadDataCompleted ( -// new DownloadDataCompletedEventArgs (data, null, false, args [1])); -// } catch (ThreadInterruptedException){ -// OnDownloadDataCompleted ( -// new DownloadDataCompletedEventArgs (null, null, true, args [1])); -// throw; -// } catch (Exception e){ -// OnDownloadDataCompleted ( -// new DownloadDataCompletedEventArgs (null, e, false, args [1])); -// } -// }); -// object [] cb_args = new object [] {address, userToken}; -// async_thread.Start (cb_args); -// } -// } -// -// // DownloadFileAsync -// -// public void DownloadFileAsync (Uri address, string fileName) -// { -// DownloadFileAsync (address, fileName, null); -// } -// -// public void DownloadFileAsync (Uri address, string fileName, object userToken) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (fileName == null) -// throw new ArgumentNullException ("fileName"); -// -// lock (this) { -// SetBusy (); -// async = true; -// -// async_thread = new Thread (delegate (object state) { -// object [] args = (object []) state; -// try { -// DownloadFileCore ((Uri) args [0], (string) args [1], args [2]); -// OnDownloadFileCompleted ( -// new AsyncCompletedEventArgs (null, false, args [2])); -// } catch (ThreadInterruptedException){ -// OnDownloadFileCompleted ( -// new AsyncCompletedEventArgs (null, true, args [2])); -// } catch (Exception e){ -// OnDownloadFileCompleted ( -// new AsyncCompletedEventArgs (e, false, args [2])); -// }}); -// object [] cb_args = new object [] {address, fileName, userToken}; -// async_thread.Start (cb_args); -// } -// } -// -// // DownloadStringAsync -// -// public void DownloadStringAsync (Uri address) -// { -// DownloadStringAsync (address, null); -// } -// -// public void DownloadStringAsync (Uri address, object userToken) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// -// lock (this) { -// SetBusy (); -// async = true; -// -// async_thread = new Thread (delegate (object state) { -// object [] args = (object []) state; -// try { -// string data = encoding.GetString (DownloadDataCore ((Uri) args [0], args [1])); -// OnDownloadStringCompleted ( -// new DownloadStringCompletedEventArgs (data, null, false, args [1])); -// } catch (ThreadInterruptedException){ -// OnDownloadStringCompleted ( -// new DownloadStringCompletedEventArgs (null, null, true, args [1])); -// } catch (Exception e){ -// OnDownloadStringCompleted ( -// new DownloadStringCompletedEventArgs (null, e, false, args [1])); -// }}); -// object [] cb_args = new object [] {address, userToken}; -// async_thread.Start (cb_args); -// } -// } -// // OpenReadAsync public void OpenReadAsync (Uri address) @@ -1153,341 +288,285 @@ namespace System.Net if (address == null) throw new ArgumentNullException ("address"); - lock (this) { + lock (locker) { SetBusy (); - async = true; - - async_thread = new Thread (delegate (object state) { - object [] args = (object []) state; - WebRequest request = null; - try { - request = SetupRequest ((Uri) args [0]); - //WebResponse response = request.GetResponse (); - IAsyncResult asyncresult = request.BeginGetResponse (null, userToken); - asyncresult.AsyncWaitHandle.WaitOne (); - WebResponse response = request.EndGetResponse (asyncresult); - Stream stream = ProcessResponse (response); - OnOpenReadCompleted ( - new OpenReadCompletedEventArgs (stream, null, false, args [1])); - } catch (ThreadInterruptedException){ - if (request != null) - request.Abort (); - - OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, args [1])); - } catch (Exception e){ - OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, e, false, args [1])); - } }); - object [] cb_args = new object [] {address, userToken}; - async_thread.Start (cb_args); + + try { + request = SetupRequest (address, "GET", new CallbackData (userToken)); + request.BeginGetResponse (new AsyncCallback (OpenReadAsyncCallback), null); + } + catch (Exception e) { + WebException wex = new WebException ("Could not start operation.", e); + OnOpenReadCompleted ( + new OpenReadCompletedEventArgs (null, wex, false, userToken)); + } } } -// // OpenWriteAsync -// -// public void OpenWriteAsync (Uri address) -// { -// OpenWriteAsync (address, null); -// } -// -// public void OpenWriteAsync (Uri address, string method) -// { -// OpenWriteAsync (address, method, null); -// } -// -// public void OpenWriteAsync (Uri address, string method, object userToken) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// -// lock (this) { -// SetBusy (); -// async = true; -// -// async_thread = new Thread (delegate (object state) { -// object [] args = (object []) state; -// WebRequest request = null; -// try { -// request = SetupRequest ((Uri) args [0], (string) args [1]); -// Stream stream = request.GetRequestStream (); -// OnOpenWriteCompleted ( -// new OpenWriteCompletedEventArgs (stream, null, false, args [2])); -// } catch (ThreadInterruptedException){ -// if (request != null) -// request.Abort (); -// OnOpenWriteCompleted ( -// new OpenWriteCompletedEventArgs (null, null, true, args [2])); -// } catch (Exception e){ -// OnOpenWriteCompleted ( -// new OpenWriteCompletedEventArgs (null, e, false, args [2])); -// }}); -// object [] cb_args = new object [] {address, method, userToken}; -// async_thread.Start (cb_args); -// } -// } -// -// // UploadDataAsync -// -// public void UploadDataAsync (Uri address, byte [] data) -// { -// UploadDataAsync (address, null, data); -// } -// -// public void UploadDataAsync (Uri address, string method, byte [] data) -// { -// UploadDataAsync (address, method, data, null); -// } -// -// public void UploadDataAsync (Uri address, string method, byte [] data, object userToken) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (data == null) -// throw new ArgumentNullException ("data"); -// -// lock (this) { -// SetBusy (); -// async = true; -// -// async_thread = new Thread (delegate (object state) { -// object [] args = (object []) state; -// byte [] data2; -// -// try { -// data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]); -// -// OnUploadDataCompleted ( -// new UploadDataCompletedEventArgs (data2, null, false, args [3])); -// } catch (ThreadInterruptedException){ -// OnUploadDataCompleted ( -// new UploadDataCompletedEventArgs (null, null, true, args [3])); -// } catch (Exception e){ -// OnUploadDataCompleted ( -// new UploadDataCompletedEventArgs (null, e, false, args [3])); -// }}); -// object [] cb_args = new object [] {address, method, data, userToken}; -// async_thread.Start (cb_args); -// } -// } -// -// // UploadFileAsync -// -// public void UploadFileAsync (Uri address, string fileName) -// { -// UploadFileAsync (address, null, fileName); -// } -// -// public void UploadFileAsync (Uri address, string method, string fileName) -// { -// UploadFileAsync (address, method, fileName, null); -// } -// -// public void UploadFileAsync (Uri address, string method, string fileName, object userToken) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (fileName == null) -// throw new ArgumentNullException ("fileName"); -// -// lock (this) { -// SetBusy (); -// async = true; -// -// async_thread = new Thread (delegate (object state) { -// object [] args = (object []) state; -// byte [] data; -// -// try { -// data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]); -// OnUploadFileCompleted ( -// new UploadFileCompletedEventArgs (data, null, false, args [3])); -// } catch (ThreadInterruptedException){ -// OnUploadFileCompleted ( -// new UploadFileCompletedEventArgs (null, null, true, args [3])); -// } catch (Exception e){ -// OnUploadFileCompleted ( -// new UploadFileCompletedEventArgs (null, e, false, args [3])); -// }}); -// object [] cb_args = new object [] {address, method, fileName, userToken}; -// async_thread.Start (cb_args); -// } -// } -// -// // UploadStringAsync -// -// public void UploadStringAsync (Uri address, string data) -// { -// UploadStringAsync (address, null, data); -// } -// -// public void UploadStringAsync (Uri address, string method, string data) -// { -// UploadStringAsync (address, method, data, null); -// } -// -// public void UploadStringAsync (Uri address, string method, string data, object userToken) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (data == null) -// throw new ArgumentNullException ("data"); -// -// lock (this) { -// SetBusy (); -// async = true; -// -// async_thread = new Thread (delegate (object state) { -// object [] args = (object []) state; -// -// try { -// string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]); -// OnUploadStringCompleted ( -// new UploadStringCompletedEventArgs (data2, null, false, args [3])); -// } catch (ThreadInterruptedException){ -// OnUploadStringCompleted ( -// new UploadStringCompletedEventArgs (null, null, true, args [3])); -// } catch (Exception e){ -// OnUploadStringCompleted ( -// new UploadStringCompletedEventArgs (null, e, false, args [3])); -// }}); -// object [] cb_args = new object [] {address, method, data, userToken}; -// async_thread.Start (cb_args); -// } -// } -// -// // UploadValuesAsync -// -// public void UploadValuesAsync (Uri address, NameValueCollection values) -// { -// UploadValuesAsync (address, null, values); -// } -// -// public void UploadValuesAsync (Uri address, string method, NameValueCollection values) -// { -// UploadValuesAsync (address, method, values, null); -// } -// -// public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken) -// { -// if (address == null) -// throw new ArgumentNullException ("address"); -// if (values == null) -// throw new ArgumentNullException ("values"); -// -// lock (this) { -// CheckBusy (); -// async = true; -// -// async_thread = new Thread (delegate (object state) { -// object [] args = (object []) state; -// try { -// byte [] data = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]); -// OnUploadValuesCompleted ( -// new UploadValuesCompletedEventArgs (data, null, false, args [3])); -// } catch (ThreadInterruptedException){ -// OnUploadValuesCompleted ( -// new UploadValuesCompletedEventArgs (null, null, true, args [3])); -// } catch (Exception e){ -// OnUploadValuesCompleted ( -// new UploadValuesCompletedEventArgs (null, e, false, args [3])); -// }}); -// object [] cb_args = new object [] {address, method, values, userToken}; -// async_thread.Start (cb_args); -// } -// } -// -// protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args) -// { -// CompleteAsync (); -// if (DownloadDataCompleted != null) -// DownloadDataCompleted (this, args); -// } -// -// protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args) -// { -// CompleteAsync (); -// if (DownloadFileCompleted != null) -// DownloadFileCompleted (this, args); -// } -// - protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e) + private void OpenReadAsyncCallback (IAsyncResult result) { - if (DownloadProgressChanged != null) - DownloadProgressChanged (this, e); + Stream stream = null; + Exception ex = null; + bool cancel = false; + try { + WebResponse response = request.EndGetResponse (result); + stream = ProcessResponse (response); + } + catch (WebException web) { + cancel = (web.Status == WebExceptionStatus.RequestCanceled); + ex = web; + } + catch (Exception e) { + ex = e; + } + finally { + callback_data.sync_context.Post (delegate (object sender) { + OnOpenReadCompleted (new OpenReadCompletedEventArgs (stream, ex, cancel, callback_data.user_token)); + }, null); + } } -// protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args) -// { -// CompleteAsync (); -// if (DownloadStringCompleted != null) -// DownloadStringCompleted (this, args); -// } -// + // OpenWriteAsync + + public void OpenWriteAsync (Uri address) + { + OpenWriteAsync (address, null); + } + + public void OpenWriteAsync (Uri address, string method) + { + OpenWriteAsync (address, method, null); + } + + public void OpenWriteAsync (Uri address, string method, object userToken) + { + if (address == null) + throw new ArgumentNullException ("address"); + + lock (locker) { + SetBusy (); + + try { + request = SetupRequest (address, method, new CallbackData (userToken)); + request.BeginGetRequestStream (new AsyncCallback (OpenWriteAsyncCallback), null); + } + catch (Exception e) { + WebException wex = new WebException ("Could not start operation.", e); + OnOpenWriteCompleted ( + new OpenWriteCompletedEventArgs (null, wex, false, userToken)); + } + } + } + + private void OpenWriteAsyncCallback (IAsyncResult result) + { + Stream stream = null; + Exception ex = null; + bool cancel = false; + InternalWebRequestStreamWrapper internal_stream; + + try { + stream = request.EndGetRequestStream (result); + internal_stream = (InternalWebRequestStreamWrapper) stream; + internal_stream.WebClient = this; + internal_stream.WebClientData = callback_data; + } + catch (WebException web) { + cancel = (web.Status == WebExceptionStatus.RequestCanceled); + ex = web; + } + catch (Exception e) { + ex = e; + } + finally { + callback_data.sync_context.Post (delegate (object sender) { + OnOpenWriteCompleted (new OpenWriteCompletedEventArgs (stream, ex, cancel, callback_data.user_token)); + }, null); + } + } + + internal void WriteStreamClosedCallback (object WebClientData) + { + try { + request.BeginGetResponse (OpenWriteAsyncResponseCallback, WebClientData); + } + catch (Exception e) { + callback_data.sync_context.Post (delegate (object sender) { + OnWriteStreamClosed (new WriteStreamClosedEventArgs (e)); + }, null); + } + } + + private void OpenWriteAsyncResponseCallback (IAsyncResult result) + { + try { + WebResponse response = request.EndGetResponse (result); + ProcessResponse (response); + } + catch (Exception e) { + callback_data.sync_context.Post (delegate (object sender) { + OnWriteStreamClosed (new WriteStreamClosedEventArgs (e)); + }, null); + } + } + + // UploadStringAsync + + public void UploadStringAsync (Uri address, string data) + { + UploadStringAsync (address, null, data); + } + + public void UploadStringAsync (Uri address, string method, string data) + { + UploadStringAsync (address, method, data, null); + } + + public void UploadStringAsync (Uri address, string method, string data, object userToken) + { + if (address == null) + throw new ArgumentNullException ("address"); + if (data == null) + throw new ArgumentNullException ("data"); + + lock (locker) { + SetBusy (); + + try { + request = SetupRequest (address, method, new CallbackData (userToken, encoding.GetBytes (data))); + request.BeginGetRequestStream (new AsyncCallback (UploadStringRequestAsyncCallback), null); + } + catch (Exception e) { + WebException wex = new WebException ("Could not start operation.", e); + OnUploadStringCompleted ( + new UploadStringCompletedEventArgs (null, wex, false, userToken)); + } + } + } + + private void UploadStringRequestAsyncCallback (IAsyncResult result) + { + try { + Stream stream = request.EndGetRequestStream (result); + stream.Write (callback_data.data, 0, callback_data.data.Length); + request.BeginGetResponse (new AsyncCallback (UploadStringResponseAsyncCallback), null); + } + catch { + request.Abort (); + throw; + } + } + + private void UploadStringResponseAsyncCallback (IAsyncResult result) + { + string data = null; + Exception ex = null; + bool cancel = false; + try { + WebResponse response = request.EndGetResponse (result); + Stream stream = ProcessResponse (response); + + using (StreamReader sr = new StreamReader (stream, encoding, true)) { + data = sr.ReadToEnd (); + } + } + catch (WebException web) { + cancel = (web.Status == WebExceptionStatus.RequestCanceled); + ex = web; + } + catch (InvalidOperationException ioe) { + ex = new WebException ("An exception occurred during a WebClient request", ioe); + } + catch (Exception e) { + ex = e; + } + finally { + callback_data.sync_context.Post (delegate (object sender) { + OnUploadStringCompleted (new UploadStringCompletedEventArgs (data, ex, cancel, callback_data.user_token)); + }, null); + } + } + + protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e) + { + DownloadProgressChangedEventHandler handler = DownloadProgressChanged; + if (handler != null) + handler (this, e); + } + protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args) { CompleteAsync (); - if (OpenReadCompleted != null) - OpenReadCompleted (this, args); + OpenReadCompletedEventHandler handler = OpenReadCompleted; + if (handler != null) + handler (this, args); } -// protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args) -// { -// CompleteAsync (); -// if (OpenWriteCompleted != null) -// OpenWriteCompleted (this, args); -// } -// -// protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args) -// { -// CompleteAsync (); -// if (UploadDataCompleted != null) -// UploadDataCompleted (this, args); -// } -// -// protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args) -// { -// CompleteAsync (); -// if (UploadFileCompleted != null) -// UploadFileCompleted (this, args); -// } -// -// protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e) -// { -// if (UploadProgressChanged != null) -// UploadProgressChanged (this, e); -// } -// -// protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args) -// { -// CompleteAsync (); -// if (UploadStringCompleted != null) -// UploadStringCompleted (this, args); -// } -// -// protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args) -// { -// CompleteAsync (); -// if (UploadValuesCompleted != null) -// UploadValuesCompleted (this, args); -// } -// -// [MonoNotSupported("")] -// protected virtual WebRequest GetWebRequest (Uri address) -// { -// throw new NotImplementedException (); -// } -// -// protected virtual WebResponse GetWebResponse (WebRequest request) -// { -// return request.GetResponse (); -// } -// -// protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result) -// { -// return request.EndGetResponse (result); -// } -//#endif -#endif + protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args) + { + CompleteAsync (); + DownloadStringCompletedEventHandler handler = DownloadStringCompleted; + if (handler != null) + handler (this, args); + } + + protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args) + { + CompleteAsync (); + OpenWriteCompletedEventHandler handler = OpenWriteCompleted; + if (handler != null) + handler (this, args); + } + + protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e) + { + UploadProgressChangedEventHandler handler = UploadProgressChanged; + if (handler != null) + handler (this, e); + } + + protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args) + { + CompleteAsync (); + UploadStringCompletedEventHandler handler = UploadStringCompleted; + if (handler != null) + handler (this, args); + } + + protected virtual void OnWriteStreamClosed (WriteStreamClosedEventArgs e) + { + CompleteAsync (); + WriteStreamClosedEventHandler handler = WriteStreamClosed; + if (handler != null) + handler (this, e); + } + + protected virtual WebRequest GetWebRequest (Uri address) + { + if (address == null) + throw new ArgumentNullException ("address"); + + // if the URI is relative then we use our base address URI to make an absolute one + Uri uri = address.IsAbsoluteUri ? address : new Uri (new Uri (baseAddress), address); + + HttpWebRequest request = (HttpWebRequest) WebRequest.Create (uri); + request.AllowReadStreamBuffering = AllowReadStreamBuffering; + request.AllowWriteStreamBuffering = AllowWriteStreamBuffering; + request.UseDefaultCredentials = UseDefaultCredentials; + + request.progress = delegate (long read, long length) { + callback_data.sync_context.Post (delegate (object sender) { + OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (read, length, callback_data.user_token)); + }, null); + + }; + return request; + } + + protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result) + { + return request.EndGetResponse (result); + } } } -