The Labs \ Source Viewer \ SSCLI \ System.Net \ DownloadDataCompletedEventArgs

  1. //------------------------------------------------------------------------------
  2. // <copyright file="webclient.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Net
  16. {
  17.     using System.Collections.Specialized;
  18.     using System.ComponentModel;
  19.     using System.Diagnostics;
  20.     using System.IO;
  21.     using System.Runtime.InteropServices;
  22.     using System.Security;
  23.     using System.Security.Permissions;
  24.     using System.Text;
  25.     using System.Globalization;
  26.     using System.Threading;
  27.     using System.Net.Cache;
  28.     using System.Runtime.Versioning;
  29.    
  30.    
  31.     /// <devdoc>
  32.     /// <para>[To be supplied.]</para>
  33.     /// </devdoc>
  34.     [ComVisible(true)]
  35.     public class WebClient : Component
  36.     {
  37.        
  38.         // fields
  39.        
  40.         const int DefaultCopyBufferLength = 8192;
  41.         const int DefaultDownloadBufferLength = 65536;
  42.         const string DefaultUploadFileContentType = "application/octet-stream";
  43.         const string UploadFileContentType = "multipart/form-data";
  44.         const string UploadValuesContentType = "application/x-www-form-urlencoded";
  45.        
  46.         Uri m_baseAddress;
  47.         ICredentials m_credentials;
  48.         WebHeaderCollection m_headers;
  49.         NameValueCollection m_requestParameters;
  50.         WebResponse m_WebResponse;
  51.         WebRequest m_WebRequest;
  52.         Encoding m_Encoding = Encoding.Default;
  53.         string m_Method;
  54.         long m_ContentLength = -1;
  55.         bool m_InitWebClientAsync;
  56.         bool m_Cancelled;
  57.         ProgressData m_Progress;
  58.         IWebProxy m_Proxy;
  59.         bool m_ProxySet;
  60.         RequestCachePolicy m_CachePolicy;
  61.        
  62.         // constructors
  63.        
  64.         /// <devdoc>
  65.         /// <para>[To be supplied.]</para>
  66.         /// </devdoc>
  67.         public WebClient()
  68.         {
  69.         }
  70.        
  71.         /// <devdoc>
  72.         /// <para>Sets up async delegates, we need to create these on every instance when async</para>
  73.         /// </devdoc>
  74.         private void InitWebClientAsync()
  75.         {
  76.             if (!m_InitWebClientAsync) {
  77.                 openReadOperationCompleted = new SendOrPostCallback(OpenReadOperationCompleted);
  78.                 openWriteOperationCompleted = new SendOrPostCallback(OpenWriteOperationCompleted);
  79.                 downloadStringOperationCompleted = new SendOrPostCallback(DownloadStringOperationCompleted);
  80.                 downloadDataOperationCompleted = new SendOrPostCallback(DownloadDataOperationCompleted);
  81.                 downloadFileOperationCompleted = new SendOrPostCallback(DownloadFileOperationCompleted);
  82.                 uploadStringOperationCompleted = new SendOrPostCallback(UploadStringOperationCompleted);
  83.                 uploadDataOperationCompleted = new SendOrPostCallback(UploadDataOperationCompleted);
  84.                 uploadFileOperationCompleted = new SendOrPostCallback(UploadFileOperationCompleted);
  85.                 uploadValuesOperationCompleted = new SendOrPostCallback(UploadValuesOperationCompleted);
  86.                 reportDownloadProgressChanged = new SendOrPostCallback(ReportDownloadProgressChanged);
  87.                 reportUploadProgressChanged = new SendOrPostCallback(ReportUploadProgressChanged);
  88.                 m_Progress = new ProgressData();
  89.                 m_InitWebClientAsync = true;
  90.             }
  91.         }
  92.        
  93.         /// <devdoc>
  94.         /// <para>Sets up shared properties, to prevent a previous request's state from interfering with this request
  95.         /// ASSUMED to be called at the start of each WebClient api</para>
  96.         /// </devdoc>
  97.         private void ClearWebClientState()
  98.         {
  99.             if (AnotherCallInProgress(Interlocked.Increment(ref m_CallNesting))) {
  100.                 CompleteWebClientState();
  101.                 throw new NotSupportedException(SR.GetString(SR.net_webclient_no_concurrent_io_allowed));
  102.             }
  103.             m_ContentLength = -1;
  104.             m_WebResponse = null;
  105.             m_WebRequest = null;
  106.             m_Method = null;
  107.             m_Cancelled = false;
  108.            
  109.             if (m_Progress != null)
  110.                 m_Progress.Reset();
  111.         }
  112.        
  113.         /// <devdoc>
  114.         /// <para>Matching code for ClearWebClientState, MUST be matched with ClearWebClientState() calls</para>
  115.         /// </devdoc>
  116.         private void CompleteWebClientState()
  117.         {
  118.             Interlocked.Decrement(ref m_CallNesting);
  119.         }
  120.        
  121.        
  122.        
  123.         // properties
  124.        
  125.         /// <devdoc>
  126.         /// <para>Sets the encoding type for converting string to byte[] on String based methods</para>
  127.         /// </devdoc>
  128.         public Encoding Encoding {
  129.             get { return m_Encoding; }
  130.             set {
  131.                 if (value == null) {
  132.                     throw new ArgumentNullException("Encoding");
  133.                 }
  134.                 m_Encoding = value;
  135.             }
  136.         }
  137.        
  138.         /// <devdoc>
  139.         /// <para>[To be supplied.]</para>
  140.         /// </devdoc>
  141.         public string BaseAddress {
  142.             get { return (m_baseAddress == null) ? String.Empty : m_baseAddress.ToString(); }
  143.             set {
  144.                 if ((value == null) || (value.Length == 0)) {
  145.                     m_baseAddress = null;
  146.                 }
  147.                 else {
  148.                     try {
  149.                         m_baseAddress = new Uri(value);
  150.                     }
  151.                     catch (UriFormatException e) {
  152.                         throw new ArgumentException(SR.GetString(SR.net_webclient_invalid_baseaddress), "value", e);
  153.                     }
  154.                 }
  155.             }
  156.         }
  157.        
  158.         /// <devdoc>
  159.         /// <para>[To be supplied.]</para>
  160.         /// </devdoc>
  161.         public ICredentials Credentials {
  162.             get { return m_credentials; }
  163.             set { m_credentials = value; }
  164.         }
  165.        
  166.         /// <devdoc>
  167.         /// <para>Sets Credentials to CredentialCache.DefaultCredentials</para>
  168.         /// </devdoc>
  169.         public bool UseDefaultCredentials {
  170.             get { return (m_credentials is SystemNetworkCredential) ? true : false; }
  171.             set { m_credentials = value ? CredentialCache.DefaultCredentials : null; }
  172.         }
  173.        
  174.        
  175.         /// <devdoc>
  176.         /// <para>[To be supplied.]</para>
  177.         /// </devdoc>
  178.         public WebHeaderCollection Headers {
  179.             get {
  180.                 if (m_headers == null) {
  181.                     m_headers = new WebHeaderCollection(WebHeaderCollectionType.WebRequest);
  182.                 }
  183.                 return m_headers;
  184.             }
  185.             set { m_headers = value; }
  186.         }
  187.        
  188.         public NameValueCollection QueryString {
  189.             get {
  190.                 if (m_requestParameters == null) {
  191.                     m_requestParameters = new NameValueCollection();
  192.                 }
  193.                 return m_requestParameters;
  194.             }
  195.             set { m_requestParameters = value; }
  196.         }
  197.        
  198.         public WebHeaderCollection ResponseHeaders {
  199.             get {
  200.                 if (m_WebResponse != null) {
  201.                     return m_WebResponse.Headers;
  202.                 }
  203.                 return null;
  204.             }
  205.         }
  206.        
  207.         /// <devdoc>
  208.         /// <para>
  209.         /// Gets or sets the proxy information for a request.
  210.         /// </para>
  211.         /// </devdoc>
  212.         public IWebProxy Proxy {
  213.             get {
  214.                 ExceptionHelper.WebPermissionUnrestricted.Demand();
  215.                 if (!m_ProxySet) {
  216.                     return WebRequest.InternalDefaultWebProxy;
  217.                 }
  218.                 else {
  219.                     return m_Proxy;
  220.                 }
  221.             }
  222.             set {
  223.                 ExceptionHelper.WebPermissionUnrestricted.Demand();
  224.                 m_Proxy = value;
  225.                 m_ProxySet = true;
  226.             }
  227.         }
  228.        
  229.         public RequestCachePolicy CachePolicy {
  230.             get { return m_CachePolicy; }
  231.             set { m_CachePolicy = value; }
  232.         }
  233.         /// <devdoc>
  234.         /// <para>
  235.         /// Indicates if the request is still in progress
  236.         /// </para>
  237.         /// </devdoc>
  238.         public bool IsBusy {
  239.             get { return m_AsyncOp != null; }
  240.         }
  241.        
  242.        
  243.         // methods
  244.        
  245.         /// <devdoc>
  246.         /// <para>Creates the WebRequest</para>
  247.         /// </devdoc>
  248.         protected virtual WebRequest GetWebRequest(Uri address)
  249.         {
  250.             WebRequest request = WebRequest.Create(address);
  251.             CopyHeadersTo(request);
  252.             if (Credentials != null) {
  253.                 request.Credentials = Credentials;
  254.             }
  255.             if (m_Method != null) {
  256.                 request.Method = m_Method;
  257.             }
  258.             if (m_ContentLength != -1) {
  259.                 request.ContentLength = m_ContentLength;
  260.             }
  261.             if (m_ProxySet) {
  262.                 request.Proxy = m_Proxy;
  263.             }
  264.             if (m_CachePolicy != null) {
  265.                 request.CachePolicy = m_CachePolicy;
  266.             }
  267.             return request;
  268.         }
  269.        
  270.         /// <devdoc>
  271.         /// <para>Retrieves a WebResponse by calling GetResponse()</para>
  272.         /// </devdoc>
  273.         protected virtual WebResponse GetWebResponse(WebRequest request)
  274.         {
  275.             WebResponse response = request.GetResponse();
  276.             m_WebResponse = response;
  277.             return response;
  278.         }
  279.        
  280.         /// <devdoc>
  281.         /// <para>Retrieves a WebResponse by calling async EndGetResponse()</para>
  282.         /// </devdoc>
  283.         protected virtual WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
  284.         {
  285.             WebResponse response = request.EndGetResponse(result);
  286.             m_WebResponse = response;
  287.             return response;
  288.         }
  289.        
  290.         /// <devdoc>
  291.         /// <para>[To be supplied.]</para>
  292.         /// </devdoc>
  293.         public byte[] DownloadData(string address)
  294.         {
  295.             if (address == null)
  296.                 throw new ArgumentNullException("address");
  297.             return DownloadData(GetUri(address));
  298.         }
  299.        
  300.         public byte[] DownloadData(Uri address)
  301.         {
  302.             if (Logging.On)
  303.                 Logging.Enter(Logging.Web, this, "DownloadData", address);
  304.             if (address == null)
  305.                 throw new ArgumentNullException("address");
  306.             ClearWebClientState();
  307.             byte[] result = null;
  308.             try {
  309.                 WebRequest request;
  310.                 result = DownloadDataInternal(address, out request);
  311.                 if (Logging.On)
  312.                     Logging.Exit(Logging.Web, this, "DownloadData", result);
  313.                 return result;
  314.             }
  315.             finally {
  316.                 CompleteWebClientState();
  317.             }
  318.         }
  319.        
  320.         /// <devdoc>
  321.         /// <para>[To be supplied.]</para>
  322.         /// </devdoc>
  323.         private byte[] DownloadDataInternal(Uri address, out WebRequest request)
  324.         {
  325.             if (Logging.On)
  326.                 Logging.Enter(Logging.Web, this, "DownloadData", address);
  327.             request = null;
  328.             try {
  329.                 request = m_WebRequest = GetWebRequest(GetUri(address));
  330.                 byte[] returnBytes = DownloadBits(request, null, null, null);
  331.                 return returnBytes;
  332.             }
  333.             catch (Exception e) {
  334.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  335.                     throw;
  336.                 }
  337.                
  338.                 if (!(e is WebException || e is SecurityException)) {
  339.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  340.                 }
  341.                
  342.                 AbortRequest(request);
  343.                 throw e;
  344.             }
  345.             catch {
  346.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  347.                 AbortRequest(request);
  348.                 throw e;
  349.             }
  350.         }
  351.        
  352.        
  353.         /// <devdoc>
  354.         /// <para>[To be supplied.]</para>
  355.         /// </devdoc>
  356.         [ResourceExposure(ResourceScope.Machine)]
  357.         [ResourceConsumption(ResourceScope.Machine)]
  358.         public void DownloadFile(string address, string fileName)
  359.         {
  360.             if (address == null)
  361.                 throw new ArgumentNullException("address");
  362.             DownloadFile(GetUri(address), fileName);
  363.         }
  364.        
  365.         [ResourceExposure(ResourceScope.Machine)]
  366.         [ResourceConsumption(ResourceScope.Machine)]
  367.         public void DownloadFile(Uri address, string fileName)
  368.         {
  369.             if (Logging.On)
  370.                 Logging.Enter(Logging.Web, this, "DownloadFile", address + ", " + fileName);
  371.             if (address == null)
  372.                 throw new ArgumentNullException("address");
  373.             if (fileName == null)
  374.                 throw new ArgumentNullException("fileName");
  375.            
  376.             WebRequest request = null;
  377.             FileStream fs = null;
  378.             bool succeeded = false;
  379.             ClearWebClientState();
  380.             try {
  381.                 fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
  382.                 request = m_WebRequest = GetWebRequest(GetUri(address));
  383.                 DownloadBits(request, fs, null, null);
  384.                 succeeded = true;
  385.             }
  386.             catch (Exception e) {
  387.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  388.                     throw;
  389.                 }
  390.                
  391.                 if (!(e is WebException || e is SecurityException)) {
  392.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  393.                 }
  394.                
  395.                 AbortRequest(request);
  396.                 throw e;
  397.             }
  398.             catch {
  399.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  400.                
  401.                 AbortRequest(request);
  402.                 throw e;
  403.             }
  404.             finally {
  405.                 if (fs != null) {
  406.                     fs.Close();
  407.                     if (!succeeded) {
  408.                         File.Delete(fileName);
  409.                     }
  410.                     fs = null;
  411.                 }
  412.                 CompleteWebClientState();
  413.             }
  414.             if (Logging.On)
  415.                 Logging.Exit(Logging.Web, this, "DownloadFile", "");
  416.         }
  417.        
  418.        
  419.         /// <devdoc>
  420.         /// <para>[To be supplied.]</para>
  421.         /// </devdoc>
  422.         public Stream OpenRead(string address)
  423.         {
  424.             if (address == null)
  425.                 throw new ArgumentNullException("address");
  426.             return OpenRead(GetUri(address));
  427.         }
  428.        
  429.         public Stream OpenRead(Uri address)
  430.         {
  431.             if (Logging.On)
  432.                 Logging.Enter(Logging.Web, this, "OpenRead", address);
  433.             if (address == null)
  434.                 throw new ArgumentNullException("address");
  435.             WebRequest request = null;
  436.             ClearWebClientState();
  437.             try {
  438.                 request = m_WebRequest = GetWebRequest(GetUri(address));
  439.                 WebResponse response = m_WebResponse = GetWebResponse(request);
  440.                 Stream stream = response.GetResponseStream();
  441.                 if (Logging.On)
  442.                     Logging.Exit(Logging.Web, this, "OpenRead", stream);
  443.                 return stream;
  444.             }
  445.             catch (Exception e) {
  446.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  447.                     throw;
  448.                 }
  449.                
  450.                 if (!(e is WebException || e is SecurityException)) {
  451.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  452.                 }
  453.                
  454.                 AbortRequest(request);
  455.                 throw e;
  456.             }
  457.             catch {
  458.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  459.                
  460.                 AbortRequest(request);
  461.                 throw e;
  462.             }
  463.             finally {
  464.                 CompleteWebClientState();
  465.             }
  466.         }
  467.        
  468.         /// <devdoc>
  469.         /// <para>[To be supplied.]</para>
  470.         /// </devdoc>
  471.         public Stream OpenWrite(string address)
  472.         {
  473.             if (address == null)
  474.                 throw new ArgumentNullException("address");
  475.             return OpenWrite(GetUri(address), null);
  476.         }
  477.        
  478.         public Stream OpenWrite(Uri address)
  479.         {
  480.             return OpenWrite(address, null);
  481.         }
  482.        
  483.         /// <devdoc>
  484.         /// <para>[To be supplied.]</para>
  485.         /// </devdoc>
  486.         public Stream OpenWrite(string address, string method)
  487.         {
  488.             if (address == null)
  489.                 throw new ArgumentNullException("address");
  490.             return OpenWrite(GetUri(address), method);
  491.         }
  492.        
  493.         public Stream OpenWrite(Uri address, string method)
  494.         {
  495.             if (Logging.On)
  496.                 Logging.Enter(Logging.Web, this, "OpenWrite", address + ", " + method);
  497.             if (address == null)
  498.                 throw new ArgumentNullException("address");
  499.             if (method == null) {
  500.                 method = MapToDefaultMethod(address);
  501.             }
  502.             WebRequest request = null;
  503.             ClearWebClientState();
  504.             try {
  505.                 m_Method = method;
  506.                 request = m_WebRequest = GetWebRequest(GetUri(address));
  507.                 WebClientWriteStream webClientWriteStream = new WebClientWriteStream(request.GetRequestStream(), request, this);
  508.                 if (Logging.On)
  509.                     Logging.Exit(Logging.Web, this, "OpenWrite", webClientWriteStream);
  510.                 return webClientWriteStream;
  511.             }
  512.             catch (Exception e) {
  513.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  514.                     throw;
  515.                 }
  516.                
  517.                 if (!(e is WebException || e is SecurityException)) {
  518.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  519.                 }
  520.                
  521.                 AbortRequest(request);
  522.                 throw e;
  523.             }
  524.             catch {
  525.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  526.                
  527.                 AbortRequest(request);
  528.                 throw e;
  529.             }
  530.             finally {
  531.                 CompleteWebClientState();
  532.             }
  533.         }
  534.        
  535.         /// <devdoc>
  536.         /// <para>[To be supplied.]</para>
  537.         /// </devdoc>
  538.         public byte[] UploadData(string address, byte[] data)
  539.         {
  540.             if (address == null)
  541.                 throw new ArgumentNullException("address");
  542.             return UploadData(GetUri(address), null, data);
  543.         }
  544.        
  545.         public byte[] UploadData(Uri address, byte[] data)
  546.         {
  547.             return UploadData(address, null, data);
  548.         }
  549.        
  550.         /// <devdoc>
  551.         /// <para>[To be supplied.]</para>
  552.         /// </devdoc>
  553.         public byte[] UploadData(string address, string method, byte[] data)
  554.         {
  555.             if (address == null)
  556.                 throw new ArgumentNullException("address");
  557.             return UploadData(GetUri(address), method, data);
  558.         }
  559.        
  560.         public byte[] UploadData(Uri address, string method, byte[] data)
  561.         {
  562.             if (Logging.On)
  563.                 Logging.Enter(Logging.Web, this, "UploadData", address + ", " + method);
  564.             if (address == null)
  565.                 throw new ArgumentNullException("address");
  566.             if (data == null)
  567.                 throw new ArgumentNullException("data");
  568.             if (method == null) {
  569.                 method = MapToDefaultMethod(address);
  570.             }
  571.             ClearWebClientState();
  572.             try {
  573.                 WebRequest request;
  574.                 byte[] result = UploadDataInternal(address, method, data, out request);
  575.                 if (Logging.On)
  576.                     Logging.Exit(Logging.Web, this, "UploadData", result);
  577.                 return result;
  578.             }
  579.             finally {
  580.                 CompleteWebClientState();
  581.             }
  582.         }
  583.        
  584.         /// <devdoc>
  585.         /// <para>Internal version of UploadData used for UploadString as well</para>
  586.         /// </devdoc>
  587.         private byte[] UploadDataInternal(Uri address, string method, byte[] data, out WebRequest request)
  588.         {
  589.             request = null;
  590.             try {
  591.                 m_Method = method;
  592.                 m_ContentLength = data.Length;
  593.                 request = m_WebRequest = GetWebRequest(GetUri(address));
  594.                 UploadBits(request, null, data, null, null, null, null);
  595.                 byte[] responseBytes = DownloadBits(request, null, null, null);
  596.                 return responseBytes;
  597.             }
  598.             catch (Exception e) {
  599.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  600.                     throw;
  601.                 }
  602.                
  603.                 if (!(e is WebException || e is SecurityException)) {
  604.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  605.                 }
  606.                
  607.                 AbortRequest(request);
  608.                 throw e;
  609.             }
  610.             catch {
  611.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  612.                
  613.                 AbortRequest(request);
  614.                 throw e;
  615.             }
  616.         }
  617.        
  618.        
  619.         /// <devdoc>
  620.         /// <para>Open a fileStream and prepares data to send over a WebRequest</para>
  621.         /// </devdoc>
  622.         [ResourceExposure(ResourceScope.Machine)]
  623.         [ResourceConsumption(ResourceScope.Machine)]
  624.         private void OpenFileInternal(bool needsHeaderAndBoundary, string fileName, ref FileStream fs, ref byte[] buffer, ref byte[] formHeaderBytes, ref byte[] boundaryBytes)
  625.         {
  626.             fileName = Path.GetFullPath(fileName);
  627.            
  628.             if (m_headers == null) {
  629.                 m_headers = new WebHeaderCollection(WebHeaderCollectionType.WebRequest);
  630.             }
  631.            
  632.             string contentType = m_headers[HttpKnownHeaderNames.ContentType];
  633.            
  634.             if (contentType != null) {
  635.                 if (contentType.ToLower(CultureInfo.InvariantCulture).StartsWith("multipart/")) {
  636.                     throw new WebException(SR.GetString(SR.net_webclient_Multipart));
  637.                 }
  638.             }
  639.             else {
  640.                 contentType = DefaultUploadFileContentType;
  641.             }
  642.            
  643.             fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
  644.            
  645.             int buffSize = DefaultCopyBufferLength;
  646.             m_ContentLength = -1;
  647.            
  648.             if (m_Method.ToUpper(CultureInfo.InvariantCulture) == "POST") {
  649.                 if (needsHeaderAndBoundary) {
  650.                     string boundary = "---------------------" + DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo);
  651.                    
  652.                     m_headers[HttpKnownHeaderNames.ContentType] = UploadFileContentType + "; boundary=" + boundary;
  653.                    
  654.                     string formHeader = "--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"" + Path.GetFileName(fileName) + "\"\r\n" + "Content-Type: " + contentType + "\r\n" + "\r\n";
  655.                     formHeaderBytes = Encoding.UTF8.GetBytes(formHeader);
  656.                     boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
  657.                 }
  658.                 else {
  659.                     formHeaderBytes = new byte[0];
  660.                     boundaryBytes = new byte[0];
  661.                 }
  662.                
  663.                 if (fs.CanSeek) {
  664.                     m_ContentLength = fs.Length + formHeaderBytes.Length + boundaryBytes.Length;
  665.                     buffSize = (int)Math.Min((long)DefaultCopyBufferLength, fs.Length);
  666.                 }
  667.             }
  668.             else {
  669.                 m_headers[HttpKnownHeaderNames.ContentType] = contentType;
  670.                
  671.                 formHeaderBytes = null;
  672.                 boundaryBytes = null;
  673.                
  674.                 if (fs.CanSeek) {
  675.                     m_ContentLength = fs.Length;
  676.                     buffSize = (int)Math.Min((long)DefaultCopyBufferLength, fs.Length);
  677.                 }
  678.             }
  679.            
  680.             buffer = new byte[buffSize];
  681.         }
  682.        
  683.         /// <devdoc>
  684.         /// <para>[To be supplied.]</para>
  685.         /// </devdoc>
  686.         [ResourceExposure(ResourceScope.Machine)]
  687.         [ResourceConsumption(ResourceScope.Machine)]
  688.         public byte[] UploadFile(string address, string fileName)
  689.         {
  690.             if (address == null)
  691.                 throw new ArgumentNullException("address");
  692.             return UploadFile(GetUri(address), fileName);
  693.         }
  694.        
  695.         [ResourceExposure(ResourceScope.Machine)]
  696.         [ResourceConsumption(ResourceScope.Machine)]
  697.         public byte[] UploadFile(Uri address, string fileName)
  698.         {
  699.             return UploadFile(address, null, fileName);
  700.         }
  701.        
  702.        
  703.         /// <devdoc>
  704.         /// <para>[To be supplied.]</para>
  705.         /// </devdoc>
  706.         [ResourceExposure(ResourceScope.Machine)]
  707.         [ResourceConsumption(ResourceScope.Machine)]
  708.         public byte[] UploadFile(string address, string method, string fileName)
  709.         {
  710.             return UploadFile(GetUri(address), method, fileName);
  711.         }
  712.        
  713.         [ResourceExposure(ResourceScope.Machine)]
  714.         [ResourceConsumption(ResourceScope.Machine)]
  715.         public byte[] UploadFile(Uri address, string method, string fileName)
  716.         {
  717.             if (Logging.On)
  718.                 Logging.Enter(Logging.Web, this, "UploadFile", address + ", " + method);
  719.             if (address == null)
  720.                 throw new ArgumentNullException("address");
  721.             if (fileName == null)
  722.                 throw new ArgumentNullException("fileName");
  723.             if (method == null) {
  724.                 method = MapToDefaultMethod(address);
  725.             }
  726.             FileStream fs = null;
  727.             WebRequest request = null;
  728.             ClearWebClientState();
  729.             try {
  730.                 m_Method = method;
  731.                 byte[] formHeaderBytes = null;
  732.                 byte[] boundaryBytes = null;
  733.                 byte[] buffer = null;
  734.                 Uri uri = GetUri(address);
  735.                 bool needsHeaderAndBoundary = (uri.Scheme != Uri.UriSchemeFile);
  736.                 OpenFileInternal(needsHeaderAndBoundary, fileName, ref fs, ref buffer, ref formHeaderBytes, ref boundaryBytes);
  737.                 request = m_WebRequest = GetWebRequest(uri);
  738.                 UploadBits(request, fs, buffer, formHeaderBytes, boundaryBytes, null, null);
  739.                 byte[] responseBytes = DownloadBits(request, null, null, null);
  740.                 if (Logging.On)
  741.                     Logging.Exit(Logging.Web, this, "UploadFile", responseBytes);
  742.                 return responseBytes;
  743.             }
  744.             catch (Exception e) {
  745.                 if (fs != null) {
  746.                     fs.Close();
  747.                     fs = null;
  748.                 }
  749.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  750.                     throw;
  751.                 }
  752.                
  753.                 if (!(e is WebException || e is SecurityException)) {
  754.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  755.                 }
  756.                
  757.                 AbortRequest(request);
  758.                 throw e;
  759.             }
  760.             catch {
  761.                 if (fs != null) {
  762.                     fs.Close();
  763.                     fs = null;
  764.                 }
  765.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  766.                
  767.                 AbortRequest(request);
  768.                 throw e;
  769.             }
  770.             finally {
  771.                 CompleteWebClientState();
  772.             }
  773.         }
  774.        
  775.         /// <devdoc>
  776.         /// <para>Shared code for UploadValues, creates a memory stream of data to send</para>
  777.         /// </devdoc>
  778.         private byte[] UploadValuesInternal(NameValueCollection data)
  779.         {
  780.             if (m_headers == null) {
  781.                 m_headers = new WebHeaderCollection(WebHeaderCollectionType.WebRequest);
  782.             }
  783.            
  784.             string contentType = m_headers[HttpKnownHeaderNames.ContentType];
  785.            
  786.             if ((contentType != null) && (String.Compare(contentType, UploadValuesContentType, StringComparison.OrdinalIgnoreCase) != 0)) {
  787.                 throw new WebException(SR.GetString(SR.net_webclient_ContentType));
  788.             }
  789.             m_headers[HttpKnownHeaderNames.ContentType] = UploadValuesContentType;
  790.            
  791.             string delimiter = String.Empty;
  792.             StringBuilder values = new StringBuilder();
  793.             foreach (string name in data.AllKeys) {
  794.                 values.Append(delimiter);
  795.                 values.Append(UrlEncode(name));
  796.                 values.Append("=");
  797.                 values.Append(UrlEncode(data[name]));
  798.                 delimiter = "&";
  799.             }
  800.            
  801.             byte[] buffer = Encoding.ASCII.GetBytes(values.ToString());
  802.             m_ContentLength = buffer.Length;
  803.             return buffer;
  804.         }
  805.        
  806.         /// <devdoc>
  807.         /// <para>[To be supplied.]</para>
  808.         /// </devdoc>
  809.         public byte[] UploadValues(string address, NameValueCollection data)
  810.         {
  811.             if (address == null)
  812.                 throw new ArgumentNullException("address");
  813.             return UploadValues(GetUri(address), null, data);
  814.         }
  815.        
  816.         public byte[] UploadValues(Uri address, NameValueCollection data)
  817.         {
  818.             return UploadValues(address, null, data);
  819.         }
  820.        
  821.         /// <devdoc>
  822.         /// <para>[To be supplied.]</para>
  823.         /// </devdoc>
  824.         public byte[] UploadValues(string address, string method, NameValueCollection data)
  825.         {
  826.             if (address == null)
  827.                 throw new ArgumentNullException("address");
  828.             return UploadValues(GetUri(address), method, data);
  829.         }
  830.        
  831.         public byte[] UploadValues(Uri address, string method, NameValueCollection data)
  832.         {
  833.             if (Logging.On)
  834.                 Logging.Enter(Logging.Web, this, "UploadValues", address + ", " + method);
  835.             if (address == null)
  836.                 throw new ArgumentNullException("address");
  837.             if (data == null)
  838.                 throw new ArgumentNullException("data");
  839.             if (method == null) {
  840.                 method = MapToDefaultMethod(address);
  841.             }
  842.             WebRequest request = null;
  843.             ClearWebClientState();
  844.             try {
  845.                 byte[] buffer = UploadValuesInternal(data);
  846.                 m_Method = method;
  847.                 request = m_WebRequest = GetWebRequest(GetUri(address));
  848.                 UploadBits(request, null, buffer, null, null, null, null);
  849.                 byte[] returnBytes = DownloadBits(request, null, null, null);
  850.                 if (Logging.On)
  851.                     Logging.Exit(Logging.Web, this, "UploadValues", address + ", " + method);
  852.                 return returnBytes;
  853.             }
  854.             catch (Exception e) {
  855.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  856.                     throw;
  857.                 }
  858.                
  859.                 if (!(e is WebException || e is SecurityException)) {
  860.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  861.                 }
  862.                
  863.                 AbortRequest(request);
  864.                 throw e;
  865.             }
  866.             catch {
  867.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  868.                
  869.                 AbortRequest(request);
  870.                 throw e;
  871.             }
  872.             finally {
  873.                 CompleteWebClientState();
  874.             }
  875.         }
  876.        
  877.         //
  878.         // String Methods -
  879.         //
  880.        
  881.         /// <devdoc>
  882.         /// <para>Uploads a string of data and returns a string of data</para>
  883.         /// </devdoc>
  884.         public string UploadString(string address, string data)
  885.         {
  886.             if (address == null)
  887.                 throw new ArgumentNullException("address");
  888.             return UploadString(GetUri(address), null, data);
  889.         }
  890.        
  891.         public string UploadString(Uri address, string data)
  892.         {
  893.             return UploadString(address, null, data);
  894.         }
  895.        
  896.         /// <devdoc>
  897.         /// <para>Uploads a string of data and returns a string of data</para>
  898.         /// </devdoc>
  899.         public string UploadString(string address, string method, string data)
  900.         {
  901.             if (address == null)
  902.                 throw new ArgumentNullException("address");
  903.             return UploadString(GetUri(address), method, data);
  904.         }
  905.        
  906.         public string UploadString(Uri address, string method, string data)
  907.         {
  908.             if (Logging.On)
  909.                 Logging.Enter(Logging.Web, this, "UploadString", address + ", " + method);
  910.             if (address == null)
  911.                 throw new ArgumentNullException("address");
  912.             if (data == null)
  913.                 throw new ArgumentNullException("data");
  914.             if (method == null) {
  915.                 method = MapToDefaultMethod(address);
  916.             }
  917.             ClearWebClientState();
  918.             try {
  919.                 WebRequest request;
  920.                 byte[] requestData = Encoding.GetBytes(data);
  921.                 byte[] responseData = UploadDataInternal(address, method, requestData, out request);
  922.                 string responseStringData = GuessDownloadEncoding(request).GetString(responseData);
  923.                 if (Logging.On)
  924.                     Logging.Exit(Logging.Web, this, "UploadString", responseStringData);
  925.                 return responseStringData;
  926.             }
  927.             finally {
  928.                 CompleteWebClientState();
  929.             }
  930.         }
  931.        
  932.         /// <devdoc>
  933.         /// <para>Downloads a string from the server</para>
  934.         /// </devdoc>
  935.         public string DownloadString(string address)
  936.         {
  937.             if (address == null)
  938.                 throw new ArgumentNullException("address");
  939.             return DownloadString(GetUri(address));
  940.         }
  941.        
  942.         public string DownloadString(Uri address)
  943.         {
  944.             if (Logging.On)
  945.                 Logging.Enter(Logging.Web, this, "DownloadString", address);
  946.             if (address == null)
  947.                 throw new ArgumentNullException("address");
  948.             ClearWebClientState();
  949.             try {
  950.                 WebRequest request;
  951.                 byte[] data = DownloadDataInternal(address, out request);
  952.                 string stringData = GuessDownloadEncoding(request).GetString(data);
  953.                 if (Logging.On)
  954.                     Logging.Exit(Logging.Web, this, "DownloadString", stringData);
  955.                 return stringData;
  956.             }
  957.             finally {
  958.                 CompleteWebClientState();
  959.             }
  960.         }
  961.        
  962.         /// <devdoc>
  963.         /// <para>Aborts the request without throwing, so that we can prevent double errors</para>
  964.         /// </devdoc>
  965.         private static void AbortRequest(WebRequest request)
  966.         {
  967.             try {
  968.                 if (request != null) {
  969.                     request.Abort();
  970.                 }
  971.             }
  972.             catch (Exception exception) {
  973.                 if (exception is OutOfMemoryException || exception is StackOverflowException || exception is ThreadAbortException) {
  974.                     throw;
  975.                 }
  976.             }
  977.             catch {
  978.             }
  979.         }
  980.        
  981.         /// <devdoc>
  982.         /// <para>Copies HTTP headers to a HttpWebRequest.Headers property</para>
  983.         /// </devdoc>
  984.         private void CopyHeadersTo(WebRequest request)
  985.         {
  986.             if ((m_headers != null) && (request is HttpWebRequest)) {
  987.                
  988.                 string accept = m_headers[HttpKnownHeaderNames.Accept];
  989.                 string connection = m_headers[HttpKnownHeaderNames.Connection];
  990.                 string contentType = m_headers[HttpKnownHeaderNames.ContentType];
  991.                 string expect = m_headers[HttpKnownHeaderNames.Expect];
  992.                 string referrer = m_headers[HttpKnownHeaderNames.Referer];
  993.                 string userAgent = m_headers[HttpKnownHeaderNames.UserAgent];
  994.                
  995.                 m_headers.RemoveInternal(HttpKnownHeaderNames.Accept);
  996.                 m_headers.RemoveInternal(HttpKnownHeaderNames.Connection);
  997.                 m_headers.RemoveInternal(HttpKnownHeaderNames.ContentType);
  998.                 m_headers.RemoveInternal(HttpKnownHeaderNames.Expect);
  999.                 m_headers.RemoveInternal(HttpKnownHeaderNames.Referer);
  1000.                 m_headers.RemoveInternal(HttpKnownHeaderNames.UserAgent);
  1001.                 request.Headers = m_headers;
  1002.                 if ((accept != null) && (accept.Length > 0)) {
  1003.                     ((HttpWebRequest)request).Accept = accept;
  1004.                 }
  1005.                 if ((connection != null) && (connection.Length > 0)) {
  1006.                     ((HttpWebRequest)request).Connection = connection;
  1007.                 }
  1008.                 if ((contentType != null) && (contentType.Length > 0)) {
  1009.                     ((HttpWebRequest)request).ContentType = contentType;
  1010.                 }
  1011.                 if ((expect != null) && (expect.Length > 0)) {
  1012.                     ((HttpWebRequest)request).Expect = expect;
  1013.                 }
  1014.                 if ((referrer != null) && (referrer.Length > 0)) {
  1015.                     ((HttpWebRequest)request).Referer = referrer;
  1016.                 }
  1017.                 if ((userAgent != null) && (userAgent.Length > 0)) {
  1018.                     ((HttpWebRequest)request).UserAgent = userAgent;
  1019.                 }
  1020.             }
  1021.         }
  1022.        
  1023.         /// <devdoc>
  1024.         /// <para>Parses the string uri into a properly formed uri - uses Uri class</para>
  1025.         /// </devdoc>
  1026.         [ResourceExposure(ResourceScope.Machine)]
  1027.         [ResourceConsumption(ResourceScope.Machine)]
  1028.         private Uri GetUri(string path)
  1029.         {
  1030.            
  1031.             Uri uri;
  1032.            
  1033.             if (m_baseAddress != null) {
  1034.                 if (!Uri.TryCreate(m_baseAddress, path, out uri))
  1035.                     return new Uri(Path.GetFullPath(path));
  1036.             }
  1037.             else {
  1038.                 if (!Uri.TryCreate(path, UriKind.Absolute, out uri))
  1039.                     return new Uri(Path.GetFullPath(path));
  1040.             }
  1041.            
  1042.             return GetUri(uri);
  1043.         }
  1044.        
  1045.         /// <devdoc>
  1046.         /// <para>Parses the string uri into a properly formed uri - uses Uri class</para>
  1047.         /// </devdoc>
  1048.         private Uri GetUri(Uri address)
  1049.         {
  1050.             if (address == null)
  1051.                 throw new ArgumentNullException("address");
  1052.            
  1053.             Uri uri = address;
  1054.            
  1055.             if (!address.IsAbsoluteUri && m_baseAddress != null) {
  1056.                 if (!Uri.TryCreate(m_baseAddress, address, out uri))
  1057.                     return address;
  1058.             }
  1059.            
  1060.             if ((uri.Query == null || uri.Query == string.Empty) && m_requestParameters != null) {
  1061.                
  1062.                 StringBuilder sb = new StringBuilder();
  1063.                 string delimiter = String.Empty;
  1064.                
  1065.                 for (int i = 0; i < m_requestParameters.Count; ++i) {
  1066.                     sb.Append(delimiter + m_requestParameters.AllKeys[i] + "=" + m_requestParameters[i]);
  1067.                     delimiter = "&";
  1068.                 }
  1069.                
  1070.                 UriBuilder ub = new UriBuilder(uri);
  1071.                
  1072.                 ub.Query = sb.ToString();
  1073.                 uri = ub.Uri;
  1074.             }
  1075.            
  1076.             return uri;
  1077.         }
  1078.        
  1079.        
  1080.         //
  1081.         // ProgressData
  1082.         // Keeps track of overall operation progress
  1083.         // Used by async operations for client updates, especially to hold state from the upload phase to download.
  1084.         //
  1085.         private class ProgressData
  1086.         {
  1087.             internal long BytesSent = 0;
  1088.             internal long TotalBytesToSend = -1;
  1089.             internal long BytesReceived = 0;
  1090.             internal long TotalBytesToReceive = -1;
  1091.             internal bool HasUploadPhase = false;
  1092.            
  1093.             internal void Reset()
  1094.             {
  1095.                 BytesSent = 0;
  1096.                 TotalBytesToSend = -1;
  1097.                 BytesReceived = 0;
  1098.                 TotalBytesToReceive = -1;
  1099.                 HasUploadPhase = false;
  1100.             }
  1101.         }
  1102.        
  1103.        
  1104.         //
  1105.         // DownloadBits -
  1106.         // works by abstracting the process of downloading using WebRequest.GetResponse()
  1107.         // 3 levels of functions/methods are used for this process
  1108.         //
  1109.         // 1. DownloadBits - generates a state object of DownloadBitsState, then
  1110.         // starts the async GetResponse(), or drives calls directly to
  1111.         // DownloadBitsState.SetResponse() and DownloadBitsState.RetrieveBytes
  1112.         //
  1113.         // 2. DownloadBitsResponseCallback and DownloadBitsReadCallback -
  1114.         // Abstracts the async EndGetResponse and Stream.EndRead
  1115.         // calls from the process of downloading data. Notifies the caller of
  1116.         // DownloadBits through a callback when completed. Catches exceptions
  1117.         // and errors and passes them through the callback
  1118.         //
  1119.         // 3. DownloadBitsState.SetResponse() and DownloadBitsState.RetrieveBytes -
  1120.         // Updates the state of the download by seeding variables and pumps
  1121.         // data through the streams and structures
  1122.         //
  1123.         //
  1124.        
  1125.        
  1126.         /// <devdoc>
  1127.         /// <para>Holds the state and handles the basic async logic of downloading</para>
  1128.         /// </devdoc>
  1129.         private class DownloadBitsState
  1130.         {
  1131.             internal WebClient WebClient;
  1132.             internal Stream WriteStream;
  1133.             internal byte[] InnerBuffer;
  1134.             internal AsyncOperation AsyncOp;
  1135.             internal WebRequest Request;
  1136.             internal CompletionDelegate CompletionDelegate;
  1137.             internal Stream ReadStream;
  1138.             internal ScatterGatherBuffers SgBuffers;
  1139.            
  1140.             internal DownloadBitsState(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp, ProgressData progress, WebClient webClient)
  1141.             {
  1142.                 WriteStream = writeStream;
  1143.                 Request = request;
  1144.                 AsyncOp = asyncOp;
  1145.                 CompletionDelegate = completionDelegate;
  1146.                 WebClient = webClient;
  1147.                 Progress = progress;
  1148.             }
  1149.            
  1150.             internal long ContentLength;
  1151.             internal long Length;
  1152.             internal int Offset;
  1153.            
  1154.            
  1155.             internal ProgressData Progress;
  1156.            
  1157.             internal bool Async {
  1158.                 get { return AsyncOp != null; }
  1159.             }
  1160.            
  1161.             internal int SetResponse(WebResponse response)
  1162.             {
  1163.                 ContentLength = response.ContentLength;
  1164.                
  1165.                 if (ContentLength == -1 || ContentLength > DefaultDownloadBufferLength) {
  1166.                     Length = DefaultDownloadBufferLength;
  1167.                     // Read buffer length
  1168.                 }
  1169.                 else {
  1170.                     Length = ContentLength;
  1171.                     // Read buffer length
  1172.                 }
  1173.                
  1174.                 // If we are not writing to a stream, we are accumulating in memory
  1175.                 if (WriteStream == null) {
  1176.                     // We are putting a cap on the size we will accumulate in memory
  1177.                     if (ContentLength > Int32.MaxValue) {
  1178.                         throw new WebException(SR.GetString(SR.net_webstatus_MessageLengthLimitExceeded), WebExceptionStatus.MessageLengthLimitExceeded);
  1179.                     }
  1180.                     SgBuffers = new ScatterGatherBuffers(Length);
  1181.                     // Write buffer
  1182.                 }
  1183.                
  1184.                 InnerBuffer = new byte[(int)Length];
  1185.                
  1186.                 ReadStream = response.GetResponseStream();
  1187.                 if (Async && response.ContentLength >= 0)
  1188.                     Progress.TotalBytesToReceive = response.ContentLength;
  1189.                
  1190.                 if (Async) {
  1191.                     if (ReadStream == null || ReadStream == Stream.Null)
  1192.                         DownloadBitsReadCallbackState(this, null);
  1193.                     else
  1194.                         ReadStream.BeginRead(InnerBuffer, Offset, (int)Length - Offset, new AsyncCallback(DownloadBitsReadCallback), this);
  1195.                 }
  1196.                 else {
  1197.                     if (ReadStream == null || ReadStream == Stream.Null)
  1198.                         return 0;
  1199.                     else
  1200.                         return ReadStream.Read(InnerBuffer, Offset, (int)Length - Offset);
  1201.                 }
  1202.                 return -1;
  1203.             }
  1204.            
  1205.             internal bool RetrieveBytes(ref int bytesRetrieved)
  1206.             {
  1207.                 if (bytesRetrieved > 0) {
  1208.                     if (WriteStream != null) {
  1209.                         WriteStream.Write(InnerBuffer, 0, bytesRetrieved);
  1210.                     }
  1211.                     else {
  1212.                         SgBuffers.Write(InnerBuffer, 0, bytesRetrieved);
  1213.                     }
  1214.                    
  1215.                     if (Async)
  1216.                         Progress.BytesReceived += bytesRetrieved;
  1217.                    
  1218.                     if (Offset != ContentLength) {
  1219.                         if (Async) {
  1220.                             WebClient.PostProgressChanged(AsyncOp, Progress);
  1221.                             ReadStream.BeginRead(InnerBuffer, Offset, (int)Length - Offset, new AsyncCallback(DownloadBitsReadCallback), this);
  1222.                         }
  1223.                         else {
  1224.                             bytesRetrieved = ReadStream.Read(InnerBuffer, Offset, (int)Length - Offset);
  1225.                         }
  1226.                         return false;
  1227.                     }
  1228.                 }
  1229.                
  1230.                 // Final change notification
  1231.                 if (Async) {
  1232.                     if (Progress.TotalBytesToReceive < 0)
  1233.                         Progress.TotalBytesToReceive = Progress.BytesReceived;
  1234.                     WebClient.PostProgressChanged(AsyncOp, Progress);
  1235.                 }
  1236.                
  1237.                 // completed here
  1238.                 if (ReadStream != null)
  1239.                     ReadStream.Close();
  1240.                 if (WriteStream != null) {
  1241.                     WriteStream.Close();
  1242.                 }
  1243.                 else {
  1244.                     if (WriteStream == null) {
  1245.                         // We are using Scatter-Gather buffers
  1246.                         byte[] newbuf = new byte[SgBuffers.Length];
  1247.                         if (SgBuffers.Length > 0) {
  1248.                             BufferOffsetSize[] bufferArray = SgBuffers.GetBuffers();
  1249.                             int newBufOffset = 0;
  1250.                             for (int i = 0; i < bufferArray.Length; i++) {
  1251.                                 BufferOffsetSize bufferOffsetSize = bufferArray[i];
  1252.                                 Buffer.BlockCopy(bufferOffsetSize.Buffer, 0, newbuf, newBufOffset, bufferOffsetSize.Size);
  1253.                                 newBufOffset += bufferOffsetSize.Size;
  1254.                             }
  1255.                         }
  1256.                         InnerBuffer = newbuf;
  1257.                     }
  1258.                 }
  1259.                 // do callback now
  1260.                 return true;
  1261.             }
  1262.            
  1263.             internal void Close()
  1264.             {
  1265.                 if (WriteStream != null) {
  1266.                     WriteStream.Close();
  1267.                 }
  1268.                 if (ReadStream != null) {
  1269.                     ReadStream.Close();
  1270.                 }
  1271.             }
  1272.         }
  1273.        
  1274.         private static void DownloadBitsResponseCallback(IAsyncResult result)
  1275.         {
  1276.             DownloadBitsState state = (DownloadBitsState)result.AsyncState;
  1277.             WebRequest request = (WebRequest)state.Request;
  1278.             Exception exception = null;
  1279.            
  1280.             try {
  1281.                 WebResponse response = state.WebClient.GetWebResponse(request, result);
  1282.                 state.WebClient.m_WebResponse = response;
  1283.                 state.SetResponse(response);
  1284.             }
  1285.             catch (Exception e) {
  1286.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  1287.                     throw;
  1288.                 }
  1289.                 exception = e;
  1290.                 if (!(e is WebException || e is SecurityException)) {
  1291.                     exception = new WebException(SR.GetString(SR.net_webclient), e);
  1292.                 }
  1293.                 AbortRequest(request);
  1294.                 if (state != null && state.WriteStream != null) {
  1295.                     state.WriteStream.Close();
  1296.                 }
  1297.             }
  1298.             finally {
  1299.                 if (exception != null) {
  1300.                     state.CompletionDelegate(null, exception, state.AsyncOp);
  1301.                 }
  1302.             }
  1303.            
  1304.         }
  1305.        
  1306.         private static void DownloadBitsReadCallback(IAsyncResult result)
  1307.         {
  1308.             DownloadBitsState state = (DownloadBitsState)result.AsyncState;
  1309.             DownloadBitsReadCallbackState(state, result);
  1310.         }
  1311.        
  1312.         private static void DownloadBitsReadCallbackState(DownloadBitsState state, IAsyncResult result)
  1313.         {
  1314.             Stream stream = state.ReadStream;
  1315.            
  1316.             Exception exception = null;
  1317.             bool completed = false;
  1318.            
  1319.             try {
  1320.                 int bytesRead = 0;
  1321.                 if (stream != null && stream != Stream.Null)
  1322.                     bytesRead = stream.EndRead(result);
  1323.                 completed = state.RetrieveBytes(ref bytesRead);
  1324.             }
  1325.             catch (Exception e) {
  1326.                 completed = true;
  1327.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  1328.                     throw;
  1329.                 }
  1330.                 exception = e;
  1331.                 state.InnerBuffer = null;
  1332.                 if (!(e is WebException || e is SecurityException)) {
  1333.                     exception = new WebException(SR.GetString(SR.net_webclient), e);
  1334.                 }
  1335.                 AbortRequest(state.Request);
  1336.                 if (state != null && state.WriteStream != null) {
  1337.                     state.WriteStream.Close();
  1338.                 }
  1339.             }
  1340.             finally {
  1341.                 if (completed) {
  1342.                     if (exception == null) {
  1343.                         state.Close();
  1344.                     }
  1345.                     state.CompletionDelegate(state.InnerBuffer, exception, state.AsyncOp);
  1346.                 }
  1347.             }
  1348.            
  1349.         }
  1350.        
  1351.        
  1352.         /// <devdoc>
  1353.         /// <para>Generates a byte array or downloads data to an open file stream</para>
  1354.         /// </devdoc>
  1355.         private byte[] DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp)
  1356.         {
  1357.             WebResponse response = null;
  1358.             DownloadBitsState state = new DownloadBitsState(request, writeStream, completionDelegate, asyncOp, m_Progress, this);
  1359.            
  1360.             if (state.Async) {
  1361.                 request.BeginGetResponse(new AsyncCallback(DownloadBitsResponseCallback), state);
  1362.                 return null;
  1363.             }
  1364.             else {
  1365.                 response = m_WebResponse = GetWebResponse(request);
  1366.             }
  1367.            
  1368.             bool completed;
  1369.             int bytesRead = state.SetResponse(response);
  1370.             do {
  1371.                 completed = state.RetrieveBytes(ref bytesRead);
  1372.             }
  1373.             while (!completed);
  1374.             state.Close();
  1375.             return state.InnerBuffer;
  1376.         }
  1377.        
  1378.         //
  1379.         // UploadBits -
  1380.         // works by abstracting the process of uploading using WebRequest.GetRequestStream()
  1381.         // 3 levels of functions/methods are used for this process
  1382.         //
  1383.         // 1. UploadBits - generates a state object of UploadBitsState, then
  1384.         // starts the async GetRequestStream, or drives calls directly to
  1385.         // UploadBitsState.SetRequestStream() and UploadBitsState.WriteBytes
  1386.         //
  1387.         // 2. UploadBitsRequestCallback and UploadBitsWriteCallback -
  1388.         // Abstracts the async EndGetRequestStream and Stream.EndWrite
  1389.         // calls from the process of uploading data. Notifies the caller of
  1390.         // UploadBits through a callback when completed.
  1391.         //
  1392.         // 3. UploadBitsState.SetRequestStream() and UploadBitsState.WriteBytes -
  1393.         // Updates the state of the upload by seeding variables and pumps
  1394.         // data through the streams and structures
  1395.         //
  1396.         //
  1397.        
  1398.         /// <devdoc>
  1399.         /// <para>Holds the state and handles the basic async logic of uploading</para>
  1400.         /// </devdoc>
  1401.         private class UploadBitsState
  1402.         {
  1403.             internal WebClient WebClient;
  1404.             internal Stream WriteStream;
  1405.             internal byte[] InnerBuffer;
  1406.             internal byte[] Header;
  1407.             internal byte[] Footer;
  1408.             internal AsyncOperation AsyncOp;
  1409.             internal WebRequest Request;
  1410.             internal CompletionDelegate CompletionDelegate;
  1411.            
  1412.             internal Stream ReadStream;
  1413.            
  1414.             internal UploadBitsState(WebRequest request, Stream readStream, byte[] buffer, byte[] header, byte[] footer, CompletionDelegate completionDelegate, AsyncOperation asyncOp, ProgressData progress, WebClient webClient)
  1415.             {
  1416.                 InnerBuffer = buffer;
  1417.                 Header = header;
  1418.                 Footer = footer;
  1419.                 ReadStream = readStream;
  1420.                 Request = request;
  1421.                 AsyncOp = asyncOp;
  1422.                 CompletionDelegate = completionDelegate;
  1423.                
  1424.                 if (AsyncOp != null) {
  1425.                     Progress = progress;
  1426.                     Progress.HasUploadPhase = true;
  1427.                     Progress.TotalBytesToSend = request.ContentLength < 0 ? -1 : request.ContentLength;
  1428.                 }
  1429.                
  1430.                 WebClient = webClient;
  1431.             }
  1432.            
  1433.             internal long Length;
  1434.             internal int Offset;
  1435.            
  1436.             internal ProgressData Progress;
  1437.            
  1438.             internal bool FileUpload {
  1439.                 get { return ReadStream != null; }
  1440.             }
  1441.            
  1442.             internal bool Async {
  1443.                 get { return AsyncOp != null; }
  1444.             }
  1445.             internal void SetRequestStream(Stream writeStream)
  1446.             {
  1447.                 WriteStream = writeStream;
  1448.                 byte[] bytesToWrite = null;
  1449.                
  1450.                 if (Header != null) {
  1451.                     bytesToWrite = Header;
  1452.                     Header = null;
  1453.                 }
  1454.                 else {
  1455.                     bytesToWrite = new byte[0];
  1456.                 }
  1457.                
  1458.                 if (Async) {
  1459.                     Progress.BytesSent += bytesToWrite.Length;
  1460.                     WriteStream.BeginWrite(bytesToWrite, 0, bytesToWrite.Length, new AsyncCallback(UploadBitsWriteCallback), this);
  1461.                 }
  1462.                 else {
  1463.                     WriteStream.Write(bytesToWrite, 0, bytesToWrite.Length);
  1464.                 }
  1465.             }
  1466.            
  1467.             internal bool WriteBytes()
  1468.             {
  1469.                 byte[] bytesToWrite = null;
  1470.                 int bytesToWriteLength = 0;
  1471.                
  1472.                 if (Async) {
  1473.                     WebClient.PostProgressChanged(AsyncOp, Progress);
  1474.                 }
  1475.                
  1476.                 if (FileUpload) {
  1477.                     int bytesRead = 0;
  1478.                     if (InnerBuffer != null) {
  1479.                         bytesRead = ReadStream.Read(InnerBuffer, 0, (int)InnerBuffer.Length);
  1480.                         if (bytesRead <= 0) {
  1481.                             ReadStream.Close();
  1482.                             InnerBuffer = null;
  1483.                         }
  1484.                     }
  1485.                     if (InnerBuffer != null) {
  1486.                         bytesToWriteLength = bytesRead;
  1487.                         bytesToWrite = InnerBuffer;
  1488.                     }
  1489.                     else if (Footer != null) {
  1490.                         bytesToWriteLength = Footer.Length;
  1491.                         bytesToWrite = Footer;
  1492.                         Footer = null;
  1493.                     }
  1494.                     else {
  1495.                         return true;
  1496.                         // completed
  1497.                     }
  1498.                 }
  1499.                 else if (InnerBuffer != null) {
  1500.                     bytesToWriteLength = InnerBuffer.Length;
  1501.                     bytesToWrite = InnerBuffer;
  1502.                     InnerBuffer = null;
  1503.                 }
  1504.                 else {
  1505.                     return true;
  1506.                     // completed
  1507.                 }
  1508.                
  1509.                 if (Async) {
  1510.                     Progress.BytesSent += bytesToWriteLength;
  1511.                     WriteStream.BeginWrite(bytesToWrite, 0, bytesToWriteLength, new AsyncCallback(UploadBitsWriteCallback), this);
  1512.                 }
  1513.                 else {
  1514.                     WriteStream.Write(bytesToWrite, 0, bytesToWriteLength);
  1515.                 }
  1516.                
  1517.                 return false;
  1518.                 // not complete
  1519.             }
  1520.            
  1521.             internal void Close()
  1522.             {
  1523.                 if (WriteStream != null) {
  1524.                     WriteStream.Close();
  1525.                 }
  1526.                 if (ReadStream != null) {
  1527.                     ReadStream.Close();
  1528.                 }
  1529.             }
  1530.         }
  1531.        
  1532.        
  1533.         private static void UploadBitsRequestCallback(IAsyncResult result)
  1534.         {
  1535.             UploadBitsState state = (UploadBitsState)result.AsyncState;
  1536.             WebRequest request = (WebRequest)state.Request;
  1537.            
  1538.             Exception exception = null;
  1539.            
  1540.             try {
  1541.                 Stream stream = request.EndGetRequestStream(result);
  1542.                 state.SetRequestStream(stream);
  1543.             }
  1544.             catch (Exception e) {
  1545.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  1546.                     throw;
  1547.                 }
  1548.                 exception = e;
  1549.                 if (!(e is WebException || e is SecurityException)) {
  1550.                     exception = new WebException(SR.GetString(SR.net_webclient), e);
  1551.                 }
  1552.                 AbortRequest(request);
  1553.                 if (state != null && state.ReadStream != null) {
  1554.                     state.ReadStream.Close();
  1555.                 }
  1556.             }
  1557.             finally {
  1558.                 if (exception != null) {
  1559.                     state.CompletionDelegate(null, exception, state.AsyncOp);
  1560.                 }
  1561.             }
  1562.         }
  1563.        
  1564.         private static void UploadBitsWriteCallback(IAsyncResult result)
  1565.         {
  1566.             UploadBitsState state = (UploadBitsState)result.AsyncState;
  1567.             Stream stream = (Stream)state.WriteStream;
  1568.            
  1569.             Exception exception = null;
  1570.             bool completed = false;
  1571.            
  1572.             try {
  1573.                 stream.EndWrite(result);
  1574.                 completed = state.WriteBytes();
  1575.             }
  1576.             catch (Exception e) {
  1577.                 completed = true;
  1578.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  1579.                     throw;
  1580.                 }
  1581.                 exception = e;
  1582.                 if (!(e is WebException || e is SecurityException)) {
  1583.                     exception = new WebException(SR.GetString(SR.net_webclient), e);
  1584.                 }
  1585.                 AbortRequest(state.Request);
  1586.                 if (state != null && state.ReadStream != null) {
  1587.                     state.ReadStream.Close();
  1588.                 }
  1589.             }
  1590.             finally {
  1591.                 if (completed) {
  1592.                     if (exception == null) {
  1593.                         state.Close();
  1594.                     }
  1595.                     state.CompletionDelegate(null, exception, state.AsyncOp);
  1596.                 }
  1597.             }
  1598.         }
  1599.        
  1600.        
  1601.         /// <devdoc>
  1602.         /// <para>Takes a byte array or an open file stream and writes it to a server</para>
  1603.         /// </devdoc>
  1604.        
  1605.         private void UploadBits(WebRequest request, Stream readStream, byte[] buffer, byte[] header, byte[] footer, CompletionDelegate completionDelegate, AsyncOperation asyncOp)
  1606.         {
  1607.             if (request.RequestUri.Scheme == Uri.UriSchemeFile)
  1608.                 header = footer = null;
  1609.             UploadBitsState state = new UploadBitsState(request, readStream, buffer, header, footer, completionDelegate, asyncOp, m_Progress, this);
  1610.             Stream writeStream;
  1611.             if (state.Async) {
  1612.                 request.BeginGetRequestStream(new AsyncCallback(UploadBitsRequestCallback), state);
  1613.                 return;
  1614.             }
  1615.             else {
  1616.                 writeStream = request.GetRequestStream();
  1617.             }
  1618.             state.SetRequestStream(writeStream);
  1619.             while (!state.WriteBytes())
  1620.                 ;
  1621.             state.Close();
  1622.         }
  1623.        
  1624.        
  1625.         /// <devdoc>
  1626.         /// <para>Parses a string of the form:
  1627.         /// text/html; charset=ISO-8859-4
  1628.         /// and should return the Encoding form of "ISO-8859-4" portion
  1629.         /// </para>
  1630.         /// </devdoc>
  1631.         private Encoding GuessDownloadEncoding(WebRequest request)
  1632.         {
  1633.             try {
  1634.                 string contentType;
  1635.                 if ((contentType = request.ContentType) == null) {
  1636.                     return this.Encoding;
  1637.                 }
  1638.                 contentType = contentType.ToLower(CultureInfo.InvariantCulture);
  1639.                 string[] parsedList = contentType.Split(new char[] {';', '=', ' '});
  1640.                 bool nextItem = false;
  1641.                 foreach (string item in parsedList) {
  1642.                     if (item == "charset") {
  1643.                         nextItem = true;
  1644.                     }
  1645.                     else if (nextItem) {
  1646.                         return Encoding.GetEncoding(item);
  1647.                     }
  1648.                 }
  1649.             }
  1650.             catch (Exception e) {
  1651.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  1652.                     throw;
  1653.                 }
  1654.             }
  1655.             catch {
  1656.             }
  1657.             return this.Encoding;
  1658.         }
  1659.        
  1660. /*
  1661.         //                                   
  1662.         private string MapToDefaultMethod(string address) {
  1663.             Uri uri;
  1664.             if (m_baseAddress != null) {
  1665.                 uri = new Uri(m_baseAddress, address);
  1666.             } else {
  1667.                 uri = new Uri(address);
  1668.             }
  1669.             return MapToDefaultMethod(uri);
  1670.         }
  1671.         */       
  1672.        
  1673.         private string MapToDefaultMethod(Uri address)
  1674.         {
  1675.             Uri uri;
  1676.             if (!address.IsAbsoluteUri && m_baseAddress != null) {
  1677.                 uri = new Uri(m_baseAddress, address);
  1678.             }
  1679.             else {
  1680.                 uri = address;
  1681.             }
  1682.             if (uri.Scheme.ToLower(CultureInfo.InvariantCulture) == "ftp") {
  1683.                 return WebRequestMethods.Ftp.UploadFile;
  1684.             }
  1685.             else {
  1686.                 return "POST";
  1687.             }
  1688.         }
  1689.        
  1690.         private static string UrlEncode(string str)
  1691.         {
  1692.             if (str == null)
  1693.                 return null;
  1694.             return UrlEncode(str, Encoding.UTF8);
  1695.         }
  1696.        
  1697.         private static string UrlEncode(string str, Encoding e)
  1698.         {
  1699.             if (str == null)
  1700.                 return null;
  1701.             return Encoding.ASCII.GetString(UrlEncodeToBytes(str, e));
  1702.         }
  1703.        
  1704.         private static byte[] UrlEncodeToBytes(string str, Encoding e)
  1705.         {
  1706.             if (str == null)
  1707.                 return null;
  1708.             byte[] bytes = e.GetBytes(str);
  1709.             return UrlEncodeBytesToBytesInternal(bytes, 0, bytes.Length, false);
  1710.         }
  1711.        
  1712.         private static byte[] UrlEncodeBytesToBytesInternal(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue)
  1713.         {
  1714.             int cSpaces = 0;
  1715.             int cUnsafe = 0;
  1716.            
  1717.             // count them first
  1718.             for (int i = 0; i < count; i++) {
  1719.                 char ch = (char)bytes[offset + i];
  1720.                
  1721.                 if (ch == ' ')
  1722.                     cSpaces++;
  1723.                 else if (!IsSafe(ch))
  1724.                     cUnsafe++;
  1725.             }
  1726.            
  1727.             // nothing to expand?
  1728.             if (!alwaysCreateReturnValue && cSpaces == 0 && cUnsafe == 0)
  1729.                 return bytes;
  1730.            
  1731.             // expand not 'safe' characters into %XX, spaces to +s
  1732.             byte[] expandedBytes = new byte[count + cUnsafe * 2];
  1733.             int pos = 0;
  1734.            
  1735.             for (int i = 0; i < count; i++) {
  1736.                 byte b = bytes[offset + i];
  1737.                 char ch = (char)b;
  1738.                
  1739.                 if (IsSafe(ch)) {
  1740.                     expandedBytes[pos++] = b;
  1741.                 }
  1742.                 else if (ch == ' ') {
  1743.                     expandedBytes[pos++] = (byte)'+';
  1744.                 }
  1745.                 else {
  1746.                     expandedBytes[pos++] = (byte)'%';
  1747.                     expandedBytes[pos++] = (byte)IntToHex((b >> 4) & 15);
  1748.                     expandedBytes[pos++] = (byte)IntToHex(b & 15);
  1749.                 }
  1750.             }
  1751.            
  1752.             return expandedBytes;
  1753.         }
  1754.        
  1755.         private static char IntToHex(int n)
  1756.         {
  1757.             Debug.Assert(n < 16);
  1758.            
  1759.             if (n <= 9)
  1760.                 return (char)(n + (int)'0');
  1761.             else
  1762.                 return (char)(n - 10 + (int)'a');
  1763.         }
  1764.        
  1765.         private static bool IsSafe(char ch)
  1766.         {
  1767.             if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')
  1768.                 return true;
  1769.            
  1770.             switch (ch) {
  1771.                 case '-':
  1772.                 case '_':
  1773.                 case '.':
  1774.                 case '!':
  1775.                 case '*':
  1776.                 case '\'':
  1777.                 case '(':
  1778.                 case ')':
  1779.                     return true;
  1780.             }
  1781.            
  1782.             return false;
  1783.         }
  1784.        
  1785.         private int m_CallNesting;
  1786.         // > 0 if we're in a Read/Write call
  1787.         private AsyncOperation m_AsyncOp;
  1788.        
  1789.         private void InvokeOperationCompleted(AsyncOperation asyncOp, SendOrPostCallback callback, AsyncCompletedEventArgs eventArgs)
  1790.         {
  1791.             if ((object)Interlocked.CompareExchange<AsyncOperation>(ref m_AsyncOp, null, asyncOp) == (object)asyncOp) {
  1792.                 CompleteWebClientState();
  1793.                 // AsyncOperationManager is responsible for invoke the callback
  1794.                 asyncOp.PostOperationCompleted(callback, eventArgs);
  1795.             }
  1796.         }
  1797.        
  1798.         private bool AnotherCallInProgress(int callNesting)
  1799.         {
  1800.             return callNesting > 1;
  1801.         }
  1802.        
  1803.        
  1804.         //
  1805.        
  1806.         //
  1807.         public event OpenReadCompletedEventHandler OpenReadCompleted;
  1808.         protected virtual void OnOpenReadCompleted(OpenReadCompletedEventArgs e)
  1809.         {
  1810.             if (OpenReadCompleted != null) {
  1811.                 OpenReadCompleted(this, e);
  1812.             }
  1813.         }
  1814.         private SendOrPostCallback openReadOperationCompleted;
  1815.         private void OpenReadOperationCompleted(object arg)
  1816.         {
  1817.             OnOpenReadCompleted((OpenReadCompletedEventArgs)arg);
  1818.         }
  1819.         private void OpenReadAsyncCallback(IAsyncResult result)
  1820.         {
  1821.             LazyAsyncResult lazyAsyncResult = (LazyAsyncResult)result;
  1822.             AsyncOperation asyncOp = (AsyncOperation)lazyAsyncResult.AsyncState;
  1823.             WebRequest request = (WebRequest)lazyAsyncResult.AsyncObject;
  1824.             Stream stream = null;
  1825.             Exception exception = null;
  1826.             try {
  1827.                 WebResponse response = m_WebResponse = GetWebResponse(request, result);
  1828.                 stream = response.GetResponseStream();
  1829.             }
  1830.             catch (Exception e) {
  1831.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  1832.                     throw;
  1833.                 }
  1834.                 exception = e;
  1835.                 if (!(e is WebException || e is SecurityException)) {
  1836.                     exception = new WebException(SR.GetString(SR.net_webclient), e);
  1837.                 }
  1838.             }
  1839.             catch {
  1840.                 exception = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  1841.             }
  1842.             OpenReadCompletedEventArgs eventArgs = new OpenReadCompletedEventArgs(stream, exception, m_Cancelled, asyncOp.UserSuppliedState);
  1843.            
  1844.             InvokeOperationCompleted(asyncOp, openReadOperationCompleted, eventArgs);
  1845.         }
  1846.        
  1847.         [HostProtection(ExternalThreading = true)]
  1848.         public void OpenReadAsync(Uri address)
  1849.         {
  1850.             OpenReadAsync(address, null);
  1851.         }
  1852.        
  1853.         [HostProtection(ExternalThreading = true)]
  1854.         public void OpenReadAsync(Uri address, object userToken)
  1855.         {
  1856.             if (Logging.On)
  1857.                 Logging.Enter(Logging.Web, this, "OpenReadAsync", address);
  1858.             if (address == null)
  1859.                 throw new ArgumentNullException("address");
  1860.             InitWebClientAsync();
  1861.             ClearWebClientState();
  1862.             AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
  1863.             m_AsyncOp = asyncOp;
  1864.             try {
  1865.                 WebRequest request = m_WebRequest = GetWebRequest(GetUri(address));
  1866.                 request.BeginGetResponse(new AsyncCallback(OpenReadAsyncCallback), asyncOp);
  1867.             }
  1868.             catch (Exception e) {
  1869.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  1870.                     throw;
  1871.                 }
  1872.                 if (!(e is WebException || e is SecurityException)) {
  1873.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  1874.                 }
  1875.                
  1876.                 OpenReadCompletedEventArgs eventArgs = new OpenReadCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState);
  1877.                 InvokeOperationCompleted(asyncOp, openReadOperationCompleted, eventArgs);
  1878.             }
  1879.             catch {
  1880.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  1881.                 OpenReadCompletedEventArgs eventArgs = new OpenReadCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState);
  1882.                 InvokeOperationCompleted(asyncOp, openReadOperationCompleted, eventArgs);
  1883.             }
  1884.             if (Logging.On)
  1885.                 Logging.Exit(Logging.Web, this, "OpenReadAsync", null);
  1886.         }
  1887.        
  1888.         //
  1889.         //OpenWrite
  1890.         //
  1891.        
  1892.         public event OpenWriteCompletedEventHandler OpenWriteCompleted;
  1893.         protected virtual void OnOpenWriteCompleted(OpenWriteCompletedEventArgs e)
  1894.         {
  1895.             if (OpenWriteCompleted != null) {
  1896.                 OpenWriteCompleted(this, e);
  1897.             }
  1898.         }
  1899.         private SendOrPostCallback openWriteOperationCompleted;
  1900.         private void OpenWriteOperationCompleted(object arg)
  1901.         {
  1902.             OnOpenWriteCompleted((OpenWriteCompletedEventArgs)arg);
  1903.         }
  1904.         private void OpenWriteAsyncCallback(IAsyncResult result)
  1905.         {
  1906.             LazyAsyncResult lazyAsyncResult = (LazyAsyncResult)result;
  1907.             AsyncOperation asyncOp = (AsyncOperation)lazyAsyncResult.AsyncState;
  1908.             WebRequest request = (WebRequest)lazyAsyncResult.AsyncObject;
  1909.             WebClientWriteStream stream = null;
  1910.             Exception exception = null;
  1911.            
  1912.             try {
  1913.                 stream = new WebClientWriteStream(request.EndGetRequestStream(result), request, this);
  1914.             }
  1915.             catch (Exception e) {
  1916.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  1917.                     throw;
  1918.                 }
  1919.                 exception = e;
  1920.                 if (!(e is WebException || e is SecurityException)) {
  1921.                     exception = new WebException(SR.GetString(SR.net_webclient), e);
  1922.                 }
  1923.             }
  1924.             catch {
  1925.                 exception = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  1926.             }
  1927.            
  1928.             OpenWriteCompletedEventArgs eventArgs = new OpenWriteCompletedEventArgs(stream, exception, m_Cancelled, asyncOp.UserSuppliedState);
  1929.             InvokeOperationCompleted(asyncOp, openWriteOperationCompleted, eventArgs);
  1930.         }
  1931.        
  1932.        
  1933.         [HostProtection(ExternalThreading = true)]
  1934.         public void OpenWriteAsync(Uri address)
  1935.         {
  1936.             OpenWriteAsync(address, null, null);
  1937.         }
  1938.        
  1939.         [HostProtection(ExternalThreading = true)]
  1940.         public void OpenWriteAsync(Uri address, string method)
  1941.         {
  1942.             OpenWriteAsync(address, method, null);
  1943.         }
  1944.        
  1945.         [HostProtection(ExternalThreading = true)]
  1946.         public void OpenWriteAsync(Uri address, string method, object userToken)
  1947.         {
  1948.             if (Logging.On)
  1949.                 Logging.Enter(Logging.Web, this, "OpenWriteAsync", address + ", " + method);
  1950.             if (address == null)
  1951.                 throw new ArgumentNullException("address");
  1952.             if (method == null) {
  1953.                 method = MapToDefaultMethod(address);
  1954.             }
  1955.             InitWebClientAsync();
  1956.             ClearWebClientState();
  1957.             AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
  1958.             m_AsyncOp = asyncOp;
  1959.             try {
  1960.                 m_Method = method;
  1961.                 WebRequest request = m_WebRequest = GetWebRequest(GetUri(address));
  1962.                 request.BeginGetRequestStream(new AsyncCallback(OpenWriteAsyncCallback), asyncOp);
  1963.             }
  1964.             catch (Exception e) {
  1965.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  1966.                     throw;
  1967.                 }
  1968.                 if (!(e is WebException || e is SecurityException)) {
  1969.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  1970.                 }
  1971.                
  1972.                 OpenWriteCompletedEventArgs eventArgs = new OpenWriteCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState);
  1973.                 InvokeOperationCompleted(asyncOp, openWriteOperationCompleted, eventArgs);
  1974.             }
  1975.             catch {
  1976.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  1977.                
  1978.                 OpenWriteCompletedEventArgs eventArgs = new OpenWriteCompletedEventArgs(null, e, m_Cancelled, asyncOp.UserSuppliedState);
  1979.                 InvokeOperationCompleted(asyncOp, openWriteOperationCompleted, eventArgs);
  1980.             }
  1981.             if (Logging.On)
  1982.                 Logging.Exit(Logging.Web, this, "OpenWriteAsync", null);
  1983.         }
  1984.        
  1985.         //
  1986.         //DownloadString
  1987.         //
  1988.        
  1989.         public event DownloadStringCompletedEventHandler DownloadStringCompleted;
  1990.         protected virtual void OnDownloadStringCompleted(DownloadStringCompletedEventArgs e)
  1991.         {
  1992.             if (DownloadStringCompleted != null) {
  1993.                 DownloadStringCompleted(this, e);
  1994.             }
  1995.         }
  1996.         private SendOrPostCallback downloadStringOperationCompleted;
  1997.         private void DownloadStringOperationCompleted(object arg)
  1998.         {
  1999.             OnDownloadStringCompleted((DownloadStringCompletedEventArgs)arg);
  2000.         }
  2001.        
  2002.         private void DownloadStringAsyncCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2003.         {
  2004.            
  2005.             string stringData = null;
  2006.             try {
  2007.                 if (returnBytes != null) {
  2008.                     stringData = GuessDownloadEncoding(m_WebRequest).GetString(returnBytes);
  2009.                 }
  2010.             }
  2011.             catch (Exception e) {
  2012.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  2013.                     throw;
  2014.                 }
  2015.                 exception = e;
  2016.             }
  2017.             catch {
  2018.                 exception = new Exception(SR.GetString(SR.net_nonClsCompliantException));
  2019.             }
  2020.            
  2021.             DownloadStringCompletedEventArgs eventArgs = new DownloadStringCompletedEventArgs(stringData, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2022.            
  2023.             InvokeOperationCompleted(asyncOp, downloadStringOperationCompleted, eventArgs);
  2024.         }
  2025.        
  2026.         [HostProtection(ExternalThreading = true)]
  2027.         public void DownloadStringAsync(Uri address)
  2028.         {
  2029.             DownloadStringAsync(address, null);
  2030.         }
  2031.         [HostProtection(ExternalThreading = true)]
  2032.         public void DownloadStringAsync(Uri address, object userToken)
  2033.         {
  2034.             if (Logging.On)
  2035.                 Logging.Enter(Logging.Web, this, "DownloadStringAsync", address);
  2036.             if (address == null)
  2037.                 throw new ArgumentNullException("address");
  2038.             InitWebClientAsync();
  2039.             ClearWebClientState();
  2040.             AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
  2041.             m_AsyncOp = asyncOp;
  2042.             try {
  2043.                 WebRequest request = m_WebRequest = GetWebRequest(GetUri(address));
  2044.                 DownloadBits(request, null, new CompletionDelegate(DownloadStringAsyncCallback), asyncOp);
  2045.             }
  2046.             catch (Exception e) {
  2047.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  2048.                     throw;
  2049.                 }
  2050.                 if (!(e is WebException || e is SecurityException)) {
  2051.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  2052.                 }
  2053.                 DownloadStringAsyncCallback(null, e, asyncOp);
  2054.             }
  2055.             catch {
  2056.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  2057.                 DownloadStringAsyncCallback(null, e, asyncOp);
  2058.             }
  2059.             if (Logging.On)
  2060.                 Logging.Exit(Logging.Web, this, "DownloadStringAsync", "");
  2061.         }
  2062.        
  2063.         //
  2064.         //DownloadData
  2065.         //
  2066.         public event DownloadDataCompletedEventHandler DownloadDataCompleted;
  2067.         protected virtual void OnDownloadDataCompleted(DownloadDataCompletedEventArgs e)
  2068.         {
  2069.             if (DownloadDataCompleted != null) {
  2070.                 DownloadDataCompleted(this, e);
  2071.             }
  2072.         }
  2073.         private SendOrPostCallback downloadDataOperationCompleted;
  2074.         private void DownloadDataOperationCompleted(object arg)
  2075.         {
  2076.             OnDownloadDataCompleted((DownloadDataCompletedEventArgs)arg);
  2077.         }
  2078.        
  2079.         private void DownloadDataAsyncCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2080.         {
  2081.             DownloadDataCompletedEventArgs eventArgs = new DownloadDataCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2082.            
  2083.             InvokeOperationCompleted(asyncOp, downloadDataOperationCompleted, eventArgs);
  2084.         }
  2085.        
  2086.         [HostProtection(ExternalThreading = true)]
  2087.         public void DownloadDataAsync(Uri address)
  2088.         {
  2089.             DownloadDataAsync(address, null);
  2090.         }
  2091.        
  2092.         [HostProtection(ExternalThreading = true)]
  2093.         public void DownloadDataAsync(Uri address, object userToken)
  2094.         {
  2095.             if (Logging.On)
  2096.                 Logging.Enter(Logging.Web, this, "DownloadDataAsync", address);
  2097.             if (address == null)
  2098.                 throw new ArgumentNullException("address");
  2099.             InitWebClientAsync();
  2100.             ClearWebClientState();
  2101.             AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
  2102.             m_AsyncOp = asyncOp;
  2103.             try {
  2104.                 WebRequest request = m_WebRequest = GetWebRequest(GetUri(address));
  2105.                 DownloadBits(request, null, new CompletionDelegate(DownloadDataAsyncCallback), asyncOp);
  2106.             }
  2107.             catch (Exception e) {
  2108.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  2109.                     throw;
  2110.                 }
  2111.                 if (!(e is WebException || e is SecurityException)) {
  2112.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  2113.                 }
  2114.                 DownloadDataAsyncCallback(null, e, asyncOp);
  2115.             }
  2116.             catch {
  2117.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  2118.                 DownloadDataAsyncCallback(null, e, asyncOp);
  2119.             }
  2120.             if (Logging.On)
  2121.                 Logging.Exit(Logging.Web, this, "DownloadDataAsync", null);
  2122.         }
  2123.        
  2124.         //
  2125.         //DownloadFile
  2126.         //
  2127.        
  2128.         public event AsyncCompletedEventHandler DownloadFileCompleted;
  2129.         protected virtual void OnDownloadFileCompleted(AsyncCompletedEventArgs e)
  2130.         {
  2131.             if (DownloadFileCompleted != null) {
  2132.                 DownloadFileCompleted(this, e);
  2133.             }
  2134.         }
  2135.         private SendOrPostCallback downloadFileOperationCompleted;
  2136.         private void DownloadFileOperationCompleted(object arg)
  2137.         {
  2138.             OnDownloadFileCompleted((AsyncCompletedEventArgs)arg);
  2139.         }
  2140.        
  2141.         private void DownloadFileAsyncCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2142.         {
  2143.            
  2144.             AsyncCompletedEventArgs eventArgs = new AsyncCompletedEventArgs(exception, m_Cancelled, asyncOp.UserSuppliedState);
  2145.            
  2146.             InvokeOperationCompleted(asyncOp, downloadFileOperationCompleted, eventArgs);
  2147.         }
  2148.        
  2149.        
  2150.         [HostProtection(ExternalThreading = true)]
  2151.         public void DownloadFileAsync(Uri address, string fileName)
  2152.         {
  2153.             DownloadFileAsync(address, fileName, null);
  2154.         }
  2155.         [HostProtection(ExternalThreading = true)]
  2156.         public void DownloadFileAsync(Uri address, string fileName, object userToken)
  2157.         {
  2158.             if (Logging.On)
  2159.                 Logging.Enter(Logging.Web, this, "DownloadFileAsync", address);
  2160.             if (address == null)
  2161.                 throw new ArgumentNullException("address");
  2162.             if (fileName == null)
  2163.                 throw new ArgumentNullException("fileName");
  2164.             FileStream fs = null;
  2165.             InitWebClientAsync();
  2166.             ClearWebClientState();
  2167.             AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
  2168.             m_AsyncOp = asyncOp;
  2169.             try {
  2170.                 fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
  2171.                 WebRequest request = m_WebRequest = GetWebRequest(GetUri(address));
  2172.                 DownloadBits(request, fs, new CompletionDelegate(DownloadFileAsyncCallback), asyncOp);
  2173.             }
  2174.             catch (Exception e) {
  2175.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  2176.                     throw;
  2177.                 }
  2178.                 if (fs != null) {
  2179.                     fs.Close();
  2180.                 }
  2181.                 if (!(e is WebException || e is SecurityException)) {
  2182.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  2183.                 }
  2184.                 DownloadFileAsyncCallback(null, e, asyncOp);
  2185.             }
  2186.             if (Logging.On)
  2187.                 Logging.Exit(Logging.Web, this, "DownloadFileAsync", null);
  2188.         }
  2189.        
  2190.         //
  2191.         //UploadString
  2192.         //
  2193.        
  2194.         public event UploadStringCompletedEventHandler UploadStringCompleted;
  2195.         protected virtual void OnUploadStringCompleted(UploadStringCompletedEventArgs e)
  2196.         {
  2197.             if (UploadStringCompleted != null) {
  2198.                 UploadStringCompleted(this, e);
  2199.             }
  2200.         }
  2201.         private SendOrPostCallback uploadStringOperationCompleted;
  2202.         private void UploadStringOperationCompleted(object arg)
  2203.         {
  2204.             OnUploadStringCompleted((UploadStringCompletedEventArgs)arg);
  2205.         }
  2206.        
  2207.         private void UploadStringAsyncWriteCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2208.         {
  2209.            
  2210.             if (exception != null) {
  2211.                 UploadStringCompletedEventArgs eventArgs = new UploadStringCompletedEventArgs(null, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2212.                
  2213.                 InvokeOperationCompleted(asyncOp, uploadStringOperationCompleted, eventArgs);
  2214.             }
  2215.            
  2216.         }
  2217.        
  2218.         private void UploadStringAsyncReadCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2219.         {
  2220.            
  2221.             string stringData = null;
  2222.             try {
  2223.                 if (returnBytes != null) {
  2224.                     stringData = GuessDownloadEncoding(m_WebRequest).GetString(returnBytes);
  2225.                 }
  2226.             }
  2227.             catch (Exception e) {
  2228.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  2229.                     throw;
  2230.                 }
  2231.                 exception = e;
  2232.             }
  2233.             catch {
  2234.                 exception = new Exception(SR.GetString(SR.net_nonClsCompliantException));
  2235.             }
  2236.            
  2237.             UploadStringCompletedEventArgs eventArgs = new UploadStringCompletedEventArgs(stringData, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2238.            
  2239.             InvokeOperationCompleted(asyncOp, uploadStringOperationCompleted, eventArgs);
  2240.         }
  2241.        
  2242.        
  2243.        
  2244.        
  2245.         [HostProtection(ExternalThreading = true)]
  2246.         public void UploadStringAsync(Uri address, string data)
  2247.         {
  2248.             UploadStringAsync(address, null, data, null);
  2249.         }
  2250.        
  2251.         [HostProtection(ExternalThreading = true)]
  2252.         public void UploadStringAsync(Uri address, string method, string data)
  2253.         {
  2254.             UploadStringAsync(address, method, data, null);
  2255.         }
  2256.        
  2257.         [HostProtection(ExternalThreading = true)]
  2258.         public void UploadStringAsync(Uri address, string method, string data, object userToken)
  2259.         {
  2260.             if (Logging.On)
  2261.                 Logging.Enter(Logging.Web, this, "UploadStringAsync", address);
  2262.             if (address == null)
  2263.                 throw new ArgumentNullException("address");
  2264.             if (data == null)
  2265.                 throw new ArgumentNullException("data");
  2266.             if (method == null) {
  2267.                 method = MapToDefaultMethod(address);
  2268.             }
  2269.             InitWebClientAsync();
  2270.             ClearWebClientState();
  2271.             AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
  2272.             m_AsyncOp = asyncOp;
  2273.             try {
  2274.                 byte[] requestData = Encoding.GetBytes(data);
  2275.                 m_Method = method;
  2276.                 m_ContentLength = requestData.Length;
  2277.                 WebRequest request = m_WebRequest = GetWebRequest(GetUri(address));
  2278.                 UploadBits(request, null, requestData, null, null, new CompletionDelegate(UploadStringAsyncWriteCallback), asyncOp);
  2279.                 DownloadBits(request, null, new CompletionDelegate(UploadStringAsyncReadCallback), asyncOp);
  2280.             }
  2281.             catch (Exception e) {
  2282.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  2283.                     throw;
  2284.                 }
  2285.                 if (!(e is WebException || e is SecurityException)) {
  2286.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  2287.                 }
  2288.                 UploadStringAsyncWriteCallback(null, e, asyncOp);
  2289.             }
  2290.             catch {
  2291.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  2292.                 UploadStringAsyncWriteCallback(null, e, asyncOp);
  2293.             }
  2294.             if (Logging.On)
  2295.                 Logging.Exit(Logging.Web, this, "UploadStringAsync", null);
  2296.         }
  2297.        
  2298.         //
  2299.         //UploadData
  2300.         //
  2301.        
  2302.         public event UploadDataCompletedEventHandler UploadDataCompleted;
  2303.         protected virtual void OnUploadDataCompleted(UploadDataCompletedEventArgs e)
  2304.         {
  2305.             if (UploadDataCompleted != null) {
  2306.                 UploadDataCompleted(this, e);
  2307.             }
  2308.         }
  2309.         private SendOrPostCallback uploadDataOperationCompleted;
  2310.         private void UploadDataOperationCompleted(object arg)
  2311.         {
  2312.             OnUploadDataCompleted((UploadDataCompletedEventArgs)arg);
  2313.         }
  2314.        
  2315.        
  2316.         private void UploadDataAsyncWriteCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2317.         {
  2318.            
  2319.             if (exception != null) {
  2320.                 UploadDataCompletedEventArgs eventArgs = new UploadDataCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2321.                
  2322.                 InvokeOperationCompleted(asyncOp, uploadDataOperationCompleted, eventArgs);
  2323.             }
  2324.            
  2325.         }
  2326.        
  2327.         private void UploadDataAsyncReadCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2328.         {
  2329.            
  2330.             UploadDataCompletedEventArgs eventArgs = new UploadDataCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2331.            
  2332.             InvokeOperationCompleted(asyncOp, uploadDataOperationCompleted, eventArgs);
  2333.         }
  2334.        
  2335.        
  2336.        
  2337.         [HostProtection(ExternalThreading = true)]
  2338.         public void UploadDataAsync(Uri address, byte[] data)
  2339.         {
  2340.             UploadDataAsync(address, null, data, null);
  2341.         }
  2342.        
  2343.         [HostProtection(ExternalThreading = true)]
  2344.         public void UploadDataAsync(Uri address, string method, byte[] data)
  2345.         {
  2346.             UploadDataAsync(address, method, data, null);
  2347.         }
  2348.        
  2349.         [HostProtection(ExternalThreading = true)]
  2350.         public void UploadDataAsync(Uri address, string method, byte[] data, object userToken)
  2351.         {
  2352.             if (Logging.On)
  2353.                 Logging.Enter(Logging.Web, this, "UploadDataAsync", address + ", " + method);
  2354.             if (address == null)
  2355.                 throw new ArgumentNullException("address");
  2356.             if (data == null)
  2357.                 throw new ArgumentNullException("data");
  2358.             if (method == null) {
  2359.                 method = MapToDefaultMethod(address);
  2360.             }
  2361.             InitWebClientAsync();
  2362.             ClearWebClientState();
  2363.             AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
  2364.             m_AsyncOp = asyncOp;
  2365.             try {
  2366.                 m_Method = method;
  2367.                 m_ContentLength = data.Length;
  2368.                 WebRequest request = m_WebRequest = GetWebRequest(GetUri(address));
  2369.                 UploadBits(request, null, data, null, null, new CompletionDelegate(UploadDataAsyncWriteCallback), asyncOp);
  2370.                 DownloadBits(request, null, new CompletionDelegate(UploadDataAsyncReadCallback), asyncOp);
  2371.             }
  2372.             catch (Exception e) {
  2373.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  2374.                     throw;
  2375.                 }
  2376.                 if (!(e is WebException || e is SecurityException)) {
  2377.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  2378.                 }
  2379.                 UploadDataAsyncWriteCallback(null, e, asyncOp);
  2380.             }
  2381.             catch {
  2382.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  2383.                 UploadDataAsyncWriteCallback(null, e, asyncOp);
  2384.             }
  2385.             if (Logging.On)
  2386.                 Logging.Exit(Logging.Web, this, "UploadDataAsync", null);
  2387.         }
  2388.        
  2389.         //
  2390.         //UploadFile
  2391.         //
  2392.        
  2393.         public event UploadFileCompletedEventHandler UploadFileCompleted;
  2394.         protected virtual void OnUploadFileCompleted(UploadFileCompletedEventArgs e)
  2395.         {
  2396.             if (UploadFileCompleted != null) {
  2397.                 UploadFileCompleted(this, e);
  2398.             }
  2399.         }
  2400.         private SendOrPostCallback uploadFileOperationCompleted;
  2401.         private void UploadFileOperationCompleted(object arg)
  2402.         {
  2403.             OnUploadFileCompleted((UploadFileCompletedEventArgs)arg);
  2404.         }
  2405.        
  2406.         private void UploadFileAsyncWriteCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2407.         {
  2408.            
  2409.             if (exception != null) {
  2410.                 UploadFileCompletedEventArgs eventArgs = new UploadFileCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2411.                
  2412.                 InvokeOperationCompleted(asyncOp, uploadFileOperationCompleted, eventArgs);
  2413.             }
  2414.            
  2415.         }
  2416.        
  2417.         private void UploadFileAsyncReadCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2418.         {
  2419.            
  2420.             UploadFileCompletedEventArgs eventArgs = new UploadFileCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2421.            
  2422.             InvokeOperationCompleted(asyncOp, uploadFileOperationCompleted, eventArgs);
  2423.         }
  2424.        
  2425.        
  2426.         [HostProtection(ExternalThreading = true)]
  2427.         [ResourceExposure(ResourceScope.Machine)]
  2428.         [ResourceConsumption(ResourceScope.Machine)]
  2429.         public void UploadFileAsync(Uri address, string fileName)
  2430.         {
  2431.             UploadFileAsync(address, null, fileName, null);
  2432.         }
  2433.        
  2434.         [HostProtection(ExternalThreading = true)]
  2435.         [ResourceExposure(ResourceScope.Machine)]
  2436.         [ResourceConsumption(ResourceScope.Machine)]
  2437.         public void UploadFileAsync(Uri address, string method, string fileName)
  2438.         {
  2439.             UploadFileAsync(address, method, fileName, null);
  2440.         }
  2441.        
  2442.         [HostProtection(ExternalThreading = true)]
  2443.         [ResourceExposure(ResourceScope.Machine)]
  2444.         [ResourceConsumption(ResourceScope.Machine)]
  2445.         public void UploadFileAsync(Uri address, string method, string fileName, object userToken)
  2446.         {
  2447.             if (Logging.On)
  2448.                 Logging.Enter(Logging.Web, this, "UploadFileAsync", address + ", " + method);
  2449.             if (address == null)
  2450.                 throw new ArgumentNullException("address");
  2451.             if (fileName == null)
  2452.                 throw new ArgumentNullException("fileName");
  2453.             if (method == null) {
  2454.                 method = MapToDefaultMethod(address);
  2455.             }
  2456.             InitWebClientAsync();
  2457.             ClearWebClientState();
  2458.             AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
  2459.             m_AsyncOp = asyncOp;
  2460.             FileStream fs = null;
  2461.            
  2462.             try {
  2463.                 m_Method = method;
  2464.                 byte[] formHeaderBytes = null;
  2465.                 byte[] boundaryBytes = null;
  2466.                 byte[] buffer = null;
  2467.                 Uri uri = GetUri(address);
  2468.                 bool needsHeaderAndBoundary = (uri.Scheme != Uri.UriSchemeFile);
  2469.                 OpenFileInternal(needsHeaderAndBoundary, fileName, ref fs, ref buffer, ref formHeaderBytes, ref boundaryBytes);
  2470.                 WebRequest request = m_WebRequest = GetWebRequest(uri);
  2471.                 UploadBits(request, fs, buffer, formHeaderBytes, boundaryBytes, new CompletionDelegate(UploadFileAsyncWriteCallback), asyncOp);
  2472.                 DownloadBits(request, null, new CompletionDelegate(UploadFileAsyncReadCallback), asyncOp);
  2473.             }
  2474.             catch (Exception e) {
  2475.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  2476.                     throw;
  2477.                 }
  2478.                 if (fs != null) {
  2479.                     fs.Close();
  2480.                 }
  2481.                 if (!(e is WebException || e is SecurityException)) {
  2482.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  2483.                 }
  2484.                 UploadFileAsyncWriteCallback(null, e, asyncOp);
  2485.             }
  2486.             if (Logging.On)
  2487.                 Logging.Exit(Logging.Web, this, "UploadFileAsync", null);
  2488.         }
  2489.        
  2490.        
  2491.         //
  2492.         //UploadValues
  2493.         //
  2494.        
  2495.         public event UploadValuesCompletedEventHandler UploadValuesCompleted;
  2496.         protected virtual void OnUploadValuesCompleted(UploadValuesCompletedEventArgs e)
  2497.         {
  2498.             if (UploadValuesCompleted != null) {
  2499.                 UploadValuesCompleted(this, e);
  2500.             }
  2501.         }
  2502.         private SendOrPostCallback uploadValuesOperationCompleted;
  2503.         private void UploadValuesOperationCompleted(object arg)
  2504.         {
  2505.             OnUploadValuesCompleted((UploadValuesCompletedEventArgs)arg);
  2506.         }
  2507.        
  2508.        
  2509.         private void UploadValuesAsyncWriteCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2510.         {
  2511.            
  2512.             if (exception != null) {
  2513.                 UploadValuesCompletedEventArgs eventArgs = new UploadValuesCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2514.                
  2515.                 InvokeOperationCompleted(asyncOp, uploadValuesOperationCompleted, eventArgs);
  2516.             }
  2517.            
  2518.         }
  2519.        
  2520.         private void UploadValuesAsyncReadCallback(byte[] returnBytes, Exception exception, AsyncOperation asyncOp)
  2521.         {
  2522.            
  2523.             UploadValuesCompletedEventArgs eventArgs = new UploadValuesCompletedEventArgs(returnBytes, exception, m_Cancelled, asyncOp.UserSuppliedState);
  2524.            
  2525.             InvokeOperationCompleted(asyncOp, uploadValuesOperationCompleted, eventArgs);
  2526.         }
  2527.        
  2528.        
  2529.         [HostProtection(ExternalThreading = true)]
  2530.         public void UploadValuesAsync(Uri address, NameValueCollection data)
  2531.         {
  2532.             UploadValuesAsync(address, null, data, null);
  2533.         }
  2534.        
  2535.         [HostProtection(ExternalThreading = true)]
  2536.         public void UploadValuesAsync(Uri address, string method, NameValueCollection data)
  2537.         {
  2538.             UploadValuesAsync(address, method, data, null);
  2539.         }
  2540.        
  2541.         [HostProtection(ExternalThreading = true)]
  2542.         public void UploadValuesAsync(Uri address, string method, NameValueCollection data, object userToken)
  2543.         {
  2544.             if (Logging.On)
  2545.                 Logging.Enter(Logging.Web, this, "UploadValuesAsync", address + ", " + method);
  2546.             if (address == null)
  2547.                 throw new ArgumentNullException("address");
  2548.             if (data == null)
  2549.                 throw new ArgumentNullException("data");
  2550.             if (method == null) {
  2551.                 method = MapToDefaultMethod(address);
  2552.             }
  2553.             InitWebClientAsync();
  2554.             ClearWebClientState();
  2555.             AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
  2556.             m_AsyncOp = asyncOp;
  2557.             try {
  2558.                 byte[] buffer = UploadValuesInternal(data);
  2559.                 m_Method = method;
  2560.                 WebRequest request = m_WebRequest = GetWebRequest(GetUri(address));
  2561.                 UploadBits(request, null, buffer, null, null, new CompletionDelegate(UploadValuesAsyncWriteCallback), asyncOp);
  2562.                 DownloadBits(request, null, new CompletionDelegate(UploadValuesAsyncReadCallback), asyncOp);
  2563.             }
  2564.             catch (Exception e) {
  2565.                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  2566.                     throw;
  2567.                 }
  2568.                 if (!(e is WebException || e is SecurityException)) {
  2569.                     e = new WebException(SR.GetString(SR.net_webclient), e);
  2570.                 }
  2571.                 UploadValuesAsyncWriteCallback(null, e, asyncOp);
  2572.             }
  2573.             catch {
  2574.                 Exception e = new WebException(SR.GetString(SR.net_webclient), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  2575.                 UploadValuesAsyncWriteCallback(null, e, asyncOp);
  2576.             }
  2577.             if (Logging.On)
  2578.                 Logging.Exit(Logging.Web, this, "UploadValuesAsync", null);
  2579.         }
  2580.        
  2581.        
  2582.         public void CancelAsync()
  2583.         {
  2584.             WebRequest request = m_WebRequest;
  2585.             m_Cancelled = true;
  2586.             AbortRequest(request);
  2587.         }
  2588.        
  2589.         //
  2590.         //ProgressChanged event - code for handling progress updates during uploads and downloads.
  2591.         //
  2592.        
  2593.         public event DownloadProgressChangedEventHandler DownloadProgressChanged;
  2594.         public event UploadProgressChangedEventHandler UploadProgressChanged;
  2595.        
  2596.         protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e)
  2597.         {
  2598.             if (DownloadProgressChanged != null) {
  2599.                 DownloadProgressChanged(this, e);
  2600.             }
  2601.         }
  2602.        
  2603.         protected virtual void OnUploadProgressChanged(UploadProgressChangedEventArgs e)
  2604.         {
  2605.             if (UploadProgressChanged != null) {
  2606.                 UploadProgressChanged(this, e);
  2607.             }
  2608.         }
  2609.        
  2610.         private SendOrPostCallback reportDownloadProgressChanged;
  2611.         private void ReportDownloadProgressChanged(object arg)
  2612.         {
  2613.             OnDownloadProgressChanged((DownloadProgressChangedEventArgs)arg);
  2614.         }
  2615.        
  2616.         private SendOrPostCallback reportUploadProgressChanged;
  2617.         private void ReportUploadProgressChanged(object arg)
  2618.         {
  2619.             OnUploadProgressChanged((UploadProgressChangedEventArgs)arg);
  2620.         }
  2621.        
  2622.         private void PostProgressChanged(AsyncOperation asyncOp, ProgressData progress)
  2623.         {
  2624.             if (asyncOp != null && progress.BytesSent + progress.BytesReceived > 0) {
  2625.                 int progressPercentage;
  2626.                 if (progress.HasUploadPhase) {
  2627.                     if (progress.TotalBytesToReceive < 0 && progress.BytesReceived == 0) {
  2628.                         progressPercentage = progress.TotalBytesToSend < 0 ? 0 : progress.TotalBytesToSend == 0 ? 50 : (int)((50 * progress.BytesSent) / progress.TotalBytesToSend);
  2629.                     }
  2630.                     else {
  2631.                         progressPercentage = progress.TotalBytesToSend < 0 ? 50 : progress.TotalBytesToReceive == 0 ? 100 : (int)((50 * progress.BytesReceived) / progress.TotalBytesToReceive + 50);
  2632.                     }
  2633.                     asyncOp.Post(reportUploadProgressChanged, new UploadProgressChangedEventArgs(progressPercentage, asyncOp.UserSuppliedState, progress.BytesSent, progress.TotalBytesToSend, progress.BytesReceived, progress.TotalBytesToReceive));
  2634.                 }
  2635.                 else {
  2636.                     progressPercentage = progress.TotalBytesToReceive < 0 ? 0 : progress.TotalBytesToReceive == 0 ? 100 : (int)((100 * progress.BytesReceived) / progress.TotalBytesToReceive);
  2637.                     asyncOp.Post(reportDownloadProgressChanged, new DownloadProgressChangedEventArgs(progressPercentage, asyncOp.UserSuppliedState, progress.BytesReceived, progress.TotalBytesToReceive));
  2638.                 }
  2639.             }
  2640.         }
  2641.        
  2642.        
  2643.         //
  2644.         // WebClientWriteStream
  2645.         //
  2646.         private class WebClientWriteStream : Stream
  2647.         {
  2648.            
  2649.             private WebRequest m_request;
  2650.             private Stream m_stream;
  2651.             private WebClient m_WebClient;
  2652.            
  2653.             public WebClientWriteStream(Stream stream, WebRequest request, WebClient webClient)
  2654.             {
  2655.                 m_request = request;
  2656.                 m_stream = stream;
  2657.                 m_WebClient = webClient;
  2658.             }
  2659.            
  2660.             public override bool CanRead {
  2661.                 get { return m_stream.CanRead; }
  2662.             }
  2663.            
  2664.             public override bool CanSeek {
  2665.                 get { return m_stream.CanSeek; }
  2666.             }
  2667.            
  2668.             public override bool CanWrite {
  2669.                 get { return m_stream.CanWrite; }
  2670.             }
  2671.            
  2672.             public override bool CanTimeout {
  2673.                 get { return m_stream.CanTimeout; }
  2674.             }
  2675.            
  2676.             public override int ReadTimeout {
  2677.                 get { return m_stream.ReadTimeout; }
  2678.                 set { m_stream.ReadTimeout = value; }
  2679.             }
  2680.            
  2681.             public override int WriteTimeout {
  2682.                 get { return m_stream.WriteTimeout; }
  2683.                 set { m_stream.WriteTimeout = value; }
  2684.             }
  2685.            
  2686.             public override long Length {
  2687.                 get { return m_stream.Length; }
  2688.             }
  2689.            
  2690.             public override long Position {
  2691.                 get { return m_stream.Position; }
  2692.                 set { m_stream.Position = value; }
  2693.             }
  2694.            
  2695.             [HostProtection(ExternalThreading = true)]
  2696.             public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
  2697.             {
  2698.                 return m_stream.BeginRead(buffer, offset, size, callback, state);
  2699.             }
  2700.            
  2701.             [HostProtection(ExternalThreading = true)]
  2702.             public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
  2703.             {
  2704.                 return m_stream.BeginWrite(buffer, offset, size, callback, state);
  2705.             }
  2706.            
  2707.             protected override void Dispose(bool disposing)
  2708.             {
  2709.                 try {
  2710.                     if (disposing) {
  2711.                         m_stream.Close();
  2712.                         m_WebClient.GetWebResponse(m_request).Close();
  2713.                     }
  2714.                 }
  2715.                 finally {
  2716.                     base.Dispose(disposing);
  2717.                 }
  2718.             }
  2719.            
  2720.             public override int EndRead(IAsyncResult result)
  2721.             {
  2722.                 return m_stream.EndRead(result);
  2723.             }
  2724.            
  2725.             public override void EndWrite(IAsyncResult result)
  2726.             {
  2727.                 m_stream.EndWrite(result);
  2728.             }
  2729.            
  2730.             public override void Flush()
  2731.             {
  2732.                 m_stream.Flush();
  2733.             }
  2734.            
  2735.             public override int Read(byte[] buffer, int offset, int count)
  2736.             {
  2737.                 return m_stream.Read(buffer, offset, count);
  2738.             }
  2739.            
  2740.             public override long Seek(long offset, SeekOrigin origin)
  2741.             {
  2742.                 return m_stream.Seek(offset, origin);
  2743.             }
  2744.            
  2745.             public override void SetLength(long value)
  2746.             {
  2747.                 m_stream.SetLength(value);
  2748.             }
  2749.            
  2750.             public override void Write(byte[] buffer, int offset, int count)
  2751.             {
  2752.                 m_stream.Write(buffer, offset, count);
  2753.             }
  2754.         }
  2755.        
  2756.     }
  2757.    
  2758.     //
  2759.     // Delegates and supporting CompletedEventArgs classes are used by async code
  2760.     //
  2761.    
  2762.     // Used by internal Async code to notify that we're done, or have an error
  2763.     internal delegate void CompletionDelegate(byte[] responseBytes, Exception exception, AsyncOperation asyncOp);
  2764.    
  2765.     public delegate void OpenReadCompletedEventHandler(object sender, OpenReadCompletedEventArgs e);
  2766.    
  2767.     public class OpenReadCompletedEventArgs : AsyncCompletedEventArgs
  2768.     {
  2769.         private Stream m_Result;
  2770.         internal OpenReadCompletedEventArgs(Stream result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken)
  2771.         {
  2772.             m_Result = result;
  2773.         }
  2774.         public Stream Result {
  2775.             get {
  2776.                 RaiseExceptionIfNecessary();
  2777.                 return m_Result;
  2778.             }
  2779.         }
  2780.     }
  2781.    
  2782.     public delegate void OpenWriteCompletedEventHandler(object sender, OpenWriteCompletedEventArgs e);
  2783.    
  2784.     public class OpenWriteCompletedEventArgs : AsyncCompletedEventArgs
  2785.     {
  2786.         private Stream m_Result;
  2787.         internal OpenWriteCompletedEventArgs(Stream result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken)
  2788.         {
  2789.             m_Result = result;
  2790.         }
  2791.         public Stream Result {
  2792.             get {
  2793.                 RaiseExceptionIfNecessary();
  2794.                 return m_Result;
  2795.             }
  2796.         }
  2797.     }
  2798.    
  2799.     public delegate void DownloadStringCompletedEventHandler(object sender, DownloadStringCompletedEventArgs e);
  2800.    
  2801.     public class DownloadStringCompletedEventArgs : AsyncCompletedEventArgs
  2802.     {
  2803.         string m_Result;
  2804.         internal DownloadStringCompletedEventArgs(string result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken)
  2805.         {
  2806.             m_Result = result;
  2807.         }
  2808.         public string Result {
  2809.             get {
  2810.                 RaiseExceptionIfNecessary();
  2811.                 return m_Result;
  2812.             }
  2813.         }
  2814.        
  2815.     }
  2816.    
  2817.     public delegate void DownloadDataCompletedEventHandler(object sender, DownloadDataCompletedEventArgs e);
  2818.    
  2819.     public class DownloadDataCompletedEventArgs : AsyncCompletedEventArgs
  2820.     {
  2821.         byte[] m_Result;
  2822.         internal DownloadDataCompletedEventArgs(byte[] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken)
  2823.         {
  2824.             m_Result = result;
  2825.         }
  2826.         public byte[] Result {
  2827.             get {
  2828.                 RaiseExceptionIfNecessary();
  2829.                 return m_Result;
  2830.             }
  2831.         }
  2832.        
  2833.     }
  2834.    
  2835.     public delegate void UploadStringCompletedEventHandler(object sender, UploadStringCompletedEventArgs e);
  2836.    
  2837.     public class UploadStringCompletedEventArgs : AsyncCompletedEventArgs
  2838.     {
  2839.         string m_Result;
  2840.         internal UploadStringCompletedEventArgs(string result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken)
  2841.         {
  2842.             m_Result = result;
  2843.         }
  2844.         public string Result {
  2845.             get {
  2846.                 RaiseExceptionIfNecessary();
  2847.                 return m_Result;
  2848.             }
  2849.         }
  2850.        
  2851.     }
  2852.    
  2853.     public delegate void UploadDataCompletedEventHandler(object sender, UploadDataCompletedEventArgs e);
  2854.    
  2855.     public class UploadDataCompletedEventArgs : AsyncCompletedEventArgs
  2856.     {
  2857.         byte[] m_Result;
  2858.         internal UploadDataCompletedEventArgs(byte[] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken)
  2859.         {
  2860.             m_Result = result;
  2861.         }
  2862.        
  2863.         public byte[] Result {
  2864.             get {
  2865.                 RaiseExceptionIfNecessary();
  2866.                 return m_Result;
  2867.             }
  2868.         }
  2869.     }
  2870.    
  2871.     public delegate void UploadFileCompletedEventHandler(object sender, UploadFileCompletedEventArgs e);
  2872.    
  2873.     public class UploadFileCompletedEventArgs : AsyncCompletedEventArgs
  2874.     {
  2875.         byte[] m_Result;
  2876.         internal UploadFileCompletedEventArgs(byte[] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken)
  2877.         {
  2878.             m_Result = result;
  2879.         }
  2880.        
  2881.         public byte[] Result {
  2882.             get {
  2883.                 RaiseExceptionIfNecessary();
  2884.                 return m_Result;
  2885.             }
  2886.         }
  2887.     }
  2888.    
  2889.     public delegate void UploadValuesCompletedEventHandler(object sender, UploadValuesCompletedEventArgs e);
  2890.    
  2891.     public class UploadValuesCompletedEventArgs : AsyncCompletedEventArgs
  2892.     {
  2893.         byte[] m_Result;
  2894.         internal UploadValuesCompletedEventArgs(byte[] result, Exception exception, bool cancelled, object userToken) : base(exception, cancelled, userToken)
  2895.         {
  2896.             m_Result = result;
  2897.         }
  2898.        
  2899.         public byte[] Result {
  2900.             get {
  2901.                 RaiseExceptionIfNecessary();
  2902.                 return m_Result;
  2903.             }
  2904.         }
  2905.     }
  2906.    
  2907.     public delegate void DownloadProgressChangedEventHandler(object sender, DownloadProgressChangedEventArgs e);
  2908.    
  2909.     public class DownloadProgressChangedEventArgs : ProgressChangedEventArgs
  2910.     {
  2911.         long m_BytesReceived;
  2912.         long m_TotalBytesToReceive;
  2913.        
  2914.         internal DownloadProgressChangedEventArgs(int progressPercentage, object userToken, long bytesReceived, long totalBytesToReceive) : base(progressPercentage, userToken)
  2915.         {
  2916.             m_BytesReceived = bytesReceived;
  2917.             m_TotalBytesToReceive = totalBytesToReceive;
  2918.         }
  2919.        
  2920.         public long BytesReceived {
  2921.             get { return m_BytesReceived; }
  2922.         }
  2923.        
  2924.         public long TotalBytesToReceive {
  2925.             get { return m_TotalBytesToReceive; }
  2926.         }
  2927.     }
  2928.    
  2929.     public delegate void UploadProgressChangedEventHandler(object sender, UploadProgressChangedEventArgs e);
  2930.    
  2931.     public class UploadProgressChangedEventArgs : ProgressChangedEventArgs
  2932.     {
  2933.         long m_BytesReceived;
  2934.         long m_TotalBytesToReceive;
  2935.         long m_BytesSent;
  2936.         long m_TotalBytesToSend;
  2937.        
  2938.         internal UploadProgressChangedEventArgs(int progressPercentage, object userToken, long bytesSent, long totalBytesToSend, long bytesReceived, long totalBytesToReceive) : base(progressPercentage, userToken)
  2939.         {
  2940.             m_BytesReceived = bytesReceived;
  2941.             m_TotalBytesToReceive = totalBytesToReceive;
  2942.             m_BytesSent = bytesSent;
  2943.             m_TotalBytesToSend = totalBytesToSend;
  2944.         }
  2945.        
  2946.         public long BytesReceived {
  2947.             get { return m_BytesReceived; }
  2948.         }
  2949.        
  2950.         public long TotalBytesToReceive {
  2951.             get { return m_TotalBytesToReceive; }
  2952.         }
  2953.        
  2954.         public long BytesSent {
  2955.             get { return m_BytesSent; }
  2956.         }
  2957.        
  2958.         public long TotalBytesToSend {
  2959.             get { return m_TotalBytesToSend; }
  2960.         }
  2961.        
  2962.     }
  2963. }

Developer Fusion