Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Net / System / Net / webclient.cs / 1 / webclient.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net { using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Globalization; using System.Threading; using System.Net.Cache; using System.Runtime.Versioning; ////// [ComVisible(true)] public class WebClient : Component { // fields const int DefaultCopyBufferLength = 8192; const int DefaultDownloadBufferLength = 65536; const string DefaultUploadFileContentType = "application/octet-stream"; const string UploadFileContentType = "multipart/form-data"; const string UploadValuesContentType = "application/x-www-form-urlencoded"; Uri m_baseAddress; ICredentials m_credentials; WebHeaderCollection m_headers; NameValueCollection m_requestParameters; WebResponse m_WebResponse; WebRequest m_WebRequest; Encoding m_Encoding = Encoding.Default; string m_Method; long m_ContentLength = -1; bool m_InitWebClientAsync; bool m_Cancelled; ProgressData m_Progress; IWebProxy m_Proxy; bool m_ProxySet; RequestCachePolicy m_CachePolicy; // constructors ///[To be supplied.] ////// public WebClient() { } ///[To be supplied.] ////// private void InitWebClientAsync() { if (!m_InitWebClientAsync) { openReadOperationCompleted = new SendOrPostCallback(OpenReadOperationCompleted); openWriteOperationCompleted = new SendOrPostCallback(OpenWriteOperationCompleted); downloadStringOperationCompleted = new SendOrPostCallback(DownloadStringOperationCompleted); downloadDataOperationCompleted = new SendOrPostCallback(DownloadDataOperationCompleted); downloadFileOperationCompleted = new SendOrPostCallback(DownloadFileOperationCompleted); uploadStringOperationCompleted = new SendOrPostCallback(UploadStringOperationCompleted); uploadDataOperationCompleted = new SendOrPostCallback(UploadDataOperationCompleted); uploadFileOperationCompleted = new SendOrPostCallback(UploadFileOperationCompleted); uploadValuesOperationCompleted = new SendOrPostCallback(UploadValuesOperationCompleted); reportDownloadProgressChanged = new SendOrPostCallback(ReportDownloadProgressChanged); reportUploadProgressChanged = new SendOrPostCallback(ReportUploadProgressChanged); m_Progress = new ProgressData(); m_InitWebClientAsync = true; } } ///Sets up async delegates, we need to create these on every instance when async ////// private void ClearWebClientState() { if (AnotherCallInProgress(Interlocked.Increment(ref m_CallNesting))) { CompleteWebClientState(); throw new NotSupportedException(SR.GetString(SR.net_webclient_no_concurrent_io_allowed)); } m_ContentLength = -1; m_WebResponse = null; m_WebRequest = null; m_Method = null; m_Cancelled = false; if (m_Progress != null) m_Progress.Reset(); } ///Sets up shared properties, to prevent a previous request's state from interfering with this request /// ASSUMED to be called at the start of each WebClient api ////// private void CompleteWebClientState() { Interlocked.Decrement(ref m_CallNesting); } // properties ///Matching code for ClearWebClientState, MUST be matched with ClearWebClientState() calls ////// public Encoding Encoding { get { return m_Encoding; } set { if (value==null) { throw new ArgumentNullException("Encoding"); } m_Encoding = value; } } ///Sets the encoding type for converting string to byte[] on String based methods ////// public string BaseAddress { get { return (m_baseAddress == null) ? String.Empty : m_baseAddress.ToString(); } set { if ((value == null) || (value.Length == 0)) { m_baseAddress = null; } else { try { m_baseAddress = new Uri(value); } catch (UriFormatException e) { throw new ArgumentException(SR.GetString(SR.net_webclient_invalid_baseaddress), "value", e); } } } } ///[To be supplied.] ////// public ICredentials Credentials { get { return m_credentials; } set { m_credentials = value; } } ///[To be supplied.] ////// public bool UseDefaultCredentials { get { return (m_credentials is SystemNetworkCredential) ? true : false; } set { m_credentials = value ? CredentialCache.DefaultCredentials : null; } } ///Sets Credentials to CredentialCache.DefaultCredentials ////// public WebHeaderCollection Headers { get { if (m_headers == null) { m_headers = new WebHeaderCollection(WebHeaderCollectionType.WebRequest); } return m_headers; } set { m_headers = value; } } public NameValueCollection QueryString { get { if (m_requestParameters == null) { m_requestParameters = new NameValueCollection(); } return m_requestParameters; } set { m_requestParameters = value; } } public WebHeaderCollection ResponseHeaders { get { if (m_WebResponse != null) { return m_WebResponse.Headers; } return null; } } ///[To be supplied.] ////// public IWebProxy Proxy { get { ExceptionHelper.WebPermissionUnrestricted.Demand(); if (!m_ProxySet) { return WebRequest.InternalDefaultWebProxy; } else { return m_Proxy; } } set { ExceptionHelper.WebPermissionUnrestricted.Demand(); m_Proxy = value; m_ProxySet = true; } } public RequestCachePolicy CachePolicy { get { return m_CachePolicy; } set { m_CachePolicy = value; } } ////// Gets or sets the proxy information for a request. /// ////// public bool IsBusy { get { return m_AsyncOp != null; } } // methods ////// Indicates if the request is still in progress /// ////// protected virtual WebRequest GetWebRequest(Uri address) { WebRequest request = WebRequest.Create(address); CopyHeadersTo(request); if (Credentials != null) { request.Credentials = Credentials; } if (m_Method != null) { request.Method = m_Method; } if (m_ContentLength != -1) { request.ContentLength = m_ContentLength; } if (m_ProxySet) { request.Proxy = m_Proxy; } if (m_CachePolicy != null) { request.CachePolicy = m_CachePolicy; } return request; } ///Creates the WebRequest ////// protected virtual WebResponse GetWebResponse(WebRequest request) { WebResponse response = request.GetResponse(); m_WebResponse = response; return response; } ///Retrieves a WebResponse by calling GetResponse() ////// protected virtual WebResponse GetWebResponse(WebRequest request, IAsyncResult result) { WebResponse response = request.EndGetResponse(result); m_WebResponse = response; return response; } ///Retrieves a WebResponse by calling async EndGetResponse() ////// public byte[] DownloadData(string address) { if (address == null) throw new ArgumentNullException("address"); return DownloadData(GetUri(address)); } public byte[] DownloadData(Uri address) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadData", address); if (address == null) throw new ArgumentNullException("address"); ClearWebClientState(); byte[] result = null; try { WebRequest request; result = DownloadDataInternal(address, out request); if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadData", result); return result; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// private byte[] DownloadDataInternal(Uri address, out WebRequest request) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadData", address); request = null; try { request = m_WebRequest = GetWebRequest(GetUri(address)); byte [] returnBytes = DownloadBits(request, null, null, null); return returnBytes; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } } ///[To be supplied.] ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void DownloadFile(string address, string fileName) { if (address == null) throw new ArgumentNullException("address"); DownloadFile(GetUri(address), fileName); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void DownloadFile(Uri address, string fileName) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadFile", address+", "+fileName); if (address == null) throw new ArgumentNullException("address"); if (fileName == null) throw new ArgumentNullException("fileName"); WebRequest request = null; FileStream fs = null; bool succeeded = false; ClearWebClientState(); try { fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); request = m_WebRequest = GetWebRequest(GetUri(address)); DownloadBits(request, fs, null, null); succeeded = true; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { if (fs != null) { fs.Close(); if (!succeeded) { // Security Review: If we were able to create a file we should be able to delete it File.Delete(fileName); } fs = null; } CompleteWebClientState(); } if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadFile", ""); } ///[To be supplied.] ////// public Stream OpenRead(string address) { if (address == null) throw new ArgumentNullException("address"); return OpenRead(GetUri(address)); } public Stream OpenRead(Uri address) { if(Logging.On)Logging.Enter(Logging.Web, this, "OpenRead", address); if (address == null) throw new ArgumentNullException("address"); WebRequest request = null; ClearWebClientState(); try { request = m_WebRequest = GetWebRequest(GetUri(address)); WebResponse response = m_WebResponse = GetWebResponse(request); Stream stream = response.GetResponseStream(); if(Logging.On)Logging.Exit(Logging.Web, this, "OpenRead", stream); return stream; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// public Stream OpenWrite(string address) { if (address == null) throw new ArgumentNullException("address"); return OpenWrite(GetUri(address), null); } public Stream OpenWrite(Uri address) { return OpenWrite(address, null); } ///[To be supplied.] ////// public Stream OpenWrite(string address, string method) { if (address == null) throw new ArgumentNullException("address"); return OpenWrite(GetUri(address), method); } public Stream OpenWrite(Uri address, string method) { if(Logging.On)Logging.Enter(Logging.Web, this, "OpenWrite", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (method == null) { method = MapToDefaultMethod(address); } WebRequest request = null; ClearWebClientState(); try { m_Method = method; request = m_WebRequest = GetWebRequest(GetUri(address)); WebClientWriteStream webClientWriteStream = new WebClientWriteStream(request.GetRequestStream(), request, this); if(Logging.On)Logging.Exit(Logging.Web, this, "OpenWrite", webClientWriteStream); return webClientWriteStream; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// public byte[] UploadData(string address, byte[] data) { if (address == null) throw new ArgumentNullException("address"); return UploadData(GetUri(address), null, data); } public byte[] UploadData(Uri address, byte[] data) { return UploadData(address, null, data); } ///[To be supplied.] ////// public byte[] UploadData(string address, string method, byte[] data) { if (address == null) throw new ArgumentNullException("address"); return UploadData(GetUri(address), method, data); } public byte[] UploadData(Uri address, string method, byte[] data) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadData", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } ClearWebClientState(); try { WebRequest request; byte [] result = UploadDataInternal(address, method, data, out request); if(Logging.On)Logging.Exit(Logging.Web, this, "UploadData", result); return result; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// private byte[] UploadDataInternal(Uri address, string method, byte[] data, out WebRequest request) { request = null; try { m_Method = method; m_ContentLength = data.Length; request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, data, null, null, null, null); byte [] responseBytes = DownloadBits(request, null, null, null); return responseBytes; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } } ///Internal version of UploadData used for UploadString as well ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private void OpenFileInternal(bool needsHeaderAndBoundary, string fileName, ref FileStream fs, ref byte[] buffer, ref byte[] formHeaderBytes, ref byte[] boundaryBytes) { fileName = Path.GetFullPath(fileName); if (m_headers == null) { m_headers = new WebHeaderCollection(WebHeaderCollectionType.WebRequest); } string contentType = m_headers[HttpKnownHeaderNames.ContentType]; if (contentType != null) { if (contentType.ToLower(CultureInfo.InvariantCulture).StartsWith("multipart/")) { throw new WebException(SR.GetString(SR.net_webclient_Multipart)); } } else { contentType = DefaultUploadFileContentType; } fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); int buffSize = DefaultCopyBufferLength; m_ContentLength = -1; if (m_Method.ToUpper(CultureInfo.InvariantCulture) == "POST") { if (needsHeaderAndBoundary) { string boundary = "---------------------" + DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo); m_headers[HttpKnownHeaderNames.ContentType] = UploadFileContentType + "; boundary=" + boundary; string formHeader = "--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"" + Path.GetFileName(fileName) + "\"\r\n" + "Content-Type: " + contentType + "\r\n" + "\r\n"; formHeaderBytes = Encoding.UTF8.GetBytes(formHeader); boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); } else { formHeaderBytes = new byte[0]; boundaryBytes = new byte[0]; } if (fs.CanSeek) { m_ContentLength = fs.Length + formHeaderBytes.Length + boundaryBytes.Length; buffSize = (int)Math.Min((long)DefaultCopyBufferLength, fs.Length); } } else { m_headers[HttpKnownHeaderNames.ContentType] = contentType; formHeaderBytes = null; boundaryBytes = null; if (fs.CanSeek) { m_ContentLength = fs.Length; buffSize = (int) Math.Min((long) DefaultCopyBufferLength, fs.Length); } } buffer = new byte[buffSize]; } ///Open a fileStream and prepares data to send over a WebRequest ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public byte[] UploadFile(string address, string fileName) { if (address == null) throw new ArgumentNullException("address"); return UploadFile(GetUri(address), fileName); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public byte[] UploadFile(Uri address, string fileName) { return UploadFile(address, null, fileName); } ///[To be supplied.] ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public byte[] UploadFile(string address, string method, string fileName) { return UploadFile(GetUri(address), method, fileName); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public byte[] UploadFile(Uri address, string method, string fileName) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadFile", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (fileName == null) throw new ArgumentNullException("fileName"); if (method == null) { method = MapToDefaultMethod(address); } FileStream fs = null; WebRequest request = null; ClearWebClientState(); try { m_Method = method; byte [] formHeaderBytes = null, boundaryBytes = null, buffer = null; Uri uri = GetUri(address); bool needsHeaderAndBoundary = (uri.Scheme != Uri.UriSchemeFile); OpenFileInternal(needsHeaderAndBoundary, fileName, ref fs, ref buffer, ref formHeaderBytes, ref boundaryBytes); request = m_WebRequest = GetWebRequest(uri); UploadBits(request, fs, buffer, formHeaderBytes, boundaryBytes, null, null); byte [] responseBytes = DownloadBits(request, null, null, null); if(Logging.On)Logging.Exit(Logging.Web, this, "UploadFile", responseBytes); return responseBytes; } catch (Exception e) { if (fs != null) { fs.Close(); fs = null; } if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { if (fs != null) { fs.Close(); fs = null; } Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// private byte[] UploadValuesInternal(NameValueCollection data) { if (m_headers == null) { m_headers = new WebHeaderCollection(WebHeaderCollectionType.WebRequest); } string contentType = m_headers[HttpKnownHeaderNames.ContentType]; if ((contentType != null) && (String.Compare(contentType, UploadValuesContentType, StringComparison.OrdinalIgnoreCase) != 0)) { throw new WebException(SR.GetString(SR.net_webclient_ContentType)); } m_headers[HttpKnownHeaderNames.ContentType] = UploadValuesContentType; string delimiter = String.Empty; StringBuilder values = new StringBuilder(); foreach (string name in data.AllKeys) { values.Append(delimiter); values.Append( UrlEncode(name)); values.Append("="); values.Append(UrlEncode(data[name])); delimiter = "&"; } byte[] buffer = Encoding.ASCII.GetBytes(values.ToString()); m_ContentLength = buffer.Length; return buffer; } ///Shared code for UploadValues, creates a memory stream of data to send ////// public byte[] UploadValues(string address, NameValueCollection data) { if (address == null) throw new ArgumentNullException("address"); return UploadValues(GetUri(address), null, data); } public byte[] UploadValues(Uri address, NameValueCollection data) { return UploadValues(address, null, data); } ///[To be supplied.] ////// public byte[] UploadValues(string address, string method, NameValueCollection data) { if (address == null) throw new ArgumentNullException("address"); return UploadValues(GetUri(address), method, data); } public byte[] UploadValues(Uri address, string method, NameValueCollection data) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadValues", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } WebRequest request = null; ClearWebClientState(); try { byte[] buffer = UploadValuesInternal(data); m_Method = method; request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, buffer, null, null, null, null); byte [] returnBytes = DownloadBits(request, null, null, null); if(Logging.On)Logging.Exit(Logging.Web, this, "UploadValues", address +", "+method); return returnBytes; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { CompleteWebClientState(); } } // // String Methods - // ///[To be supplied.] ////// public string UploadString(string address, string data) { if (address == null) throw new ArgumentNullException("address"); return UploadString(GetUri(address), null, data); } public string UploadString(Uri address, string data) { return UploadString(address, null, data); } ///Uploads a string of data and returns a string of data ////// public string UploadString(string address, string method, string data) { if (address == null) throw new ArgumentNullException("address"); return UploadString(GetUri(address), method, data); } public string UploadString(Uri address, string method, string data) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadString", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } ClearWebClientState(); try { WebRequest request; byte [] requestData = Encoding.GetBytes(data); byte [] responseData = UploadDataInternal(address, method, requestData, out request); string responseStringData = GuessDownloadEncoding(request).GetString(responseData); if(Logging.On)Logging.Exit(Logging.Web, this, "UploadString", responseStringData); return responseStringData; } finally { CompleteWebClientState(); } } ///Uploads a string of data and returns a string of data ////// public string DownloadString(string address) { if (address == null) throw new ArgumentNullException("address"); return DownloadString(GetUri(address)); } public string DownloadString(Uri address) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadString", address); if (address == null) throw new ArgumentNullException("address"); ClearWebClientState(); try { WebRequest request; byte [] data = DownloadDataInternal(address, out request); string stringData = GuessDownloadEncoding(request).GetString(data); if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadString", stringData); return stringData; } finally { CompleteWebClientState(); } } ///Downloads a string from the server ////// private static void AbortRequest(WebRequest request) { try { if (request != null) { request.Abort(); } } catch (Exception exception) { if (exception is OutOfMemoryException || exception is StackOverflowException || exception is ThreadAbortException) { throw; } } catch { } } ///Aborts the request without throwing, so that we can prevent double errors ////// private void CopyHeadersTo(WebRequest request) { if ((m_headers != null) && (request is HttpWebRequest)) { string accept = m_headers[HttpKnownHeaderNames.Accept]; string connection = m_headers[HttpKnownHeaderNames.Connection]; string contentType = m_headers[HttpKnownHeaderNames.ContentType]; string expect = m_headers[HttpKnownHeaderNames.Expect]; string referrer = m_headers[HttpKnownHeaderNames.Referer]; string userAgent = m_headers[HttpKnownHeaderNames.UserAgent]; m_headers.RemoveInternal(HttpKnownHeaderNames.Accept); m_headers.RemoveInternal(HttpKnownHeaderNames.Connection); m_headers.RemoveInternal(HttpKnownHeaderNames.ContentType); m_headers.RemoveInternal(HttpKnownHeaderNames.Expect); m_headers.RemoveInternal(HttpKnownHeaderNames.Referer); m_headers.RemoveInternal(HttpKnownHeaderNames.UserAgent); request.Headers = m_headers; if ((accept != null) && (accept.Length > 0)) { ((HttpWebRequest)request).Accept = accept; } if ((connection != null) && (connection.Length > 0)) { ((HttpWebRequest)request).Connection = connection; } if ((contentType != null) && (contentType.Length > 0)) { ((HttpWebRequest)request).ContentType = contentType; } if ((expect != null) && (expect.Length > 0)) { ((HttpWebRequest)request).Expect = expect; } if ((referrer != null) && (referrer.Length > 0)) { ((HttpWebRequest)request).Referer = referrer; } if ((userAgent != null) && (userAgent.Length > 0)) { ((HttpWebRequest)request).UserAgent = userAgent; } } } ///Copies HTTP headers to a HttpWebRequest.Headers property ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private Uri GetUri(string path) { Uri uri; if (m_baseAddress != null) { if (!Uri.TryCreate(m_baseAddress, path, out uri)) return new Uri(Path.GetFullPath(path)); } else { if (!Uri.TryCreate(path, UriKind.Absolute, out uri)) return new Uri(Path.GetFullPath(path)); } return GetUri(uri); } ///Parses the string uri into a properly formed uri - uses Uri class ////// private Uri GetUri(Uri address) { if (address == null) throw new ArgumentNullException("address"); Uri uri = address; if (!address.IsAbsoluteUri && m_baseAddress != null) { if (!Uri.TryCreate(m_baseAddress, address, out uri)) return address; } if ((uri.Query == null || uri.Query == string.Empty) && m_requestParameters != null) { StringBuilder sb = new StringBuilder(); string delimiter = String.Empty; for (int i = 0; i < m_requestParameters.Count; ++i) { sb.Append(delimiter + m_requestParameters.AllKeys[i] + "=" + m_requestParameters[i] ); delimiter = "&"; } UriBuilder ub = new UriBuilder(uri); ub.Query = sb.ToString(); uri = ub.Uri; } return uri; } // // ProgressData // Keeps track of overall operation progress // Used by async operations for client updates, especially to hold state from the upload phase to download. // private class ProgressData { internal long BytesSent = 0; internal long TotalBytesToSend = -1; internal long BytesReceived = 0; internal long TotalBytesToReceive = -1; internal bool HasUploadPhase = false; internal void Reset() { BytesSent = 0; TotalBytesToSend = -1; BytesReceived = 0; TotalBytesToReceive = -1; HasUploadPhase = false; } } // // DownloadBits - // works by abstracting the process of downloading using WebRequest.GetResponse() // 3 levels of functions/methods are used for this process // // 1. DownloadBits - generates a state object of DownloadBitsState, then // starts the async GetResponse(), or drives calls directly to // DownloadBitsState.SetResponse() and DownloadBitsState.RetrieveBytes // // 2. DownloadBitsResponseCallback and DownloadBitsReadCallback - // Abstracts the async EndGetResponse and Stream.EndRead // calls from the process of downloading data. Notifies the caller of // DownloadBits through a callback when completed. Catches exceptions // and errors and passes them through the callback // // 3. DownloadBitsState.SetResponse() and DownloadBitsState.RetrieveBytes - // Updates the state of the download by seeding variables and pumps // data through the streams and structures // // ///Parses the string uri into a properly formed uri - uses Uri class ////// private class DownloadBitsState { internal WebClient WebClient; internal Stream WriteStream; internal byte[] InnerBuffer; internal AsyncOperation AsyncOp; internal WebRequest Request; internal CompletionDelegate CompletionDelegate; internal Stream ReadStream; internal ScatterGatherBuffers SgBuffers; internal DownloadBitsState(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp, ProgressData progress, WebClient webClient) { WriteStream = writeStream; Request = request; AsyncOp = asyncOp; CompletionDelegate = completionDelegate; WebClient = webClient; Progress = progress; } internal long ContentLength; internal long Length; internal int Offset; internal ProgressData Progress; internal bool Async { get { return AsyncOp != null; } } internal int SetResponse(WebResponse response) { ContentLength = response.ContentLength; if (ContentLength == -1 || ContentLength > DefaultDownloadBufferLength) { Length = DefaultDownloadBufferLength; // Read buffer length } else { Length = ContentLength; // Read buffer length } // If we are not writing to a stream, we are accumulating in memory if (WriteStream == null) { // We are putting a cap on the size we will accumulate in memory if (ContentLength > Int32.MaxValue) { throw new WebException(SR.GetString(SR.net_webstatus_MessageLengthLimitExceeded), WebExceptionStatus.MessageLengthLimitExceeded); } SgBuffers = new ScatterGatherBuffers(Length); // Write buffer } InnerBuffer = new byte[(int)Length]; ReadStream = response.GetResponseStream(); if (Async && response.ContentLength >= 0) Progress.TotalBytesToReceive = response.ContentLength; if (Async) { if (ReadStream == null || ReadStream == Stream.Null) DownloadBitsReadCallbackState(this, null); else ReadStream.BeginRead(InnerBuffer, Offset, (int)Length-Offset, new AsyncCallback(DownloadBitsReadCallback), this); } else { if (ReadStream == null || ReadStream == Stream.Null) return 0; else return ReadStream.Read(InnerBuffer, Offset, (int)Length-Offset); } return -1; } internal bool RetrieveBytes(ref int bytesRetrieved) { if (bytesRetrieved > 0) { if (WriteStream != null) { WriteStream.Write(InnerBuffer, 0, bytesRetrieved); } else { SgBuffers.Write(InnerBuffer, 0, bytesRetrieved); } if (Async) Progress.BytesReceived += bytesRetrieved; if (Offset != ContentLength) { if (Async) { WebClient.PostProgressChanged(AsyncOp, Progress); ReadStream.BeginRead(InnerBuffer, Offset, (int)Length-Offset, new AsyncCallback(DownloadBitsReadCallback), this); } else { bytesRetrieved = ReadStream.Read(InnerBuffer, Offset, (int)Length-Offset); } return false; } } // Final change notification if (Async) { if (Progress.TotalBytesToReceive < 0) Progress.TotalBytesToReceive = Progress.BytesReceived; WebClient.PostProgressChanged(AsyncOp, Progress); } // completed here if (ReadStream != null) ReadStream.Close(); if (WriteStream != null) { WriteStream.Close(); } else { if (WriteStream == null) { // We are using Scatter-Gather buffers byte[] newbuf = new byte[SgBuffers.Length]; if (SgBuffers.Length > 0) { BufferOffsetSize[] bufferArray = SgBuffers.GetBuffers(); int newBufOffset = 0; for (int i=0; iHolds the state and handles the basic async logic of downloading ////// Generates a byte array or downloads data to an open file stream /// private byte[] DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp) { WebResponse response = null; DownloadBitsState state = new DownloadBitsState(request, writeStream, completionDelegate, asyncOp, m_Progress, this); if (state.Async) { request.BeginGetResponse(new AsyncCallback(DownloadBitsResponseCallback), state); return null; } else { response = m_WebResponse = GetWebResponse(request); } bool completed; int bytesRead = state.SetResponse(response); do { completed = state.RetrieveBytes(ref bytesRead); } while (!completed); state.Close(); return state.InnerBuffer; } // // UploadBits - // works by abstracting the process of uploading using WebRequest.GetRequestStream() // 3 levels of functions/methods are used for this process // // 1. UploadBits - generates a state object of UploadBitsState, then // starts the async GetRequestStream, or drives calls directly to // UploadBitsState.SetRequestStream() and UploadBitsState.WriteBytes // // 2. UploadBitsRequestCallback and UploadBitsWriteCallback - // Abstracts the async EndGetRequestStream and Stream.EndWrite // calls from the process of uploading data. Notifies the caller of // UploadBits through a callback when completed. // // 3. UploadBitsState.SetRequestStream() and UploadBitsState.WriteBytes - // Updates the state of the upload by seeding variables and pumps // data through the streams and structures // // ////// private class UploadBitsState { internal WebClient WebClient; internal Stream WriteStream; internal byte[] InnerBuffer; internal byte[] Header; internal byte[] Footer; internal AsyncOperation AsyncOp; internal WebRequest Request; internal CompletionDelegate CompletionDelegate; internal Stream ReadStream; internal UploadBitsState(WebRequest request, Stream readStream, byte [] buffer, byte [] header, byte [] footer, CompletionDelegate completionDelegate, AsyncOperation asyncOp, ProgressData progress, WebClient webClient) { InnerBuffer = buffer; Header = header; Footer = footer; ReadStream = readStream; Request = request; AsyncOp = asyncOp; CompletionDelegate = completionDelegate; if (AsyncOp != null) { Progress = progress; Progress.HasUploadPhase = true; Progress.TotalBytesToSend = request.ContentLength < 0 ? -1 : request.ContentLength; } WebClient = webClient; } internal long Length; internal int Offset; internal ProgressData Progress; internal bool FileUpload { get { return ReadStream != null; } } internal bool Async { get { return AsyncOp != null; } } internal void SetRequestStream(Stream writeStream) { WriteStream = writeStream; byte [] bytesToWrite = null; if (Header != null) { bytesToWrite = Header; Header = null; } else { bytesToWrite = new byte[0]; } if (Async) { Progress.BytesSent += bytesToWrite.Length; WriteStream.BeginWrite(bytesToWrite, 0, bytesToWrite.Length, new AsyncCallback(UploadBitsWriteCallback), this); } else { WriteStream.Write(bytesToWrite, 0, bytesToWrite.Length); } } internal bool WriteBytes() { byte [] bytesToWrite = null; int bytesToWriteLength = 0; if (Async) { WebClient.PostProgressChanged(AsyncOp, Progress); } if (FileUpload) { int bytesRead = 0; if (InnerBuffer != null) { bytesRead = ReadStream.Read(InnerBuffer, 0, (int)InnerBuffer.Length); if (bytesRead <= 0) { ReadStream.Close(); InnerBuffer = null; } } if (InnerBuffer != null) { bytesToWriteLength = bytesRead; bytesToWrite = InnerBuffer; } else if (Footer != null) { bytesToWriteLength = Footer.Length; bytesToWrite = Footer; Footer = null; } else { return true; // completed } } else if (InnerBuffer != null) { bytesToWriteLength = InnerBuffer.Length; bytesToWrite = InnerBuffer; InnerBuffer = null; } else { return true; // completed } if (Async) { Progress.BytesSent += bytesToWriteLength; WriteStream.BeginWrite(bytesToWrite, 0, bytesToWriteLength, new AsyncCallback(UploadBitsWriteCallback), this); } else { WriteStream.Write(bytesToWrite, 0, bytesToWriteLength); } return false; // not complete } internal void Close() { if (WriteStream != null) { WriteStream.Close(); } if (ReadStream != null) { ReadStream.Close(); } } } static private void UploadBitsRequestCallback(IAsyncResult result) { UploadBitsState state = (UploadBitsState) result.AsyncState; WebRequest request = (WebRequest) state.Request; Exception exception = null; try { Stream stream = request.EndGetRequestStream(result); state.SetRequestStream(stream); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; if (!(e is WebException || e is SecurityException)) { exception = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); if(state != null && state.ReadStream != null){ state.ReadStream.Close(); } } finally { if (exception != null) { state.CompletionDelegate(null, exception, state.AsyncOp); } } } static private void UploadBitsWriteCallback(IAsyncResult result) { UploadBitsState state = (UploadBitsState) result.AsyncState; Stream stream = (Stream) state.WriteStream; Exception exception = null; bool completed = false; try { stream.EndWrite(result); completed = state.WriteBytes(); } catch (Exception e) { completed = true; if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; if (!(e is WebException || e is SecurityException)) { exception = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(state.Request); if(state != null && state.ReadStream != null){ state.ReadStream.Close(); } } finally { if (completed) { if(exception == null){ state.Close(); } state.CompletionDelegate(null, exception, state.AsyncOp); } } } ///Holds the state and handles the basic async logic of uploading ////// private void UploadBits(WebRequest request, Stream readStream, byte[] buffer, byte [] header, byte [] footer, CompletionDelegate completionDelegate, AsyncOperation asyncOp) { if (request.RequestUri.Scheme == Uri.UriSchemeFile) header = footer = null; UploadBitsState state = new UploadBitsState(request, readStream, buffer, header, footer, completionDelegate, asyncOp, m_Progress, this); Stream writeStream; if (state.Async) { request.BeginGetRequestStream(new AsyncCallback(UploadBitsRequestCallback), state); return; } else { writeStream = request.GetRequestStream(); } state.SetRequestStream(writeStream); while(!state.WriteBytes()); state.Close(); } ///Takes a byte array or an open file stream and writes it to a server ////// private Encoding GuessDownloadEncoding(WebRequest request) { try { string contentType; if ((contentType = request.ContentType) == null) { return this.Encoding; } contentType = contentType.ToLower(CultureInfo.InvariantCulture); string [] parsedList = contentType.Split(new char [] {';','=',' '}); bool nextItem = false; foreach (string item in parsedList) { if (item == "charset") { nextItem = true; } else if (nextItem) { return Encoding.GetEncoding(item); } } } catch(Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } } catch { } return this.Encoding; } /* // Consider removing. private string MapToDefaultMethod(string address) { Uri uri; if (m_baseAddress != null) { uri = new Uri(m_baseAddress, address); } else { uri = new Uri(address); } return MapToDefaultMethod(uri); } */ private string MapToDefaultMethod(Uri address) { Uri uri; if (!address.IsAbsoluteUri && m_baseAddress != null) { uri = new Uri(m_baseAddress, address); } else { uri = address; } if (uri.Scheme.ToLower(CultureInfo.InvariantCulture) == "ftp") { return WebRequestMethods.Ftp.UploadFile; } else { return "POST"; } } private static string UrlEncode(string str) { if (str == null) return null; return UrlEncode(str, Encoding.UTF8); } private static string UrlEncode(string str, Encoding e) { if (str == null) return null; return Encoding.ASCII.GetString(UrlEncodeToBytes(str, e)); } private static byte[] UrlEncodeToBytes(string str, Encoding e) { if (str == null) return null; byte[] bytes = e.GetBytes(str); return UrlEncodeBytesToBytesInternal(bytes, 0, bytes.Length, false); } private static byte[] UrlEncodeBytesToBytesInternal(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue) { int cSpaces = 0; int cUnsafe = 0; // count them first for (int i = 0; i < count; i++) { char ch = (char)bytes[offset+i]; if (ch == ' ') cSpaces++; else if (!IsSafe(ch)) cUnsafe++; } // nothing to expand? if (!alwaysCreateReturnValue && cSpaces == 0 && cUnsafe == 0) return bytes; // expand not 'safe' characters into %XX, spaces to +s byte[] expandedBytes = new byte[count + cUnsafe*2]; int pos = 0; for (int i = 0; i < count; i++) { byte b = bytes[offset+i]; char ch = (char)b; if (IsSafe(ch)) { expandedBytes[pos++] = b; } else if (ch == ' ') { expandedBytes[pos++] = (byte)'+'; } else { expandedBytes[pos++] = (byte)'%'; expandedBytes[pos++] = (byte)IntToHex((b >> 4) & 0xf); expandedBytes[pos++] = (byte)IntToHex(b & 0x0f); } } return expandedBytes; } private static char IntToHex(int n) { Debug.Assert(n < 0x10); if (n <= 9) return(char)(n + (int)'0'); else return(char)(n - 10 + (int)'a'); } private static bool IsSafe(char ch) { if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9') return true; switch (ch) { case '-': case '_': case '.': case '!': case '*': case '\'': case '(': case ')': return true; } return false; } private int m_CallNesting; // > 0 if we're in a Read/Write call private AsyncOperation m_AsyncOp; private void InvokeOperationCompleted(AsyncOperation asyncOp, SendOrPostCallback callback, AsyncCompletedEventArgs eventArgs) { if ((object)Interlocked.CompareExchangeParses a string of the form: /// text/html; charset=ISO-8859-4 /// and should return the Encoding form of "ISO-8859-4" portion /// ///(ref m_AsyncOp, null, asyncOp) == (object) asyncOp) { CompleteWebClientState(); // AsyncOperationManager is responsible for invoke the callback asyncOp.PostOperationCompleted(callback, eventArgs); } } private bool AnotherCallInProgress(int callNesting) { return callNesting>1; } // // Async methods and strucs - // See spec models at the following addresses: // http://dotnetclient/whidbey/M2%20Specs/AsynchronousOperationManager.doc // http://dotnetclient/whidbey/M2%20Specs/Guidelines%20and%20Usage%20Model%20for%20Asynchronous%20Pattern%20for%20Components.doc // // // OpenRead // public event OpenReadCompletedEventHandler OpenReadCompleted; protected virtual void OnOpenReadCompleted(OpenReadCompletedEventArgs e) { if (OpenReadCompleted != null) { OpenReadCompleted(this, e); } } private SendOrPostCallback openReadOperationCompleted; private void OpenReadOperationCompleted(object arg) { OnOpenReadCompleted((OpenReadCompletedEventArgs)arg); } private void OpenReadAsyncCallback(IAsyncResult result) { LazyAsyncResult lazyAsyncResult = (LazyAsyncResult) result; AsyncOperation asyncOp = (AsyncOperation) lazyAsyncResult.AsyncState; WebRequest request = (WebRequest) lazyAsyncResult.AsyncObject; Stream stream = null; Exception exception = null; try { WebResponse response = m_WebResponse = GetWebResponse(request, result); stream = response.GetResponseStream(); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; if (!(e is WebException || e is SecurityException)) { exception = new WebException(SR.GetString(SR.net_webclient), e); } } catch { exception = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } OpenReadCompletedEventArgs eventArgs = new OpenReadCompletedEventArgs(stream, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openReadOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void OpenReadAsync(Uri address) { OpenReadAsync(address, null); } [HostProtection(ExternalThreading=true)] public void OpenReadAsync(Uri address, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "OpenReadAsync", address); if (address == null) throw new ArgumentNullException("address"); InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); request.BeginGetResponse(new AsyncCallback(OpenReadAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } OpenReadCompletedEventArgs eventArgs = new OpenReadCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openReadOperationCompleted, eventArgs); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); OpenReadCompletedEventArgs eventArgs = new OpenReadCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openReadOperationCompleted, eventArgs); } if(Logging.On)Logging.Exit(Logging.Web, this, "OpenReadAsync", null); } // //OpenWrite // public event OpenWriteCompletedEventHandler OpenWriteCompleted; protected virtual void OnOpenWriteCompleted(OpenWriteCompletedEventArgs e) { if (OpenWriteCompleted != null) { OpenWriteCompleted(this, e); } } private SendOrPostCallback openWriteOperationCompleted; private void OpenWriteOperationCompleted(object arg) { OnOpenWriteCompleted((OpenWriteCompletedEventArgs)arg); } private void OpenWriteAsyncCallback(IAsyncResult result) { LazyAsyncResult lazyAsyncResult = (LazyAsyncResult) result; AsyncOperation asyncOp = (AsyncOperation) lazyAsyncResult.AsyncState; WebRequest request = (WebRequest) lazyAsyncResult.AsyncObject; WebClientWriteStream stream = null; Exception exception = null; try { stream = new WebClientWriteStream(request.EndGetRequestStream(result), request, this); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; if (!(e is WebException || e is SecurityException)) { exception = new WebException(SR.GetString(SR.net_webclient), e); } } catch { exception = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } OpenWriteCompletedEventArgs eventArgs = new OpenWriteCompletedEventArgs(stream, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openWriteOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void OpenWriteAsync(Uri address) { OpenWriteAsync(address, null, null); } [HostProtection(ExternalThreading=true)] public void OpenWriteAsync(Uri address, string method) { OpenWriteAsync(address, method, null); } [HostProtection(ExternalThreading=true)] public void OpenWriteAsync(Uri address, string method, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "OpenWriteAsync", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { m_Method = method; WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); request.BeginGetRequestStream(new AsyncCallback(OpenWriteAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } OpenWriteCompletedEventArgs eventArgs = new OpenWriteCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openWriteOperationCompleted, eventArgs); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); OpenWriteCompletedEventArgs eventArgs = new OpenWriteCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openWriteOperationCompleted, eventArgs); } if(Logging.On)Logging.Exit(Logging.Web, this, "OpenWriteAsync", null); } // //DownloadString // public event DownloadStringCompletedEventHandler DownloadStringCompleted; protected virtual void OnDownloadStringCompleted(DownloadStringCompletedEventArgs e) { if (DownloadStringCompleted != null) { DownloadStringCompleted(this, e); } } private SendOrPostCallback downloadStringOperationCompleted; private void DownloadStringOperationCompleted(object arg) { OnDownloadStringCompleted((DownloadStringCompletedEventArgs)arg); } private void DownloadStringAsyncCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { string stringData = null; try { if (returnBytes != null) { stringData = GuessDownloadEncoding(m_WebRequest).GetString(returnBytes); } } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; } catch { exception = new Exception(SR.GetString(SR.net_nonClsCompliantException)); } DownloadStringCompletedEventArgs eventArgs = new DownloadStringCompletedEventArgs(stringData, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, downloadStringOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void DownloadStringAsync(Uri address) { DownloadStringAsync(address, null); } [HostProtection(ExternalThreading=true)] public void DownloadStringAsync(Uri address, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadStringAsync", address); if (address == null) throw new ArgumentNullException("address"); InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); DownloadBits(request, null, new CompletionDelegate(DownloadStringAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } DownloadStringAsyncCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); DownloadStringAsyncCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadStringAsync", ""); } // //DownloadData // public event DownloadDataCompletedEventHandler DownloadDataCompleted; protected virtual void OnDownloadDataCompleted(DownloadDataCompletedEventArgs e) { if (DownloadDataCompleted != null) { DownloadDataCompleted(this, e); } } private SendOrPostCallback downloadDataOperationCompleted; private void DownloadDataOperationCompleted(object arg) { OnDownloadDataCompleted((DownloadDataCompletedEventArgs)arg); } private void DownloadDataAsyncCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { DownloadDataCompletedEventArgs eventArgs = new DownloadDataCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, downloadDataOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void DownloadDataAsync(Uri address) { DownloadDataAsync(address, null); } [HostProtection(ExternalThreading=true)] public void DownloadDataAsync(Uri address, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadDataAsync", address); if (address == null) throw new ArgumentNullException("address"); InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); DownloadBits(request, null, new CompletionDelegate(DownloadDataAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } DownloadDataAsyncCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); DownloadDataAsyncCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadDataAsync", null); } // //DownloadFile // public event AsyncCompletedEventHandler DownloadFileCompleted; protected virtual void OnDownloadFileCompleted(AsyncCompletedEventArgs e) { if (DownloadFileCompleted != null) { DownloadFileCompleted(this, e); } } private SendOrPostCallback downloadFileOperationCompleted; private void DownloadFileOperationCompleted(object arg) { OnDownloadFileCompleted((AsyncCompletedEventArgs)arg); } private void DownloadFileAsyncCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { AsyncCompletedEventArgs eventArgs = new AsyncCompletedEventArgs(exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, downloadFileOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void DownloadFileAsync(Uri address, string fileName) { DownloadFileAsync(address, fileName, null); } [HostProtection(ExternalThreading=true)] public void DownloadFileAsync(Uri address, string fileName, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadFileAsync", address); if (address == null) throw new ArgumentNullException("address"); if (fileName == null) throw new ArgumentNullException("fileName"); FileStream fs = null; InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); DownloadBits(request, fs, new CompletionDelegate(DownloadFileAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if(fs != null){ fs.Close(); } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } DownloadFileAsyncCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadFileAsync", null); } // //UploadString // public event UploadStringCompletedEventHandler UploadStringCompleted; protected virtual void OnUploadStringCompleted(UploadStringCompletedEventArgs e) { if (UploadStringCompleted != null) { UploadStringCompleted(this, e); } } private SendOrPostCallback uploadStringOperationCompleted; private void UploadStringOperationCompleted(object arg) { OnUploadStringCompleted((UploadStringCompletedEventArgs)arg); } private void UploadStringAsyncWriteCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { if (exception != null) { UploadStringCompletedEventArgs eventArgs = new UploadStringCompletedEventArgs(null, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadStringOperationCompleted, eventArgs); } } private void UploadStringAsyncReadCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { string stringData = null; try { if (returnBytes != null) { stringData = GuessDownloadEncoding(m_WebRequest).GetString(returnBytes); } } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; } catch { exception = new Exception(SR.GetString(SR.net_nonClsCompliantException)); } UploadStringCompletedEventArgs eventArgs = new UploadStringCompletedEventArgs(stringData, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadStringOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void UploadStringAsync(Uri address, string data) { UploadStringAsync(address, null, data, null); } [HostProtection(ExternalThreading=true)] public void UploadStringAsync(Uri address, string method, string data) { UploadStringAsync(address, method, data, null); } [HostProtection(ExternalThreading=true)] public void UploadStringAsync(Uri address, string method, string data, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadStringAsync", address); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { byte [] requestData = Encoding.GetBytes(data); m_Method = method; m_ContentLength = requestData.Length; WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, requestData, null, null, new CompletionDelegate(UploadStringAsyncWriteCallback), asyncOp); DownloadBits(request, null, new CompletionDelegate(UploadStringAsyncReadCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } UploadStringAsyncWriteCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); UploadStringAsyncWriteCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "UploadStringAsync", null); } // //UploadData // public event UploadDataCompletedEventHandler UploadDataCompleted; protected virtual void OnUploadDataCompleted(UploadDataCompletedEventArgs e) { if (UploadDataCompleted != null) { UploadDataCompleted(this, e); } } private SendOrPostCallback uploadDataOperationCompleted; private void UploadDataOperationCompleted(object arg) { OnUploadDataCompleted((UploadDataCompletedEventArgs)arg); } private void UploadDataAsyncWriteCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { if (exception != null) { UploadDataCompletedEventArgs eventArgs = new UploadDataCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadDataOperationCompleted, eventArgs); } } private void UploadDataAsyncReadCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { UploadDataCompletedEventArgs eventArgs = new UploadDataCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadDataOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void UploadDataAsync(Uri address, byte[] data) { UploadDataAsync(address, null, data, null); } [HostProtection(ExternalThreading=true)] public void UploadDataAsync(Uri address, string method, byte[] data) { UploadDataAsync(address, method, data, null); } [HostProtection(ExternalThreading=true)] public void UploadDataAsync(Uri address, string method, byte[] data, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadDataAsync", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { m_Method = method; m_ContentLength = data.Length; WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, data, null, null, new CompletionDelegate(UploadDataAsyncWriteCallback), asyncOp); DownloadBits(request, null, new CompletionDelegate(UploadDataAsyncReadCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } UploadDataAsyncWriteCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); UploadDataAsyncWriteCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "UploadDataAsync", null); } // //UploadFile // public event UploadFileCompletedEventHandler UploadFileCompleted; protected virtual void OnUploadFileCompleted(UploadFileCompletedEventArgs e) { if (UploadFileCompleted != null) { UploadFileCompleted(this, e); } } private SendOrPostCallback uploadFileOperationCompleted; private void UploadFileOperationCompleted(object arg) { OnUploadFileCompleted((UploadFileCompletedEventArgs)arg); } private void UploadFileAsyncWriteCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { if (exception != null) { UploadFileCompletedEventArgs eventArgs = new UploadFileCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadFileOperationCompleted, eventArgs); } } private void UploadFileAsyncReadCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { UploadFileCompletedEventArgs eventArgs = new UploadFileCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadFileOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void UploadFileAsync(Uri address, string fileName) { UploadFileAsync(address, null, fileName, null); } [HostProtection(ExternalThreading=true)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void UploadFileAsync(Uri address, string method, string fileName) { UploadFileAsync(address, method, fileName, null); } [HostProtection(ExternalThreading=true)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void UploadFileAsync(Uri address, string method, string fileName, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadFileAsync", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (fileName == null) throw new ArgumentNullException("fileName"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; FileStream fs = null; try { m_Method = method; byte [] formHeaderBytes = null, boundaryBytes = null, buffer = null; Uri uri = GetUri(address); bool needsHeaderAndBoundary = (uri.Scheme != Uri.UriSchemeFile); OpenFileInternal(needsHeaderAndBoundary, fileName, ref fs, ref buffer, ref formHeaderBytes, ref boundaryBytes); WebRequest request = m_WebRequest = GetWebRequest(uri); UploadBits(request, fs, buffer, formHeaderBytes, boundaryBytes, new CompletionDelegate(UploadFileAsyncWriteCallback), asyncOp); DownloadBits(request, null, new CompletionDelegate(UploadFileAsyncReadCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if(fs != null){ fs.Close(); } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } UploadFileAsyncWriteCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "UploadFileAsync", null); } // //UploadValues // public event UploadValuesCompletedEventHandler UploadValuesCompleted; protected virtual void OnUploadValuesCompleted(UploadValuesCompletedEventArgs e) { if (UploadValuesCompleted != null) { UploadValuesCompleted(this, e); } } private SendOrPostCallback uploadValuesOperationCompleted; private void UploadValuesOperationCompleted(object arg) { OnUploadValuesCompleted((UploadValuesCompletedEventArgs)arg); } private void UploadValuesAsyncWriteCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { if (exception != null) { UploadValuesCompletedEventArgs eventArgs = new UploadValuesCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadValuesOperationCompleted, eventArgs); } } private void UploadValuesAsyncReadCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { UploadValuesCompletedEventArgs eventArgs = new UploadValuesCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadValuesOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void UploadValuesAsync(Uri address, NameValueCollection data) { UploadValuesAsync(address, null, data, null); } [HostProtection(ExternalThreading=true)] public void UploadValuesAsync(Uri address, string method, NameValueCollection data) { UploadValuesAsync(address, method, data, null); } [HostProtection(ExternalThreading=true)] public void UploadValuesAsync(Uri address, string method, NameValueCollection data, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadValuesAsync", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { byte[] buffer = UploadValuesInternal(data); m_Method = method; WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, buffer, null, null, new CompletionDelegate(UploadValuesAsyncWriteCallback), asyncOp); DownloadBits(request, null, new CompletionDelegate(UploadValuesAsyncReadCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } UploadValuesAsyncWriteCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); UploadValuesAsyncWriteCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "UploadValuesAsync", null); } public void CancelAsync() { WebRequest request = m_WebRequest; m_Cancelled = true; AbortRequest(request); } // //ProgressChanged event - code for handling progress updates during uploads and downloads. // public event DownloadProgressChangedEventHandler DownloadProgressChanged; public event UploadProgressChangedEventHandler UploadProgressChanged; protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e) { if (DownloadProgressChanged != null) { DownloadProgressChanged(this, e); } } protected virtual void OnUploadProgressChanged(UploadProgressChangedEventArgs e) { if (UploadProgressChanged != null) { UploadProgressChanged(this, e); } } private SendOrPostCallback reportDownloadProgressChanged; private void ReportDownloadProgressChanged(object arg) { OnDownloadProgressChanged((DownloadProgressChangedEventArgs) arg); } private SendOrPostCallback reportUploadProgressChanged; private void ReportUploadProgressChanged(object arg) { OnUploadProgressChanged((UploadProgressChangedEventArgs) arg); } private void PostProgressChanged(AsyncOperation asyncOp, ProgressData progress) { if (asyncOp != null && progress.BytesSent + progress.BytesReceived > 0) { int progressPercentage; if (progress.HasUploadPhase) { if (progress.TotalBytesToReceive < 0 && progress.BytesReceived == 0) { progressPercentage = progress.TotalBytesToSend < 0 ? 0 : progress.TotalBytesToSend == 0 ? 50 : (int)((50 * progress.BytesSent) / progress.TotalBytesToSend); } else { progressPercentage = progress.TotalBytesToSend < 0 ? 50 : progress.TotalBytesToReceive == 0 ? 100 : (int) ((50 * progress.BytesReceived) / progress.TotalBytesToReceive + 50); } asyncOp.Post(reportUploadProgressChanged, new UploadProgressChangedEventArgs(progressPercentage, asyncOp.UserSuppliedState, progress.BytesSent, progress.TotalBytesToSend, progress.BytesReceived, progress.TotalBytesToReceive)); } else { progressPercentage = progress.TotalBytesToReceive < 0 ? 0 : progress.TotalBytesToReceive == 0 ? 100 : (int) ((100 * progress.BytesReceived) / progress.TotalBytesToReceive); asyncOp.Post(reportDownloadProgressChanged, new DownloadProgressChangedEventArgs(progressPercentage, asyncOp.UserSuppliedState, progress.BytesReceived, progress.TotalBytesToReceive)); } } } // // WebClientWriteStream // private class WebClientWriteStream : Stream { private WebRequest m_request; private Stream m_stream; private WebClient m_WebClient; public WebClientWriteStream(Stream stream, WebRequest request, WebClient webClient) { m_request = request; m_stream = stream; m_WebClient = webClient; } public override bool CanRead { get { return m_stream.CanRead; } } public override bool CanSeek { get { return m_stream.CanSeek; } } public override bool CanWrite { get { return m_stream.CanWrite; } } public override bool CanTimeout { get { return m_stream.CanTimeout; } } public override int ReadTimeout { get { return m_stream.ReadTimeout; } set { m_stream.ReadTimeout = value; } } public override int WriteTimeout { get { return m_stream.WriteTimeout; } set { m_stream.WriteTimeout = value; } } public override long Length { get { return m_stream.Length; } } public override long Position { get { return m_stream.Position; } set { m_stream.Position = value; } } [HostProtection(ExternalThreading=true)] public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state) { return m_stream.BeginRead(buffer, offset, size, callback, state); } [HostProtection(ExternalThreading=true)] public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state ) { return m_stream.BeginWrite(buffer, offset, size, callback, state); } protected override void Dispose(bool disposing) { try { if (disposing) { m_stream.Close(); m_WebClient.GetWebResponse(m_request).Close(); } } finally { base.Dispose(disposing); } } public override int EndRead(IAsyncResult result) { return m_stream.EndRead(result); } public override void EndWrite(IAsyncResult result) { m_stream.EndWrite(result); } public override void Flush() { m_stream.Flush(); } public override int Read(byte[] buffer, int offset, int count) { return m_stream.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return m_stream.Seek(offset, origin); } public override void SetLength(long value) { m_stream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { m_stream.Write(buffer, offset, count); } } } // // Delegates and supporting CompletedEventArgs classes are used by async code // // Used by internal Async code to notify that we're done, or have an error internal delegate void CompletionDelegate(byte [] responseBytes, Exception exception, AsyncOperation asyncOp); public delegate void OpenReadCompletedEventHandler(object sender, OpenReadCompletedEventArgs e); public class OpenReadCompletedEventArgs : AsyncCompletedEventArgs { private Stream m_Result; internal OpenReadCompletedEventArgs(Stream result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public Stream Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void OpenWriteCompletedEventHandler(object sender, OpenWriteCompletedEventArgs e); public class OpenWriteCompletedEventArgs : AsyncCompletedEventArgs { private Stream m_Result; internal OpenWriteCompletedEventArgs(Stream result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public Stream Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void DownloadStringCompletedEventHandler(object sender, DownloadStringCompletedEventArgs e); public class DownloadStringCompletedEventArgs : AsyncCompletedEventArgs { string m_Result; internal DownloadStringCompletedEventArgs(string result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public string Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void DownloadDataCompletedEventHandler(object sender, DownloadDataCompletedEventArgs e); public class DownloadDataCompletedEventArgs : AsyncCompletedEventArgs { byte [] m_Result; internal DownloadDataCompletedEventArgs(byte[] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public byte[] Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void UploadStringCompletedEventHandler(object sender, UploadStringCompletedEventArgs e); public class UploadStringCompletedEventArgs : AsyncCompletedEventArgs { string m_Result; internal UploadStringCompletedEventArgs(string result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public string Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void UploadDataCompletedEventHandler(object sender, UploadDataCompletedEventArgs e); public class UploadDataCompletedEventArgs : AsyncCompletedEventArgs { byte [] m_Result; internal UploadDataCompletedEventArgs(byte [] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public byte[] Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void UploadFileCompletedEventHandler(object sender, UploadFileCompletedEventArgs e); public class UploadFileCompletedEventArgs : AsyncCompletedEventArgs { byte [] m_Result; internal UploadFileCompletedEventArgs(byte[] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public byte[] Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void UploadValuesCompletedEventHandler(object sender, UploadValuesCompletedEventArgs e); public class UploadValuesCompletedEventArgs : AsyncCompletedEventArgs { byte [] m_Result; internal UploadValuesCompletedEventArgs(byte [] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public byte[] Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void DownloadProgressChangedEventHandler(object sender, DownloadProgressChangedEventArgs e); public class DownloadProgressChangedEventArgs : ProgressChangedEventArgs { long m_BytesReceived; long m_TotalBytesToReceive; internal DownloadProgressChangedEventArgs(int progressPercentage, object userToken, long bytesReceived, long totalBytesToReceive) : base(progressPercentage, userToken) { m_BytesReceived = bytesReceived; m_TotalBytesToReceive = totalBytesToReceive; } public long BytesReceived { get { return m_BytesReceived; } } public long TotalBytesToReceive { get { return m_TotalBytesToReceive; } } } public delegate void UploadProgressChangedEventHandler(object sender, UploadProgressChangedEventArgs e); public class UploadProgressChangedEventArgs : ProgressChangedEventArgs { long m_BytesReceived; long m_TotalBytesToReceive; long m_BytesSent; long m_TotalBytesToSend; internal UploadProgressChangedEventArgs(int progressPercentage, object userToken, long bytesSent, long totalBytesToSend, long bytesReceived, long totalBytesToReceive) : base(progressPercentage, userToken) { m_BytesReceived = bytesReceived; m_TotalBytesToReceive = totalBytesToReceive; m_BytesSent = bytesSent; m_TotalBytesToSend = totalBytesToSend; } public long BytesReceived { get { return m_BytesReceived; } } public long TotalBytesToReceive { get { return m_TotalBytesToReceive; } } public long BytesSent { get { return m_BytesSent; } } public long TotalBytesToSend { get { return m_TotalBytesToSend; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net { using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Globalization; using System.Threading; using System.Net.Cache; using System.Runtime.Versioning; ////// [ComVisible(true)] public class WebClient : Component { // fields const int DefaultCopyBufferLength = 8192; const int DefaultDownloadBufferLength = 65536; const string DefaultUploadFileContentType = "application/octet-stream"; const string UploadFileContentType = "multipart/form-data"; const string UploadValuesContentType = "application/x-www-form-urlencoded"; Uri m_baseAddress; ICredentials m_credentials; WebHeaderCollection m_headers; NameValueCollection m_requestParameters; WebResponse m_WebResponse; WebRequest m_WebRequest; Encoding m_Encoding = Encoding.Default; string m_Method; long m_ContentLength = -1; bool m_InitWebClientAsync; bool m_Cancelled; ProgressData m_Progress; IWebProxy m_Proxy; bool m_ProxySet; RequestCachePolicy m_CachePolicy; // constructors ///[To be supplied.] ////// public WebClient() { } ///[To be supplied.] ////// private void InitWebClientAsync() { if (!m_InitWebClientAsync) { openReadOperationCompleted = new SendOrPostCallback(OpenReadOperationCompleted); openWriteOperationCompleted = new SendOrPostCallback(OpenWriteOperationCompleted); downloadStringOperationCompleted = new SendOrPostCallback(DownloadStringOperationCompleted); downloadDataOperationCompleted = new SendOrPostCallback(DownloadDataOperationCompleted); downloadFileOperationCompleted = new SendOrPostCallback(DownloadFileOperationCompleted); uploadStringOperationCompleted = new SendOrPostCallback(UploadStringOperationCompleted); uploadDataOperationCompleted = new SendOrPostCallback(UploadDataOperationCompleted); uploadFileOperationCompleted = new SendOrPostCallback(UploadFileOperationCompleted); uploadValuesOperationCompleted = new SendOrPostCallback(UploadValuesOperationCompleted); reportDownloadProgressChanged = new SendOrPostCallback(ReportDownloadProgressChanged); reportUploadProgressChanged = new SendOrPostCallback(ReportUploadProgressChanged); m_Progress = new ProgressData(); m_InitWebClientAsync = true; } } ///Sets up async delegates, we need to create these on every instance when async ////// private void ClearWebClientState() { if (AnotherCallInProgress(Interlocked.Increment(ref m_CallNesting))) { CompleteWebClientState(); throw new NotSupportedException(SR.GetString(SR.net_webclient_no_concurrent_io_allowed)); } m_ContentLength = -1; m_WebResponse = null; m_WebRequest = null; m_Method = null; m_Cancelled = false; if (m_Progress != null) m_Progress.Reset(); } ///Sets up shared properties, to prevent a previous request's state from interfering with this request /// ASSUMED to be called at the start of each WebClient api ////// private void CompleteWebClientState() { Interlocked.Decrement(ref m_CallNesting); } // properties ///Matching code for ClearWebClientState, MUST be matched with ClearWebClientState() calls ////// public Encoding Encoding { get { return m_Encoding; } set { if (value==null) { throw new ArgumentNullException("Encoding"); } m_Encoding = value; } } ///Sets the encoding type for converting string to byte[] on String based methods ////// public string BaseAddress { get { return (m_baseAddress == null) ? String.Empty : m_baseAddress.ToString(); } set { if ((value == null) || (value.Length == 0)) { m_baseAddress = null; } else { try { m_baseAddress = new Uri(value); } catch (UriFormatException e) { throw new ArgumentException(SR.GetString(SR.net_webclient_invalid_baseaddress), "value", e); } } } } ///[To be supplied.] ////// public ICredentials Credentials { get { return m_credentials; } set { m_credentials = value; } } ///[To be supplied.] ////// public bool UseDefaultCredentials { get { return (m_credentials is SystemNetworkCredential) ? true : false; } set { m_credentials = value ? CredentialCache.DefaultCredentials : null; } } ///Sets Credentials to CredentialCache.DefaultCredentials ////// public WebHeaderCollection Headers { get { if (m_headers == null) { m_headers = new WebHeaderCollection(WebHeaderCollectionType.WebRequest); } return m_headers; } set { m_headers = value; } } public NameValueCollection QueryString { get { if (m_requestParameters == null) { m_requestParameters = new NameValueCollection(); } return m_requestParameters; } set { m_requestParameters = value; } } public WebHeaderCollection ResponseHeaders { get { if (m_WebResponse != null) { return m_WebResponse.Headers; } return null; } } ///[To be supplied.] ////// public IWebProxy Proxy { get { ExceptionHelper.WebPermissionUnrestricted.Demand(); if (!m_ProxySet) { return WebRequest.InternalDefaultWebProxy; } else { return m_Proxy; } } set { ExceptionHelper.WebPermissionUnrestricted.Demand(); m_Proxy = value; m_ProxySet = true; } } public RequestCachePolicy CachePolicy { get { return m_CachePolicy; } set { m_CachePolicy = value; } } ////// Gets or sets the proxy information for a request. /// ////// public bool IsBusy { get { return m_AsyncOp != null; } } // methods ////// Indicates if the request is still in progress /// ////// protected virtual WebRequest GetWebRequest(Uri address) { WebRequest request = WebRequest.Create(address); CopyHeadersTo(request); if (Credentials != null) { request.Credentials = Credentials; } if (m_Method != null) { request.Method = m_Method; } if (m_ContentLength != -1) { request.ContentLength = m_ContentLength; } if (m_ProxySet) { request.Proxy = m_Proxy; } if (m_CachePolicy != null) { request.CachePolicy = m_CachePolicy; } return request; } ///Creates the WebRequest ////// protected virtual WebResponse GetWebResponse(WebRequest request) { WebResponse response = request.GetResponse(); m_WebResponse = response; return response; } ///Retrieves a WebResponse by calling GetResponse() ////// protected virtual WebResponse GetWebResponse(WebRequest request, IAsyncResult result) { WebResponse response = request.EndGetResponse(result); m_WebResponse = response; return response; } ///Retrieves a WebResponse by calling async EndGetResponse() ////// public byte[] DownloadData(string address) { if (address == null) throw new ArgumentNullException("address"); return DownloadData(GetUri(address)); } public byte[] DownloadData(Uri address) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadData", address); if (address == null) throw new ArgumentNullException("address"); ClearWebClientState(); byte[] result = null; try { WebRequest request; result = DownloadDataInternal(address, out request); if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadData", result); return result; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// private byte[] DownloadDataInternal(Uri address, out WebRequest request) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadData", address); request = null; try { request = m_WebRequest = GetWebRequest(GetUri(address)); byte [] returnBytes = DownloadBits(request, null, null, null); return returnBytes; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } } ///[To be supplied.] ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void DownloadFile(string address, string fileName) { if (address == null) throw new ArgumentNullException("address"); DownloadFile(GetUri(address), fileName); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void DownloadFile(Uri address, string fileName) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadFile", address+", "+fileName); if (address == null) throw new ArgumentNullException("address"); if (fileName == null) throw new ArgumentNullException("fileName"); WebRequest request = null; FileStream fs = null; bool succeeded = false; ClearWebClientState(); try { fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); request = m_WebRequest = GetWebRequest(GetUri(address)); DownloadBits(request, fs, null, null); succeeded = true; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { if (fs != null) { fs.Close(); if (!succeeded) { // Security Review: If we were able to create a file we should be able to delete it File.Delete(fileName); } fs = null; } CompleteWebClientState(); } if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadFile", ""); } ///[To be supplied.] ////// public Stream OpenRead(string address) { if (address == null) throw new ArgumentNullException("address"); return OpenRead(GetUri(address)); } public Stream OpenRead(Uri address) { if(Logging.On)Logging.Enter(Logging.Web, this, "OpenRead", address); if (address == null) throw new ArgumentNullException("address"); WebRequest request = null; ClearWebClientState(); try { request = m_WebRequest = GetWebRequest(GetUri(address)); WebResponse response = m_WebResponse = GetWebResponse(request); Stream stream = response.GetResponseStream(); if(Logging.On)Logging.Exit(Logging.Web, this, "OpenRead", stream); return stream; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// public Stream OpenWrite(string address) { if (address == null) throw new ArgumentNullException("address"); return OpenWrite(GetUri(address), null); } public Stream OpenWrite(Uri address) { return OpenWrite(address, null); } ///[To be supplied.] ////// public Stream OpenWrite(string address, string method) { if (address == null) throw new ArgumentNullException("address"); return OpenWrite(GetUri(address), method); } public Stream OpenWrite(Uri address, string method) { if(Logging.On)Logging.Enter(Logging.Web, this, "OpenWrite", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (method == null) { method = MapToDefaultMethod(address); } WebRequest request = null; ClearWebClientState(); try { m_Method = method; request = m_WebRequest = GetWebRequest(GetUri(address)); WebClientWriteStream webClientWriteStream = new WebClientWriteStream(request.GetRequestStream(), request, this); if(Logging.On)Logging.Exit(Logging.Web, this, "OpenWrite", webClientWriteStream); return webClientWriteStream; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// public byte[] UploadData(string address, byte[] data) { if (address == null) throw new ArgumentNullException("address"); return UploadData(GetUri(address), null, data); } public byte[] UploadData(Uri address, byte[] data) { return UploadData(address, null, data); } ///[To be supplied.] ////// public byte[] UploadData(string address, string method, byte[] data) { if (address == null) throw new ArgumentNullException("address"); return UploadData(GetUri(address), method, data); } public byte[] UploadData(Uri address, string method, byte[] data) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadData", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } ClearWebClientState(); try { WebRequest request; byte [] result = UploadDataInternal(address, method, data, out request); if(Logging.On)Logging.Exit(Logging.Web, this, "UploadData", result); return result; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// private byte[] UploadDataInternal(Uri address, string method, byte[] data, out WebRequest request) { request = null; try { m_Method = method; m_ContentLength = data.Length; request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, data, null, null, null, null); byte [] responseBytes = DownloadBits(request, null, null, null); return responseBytes; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } } ///Internal version of UploadData used for UploadString as well ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private void OpenFileInternal(bool needsHeaderAndBoundary, string fileName, ref FileStream fs, ref byte[] buffer, ref byte[] formHeaderBytes, ref byte[] boundaryBytes) { fileName = Path.GetFullPath(fileName); if (m_headers == null) { m_headers = new WebHeaderCollection(WebHeaderCollectionType.WebRequest); } string contentType = m_headers[HttpKnownHeaderNames.ContentType]; if (contentType != null) { if (contentType.ToLower(CultureInfo.InvariantCulture).StartsWith("multipart/")) { throw new WebException(SR.GetString(SR.net_webclient_Multipart)); } } else { contentType = DefaultUploadFileContentType; } fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); int buffSize = DefaultCopyBufferLength; m_ContentLength = -1; if (m_Method.ToUpper(CultureInfo.InvariantCulture) == "POST") { if (needsHeaderAndBoundary) { string boundary = "---------------------" + DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo); m_headers[HttpKnownHeaderNames.ContentType] = UploadFileContentType + "; boundary=" + boundary; string formHeader = "--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"" + Path.GetFileName(fileName) + "\"\r\n" + "Content-Type: " + contentType + "\r\n" + "\r\n"; formHeaderBytes = Encoding.UTF8.GetBytes(formHeader); boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); } else { formHeaderBytes = new byte[0]; boundaryBytes = new byte[0]; } if (fs.CanSeek) { m_ContentLength = fs.Length + formHeaderBytes.Length + boundaryBytes.Length; buffSize = (int)Math.Min((long)DefaultCopyBufferLength, fs.Length); } } else { m_headers[HttpKnownHeaderNames.ContentType] = contentType; formHeaderBytes = null; boundaryBytes = null; if (fs.CanSeek) { m_ContentLength = fs.Length; buffSize = (int) Math.Min((long) DefaultCopyBufferLength, fs.Length); } } buffer = new byte[buffSize]; } ///Open a fileStream and prepares data to send over a WebRequest ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public byte[] UploadFile(string address, string fileName) { if (address == null) throw new ArgumentNullException("address"); return UploadFile(GetUri(address), fileName); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public byte[] UploadFile(Uri address, string fileName) { return UploadFile(address, null, fileName); } ///[To be supplied.] ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public byte[] UploadFile(string address, string method, string fileName) { return UploadFile(GetUri(address), method, fileName); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public byte[] UploadFile(Uri address, string method, string fileName) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadFile", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (fileName == null) throw new ArgumentNullException("fileName"); if (method == null) { method = MapToDefaultMethod(address); } FileStream fs = null; WebRequest request = null; ClearWebClientState(); try { m_Method = method; byte [] formHeaderBytes = null, boundaryBytes = null, buffer = null; Uri uri = GetUri(address); bool needsHeaderAndBoundary = (uri.Scheme != Uri.UriSchemeFile); OpenFileInternal(needsHeaderAndBoundary, fileName, ref fs, ref buffer, ref formHeaderBytes, ref boundaryBytes); request = m_WebRequest = GetWebRequest(uri); UploadBits(request, fs, buffer, formHeaderBytes, boundaryBytes, null, null); byte [] responseBytes = DownloadBits(request, null, null, null); if(Logging.On)Logging.Exit(Logging.Web, this, "UploadFile", responseBytes); return responseBytes; } catch (Exception e) { if (fs != null) { fs.Close(); fs = null; } if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { if (fs != null) { fs.Close(); fs = null; } Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { CompleteWebClientState(); } } ///[To be supplied.] ////// private byte[] UploadValuesInternal(NameValueCollection data) { if (m_headers == null) { m_headers = new WebHeaderCollection(WebHeaderCollectionType.WebRequest); } string contentType = m_headers[HttpKnownHeaderNames.ContentType]; if ((contentType != null) && (String.Compare(contentType, UploadValuesContentType, StringComparison.OrdinalIgnoreCase) != 0)) { throw new WebException(SR.GetString(SR.net_webclient_ContentType)); } m_headers[HttpKnownHeaderNames.ContentType] = UploadValuesContentType; string delimiter = String.Empty; StringBuilder values = new StringBuilder(); foreach (string name in data.AllKeys) { values.Append(delimiter); values.Append( UrlEncode(name)); values.Append("="); values.Append(UrlEncode(data[name])); delimiter = "&"; } byte[] buffer = Encoding.ASCII.GetBytes(values.ToString()); m_ContentLength = buffer.Length; return buffer; } ///Shared code for UploadValues, creates a memory stream of data to send ////// public byte[] UploadValues(string address, NameValueCollection data) { if (address == null) throw new ArgumentNullException("address"); return UploadValues(GetUri(address), null, data); } public byte[] UploadValues(Uri address, NameValueCollection data) { return UploadValues(address, null, data); } ///[To be supplied.] ////// public byte[] UploadValues(string address, string method, NameValueCollection data) { if (address == null) throw new ArgumentNullException("address"); return UploadValues(GetUri(address), method, data); } public byte[] UploadValues(Uri address, string method, NameValueCollection data) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadValues", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } WebRequest request = null; ClearWebClientState(); try { byte[] buffer = UploadValuesInternal(data); m_Method = method; request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, buffer, null, null, null, null); byte [] returnBytes = DownloadBits(request, null, null, null); if(Logging.On)Logging.Exit(Logging.Web, this, "UploadValues", address +", "+method); return returnBytes; } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); throw e; } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); AbortRequest(request); throw e; } finally { CompleteWebClientState(); } } // // String Methods - // ///[To be supplied.] ////// public string UploadString(string address, string data) { if (address == null) throw new ArgumentNullException("address"); return UploadString(GetUri(address), null, data); } public string UploadString(Uri address, string data) { return UploadString(address, null, data); } ///Uploads a string of data and returns a string of data ////// public string UploadString(string address, string method, string data) { if (address == null) throw new ArgumentNullException("address"); return UploadString(GetUri(address), method, data); } public string UploadString(Uri address, string method, string data) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadString", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } ClearWebClientState(); try { WebRequest request; byte [] requestData = Encoding.GetBytes(data); byte [] responseData = UploadDataInternal(address, method, requestData, out request); string responseStringData = GuessDownloadEncoding(request).GetString(responseData); if(Logging.On)Logging.Exit(Logging.Web, this, "UploadString", responseStringData); return responseStringData; } finally { CompleteWebClientState(); } } ///Uploads a string of data and returns a string of data ////// public string DownloadString(string address) { if (address == null) throw new ArgumentNullException("address"); return DownloadString(GetUri(address)); } public string DownloadString(Uri address) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadString", address); if (address == null) throw new ArgumentNullException("address"); ClearWebClientState(); try { WebRequest request; byte [] data = DownloadDataInternal(address, out request); string stringData = GuessDownloadEncoding(request).GetString(data); if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadString", stringData); return stringData; } finally { CompleteWebClientState(); } } ///Downloads a string from the server ////// private static void AbortRequest(WebRequest request) { try { if (request != null) { request.Abort(); } } catch (Exception exception) { if (exception is OutOfMemoryException || exception is StackOverflowException || exception is ThreadAbortException) { throw; } } catch { } } ///Aborts the request without throwing, so that we can prevent double errors ////// private void CopyHeadersTo(WebRequest request) { if ((m_headers != null) && (request is HttpWebRequest)) { string accept = m_headers[HttpKnownHeaderNames.Accept]; string connection = m_headers[HttpKnownHeaderNames.Connection]; string contentType = m_headers[HttpKnownHeaderNames.ContentType]; string expect = m_headers[HttpKnownHeaderNames.Expect]; string referrer = m_headers[HttpKnownHeaderNames.Referer]; string userAgent = m_headers[HttpKnownHeaderNames.UserAgent]; m_headers.RemoveInternal(HttpKnownHeaderNames.Accept); m_headers.RemoveInternal(HttpKnownHeaderNames.Connection); m_headers.RemoveInternal(HttpKnownHeaderNames.ContentType); m_headers.RemoveInternal(HttpKnownHeaderNames.Expect); m_headers.RemoveInternal(HttpKnownHeaderNames.Referer); m_headers.RemoveInternal(HttpKnownHeaderNames.UserAgent); request.Headers = m_headers; if ((accept != null) && (accept.Length > 0)) { ((HttpWebRequest)request).Accept = accept; } if ((connection != null) && (connection.Length > 0)) { ((HttpWebRequest)request).Connection = connection; } if ((contentType != null) && (contentType.Length > 0)) { ((HttpWebRequest)request).ContentType = contentType; } if ((expect != null) && (expect.Length > 0)) { ((HttpWebRequest)request).Expect = expect; } if ((referrer != null) && (referrer.Length > 0)) { ((HttpWebRequest)request).Referer = referrer; } if ((userAgent != null) && (userAgent.Length > 0)) { ((HttpWebRequest)request).UserAgent = userAgent; } } } ///Copies HTTP headers to a HttpWebRequest.Headers property ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private Uri GetUri(string path) { Uri uri; if (m_baseAddress != null) { if (!Uri.TryCreate(m_baseAddress, path, out uri)) return new Uri(Path.GetFullPath(path)); } else { if (!Uri.TryCreate(path, UriKind.Absolute, out uri)) return new Uri(Path.GetFullPath(path)); } return GetUri(uri); } ///Parses the string uri into a properly formed uri - uses Uri class ////// private Uri GetUri(Uri address) { if (address == null) throw new ArgumentNullException("address"); Uri uri = address; if (!address.IsAbsoluteUri && m_baseAddress != null) { if (!Uri.TryCreate(m_baseAddress, address, out uri)) return address; } if ((uri.Query == null || uri.Query == string.Empty) && m_requestParameters != null) { StringBuilder sb = new StringBuilder(); string delimiter = String.Empty; for (int i = 0; i < m_requestParameters.Count; ++i) { sb.Append(delimiter + m_requestParameters.AllKeys[i] + "=" + m_requestParameters[i] ); delimiter = "&"; } UriBuilder ub = new UriBuilder(uri); ub.Query = sb.ToString(); uri = ub.Uri; } return uri; } // // ProgressData // Keeps track of overall operation progress // Used by async operations for client updates, especially to hold state from the upload phase to download. // private class ProgressData { internal long BytesSent = 0; internal long TotalBytesToSend = -1; internal long BytesReceived = 0; internal long TotalBytesToReceive = -1; internal bool HasUploadPhase = false; internal void Reset() { BytesSent = 0; TotalBytesToSend = -1; BytesReceived = 0; TotalBytesToReceive = -1; HasUploadPhase = false; } } // // DownloadBits - // works by abstracting the process of downloading using WebRequest.GetResponse() // 3 levels of functions/methods are used for this process // // 1. DownloadBits - generates a state object of DownloadBitsState, then // starts the async GetResponse(), or drives calls directly to // DownloadBitsState.SetResponse() and DownloadBitsState.RetrieveBytes // // 2. DownloadBitsResponseCallback and DownloadBitsReadCallback - // Abstracts the async EndGetResponse and Stream.EndRead // calls from the process of downloading data. Notifies the caller of // DownloadBits through a callback when completed. Catches exceptions // and errors and passes them through the callback // // 3. DownloadBitsState.SetResponse() and DownloadBitsState.RetrieveBytes - // Updates the state of the download by seeding variables and pumps // data through the streams and structures // // ///Parses the string uri into a properly formed uri - uses Uri class ////// private class DownloadBitsState { internal WebClient WebClient; internal Stream WriteStream; internal byte[] InnerBuffer; internal AsyncOperation AsyncOp; internal WebRequest Request; internal CompletionDelegate CompletionDelegate; internal Stream ReadStream; internal ScatterGatherBuffers SgBuffers; internal DownloadBitsState(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp, ProgressData progress, WebClient webClient) { WriteStream = writeStream; Request = request; AsyncOp = asyncOp; CompletionDelegate = completionDelegate; WebClient = webClient; Progress = progress; } internal long ContentLength; internal long Length; internal int Offset; internal ProgressData Progress; internal bool Async { get { return AsyncOp != null; } } internal int SetResponse(WebResponse response) { ContentLength = response.ContentLength; if (ContentLength == -1 || ContentLength > DefaultDownloadBufferLength) { Length = DefaultDownloadBufferLength; // Read buffer length } else { Length = ContentLength; // Read buffer length } // If we are not writing to a stream, we are accumulating in memory if (WriteStream == null) { // We are putting a cap on the size we will accumulate in memory if (ContentLength > Int32.MaxValue) { throw new WebException(SR.GetString(SR.net_webstatus_MessageLengthLimitExceeded), WebExceptionStatus.MessageLengthLimitExceeded); } SgBuffers = new ScatterGatherBuffers(Length); // Write buffer } InnerBuffer = new byte[(int)Length]; ReadStream = response.GetResponseStream(); if (Async && response.ContentLength >= 0) Progress.TotalBytesToReceive = response.ContentLength; if (Async) { if (ReadStream == null || ReadStream == Stream.Null) DownloadBitsReadCallbackState(this, null); else ReadStream.BeginRead(InnerBuffer, Offset, (int)Length-Offset, new AsyncCallback(DownloadBitsReadCallback), this); } else { if (ReadStream == null || ReadStream == Stream.Null) return 0; else return ReadStream.Read(InnerBuffer, Offset, (int)Length-Offset); } return -1; } internal bool RetrieveBytes(ref int bytesRetrieved) { if (bytesRetrieved > 0) { if (WriteStream != null) { WriteStream.Write(InnerBuffer, 0, bytesRetrieved); } else { SgBuffers.Write(InnerBuffer, 0, bytesRetrieved); } if (Async) Progress.BytesReceived += bytesRetrieved; if (Offset != ContentLength) { if (Async) { WebClient.PostProgressChanged(AsyncOp, Progress); ReadStream.BeginRead(InnerBuffer, Offset, (int)Length-Offset, new AsyncCallback(DownloadBitsReadCallback), this); } else { bytesRetrieved = ReadStream.Read(InnerBuffer, Offset, (int)Length-Offset); } return false; } } // Final change notification if (Async) { if (Progress.TotalBytesToReceive < 0) Progress.TotalBytesToReceive = Progress.BytesReceived; WebClient.PostProgressChanged(AsyncOp, Progress); } // completed here if (ReadStream != null) ReadStream.Close(); if (WriteStream != null) { WriteStream.Close(); } else { if (WriteStream == null) { // We are using Scatter-Gather buffers byte[] newbuf = new byte[SgBuffers.Length]; if (SgBuffers.Length > 0) { BufferOffsetSize[] bufferArray = SgBuffers.GetBuffers(); int newBufOffset = 0; for (int i=0; iHolds the state and handles the basic async logic of downloading ////// Generates a byte array or downloads data to an open file stream /// private byte[] DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp) { WebResponse response = null; DownloadBitsState state = new DownloadBitsState(request, writeStream, completionDelegate, asyncOp, m_Progress, this); if (state.Async) { request.BeginGetResponse(new AsyncCallback(DownloadBitsResponseCallback), state); return null; } else { response = m_WebResponse = GetWebResponse(request); } bool completed; int bytesRead = state.SetResponse(response); do { completed = state.RetrieveBytes(ref bytesRead); } while (!completed); state.Close(); return state.InnerBuffer; } // // UploadBits - // works by abstracting the process of uploading using WebRequest.GetRequestStream() // 3 levels of functions/methods are used for this process // // 1. UploadBits - generates a state object of UploadBitsState, then // starts the async GetRequestStream, or drives calls directly to // UploadBitsState.SetRequestStream() and UploadBitsState.WriteBytes // // 2. UploadBitsRequestCallback and UploadBitsWriteCallback - // Abstracts the async EndGetRequestStream and Stream.EndWrite // calls from the process of uploading data. Notifies the caller of // UploadBits through a callback when completed. // // 3. UploadBitsState.SetRequestStream() and UploadBitsState.WriteBytes - // Updates the state of the upload by seeding variables and pumps // data through the streams and structures // // ////// private class UploadBitsState { internal WebClient WebClient; internal Stream WriteStream; internal byte[] InnerBuffer; internal byte[] Header; internal byte[] Footer; internal AsyncOperation AsyncOp; internal WebRequest Request; internal CompletionDelegate CompletionDelegate; internal Stream ReadStream; internal UploadBitsState(WebRequest request, Stream readStream, byte [] buffer, byte [] header, byte [] footer, CompletionDelegate completionDelegate, AsyncOperation asyncOp, ProgressData progress, WebClient webClient) { InnerBuffer = buffer; Header = header; Footer = footer; ReadStream = readStream; Request = request; AsyncOp = asyncOp; CompletionDelegate = completionDelegate; if (AsyncOp != null) { Progress = progress; Progress.HasUploadPhase = true; Progress.TotalBytesToSend = request.ContentLength < 0 ? -1 : request.ContentLength; } WebClient = webClient; } internal long Length; internal int Offset; internal ProgressData Progress; internal bool FileUpload { get { return ReadStream != null; } } internal bool Async { get { return AsyncOp != null; } } internal void SetRequestStream(Stream writeStream) { WriteStream = writeStream; byte [] bytesToWrite = null; if (Header != null) { bytesToWrite = Header; Header = null; } else { bytesToWrite = new byte[0]; } if (Async) { Progress.BytesSent += bytesToWrite.Length; WriteStream.BeginWrite(bytesToWrite, 0, bytesToWrite.Length, new AsyncCallback(UploadBitsWriteCallback), this); } else { WriteStream.Write(bytesToWrite, 0, bytesToWrite.Length); } } internal bool WriteBytes() { byte [] bytesToWrite = null; int bytesToWriteLength = 0; if (Async) { WebClient.PostProgressChanged(AsyncOp, Progress); } if (FileUpload) { int bytesRead = 0; if (InnerBuffer != null) { bytesRead = ReadStream.Read(InnerBuffer, 0, (int)InnerBuffer.Length); if (bytesRead <= 0) { ReadStream.Close(); InnerBuffer = null; } } if (InnerBuffer != null) { bytesToWriteLength = bytesRead; bytesToWrite = InnerBuffer; } else if (Footer != null) { bytesToWriteLength = Footer.Length; bytesToWrite = Footer; Footer = null; } else { return true; // completed } } else if (InnerBuffer != null) { bytesToWriteLength = InnerBuffer.Length; bytesToWrite = InnerBuffer; InnerBuffer = null; } else { return true; // completed } if (Async) { Progress.BytesSent += bytesToWriteLength; WriteStream.BeginWrite(bytesToWrite, 0, bytesToWriteLength, new AsyncCallback(UploadBitsWriteCallback), this); } else { WriteStream.Write(bytesToWrite, 0, bytesToWriteLength); } return false; // not complete } internal void Close() { if (WriteStream != null) { WriteStream.Close(); } if (ReadStream != null) { ReadStream.Close(); } } } static private void UploadBitsRequestCallback(IAsyncResult result) { UploadBitsState state = (UploadBitsState) result.AsyncState; WebRequest request = (WebRequest) state.Request; Exception exception = null; try { Stream stream = request.EndGetRequestStream(result); state.SetRequestStream(stream); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; if (!(e is WebException || e is SecurityException)) { exception = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(request); if(state != null && state.ReadStream != null){ state.ReadStream.Close(); } } finally { if (exception != null) { state.CompletionDelegate(null, exception, state.AsyncOp); } } } static private void UploadBitsWriteCallback(IAsyncResult result) { UploadBitsState state = (UploadBitsState) result.AsyncState; Stream stream = (Stream) state.WriteStream; Exception exception = null; bool completed = false; try { stream.EndWrite(result); completed = state.WriteBytes(); } catch (Exception e) { completed = true; if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; if (!(e is WebException || e is SecurityException)) { exception = new WebException(SR.GetString(SR.net_webclient), e); } AbortRequest(state.Request); if(state != null && state.ReadStream != null){ state.ReadStream.Close(); } } finally { if (completed) { if(exception == null){ state.Close(); } state.CompletionDelegate(null, exception, state.AsyncOp); } } } ///Holds the state and handles the basic async logic of uploading ////// private void UploadBits(WebRequest request, Stream readStream, byte[] buffer, byte [] header, byte [] footer, CompletionDelegate completionDelegate, AsyncOperation asyncOp) { if (request.RequestUri.Scheme == Uri.UriSchemeFile) header = footer = null; UploadBitsState state = new UploadBitsState(request, readStream, buffer, header, footer, completionDelegate, asyncOp, m_Progress, this); Stream writeStream; if (state.Async) { request.BeginGetRequestStream(new AsyncCallback(UploadBitsRequestCallback), state); return; } else { writeStream = request.GetRequestStream(); } state.SetRequestStream(writeStream); while(!state.WriteBytes()); state.Close(); } ///Takes a byte array or an open file stream and writes it to a server ////// private Encoding GuessDownloadEncoding(WebRequest request) { try { string contentType; if ((contentType = request.ContentType) == null) { return this.Encoding; } contentType = contentType.ToLower(CultureInfo.InvariantCulture); string [] parsedList = contentType.Split(new char [] {';','=',' '}); bool nextItem = false; foreach (string item in parsedList) { if (item == "charset") { nextItem = true; } else if (nextItem) { return Encoding.GetEncoding(item); } } } catch(Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } } catch { } return this.Encoding; } /* // Consider removing. private string MapToDefaultMethod(string address) { Uri uri; if (m_baseAddress != null) { uri = new Uri(m_baseAddress, address); } else { uri = new Uri(address); } return MapToDefaultMethod(uri); } */ private string MapToDefaultMethod(Uri address) { Uri uri; if (!address.IsAbsoluteUri && m_baseAddress != null) { uri = new Uri(m_baseAddress, address); } else { uri = address; } if (uri.Scheme.ToLower(CultureInfo.InvariantCulture) == "ftp") { return WebRequestMethods.Ftp.UploadFile; } else { return "POST"; } } private static string UrlEncode(string str) { if (str == null) return null; return UrlEncode(str, Encoding.UTF8); } private static string UrlEncode(string str, Encoding e) { if (str == null) return null; return Encoding.ASCII.GetString(UrlEncodeToBytes(str, e)); } private static byte[] UrlEncodeToBytes(string str, Encoding e) { if (str == null) return null; byte[] bytes = e.GetBytes(str); return UrlEncodeBytesToBytesInternal(bytes, 0, bytes.Length, false); } private static byte[] UrlEncodeBytesToBytesInternal(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue) { int cSpaces = 0; int cUnsafe = 0; // count them first for (int i = 0; i < count; i++) { char ch = (char)bytes[offset+i]; if (ch == ' ') cSpaces++; else if (!IsSafe(ch)) cUnsafe++; } // nothing to expand? if (!alwaysCreateReturnValue && cSpaces == 0 && cUnsafe == 0) return bytes; // expand not 'safe' characters into %XX, spaces to +s byte[] expandedBytes = new byte[count + cUnsafe*2]; int pos = 0; for (int i = 0; i < count; i++) { byte b = bytes[offset+i]; char ch = (char)b; if (IsSafe(ch)) { expandedBytes[pos++] = b; } else if (ch == ' ') { expandedBytes[pos++] = (byte)'+'; } else { expandedBytes[pos++] = (byte)'%'; expandedBytes[pos++] = (byte)IntToHex((b >> 4) & 0xf); expandedBytes[pos++] = (byte)IntToHex(b & 0x0f); } } return expandedBytes; } private static char IntToHex(int n) { Debug.Assert(n < 0x10); if (n <= 9) return(char)(n + (int)'0'); else return(char)(n - 10 + (int)'a'); } private static bool IsSafe(char ch) { if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9') return true; switch (ch) { case '-': case '_': case '.': case '!': case '*': case '\'': case '(': case ')': return true; } return false; } private int m_CallNesting; // > 0 if we're in a Read/Write call private AsyncOperation m_AsyncOp; private void InvokeOperationCompleted(AsyncOperation asyncOp, SendOrPostCallback callback, AsyncCompletedEventArgs eventArgs) { if ((object)Interlocked.CompareExchangeParses a string of the form: /// text/html; charset=ISO-8859-4 /// and should return the Encoding form of "ISO-8859-4" portion /// ///(ref m_AsyncOp, null, asyncOp) == (object) asyncOp) { CompleteWebClientState(); // AsyncOperationManager is responsible for invoke the callback asyncOp.PostOperationCompleted(callback, eventArgs); } } private bool AnotherCallInProgress(int callNesting) { return callNesting>1; } // // Async methods and strucs - // See spec models at the following addresses: // http://dotnetclient/whidbey/M2%20Specs/AsynchronousOperationManager.doc // http://dotnetclient/whidbey/M2%20Specs/Guidelines%20and%20Usage%20Model%20for%20Asynchronous%20Pattern%20for%20Components.doc // // // OpenRead // public event OpenReadCompletedEventHandler OpenReadCompleted; protected virtual void OnOpenReadCompleted(OpenReadCompletedEventArgs e) { if (OpenReadCompleted != null) { OpenReadCompleted(this, e); } } private SendOrPostCallback openReadOperationCompleted; private void OpenReadOperationCompleted(object arg) { OnOpenReadCompleted((OpenReadCompletedEventArgs)arg); } private void OpenReadAsyncCallback(IAsyncResult result) { LazyAsyncResult lazyAsyncResult = (LazyAsyncResult) result; AsyncOperation asyncOp = (AsyncOperation) lazyAsyncResult.AsyncState; WebRequest request = (WebRequest) lazyAsyncResult.AsyncObject; Stream stream = null; Exception exception = null; try { WebResponse response = m_WebResponse = GetWebResponse(request, result); stream = response.GetResponseStream(); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; if (!(e is WebException || e is SecurityException)) { exception = new WebException(SR.GetString(SR.net_webclient), e); } } catch { exception = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } OpenReadCompletedEventArgs eventArgs = new OpenReadCompletedEventArgs(stream, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openReadOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void OpenReadAsync(Uri address) { OpenReadAsync(address, null); } [HostProtection(ExternalThreading=true)] public void OpenReadAsync(Uri address, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "OpenReadAsync", address); if (address == null) throw new ArgumentNullException("address"); InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); request.BeginGetResponse(new AsyncCallback(OpenReadAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } OpenReadCompletedEventArgs eventArgs = new OpenReadCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openReadOperationCompleted, eventArgs); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); OpenReadCompletedEventArgs eventArgs = new OpenReadCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openReadOperationCompleted, eventArgs); } if(Logging.On)Logging.Exit(Logging.Web, this, "OpenReadAsync", null); } // //OpenWrite // public event OpenWriteCompletedEventHandler OpenWriteCompleted; protected virtual void OnOpenWriteCompleted(OpenWriteCompletedEventArgs e) { if (OpenWriteCompleted != null) { OpenWriteCompleted(this, e); } } private SendOrPostCallback openWriteOperationCompleted; private void OpenWriteOperationCompleted(object arg) { OnOpenWriteCompleted((OpenWriteCompletedEventArgs)arg); } private void OpenWriteAsyncCallback(IAsyncResult result) { LazyAsyncResult lazyAsyncResult = (LazyAsyncResult) result; AsyncOperation asyncOp = (AsyncOperation) lazyAsyncResult.AsyncState; WebRequest request = (WebRequest) lazyAsyncResult.AsyncObject; WebClientWriteStream stream = null; Exception exception = null; try { stream = new WebClientWriteStream(request.EndGetRequestStream(result), request, this); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; if (!(e is WebException || e is SecurityException)) { exception = new WebException(SR.GetString(SR.net_webclient), e); } } catch { exception = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } OpenWriteCompletedEventArgs eventArgs = new OpenWriteCompletedEventArgs(stream, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openWriteOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void OpenWriteAsync(Uri address) { OpenWriteAsync(address, null, null); } [HostProtection(ExternalThreading=true)] public void OpenWriteAsync(Uri address, string method) { OpenWriteAsync(address, method, null); } [HostProtection(ExternalThreading=true)] public void OpenWriteAsync(Uri address, string method, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "OpenWriteAsync", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { m_Method = method; WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); request.BeginGetRequestStream(new AsyncCallback(OpenWriteAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } OpenWriteCompletedEventArgs eventArgs = new OpenWriteCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openWriteOperationCompleted, eventArgs); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); OpenWriteCompletedEventArgs eventArgs = new OpenWriteCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, openWriteOperationCompleted, eventArgs); } if(Logging.On)Logging.Exit(Logging.Web, this, "OpenWriteAsync", null); } // //DownloadString // public event DownloadStringCompletedEventHandler DownloadStringCompleted; protected virtual void OnDownloadStringCompleted(DownloadStringCompletedEventArgs e) { if (DownloadStringCompleted != null) { DownloadStringCompleted(this, e); } } private SendOrPostCallback downloadStringOperationCompleted; private void DownloadStringOperationCompleted(object arg) { OnDownloadStringCompleted((DownloadStringCompletedEventArgs)arg); } private void DownloadStringAsyncCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { string stringData = null; try { if (returnBytes != null) { stringData = GuessDownloadEncoding(m_WebRequest).GetString(returnBytes); } } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; } catch { exception = new Exception(SR.GetString(SR.net_nonClsCompliantException)); } DownloadStringCompletedEventArgs eventArgs = new DownloadStringCompletedEventArgs(stringData, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, downloadStringOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void DownloadStringAsync(Uri address) { DownloadStringAsync(address, null); } [HostProtection(ExternalThreading=true)] public void DownloadStringAsync(Uri address, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadStringAsync", address); if (address == null) throw new ArgumentNullException("address"); InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); DownloadBits(request, null, new CompletionDelegate(DownloadStringAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } DownloadStringAsyncCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); DownloadStringAsyncCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadStringAsync", ""); } // //DownloadData // public event DownloadDataCompletedEventHandler DownloadDataCompleted; protected virtual void OnDownloadDataCompleted(DownloadDataCompletedEventArgs e) { if (DownloadDataCompleted != null) { DownloadDataCompleted(this, e); } } private SendOrPostCallback downloadDataOperationCompleted; private void DownloadDataOperationCompleted(object arg) { OnDownloadDataCompleted((DownloadDataCompletedEventArgs)arg); } private void DownloadDataAsyncCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { DownloadDataCompletedEventArgs eventArgs = new DownloadDataCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, downloadDataOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void DownloadDataAsync(Uri address) { DownloadDataAsync(address, null); } [HostProtection(ExternalThreading=true)] public void DownloadDataAsync(Uri address, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadDataAsync", address); if (address == null) throw new ArgumentNullException("address"); InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); DownloadBits(request, null, new CompletionDelegate(DownloadDataAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } DownloadDataAsyncCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); DownloadDataAsyncCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadDataAsync", null); } // //DownloadFile // public event AsyncCompletedEventHandler DownloadFileCompleted; protected virtual void OnDownloadFileCompleted(AsyncCompletedEventArgs e) { if (DownloadFileCompleted != null) { DownloadFileCompleted(this, e); } } private SendOrPostCallback downloadFileOperationCompleted; private void DownloadFileOperationCompleted(object arg) { OnDownloadFileCompleted((AsyncCompletedEventArgs)arg); } private void DownloadFileAsyncCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { AsyncCompletedEventArgs eventArgs = new AsyncCompletedEventArgs(exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, downloadFileOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void DownloadFileAsync(Uri address, string fileName) { DownloadFileAsync(address, fileName, null); } [HostProtection(ExternalThreading=true)] public void DownloadFileAsync(Uri address, string fileName, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "DownloadFileAsync", address); if (address == null) throw new ArgumentNullException("address"); if (fileName == null) throw new ArgumentNullException("fileName"); FileStream fs = null; InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); DownloadBits(request, fs, new CompletionDelegate(DownloadFileAsyncCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if(fs != null){ fs.Close(); } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } DownloadFileAsyncCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "DownloadFileAsync", null); } // //UploadString // public event UploadStringCompletedEventHandler UploadStringCompleted; protected virtual void OnUploadStringCompleted(UploadStringCompletedEventArgs e) { if (UploadStringCompleted != null) { UploadStringCompleted(this, e); } } private SendOrPostCallback uploadStringOperationCompleted; private void UploadStringOperationCompleted(object arg) { OnUploadStringCompleted((UploadStringCompletedEventArgs)arg); } private void UploadStringAsyncWriteCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { if (exception != null) { UploadStringCompletedEventArgs eventArgs = new UploadStringCompletedEventArgs(null, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadStringOperationCompleted, eventArgs); } } private void UploadStringAsyncReadCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { string stringData = null; try { if (returnBytes != null) { stringData = GuessDownloadEncoding(m_WebRequest).GetString(returnBytes); } } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } exception = e; } catch { exception = new Exception(SR.GetString(SR.net_nonClsCompliantException)); } UploadStringCompletedEventArgs eventArgs = new UploadStringCompletedEventArgs(stringData, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadStringOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void UploadStringAsync(Uri address, string data) { UploadStringAsync(address, null, data, null); } [HostProtection(ExternalThreading=true)] public void UploadStringAsync(Uri address, string method, string data) { UploadStringAsync(address, method, data, null); } [HostProtection(ExternalThreading=true)] public void UploadStringAsync(Uri address, string method, string data, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadStringAsync", address); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { byte [] requestData = Encoding.GetBytes(data); m_Method = method; m_ContentLength = requestData.Length; WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, requestData, null, null, new CompletionDelegate(UploadStringAsyncWriteCallback), asyncOp); DownloadBits(request, null, new CompletionDelegate(UploadStringAsyncReadCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } UploadStringAsyncWriteCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); UploadStringAsyncWriteCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "UploadStringAsync", null); } // //UploadData // public event UploadDataCompletedEventHandler UploadDataCompleted; protected virtual void OnUploadDataCompleted(UploadDataCompletedEventArgs e) { if (UploadDataCompleted != null) { UploadDataCompleted(this, e); } } private SendOrPostCallback uploadDataOperationCompleted; private void UploadDataOperationCompleted(object arg) { OnUploadDataCompleted((UploadDataCompletedEventArgs)arg); } private void UploadDataAsyncWriteCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { if (exception != null) { UploadDataCompletedEventArgs eventArgs = new UploadDataCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadDataOperationCompleted, eventArgs); } } private void UploadDataAsyncReadCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { UploadDataCompletedEventArgs eventArgs = new UploadDataCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadDataOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void UploadDataAsync(Uri address, byte[] data) { UploadDataAsync(address, null, data, null); } [HostProtection(ExternalThreading=true)] public void UploadDataAsync(Uri address, string method, byte[] data) { UploadDataAsync(address, method, data, null); } [HostProtection(ExternalThreading=true)] public void UploadDataAsync(Uri address, string method, byte[] data, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadDataAsync", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { m_Method = method; m_ContentLength = data.Length; WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, data, null, null, new CompletionDelegate(UploadDataAsyncWriteCallback), asyncOp); DownloadBits(request, null, new CompletionDelegate(UploadDataAsyncReadCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } UploadDataAsyncWriteCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); UploadDataAsyncWriteCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "UploadDataAsync", null); } // //UploadFile // public event UploadFileCompletedEventHandler UploadFileCompleted; protected virtual void OnUploadFileCompleted(UploadFileCompletedEventArgs e) { if (UploadFileCompleted != null) { UploadFileCompleted(this, e); } } private SendOrPostCallback uploadFileOperationCompleted; private void UploadFileOperationCompleted(object arg) { OnUploadFileCompleted((UploadFileCompletedEventArgs)arg); } private void UploadFileAsyncWriteCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { if (exception != null) { UploadFileCompletedEventArgs eventArgs = new UploadFileCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadFileOperationCompleted, eventArgs); } } private void UploadFileAsyncReadCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { UploadFileCompletedEventArgs eventArgs = new UploadFileCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadFileOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void UploadFileAsync(Uri address, string fileName) { UploadFileAsync(address, null, fileName, null); } [HostProtection(ExternalThreading=true)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void UploadFileAsync(Uri address, string method, string fileName) { UploadFileAsync(address, method, fileName, null); } [HostProtection(ExternalThreading=true)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void UploadFileAsync(Uri address, string method, string fileName, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadFileAsync", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (fileName == null) throw new ArgumentNullException("fileName"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; FileStream fs = null; try { m_Method = method; byte [] formHeaderBytes = null, boundaryBytes = null, buffer = null; Uri uri = GetUri(address); bool needsHeaderAndBoundary = (uri.Scheme != Uri.UriSchemeFile); OpenFileInternal(needsHeaderAndBoundary, fileName, ref fs, ref buffer, ref formHeaderBytes, ref boundaryBytes); WebRequest request = m_WebRequest = GetWebRequest(uri); UploadBits(request, fs, buffer, formHeaderBytes, boundaryBytes, new CompletionDelegate(UploadFileAsyncWriteCallback), asyncOp); DownloadBits(request, null, new CompletionDelegate(UploadFileAsyncReadCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if(fs != null){ fs.Close(); } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } UploadFileAsyncWriteCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "UploadFileAsync", null); } // //UploadValues // public event UploadValuesCompletedEventHandler UploadValuesCompleted; protected virtual void OnUploadValuesCompleted(UploadValuesCompletedEventArgs e) { if (UploadValuesCompleted != null) { UploadValuesCompleted(this, e); } } private SendOrPostCallback uploadValuesOperationCompleted; private void UploadValuesOperationCompleted(object arg) { OnUploadValuesCompleted((UploadValuesCompletedEventArgs)arg); } private void UploadValuesAsyncWriteCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { if (exception != null) { UploadValuesCompletedEventArgs eventArgs = new UploadValuesCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadValuesOperationCompleted, eventArgs); } } private void UploadValuesAsyncReadCallback(byte [] returnBytes, Exception exception, AsyncOperation asyncOp) { UploadValuesCompletedEventArgs eventArgs = new UploadValuesCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState); InvokeOperationCompleted(asyncOp, uploadValuesOperationCompleted, eventArgs); } [HostProtection(ExternalThreading=true)] public void UploadValuesAsync(Uri address, NameValueCollection data) { UploadValuesAsync(address, null, data, null); } [HostProtection(ExternalThreading=true)] public void UploadValuesAsync(Uri address, string method, NameValueCollection data) { UploadValuesAsync(address, method, data, null); } [HostProtection(ExternalThreading=true)] public void UploadValuesAsync(Uri address, string method, NameValueCollection data, object userToken) { if(Logging.On)Logging.Enter(Logging.Web, this, "UploadValuesAsync", address +", "+method); if (address == null) throw new ArgumentNullException("address"); if (data == null) throw new ArgumentNullException("data"); if (method == null) { method = MapToDefaultMethod(address); } InitWebClientAsync(); ClearWebClientState(); AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken); m_AsyncOp = asyncOp; try { byte[] buffer = UploadValuesInternal(data); m_Method = method; WebRequest request = m_WebRequest = GetWebRequest(GetUri(address)); UploadBits(request, null, buffer, null, null, new CompletionDelegate(UploadValuesAsyncWriteCallback), asyncOp); DownloadBits(request, null, new CompletionDelegate(UploadValuesAsyncReadCallback), asyncOp); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (!(e is WebException || e is SecurityException)) { e = new WebException(SR.GetString(SR.net_webclient), e); } UploadValuesAsyncWriteCallback(null, e, asyncOp); } catch { Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException))); UploadValuesAsyncWriteCallback(null, e, asyncOp); } if(Logging.On)Logging.Exit(Logging.Web, this, "UploadValuesAsync", null); } public void CancelAsync() { WebRequest request = m_WebRequest; m_Cancelled = true; AbortRequest(request); } // //ProgressChanged event - code for handling progress updates during uploads and downloads. // public event DownloadProgressChangedEventHandler DownloadProgressChanged; public event UploadProgressChangedEventHandler UploadProgressChanged; protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e) { if (DownloadProgressChanged != null) { DownloadProgressChanged(this, e); } } protected virtual void OnUploadProgressChanged(UploadProgressChangedEventArgs e) { if (UploadProgressChanged != null) { UploadProgressChanged(this, e); } } private SendOrPostCallback reportDownloadProgressChanged; private void ReportDownloadProgressChanged(object arg) { OnDownloadProgressChanged((DownloadProgressChangedEventArgs) arg); } private SendOrPostCallback reportUploadProgressChanged; private void ReportUploadProgressChanged(object arg) { OnUploadProgressChanged((UploadProgressChangedEventArgs) arg); } private void PostProgressChanged(AsyncOperation asyncOp, ProgressData progress) { if (asyncOp != null && progress.BytesSent + progress.BytesReceived > 0) { int progressPercentage; if (progress.HasUploadPhase) { if (progress.TotalBytesToReceive < 0 && progress.BytesReceived == 0) { progressPercentage = progress.TotalBytesToSend < 0 ? 0 : progress.TotalBytesToSend == 0 ? 50 : (int)((50 * progress.BytesSent) / progress.TotalBytesToSend); } else { progressPercentage = progress.TotalBytesToSend < 0 ? 50 : progress.TotalBytesToReceive == 0 ? 100 : (int) ((50 * progress.BytesReceived) / progress.TotalBytesToReceive + 50); } asyncOp.Post(reportUploadProgressChanged, new UploadProgressChangedEventArgs(progressPercentage, asyncOp.UserSuppliedState, progress.BytesSent, progress.TotalBytesToSend, progress.BytesReceived, progress.TotalBytesToReceive)); } else { progressPercentage = progress.TotalBytesToReceive < 0 ? 0 : progress.TotalBytesToReceive == 0 ? 100 : (int) ((100 * progress.BytesReceived) / progress.TotalBytesToReceive); asyncOp.Post(reportDownloadProgressChanged, new DownloadProgressChangedEventArgs(progressPercentage, asyncOp.UserSuppliedState, progress.BytesReceived, progress.TotalBytesToReceive)); } } } // // WebClientWriteStream // private class WebClientWriteStream : Stream { private WebRequest m_request; private Stream m_stream; private WebClient m_WebClient; public WebClientWriteStream(Stream stream, WebRequest request, WebClient webClient) { m_request = request; m_stream = stream; m_WebClient = webClient; } public override bool CanRead { get { return m_stream.CanRead; } } public override bool CanSeek { get { return m_stream.CanSeek; } } public override bool CanWrite { get { return m_stream.CanWrite; } } public override bool CanTimeout { get { return m_stream.CanTimeout; } } public override int ReadTimeout { get { return m_stream.ReadTimeout; } set { m_stream.ReadTimeout = value; } } public override int WriteTimeout { get { return m_stream.WriteTimeout; } set { m_stream.WriteTimeout = value; } } public override long Length { get { return m_stream.Length; } } public override long Position { get { return m_stream.Position; } set { m_stream.Position = value; } } [HostProtection(ExternalThreading=true)] public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state) { return m_stream.BeginRead(buffer, offset, size, callback, state); } [HostProtection(ExternalThreading=true)] public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state ) { return m_stream.BeginWrite(buffer, offset, size, callback, state); } protected override void Dispose(bool disposing) { try { if (disposing) { m_stream.Close(); m_WebClient.GetWebResponse(m_request).Close(); } } finally { base.Dispose(disposing); } } public override int EndRead(IAsyncResult result) { return m_stream.EndRead(result); } public override void EndWrite(IAsyncResult result) { m_stream.EndWrite(result); } public override void Flush() { m_stream.Flush(); } public override int Read(byte[] buffer, int offset, int count) { return m_stream.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return m_stream.Seek(offset, origin); } public override void SetLength(long value) { m_stream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { m_stream.Write(buffer, offset, count); } } } // // Delegates and supporting CompletedEventArgs classes are used by async code // // Used by internal Async code to notify that we're done, or have an error internal delegate void CompletionDelegate(byte [] responseBytes, Exception exception, AsyncOperation asyncOp); public delegate void OpenReadCompletedEventHandler(object sender, OpenReadCompletedEventArgs e); public class OpenReadCompletedEventArgs : AsyncCompletedEventArgs { private Stream m_Result; internal OpenReadCompletedEventArgs(Stream result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public Stream Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void OpenWriteCompletedEventHandler(object sender, OpenWriteCompletedEventArgs e); public class OpenWriteCompletedEventArgs : AsyncCompletedEventArgs { private Stream m_Result; internal OpenWriteCompletedEventArgs(Stream result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public Stream Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void DownloadStringCompletedEventHandler(object sender, DownloadStringCompletedEventArgs e); public class DownloadStringCompletedEventArgs : AsyncCompletedEventArgs { string m_Result; internal DownloadStringCompletedEventArgs(string result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public string Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void DownloadDataCompletedEventHandler(object sender, DownloadDataCompletedEventArgs e); public class DownloadDataCompletedEventArgs : AsyncCompletedEventArgs { byte [] m_Result; internal DownloadDataCompletedEventArgs(byte[] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public byte[] Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void UploadStringCompletedEventHandler(object sender, UploadStringCompletedEventArgs e); public class UploadStringCompletedEventArgs : AsyncCompletedEventArgs { string m_Result; internal UploadStringCompletedEventArgs(string result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public string Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void UploadDataCompletedEventHandler(object sender, UploadDataCompletedEventArgs e); public class UploadDataCompletedEventArgs : AsyncCompletedEventArgs { byte [] m_Result; internal UploadDataCompletedEventArgs(byte [] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public byte[] Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void UploadFileCompletedEventHandler(object sender, UploadFileCompletedEventArgs e); public class UploadFileCompletedEventArgs : AsyncCompletedEventArgs { byte [] m_Result; internal UploadFileCompletedEventArgs(byte[] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public byte[] Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void UploadValuesCompletedEventHandler(object sender, UploadValuesCompletedEventArgs e); public class UploadValuesCompletedEventArgs : AsyncCompletedEventArgs { byte [] m_Result; internal UploadValuesCompletedEventArgs(byte [] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken) { m_Result = result; } public byte[] Result { get { RaiseExceptionIfNecessary(); return m_Result; } } } public delegate void DownloadProgressChangedEventHandler(object sender, DownloadProgressChangedEventArgs e); public class DownloadProgressChangedEventArgs : ProgressChangedEventArgs { long m_BytesReceived; long m_TotalBytesToReceive; internal DownloadProgressChangedEventArgs(int progressPercentage, object userToken, long bytesReceived, long totalBytesToReceive) : base(progressPercentage, userToken) { m_BytesReceived = bytesReceived; m_TotalBytesToReceive = totalBytesToReceive; } public long BytesReceived { get { return m_BytesReceived; } } public long TotalBytesToReceive { get { return m_TotalBytesToReceive; } } } public delegate void UploadProgressChangedEventHandler(object sender, UploadProgressChangedEventArgs e); public class UploadProgressChangedEventArgs : ProgressChangedEventArgs { long m_BytesReceived; long m_TotalBytesToReceive; long m_BytesSent; long m_TotalBytesToSend; internal UploadProgressChangedEventArgs(int progressPercentage, object userToken, long bytesSent, long totalBytesToSend, long bytesReceived, long totalBytesToReceive) : base(progressPercentage, userToken) { m_BytesReceived = bytesReceived; m_TotalBytesToReceive = totalBytesToReceive; m_BytesSent = bytesSent; m_TotalBytesToSend = totalBytesToSend; } public long BytesReceived { get { return m_BytesReceived; } } public long TotalBytesToReceive { get { return m_TotalBytesToReceive; } } public long BytesSent { get { return m_BytesSent; } } public long TotalBytesToSend { get { return m_TotalBytesToSend; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XamlToRtfParser.cs
- CodeDomLocalizationProvider.cs
- StringPropertyBuilder.cs
- NumberFormatter.cs
- SerializableAttribute.cs
- ValidationEventArgs.cs
- FacetValueContainer.cs
- ClientViaElement.cs
- EmptyImpersonationContext.cs
- returneventsaver.cs
- XPathSingletonIterator.cs
- PaintEvent.cs
- CodeGeneratorOptions.cs
- DataServicePagingProviderWrapper.cs
- InfoCardKeyedHashAlgorithm.cs
- CultureTableRecord.cs
- Size.cs
- DisplayInformation.cs
- DefaultTextStore.cs
- GridLength.cs
- webproxy.cs
- CircleEase.cs
- BitmapInitialize.cs
- EqualityComparer.cs
- WorkflowOperationAsyncResult.cs
- BooleanStorage.cs
- CodePropertyReferenceExpression.cs
- WpfKnownMember.cs
- DragCompletedEventArgs.cs
- MailAddressCollection.cs
- DescendentsWalker.cs
- RulePatternOps.cs
- DeploymentSectionCache.cs
- DesignerCalendarAdapter.cs
- ManipulationDelta.cs
- ViewEvent.cs
- PoisonMessageException.cs
- WindowInteropHelper.cs
- RequestResponse.cs
- LogicalExpr.cs
- XmlSchemaSubstitutionGroup.cs
- DataBindingCollection.cs
- SQLCharsStorage.cs
- TraceInternal.cs
- RangeContentEnumerator.cs
- BindUriHelper.cs
- HtmlShim.cs
- SqlProviderUtilities.cs
- AmbiguousMatchException.cs
- ObjectListCommandEventArgs.cs
- DataBoundControlHelper.cs
- EditCommandColumn.cs
- ContainerControl.cs
- BindToObject.cs
- UniqueEventHelper.cs
- AppDomainAttributes.cs
- RowToFieldTransformer.cs
- XPathCompiler.cs
- CharAnimationBase.cs
- OracleRowUpdatedEventArgs.cs
- QueryStringConverter.cs
- XmlImplementation.cs
- CustomWebEventKey.cs
- EntityDataSourceContextDisposingEventArgs.cs
- SystemUnicastIPAddressInformation.cs
- ForeignKeyFactory.cs
- ByeMessageApril2005.cs
- BrushConverter.cs
- _Win32.cs
- ContentDisposition.cs
- BitmapInitialize.cs
- AggregationMinMaxHelpers.cs
- InvalidStoreProtectionKeyException.cs
- EventManager.cs
- CheckBoxAutomationPeer.cs
- mda.cs
- ScriptManager.cs
- hebrewshape.cs
- Page.cs
- DrawingImage.cs
- TypeConverterHelper.cs
- TransactionInformation.cs
- DefaultExpression.cs
- SynchronousChannelMergeEnumerator.cs
- OrderedEnumerableRowCollection.cs
- TypeKeyValue.cs
- IntAverageAggregationOperator.cs
- BypassElement.cs
- WebPartDescription.cs
- FullTrustAssembly.cs
- XamlClipboardData.cs
- WebMessageFormatHelper.cs
- MailWriter.cs
- BaseTreeIterator.cs
- ObjectDisposedException.cs
- DataListItemCollection.cs
- AuditLog.cs
- smtpconnection.cs
- MailAddressCollection.cs
- AssemblyBuilder.cs