ClientProtocol.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Web / System / Web / Services / Protocols / ClientProtocol.cs / 1305376 / ClientProtocol.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Services.Protocols { 
    using System; 
    using System.Collections;
    using System.Diagnostics; 
    using System.ComponentModel;
    using System.IO;
    using System.Reflection;
    using System.Xml.Serialization; 
    using System.Net;
    using System.Net.Cache; 
    using System.Threading; 
    using System.Text;
    using System.Security.Cryptography.X509Certificates; 
    using System.Security.Permissions;
    using System.Runtime.InteropServices;
    using System.Web.Services.Diagnostics;
 
    internal class ClientTypeCache {
        Hashtable cache = new Hashtable(); 
 
        internal object this[Type key] {
            get { return cache[key]; } 
        }

        internal void Add(Type key, object value) {
            lock(this) { 
                if (cache[key] == value) return;
                Hashtable clone = new Hashtable(); 
                foreach (object k in cache.Keys) { 
                    clone.Add(k, cache[k]);
                } 
                cache = clone;
                cache[key] = value;
            }
        } 
    }
 
    ///  
    /// 
    ///     
    ///       Specifies the base class for all web service protocol client proxies that
    ///       use the HTTP protocol.
    ///    
    ///  
    [ComVisible(true)]
    public abstract class WebClientProtocol : Component { 
        static AsyncCallback getRequestStreamAsyncCallback; 
        static AsyncCallback getResponseAsyncCallback;
        static AsyncCallback readResponseAsyncCallback; 
        private static ClientTypeCache cache;
        private static RequestCachePolicy bypassCache;
        private ICredentials credentials;
        private bool preAuthenticate; 
        private Uri uri;
        private int timeout; 
        private string connectionGroupName; 
        private Encoding requestEncoding;
        private RemoteDebugger debugger; 
        private WebRequest pendingSyncRequest;
        object nullToken = new object();
        Hashtable asyncInvokes = Hashtable.Synchronized(new Hashtable());
 
        private static Object s_InternalSyncObject;
        internal static Object InternalSyncObject { 
            get { 
                if (s_InternalSyncObject == null) {
                    Object o = new Object(); 
                    Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
                }
                return s_InternalSyncObject;
            } 
        }
 
        static WebClientProtocol() { 
            cache = new ClientTypeCache();
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        protected WebClientProtocol() { 
            this.timeout = 100000; // should be kept in [....] with HttpWebRequest.Timeout default (see private WebRequest.DefaultTimeout) 
        }
 
        internal WebClientProtocol(WebClientProtocol protocol) {
            this.credentials        = protocol.credentials;
            this.uri                = protocol.uri;
            this.timeout            = protocol.timeout; 
            this.connectionGroupName= protocol.connectionGroupName;
            this.requestEncoding    = protocol.requestEncoding; 
        } 

        internal static RequestCachePolicy BypassCache { 
            get {
                if (bypassCache == null) {
                    bypassCache = new RequestCachePolicy(RequestCacheLevel.BypassCache);
                } 
                return bypassCache;
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public ICredentials Credentials { 
            get {
                return credentials; 
            } 
            set {
                credentials = value; 
            }
        }

        ///  
        /// 
        ///    Sets Credentials to CredentialCache.DefaultCredentials 
        ///  
        public bool UseDefaultCredentials  {
            get { 
                return (credentials == CredentialCache.DefaultCredentials) ? true : false;
            }
            set {
                credentials = value ? CredentialCache.DefaultCredentials : null; 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets a value indicating the name of the connection group to use when making a request.
        ///    
        ///  
        [DefaultValue("")]
        public string ConnectionGroupName { 
            get { return (connectionGroupName == null) ? string.Empty : connectionGroupName; } 
            set { connectionGroupName = value; }
        } 

        internal WebRequest PendingSyncRequest {
            get { return pendingSyncRequest; }
            set { pendingSyncRequest = value; } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets or sets a value indicating whether pre-authentication is enabled.
        ///    
        /// 
        [DefaultValue(false), WebServicesDescription(Res.ClientProtocolPreAuthenticate)] 
        public bool PreAuthenticate {
            get { return preAuthenticate; } 
            set { preAuthenticate = value; } 
        }
 
        /// 
        /// 
        ///    
        ///       Gets or sets the base Uri to the server to use for requests. 
        ///    
        ///  
        [DefaultValue(""), SettingsBindable(true), WebServicesDescription(Res.ClientProtocolUrl)] 
        public string Url {
            get { return uri == null ? string.Empty : uri.ToString(); } 
            set { uri = new Uri(value); }
        }

        internal Hashtable AsyncInvokes { 
            get { return asyncInvokes; }
        } 
 
        internal object NullToken {
            get { return nullToken; } 
        }

        internal Uri Uri {
            get { return uri; } 
            set { uri = value; }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets the encoding used for making the request.
        ///    
        ///  
        [DefaultValue(null), SettingsBindable(true), WebServicesDescription(Res.ClientProtocolEncoding)]
        public Encoding RequestEncoding { 
            get { return requestEncoding; } 
            set { requestEncoding = value; }
        } 

        /// 
        /// 
        ///     
        ///       Gets or sets the timeout (in milliseconds) used for synchronous calls.
        ///     
        ///  
        [DefaultValue(100000), SettingsBindable(true), WebServicesDescription(Res.ClientProtocolTimeout)]
        public int Timeout { 
            get { return timeout; }
            set { timeout = (value < Threading.Timeout.Infinite) ? Threading.Timeout.Infinite : value; }
        }
 
        /// 
        public virtual void Abort() { 
            WebRequest request = PendingSyncRequest; 
            if (request != null)
                request.Abort(); 
        }

        /// 
        ///     
        ///     Starts async request processing including async retrieval of the request stream and response.
        ///     Derived classes can use BeginSend 
        ///     to help implement their own higher level async methods like BeginInvoke. Derived 
        ///     classes can add custom behavior by overriding GetWebRequest, GetWebResponse,
        ///     InitializeAsyncRequest and WriteAsyncRequest methods. 
        ///    
        /// 
        internal IAsyncResult BeginSend(Uri requestUri, WebClientAsyncResult asyncResult, bool callWriteAsyncRequest) {
            if (readResponseAsyncCallback == null) { 
                lock (InternalSyncObject) {
                    if (readResponseAsyncCallback == null) { 
                        getRequestStreamAsyncCallback = new AsyncCallback(GetRequestStreamAsyncCallback); 
                        getResponseAsyncCallback = new AsyncCallback(GetResponseAsyncCallback);
                        readResponseAsyncCallback = new AsyncCallback(ReadResponseAsyncCallback); 
                    }
                }
            }
            Debug.Assert(asyncResult.Request == null, "calling GetWebRequest twice for the same WebClientAsyncResult"); 
            WebRequest request = GetWebRequest(requestUri);
            asyncResult.Request = request; 
            InitializeAsyncRequest(request, asyncResult.InternalAsyncState); 
            if (callWriteAsyncRequest)
                request.BeginGetRequestStream(getRequestStreamAsyncCallback, asyncResult); 
            else
                request.BeginGetResponse(getResponseAsyncCallback, asyncResult);

            if (!asyncResult.IsCompleted) 
                asyncResult.CombineCompletedSynchronously(false);
            return asyncResult; 
        } 

        static private void ProcessAsyncException(WebClientAsyncResult client, Exception e, string method) { 
            if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, typeof(WebClientProtocol), method, e);
            WebException webException = e as WebException;
            if (webException != null && webException.Response != null) {
                client.Response = webException.Response; 
            }
            else { 
                // If we've already completed the call then the exception must have come 
                // out of the user callback in which case we need to rethrow it here
                // so that it bubbles up to the AppDomain unhandled exception event. 
                if (client.IsCompleted)
                    throw new InvalidOperationException(Res.GetString(Res.ThereWasAnErrorDuringAsyncProcessing), e);
                else
                    client.Complete(e); 
            }
        } 
 
        static private void GetRequestStreamAsyncCallback(IAsyncResult asyncResult) {
            WebClientAsyncResult client = (WebClientAsyncResult)asyncResult.AsyncState; 
            client.CombineCompletedSynchronously(asyncResult.CompletedSynchronously);
            bool processingRequest = true;
            try {
                Stream requestStream = client.Request.EndGetRequestStream(asyncResult); 
                processingRequest = false;
                try { 
                    client.ClientProtocol.AsyncBufferedSerialize(client.Request, requestStream, client.InternalAsyncState); 
                }
                finally { 
                    requestStream.Close();
                }
                client.Request.BeginGetResponse(getResponseAsyncCallback, client);
            } 
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw; 
                }
                ProcessAsyncException(client, e, "GetRequestStreamAsyncCallback"); 
                if (processingRequest)
                {
                    WebException we = e as WebException;
                    if (we != null && we.Response != null) 
                    {
                        // ProcessAsyncExcption doesn't call client.Complete() if there's a response, 
                        // because it expects us to read the response. However, in certain cases 
                        // (e.g. 502 errors), the exception thrown from Request can have a response.
                        // We don't process it, so call Complete() now. 
                        client.Complete(e);
                    }
                }
            } 
        }
 
        static private void GetResponseAsyncCallback(IAsyncResult asyncResult) { 
            WebClientAsyncResult client = (WebClientAsyncResult)asyncResult.AsyncState;
            client.CombineCompletedSynchronously(asyncResult.CompletedSynchronously); 
            try {
                client.Response = client.ClientProtocol.GetWebResponse(client.Request, asyncResult);
            }
            catch (Exception e) { 
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                } 
                ProcessAsyncException(client, e, "GetResponseAsyncCallback");
                if (client.Response == null) 
                    return;
            }

            ReadAsyncResponse(client); 
        }
 
        static private void ReadAsyncResponse(WebClientAsyncResult client) { 
            if (client.Response.ContentLength == 0) {
                client.Complete(); 
                return;
            }
            try {
                client.ResponseStream = client.Response.GetResponseStream(); 
                ReadAsyncResponseStream(client);
            } 
            catch (Exception e) { 
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                }
                ProcessAsyncException(client, e, "ReadAsyncResponse");
            }
        } 

        static private void ReadAsyncResponseStream(WebClientAsyncResult client) { 
            IAsyncResult asyncResult; 
            do {
                byte[] buffer = client.Buffer; 
                long contentLength = client.Response.ContentLength;
                if (buffer == null)
                    buffer = client.Buffer = new byte[(contentLength == -1) ? 1024 : contentLength];
                else if (contentLength != -1 && contentLength > buffer.Length) 
                    buffer = client.Buffer = new byte[contentLength];
                asyncResult = client.ResponseStream.BeginRead(buffer, 0, buffer.Length, readResponseAsyncCallback, client); 
                if (!asyncResult.CompletedSynchronously) 
                    return;
            } 
            while (!ProcessAsyncResponseStreamResult(client, asyncResult));
        }

        static private bool ProcessAsyncResponseStreamResult(WebClientAsyncResult client, IAsyncResult asyncResult) { 
            bool complete;
            int bytesRead = client.ResponseStream.EndRead(asyncResult); 
            long contentLength = client.Response.ContentLength; 
            if (contentLength > 0 && bytesRead == contentLength) {
                // the non-chunked response finished in a single read 
                client.ResponseBufferedStream = new MemoryStream(client.Buffer);
                complete = true;
            }
            else if (bytesRead > 0) { 
                if (client.ResponseBufferedStream == null) {
                    int capacity = (int)((contentLength == -1) ? client.Buffer.Length : contentLength); 
                    client.ResponseBufferedStream = new MemoryStream(capacity); 
                }
                client.ResponseBufferedStream.Write(client.Buffer, 0, bytesRead); 
                complete = false;
            }
            else
                complete = true; 

            if (complete) 
                client.Complete(); 
            return complete;
        } 

        static private void ReadResponseAsyncCallback(IAsyncResult asyncResult) {
            WebClientAsyncResult client = (WebClientAsyncResult)asyncResult.AsyncState;
            client.CombineCompletedSynchronously(asyncResult.CompletedSynchronously); 
            if (asyncResult.CompletedSynchronously)
                return; 
            try { 
                bool complete = ProcessAsyncResponseStreamResult(client, asyncResult);
                if (!complete) 
                    ReadAsyncResponseStream(client);
            }
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw;
                } 
                ProcessAsyncException(client, e, "ReadResponseAsyncCallback"); 
            }
        } 

        internal void NotifyClientCallOut(WebRequest request) {
            if (RemoteDebugger.IsClientCallOutEnabled()) {
                debugger = new RemoteDebugger(); 
                debugger.NotifyClientCallOut(request);
            } 
            else { 
                debugger = null;
            } 
        }

        /// 
        ///  
        ///    
        ///     Creates a new  instance for the given url. The base implementation creates a new 
        ///     instance using the WebRequest.Create() and then sets request related properties from 
        ///     the WebClientProtocol instance. Derived classes can override this method if additional
        ///     properties need to be set on the web request instance. 
        ///    
        /// 
        protected virtual WebRequest GetWebRequest(Uri uri) {
            if (uri == null) 
                throw new InvalidOperationException(Res.GetString(Res.WebMissingPath));
            WebRequest request = (WebRequest)WebRequest.Create(uri); 
            PendingSyncRequest = request; 
            request.Timeout = this.timeout;
            request.ConnectionGroupName = connectionGroupName; 
            request.Credentials = Credentials;
            request.PreAuthenticate = PreAuthenticate;
            request.CachePolicy = BypassCache;
            return request; 
        }
 
        ///  
        /// 
        ///     
        ///     Gets the  from the given request by calling
        ///     GetResponse(). Derived classes can override this method to do additional
        ///     processing on the response instance.
        ///     
        /// 
        protected virtual WebResponse GetWebResponse(WebRequest request) { 
            TraceMethod caller = Tracing.On ? new TraceMethod(this, "GetWebResponse") : null; 
            WebResponse response = null;
            try { 
                if (Tracing.On) Tracing.Enter("WebRequest.GetResponse", caller, new TraceMethod(request, "GetResponse"));
                response = request.GetResponse();
                if (Tracing.On) Tracing.Exit("WebRequest.GetResponse", caller);
            } 
            catch (WebException e) {
                if (e.Response == null) 
                    throw e; 
                else {
                    if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "GetWebResponse", e); 
                    response = e.Response;
                }
            }
            finally { 
                if (debugger != null)
                    debugger.NotifyClientCallReturn(response); 
            } 
            return response;
        } 

        /// 
        /// 
        ///     
        ///     Gets the  from the given request by calling
        ///     EndGetResponse(). Derived classes can override this method to do additional 
        ///     processing on the response instance. This method is only called during 
        ///     async request processing.
        ///     
        /// 
        protected virtual WebResponse GetWebResponse(WebRequest request, IAsyncResult result) {
            WebResponse response = request.EndGetResponse(result);
            if (response != null && debugger != null) 
                debugger.NotifyClientCallReturn(response);
            return response; 
        } 

        ///  
        ///    
        ///     Called during async request processing to give the derived class an opportunity
        ///     to modify the web request instance before the request stream is retrieved at which
        ///     point the request headers are sent and can no longer be modified. The base implementation 
        ///     does nothing.
        ///     
        ///  
        [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
        internal virtual void InitializeAsyncRequest(WebRequest request, object internalAsyncState) { 
            return;
        }

        [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")] 
        internal virtual void AsyncBufferedSerialize(WebRequest request, Stream requestStream, object internalAsyncState) {
            throw new NotSupportedException(Res.GetString(Res.ProtocolDoesNotAsyncSerialize)); 
        } 

        internal WebResponse EndSend(IAsyncResult asyncResult, ref object internalAsyncState, ref Stream responseStream) { 
            if (asyncResult == null) throw new ArgumentNullException(Res.GetString(Res.WebNullAsyncResultInEnd));

            WebClientAsyncResult client = (WebClientAsyncResult)asyncResult;
            if (client.EndSendCalled) 
                throw new InvalidOperationException(Res.GetString(Res.CanTCallTheEndMethodOfAnAsyncCallMoreThan));
            client.EndSendCalled = true; 
            WebResponse response = client.WaitForResponse(); 
            internalAsyncState = client.InternalAsyncState;
            responseStream = client.ResponseBufferedStream; 
            return response;
        }

        ///  
        /// 
        /// Returns an instance of a client protocol handler from the cache. 
        ///  
        protected static object GetFromCache(Type type) {
            return cache[type]; 
        }

        /// 
        ///  
        ///    
        ///       Add an instance of the client protocol handler to the cache. 
        ///     
        /// 
        protected static void AddToCache(Type type, object value) { 
            cache.Add(type, value);
        }

    } 

    ///  
    [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")] 
    public class WebClientAsyncResult : IAsyncResult {
        private object userAsyncState; 
        private bool completedSynchronously;
        private bool isCompleted;
        private ManualResetEvent manualResetEvent;
        private AsyncCallback userCallback; 

        internal WebClientProtocol ClientProtocol; 
        internal object InternalAsyncState; 
        internal Exception Exception;
        internal WebResponse Response; 
        internal WebRequest Request;
        internal Stream ResponseStream;
        internal Stream ResponseBufferedStream;
        internal byte[] Buffer; 
        internal bool EndSendCalled;
 
        internal WebClientAsyncResult(WebClientProtocol clientProtocol, 
            object internalAsyncState,
            WebRequest request, 
            AsyncCallback userCallback,
            object userAsyncState)
        {
            this.ClientProtocol = clientProtocol; 
            this.InternalAsyncState = internalAsyncState;
            this.userAsyncState = userAsyncState; 
            this.userCallback = userCallback; 
            this.Request = request;
            this.completedSynchronously = true; 
        }

        /// 
        public object AsyncState { get { return userAsyncState; } } 

        ///  
        public WaitHandle AsyncWaitHandle { 
            get {
                bool savedIsCompleted = isCompleted; 
                if (manualResetEvent == null) {
                    lock (this) {
                        if (manualResetEvent == null)
                            manualResetEvent = new ManualResetEvent(savedIsCompleted); 
                    }
                } 
                if (!savedIsCompleted && isCompleted) 
                    manualResetEvent.Set();
                return (WaitHandle)manualResetEvent; 
            }
        }

        ///  
        public bool CompletedSynchronously {
            get { return completedSynchronously; } 
        } 

        ///  
        public bool IsCompleted { get { return isCompleted; } }

        /// 
        public void Abort() { 
            WebRequest req = Request;
            if (req != null) 
                req.Abort(); 
        }
 

        internal void Complete() {
            Debug.Assert(!isCompleted, "Complete called more than once.");
 
            try {
                if (ResponseStream != null) { 
                    ResponseStream.Close(); 
                    ResponseStream = null;
                } 

                if (ResponseBufferedStream != null)
                    ResponseBufferedStream.Position = 0;
            } 
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw; 
                }
                if (this.Exception == null) 
                    this.Exception = e;
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "Complete", e);
            }
 
            isCompleted = true;
 
            try { 
                if (manualResetEvent != null)
                    manualResetEvent.Set(); 
            }
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                }
                if (this.Exception == null) 
                    this.Exception = e; 
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "Complete", e);
            } 

            // We want to let exceptions in user callback to bubble up to
            // threadpool so that AppDomain.UnhandledExceptionEventHandler
            // will get it if one is registered 
            if (userCallback != null)
                userCallback(this); 
        } 

        internal void Complete(Exception e) { 
            this.Exception = e;
            Complete();
        }
 
        internal WebResponse WaitForResponse() {
            if (!isCompleted) 
                AsyncWaitHandle.WaitOne(); 

            if (this.Exception != null) 
                throw this.Exception;

            return Response;
        } 

        internal void CombineCompletedSynchronously(bool innerCompletedSynchronously) { 
            completedSynchronously = completedSynchronously && innerCompletedSynchronously; 
        }
    } 

    /// 
    /// 
    ///    [To be supplied.] 
    /// 
    public delegate void InvokeCompletedEventHandler(object sender, InvokeCompletedEventArgs e); 
 
    /// 
    ///  
    ///    [To be supplied.]
    /// 
    public class InvokeCompletedEventArgs : AsyncCompletedEventArgs {
        object[] results; 

        internal InvokeCompletedEventArgs(object[] results, Exception exception, bool cancelled, object userState) : 
            base(exception, cancelled, userState) { 
            this.results = results;
        } 

        /// 
        /// 
        ///     
        ///       Gets or sets a value indicating whether the client should automatically follow server redirects.
        ///     
        ///  
        public object[] Results {
            get { 
                return results;
            }
        }
    } 

 
    internal class UserToken { 
        SendOrPostCallback callback;
        object userState; 

        internal UserToken(SendOrPostCallback callback, object userState) {
            this.callback = callback;
            this.userState = userState; 
        }
        internal SendOrPostCallback Callback { get { return callback; } } 
        internal object UserState { get { return userState; } } 
    }
 
    /// 
    /// 
    ///    [To be supplied.]
    ///  
    [ComVisible(true)]
    public abstract class HttpWebClientProtocol : WebClientProtocol { 
        private bool allowAutoRedirect; 
        private bool enableDecompression = false;
        private CookieContainer cookieJar = null; 
        private X509CertificateCollection clientCertificates;
        private IWebProxy proxy;
        private static string UserAgentDefault = "Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol " + System.Environment.Version.ToString() + ")";
        private string userAgent; 
        private bool unsafeAuthenticatedConnectionSharing;
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        protected HttpWebClientProtocol() : base() {
            this.allowAutoRedirect = false;
            this.userAgent = UserAgentDefault; 
            // the right thing to do, for NetClasses to pick up the default
            // GlobalProxySelection settings, is to leave proxy to null 
            // (which is the default initialization value) 
            // rather than picking up GlobalProxySelection.Select
            // which will never change. 
        }

        // used by SoapHttpClientProtocol.Discover
        internal HttpWebClientProtocol(HttpWebClientProtocol protocol) 
            : base(protocol) {
            this.allowAutoRedirect  = protocol.allowAutoRedirect; 
            this.enableDecompression  = protocol.enableDecompression; 
            this.cookieJar          = protocol.cookieJar;
            this.clientCertificates = protocol.clientCertificates; 
            this.proxy              = protocol.proxy;
            this.userAgent          = protocol.userAgent;
        }
 
        /// 
        ///  
        ///     
        ///       Gets or sets a value indicating whether the client should automatically follow server redirects.
        ///     
        /// 
        [DefaultValue(false), WebServicesDescription(Res.ClientProtocolAllowAutoRedirect)]
        public bool AllowAutoRedirect {
            get { 
                return allowAutoRedirect;
            } 
 
            set {
                allowAutoRedirect = value; 
            }
        }

 
        /// 
        [DefaultValue(null), WebServicesDescription(Res.ClientProtocolCookieContainer)] 
        public CookieContainer CookieContainer { 
            get {
                return cookieJar; 
            }
            set {
                cookieJar = value;
            } 
        }
 
        ///  
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), WebServicesDescription(Res.ClientProtocolClientCertificates)]
        public X509CertificateCollection ClientCertificates { 
            get {
                if (clientCertificates == null) {
                    clientCertificates = new X509CertificateCollection();
                } 
                return clientCertificates;
            } 
        } 

        ///  
        /// 
        ///    
        ///       Gets or sets a value indicating whether the client should automatically follow server redirects.
        ///     
        /// 
        [DefaultValue(false), WebServicesDescription(Res.ClientProtocolEnableDecompression)] 
        public bool EnableDecompression { 
            get {
                return enableDecompression; 
            }

            set {
                enableDecompression = value; 
            }
        } 
 
         /// 
         ///  
         ///    
         ///       Gets or sets the value for the user agent header that is
         ///       sent with each request.
         ///     
         /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), WebServicesDescription(Res.ClientProtocolUserAgent)] 
        public string UserAgent { 
            get { return (userAgent == null) ? string.Empty : userAgent; }
            set { userAgent = value; } 
        }

        /// 
        ///  
        ///    
        ///       Gets or sets the name of the proxy server to use for requests. 
        ///     
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public IWebProxy Proxy {
            get { return proxy; }
            set { proxy = value; }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        protected override WebRequest GetWebRequest(Uri uri) {
            WebRequest request = base.GetWebRequest(uri);
            HttpWebRequest httpRequest = request as HttpWebRequest;
            if (httpRequest != null) { 
                httpRequest.UserAgent = UserAgent;
                httpRequest.AllowAutoRedirect = allowAutoRedirect; 
                httpRequest.AutomaticDecompression = enableDecompression ? DecompressionMethods.GZip : DecompressionMethods.None; 
                httpRequest.AllowWriteStreamBuffering = true;
                httpRequest.SendChunked = false; 
                if (unsafeAuthenticatedConnectionSharing != httpRequest.UnsafeAuthenticatedConnectionSharing)
                    httpRequest.UnsafeAuthenticatedConnectionSharing = unsafeAuthenticatedConnectionSharing;
                // if the user has set a proxy explictly then we need to
                // propagate that to the WebRequest, otherwise we'll let NetClasses 
                // use their global setting (GlobalProxySelection.Select).
                if (proxy != null) { 
                    httpRequest.Proxy = proxy; 
                }
                if (clientCertificates != null && clientCertificates.Count > 0) { 
                    httpRequest.ClientCertificates.AddRange(clientCertificates);
                }
                httpRequest.CookieContainer = cookieJar;
            } 
            return request;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        protected override WebResponse GetWebResponse(WebRequest request) {
            WebResponse response = base.GetWebResponse(request); 
            return response;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result) {
            WebResponse response = base.GetWebResponse(request, result); 
            return response;
        } 
 
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public bool UnsafeAuthenticatedConnectionSharing {
            get { return unsafeAuthenticatedConnectionSharing; }
            set { unsafeAuthenticatedConnectionSharing = value; }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        protected void CancelAsync(object userState) {
            if (userState == null)
                userState = NullToken;
            WebClientAsyncResult result = OperationCompleted(userState, new object[] { null }, null, true); 
            if (result != null) {
                result.Abort(); 
            } 
        }
 
        internal WebClientAsyncResult OperationCompleted(object userState, object[] parameters, Exception e, bool canceled) {
            Debug.Assert(userState != null, "We should not call OperationCompleted with null user token.");
            WebClientAsyncResult result = (WebClientAsyncResult)AsyncInvokes[userState];
            if (result != null) { 
                AsyncOperation asyncOp = (AsyncOperation)result.AsyncState;
                UserToken token = (UserToken)asyncOp.UserSuppliedState; 
                InvokeCompletedEventArgs eventArgs = new InvokeCompletedEventArgs(parameters, e, canceled, userState); 
                AsyncInvokes.Remove(userState);
                asyncOp.PostOperationCompleted(token.Callback, eventArgs); 
            }
            return result;
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public static bool GenerateXmlMappings(Type type, ArrayList mappings) { 
            if (typeof(SoapHttpClientProtocol).IsAssignableFrom(type)) {
                WebServiceBindingAttribute binding = WebServiceBindingReflector.GetAttribute(type);
                if (binding == null)
                    throw new InvalidOperationException(Res.GetString(Res.WebClientBindingAttributeRequired)); 
                // Note: Service namespace is taken from WebserviceBindingAttribute and not WebserviceAttribute because
                // the generated proxy does not have a WebServiceAttribute; however all have a WebServiceBindingAttribute. 
                string serviceNamespace = binding.Namespace; 
                bool serviceDefaultIsEncoded = SoapReflector.ServiceDefaultIsEncoded(type);
                ArrayList soapMethodList = new ArrayList(); 
                SoapClientType.GenerateXmlMappings(type, soapMethodList, serviceNamespace, serviceDefaultIsEncoded, mappings);
                return true;
            }
            return false; 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public static Hashtable GenerateXmlMappings(Type[] types, ArrayList mappings) {
            if (types == null)
                throw new ArgumentNullException("types"); 

            Hashtable mappedTypes = new Hashtable(); 
            foreach (Type type in types) { 
                ArrayList typeMappings = new ArrayList();
                if (GenerateXmlMappings(type, mappings)) { 
                    mappedTypes.Add(type, typeMappings);
                    mappings.Add(typeMappings);
                }
            } 
            return mappedTypes;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Services.Protocols { 
    using System; 
    using System.Collections;
    using System.Diagnostics; 
    using System.ComponentModel;
    using System.IO;
    using System.Reflection;
    using System.Xml.Serialization; 
    using System.Net;
    using System.Net.Cache; 
    using System.Threading; 
    using System.Text;
    using System.Security.Cryptography.X509Certificates; 
    using System.Security.Permissions;
    using System.Runtime.InteropServices;
    using System.Web.Services.Diagnostics;
 
    internal class ClientTypeCache {
        Hashtable cache = new Hashtable(); 
 
        internal object this[Type key] {
            get { return cache[key]; } 
        }

        internal void Add(Type key, object value) {
            lock(this) { 
                if (cache[key] == value) return;
                Hashtable clone = new Hashtable(); 
                foreach (object k in cache.Keys) { 
                    clone.Add(k, cache[k]);
                } 
                cache = clone;
                cache[key] = value;
            }
        } 
    }
 
    ///  
    /// 
    ///     
    ///       Specifies the base class for all web service protocol client proxies that
    ///       use the HTTP protocol.
    ///    
    ///  
    [ComVisible(true)]
    public abstract class WebClientProtocol : Component { 
        static AsyncCallback getRequestStreamAsyncCallback; 
        static AsyncCallback getResponseAsyncCallback;
        static AsyncCallback readResponseAsyncCallback; 
        private static ClientTypeCache cache;
        private static RequestCachePolicy bypassCache;
        private ICredentials credentials;
        private bool preAuthenticate; 
        private Uri uri;
        private int timeout; 
        private string connectionGroupName; 
        private Encoding requestEncoding;
        private RemoteDebugger debugger; 
        private WebRequest pendingSyncRequest;
        object nullToken = new object();
        Hashtable asyncInvokes = Hashtable.Synchronized(new Hashtable());
 
        private static Object s_InternalSyncObject;
        internal static Object InternalSyncObject { 
            get { 
                if (s_InternalSyncObject == null) {
                    Object o = new Object(); 
                    Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
                }
                return s_InternalSyncObject;
            } 
        }
 
        static WebClientProtocol() { 
            cache = new ClientTypeCache();
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        protected WebClientProtocol() { 
            this.timeout = 100000; // should be kept in [....] with HttpWebRequest.Timeout default (see private WebRequest.DefaultTimeout) 
        }
 
        internal WebClientProtocol(WebClientProtocol protocol) {
            this.credentials        = protocol.credentials;
            this.uri                = protocol.uri;
            this.timeout            = protocol.timeout; 
            this.connectionGroupName= protocol.connectionGroupName;
            this.requestEncoding    = protocol.requestEncoding; 
        } 

        internal static RequestCachePolicy BypassCache { 
            get {
                if (bypassCache == null) {
                    bypassCache = new RequestCachePolicy(RequestCacheLevel.BypassCache);
                } 
                return bypassCache;
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public ICredentials Credentials { 
            get {
                return credentials; 
            } 
            set {
                credentials = value; 
            }
        }

        ///  
        /// 
        ///    Sets Credentials to CredentialCache.DefaultCredentials 
        ///  
        public bool UseDefaultCredentials  {
            get { 
                return (credentials == CredentialCache.DefaultCredentials) ? true : false;
            }
            set {
                credentials = value ? CredentialCache.DefaultCredentials : null; 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets a value indicating the name of the connection group to use when making a request.
        ///    
        ///  
        [DefaultValue("")]
        public string ConnectionGroupName { 
            get { return (connectionGroupName == null) ? string.Empty : connectionGroupName; } 
            set { connectionGroupName = value; }
        } 

        internal WebRequest PendingSyncRequest {
            get { return pendingSyncRequest; }
            set { pendingSyncRequest = value; } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets or sets a value indicating whether pre-authentication is enabled.
        ///    
        /// 
        [DefaultValue(false), WebServicesDescription(Res.ClientProtocolPreAuthenticate)] 
        public bool PreAuthenticate {
            get { return preAuthenticate; } 
            set { preAuthenticate = value; } 
        }
 
        /// 
        /// 
        ///    
        ///       Gets or sets the base Uri to the server to use for requests. 
        ///    
        ///  
        [DefaultValue(""), SettingsBindable(true), WebServicesDescription(Res.ClientProtocolUrl)] 
        public string Url {
            get { return uri == null ? string.Empty : uri.ToString(); } 
            set { uri = new Uri(value); }
        }

        internal Hashtable AsyncInvokes { 
            get { return asyncInvokes; }
        } 
 
        internal object NullToken {
            get { return nullToken; } 
        }

        internal Uri Uri {
            get { return uri; } 
            set { uri = value; }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets the encoding used for making the request.
        ///    
        ///  
        [DefaultValue(null), SettingsBindable(true), WebServicesDescription(Res.ClientProtocolEncoding)]
        public Encoding RequestEncoding { 
            get { return requestEncoding; } 
            set { requestEncoding = value; }
        } 

        /// 
        /// 
        ///     
        ///       Gets or sets the timeout (in milliseconds) used for synchronous calls.
        ///     
        ///  
        [DefaultValue(100000), SettingsBindable(true), WebServicesDescription(Res.ClientProtocolTimeout)]
        public int Timeout { 
            get { return timeout; }
            set { timeout = (value < Threading.Timeout.Infinite) ? Threading.Timeout.Infinite : value; }
        }
 
        /// 
        public virtual void Abort() { 
            WebRequest request = PendingSyncRequest; 
            if (request != null)
                request.Abort(); 
        }

        /// 
        ///     
        ///     Starts async request processing including async retrieval of the request stream and response.
        ///     Derived classes can use BeginSend 
        ///     to help implement their own higher level async methods like BeginInvoke. Derived 
        ///     classes can add custom behavior by overriding GetWebRequest, GetWebResponse,
        ///     InitializeAsyncRequest and WriteAsyncRequest methods. 
        ///    
        /// 
        internal IAsyncResult BeginSend(Uri requestUri, WebClientAsyncResult asyncResult, bool callWriteAsyncRequest) {
            if (readResponseAsyncCallback == null) { 
                lock (InternalSyncObject) {
                    if (readResponseAsyncCallback == null) { 
                        getRequestStreamAsyncCallback = new AsyncCallback(GetRequestStreamAsyncCallback); 
                        getResponseAsyncCallback = new AsyncCallback(GetResponseAsyncCallback);
                        readResponseAsyncCallback = new AsyncCallback(ReadResponseAsyncCallback); 
                    }
                }
            }
            Debug.Assert(asyncResult.Request == null, "calling GetWebRequest twice for the same WebClientAsyncResult"); 
            WebRequest request = GetWebRequest(requestUri);
            asyncResult.Request = request; 
            InitializeAsyncRequest(request, asyncResult.InternalAsyncState); 
            if (callWriteAsyncRequest)
                request.BeginGetRequestStream(getRequestStreamAsyncCallback, asyncResult); 
            else
                request.BeginGetResponse(getResponseAsyncCallback, asyncResult);

            if (!asyncResult.IsCompleted) 
                asyncResult.CombineCompletedSynchronously(false);
            return asyncResult; 
        } 

        static private void ProcessAsyncException(WebClientAsyncResult client, Exception e, string method) { 
            if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, typeof(WebClientProtocol), method, e);
            WebException webException = e as WebException;
            if (webException != null && webException.Response != null) {
                client.Response = webException.Response; 
            }
            else { 
                // If we've already completed the call then the exception must have come 
                // out of the user callback in which case we need to rethrow it here
                // so that it bubbles up to the AppDomain unhandled exception event. 
                if (client.IsCompleted)
                    throw new InvalidOperationException(Res.GetString(Res.ThereWasAnErrorDuringAsyncProcessing), e);
                else
                    client.Complete(e); 
            }
        } 
 
        static private void GetRequestStreamAsyncCallback(IAsyncResult asyncResult) {
            WebClientAsyncResult client = (WebClientAsyncResult)asyncResult.AsyncState; 
            client.CombineCompletedSynchronously(asyncResult.CompletedSynchronously);
            bool processingRequest = true;
            try {
                Stream requestStream = client.Request.EndGetRequestStream(asyncResult); 
                processingRequest = false;
                try { 
                    client.ClientProtocol.AsyncBufferedSerialize(client.Request, requestStream, client.InternalAsyncState); 
                }
                finally { 
                    requestStream.Close();
                }
                client.Request.BeginGetResponse(getResponseAsyncCallback, client);
            } 
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw; 
                }
                ProcessAsyncException(client, e, "GetRequestStreamAsyncCallback"); 
                if (processingRequest)
                {
                    WebException we = e as WebException;
                    if (we != null && we.Response != null) 
                    {
                        // ProcessAsyncExcption doesn't call client.Complete() if there's a response, 
                        // because it expects us to read the response. However, in certain cases 
                        // (e.g. 502 errors), the exception thrown from Request can have a response.
                        // We don't process it, so call Complete() now. 
                        client.Complete(e);
                    }
                }
            } 
        }
 
        static private void GetResponseAsyncCallback(IAsyncResult asyncResult) { 
            WebClientAsyncResult client = (WebClientAsyncResult)asyncResult.AsyncState;
            client.CombineCompletedSynchronously(asyncResult.CompletedSynchronously); 
            try {
                client.Response = client.ClientProtocol.GetWebResponse(client.Request, asyncResult);
            }
            catch (Exception e) { 
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                } 
                ProcessAsyncException(client, e, "GetResponseAsyncCallback");
                if (client.Response == null) 
                    return;
            }

            ReadAsyncResponse(client); 
        }
 
        static private void ReadAsyncResponse(WebClientAsyncResult client) { 
            if (client.Response.ContentLength == 0) {
                client.Complete(); 
                return;
            }
            try {
                client.ResponseStream = client.Response.GetResponseStream(); 
                ReadAsyncResponseStream(client);
            } 
            catch (Exception e) { 
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                }
                ProcessAsyncException(client, e, "ReadAsyncResponse");
            }
        } 

        static private void ReadAsyncResponseStream(WebClientAsyncResult client) { 
            IAsyncResult asyncResult; 
            do {
                byte[] buffer = client.Buffer; 
                long contentLength = client.Response.ContentLength;
                if (buffer == null)
                    buffer = client.Buffer = new byte[(contentLength == -1) ? 1024 : contentLength];
                else if (contentLength != -1 && contentLength > buffer.Length) 
                    buffer = client.Buffer = new byte[contentLength];
                asyncResult = client.ResponseStream.BeginRead(buffer, 0, buffer.Length, readResponseAsyncCallback, client); 
                if (!asyncResult.CompletedSynchronously) 
                    return;
            } 
            while (!ProcessAsyncResponseStreamResult(client, asyncResult));
        }

        static private bool ProcessAsyncResponseStreamResult(WebClientAsyncResult client, IAsyncResult asyncResult) { 
            bool complete;
            int bytesRead = client.ResponseStream.EndRead(asyncResult); 
            long contentLength = client.Response.ContentLength; 
            if (contentLength > 0 && bytesRead == contentLength) {
                // the non-chunked response finished in a single read 
                client.ResponseBufferedStream = new MemoryStream(client.Buffer);
                complete = true;
            }
            else if (bytesRead > 0) { 
                if (client.ResponseBufferedStream == null) {
                    int capacity = (int)((contentLength == -1) ? client.Buffer.Length : contentLength); 
                    client.ResponseBufferedStream = new MemoryStream(capacity); 
                }
                client.ResponseBufferedStream.Write(client.Buffer, 0, bytesRead); 
                complete = false;
            }
            else
                complete = true; 

            if (complete) 
                client.Complete(); 
            return complete;
        } 

        static private void ReadResponseAsyncCallback(IAsyncResult asyncResult) {
            WebClientAsyncResult client = (WebClientAsyncResult)asyncResult.AsyncState;
            client.CombineCompletedSynchronously(asyncResult.CompletedSynchronously); 
            if (asyncResult.CompletedSynchronously)
                return; 
            try { 
                bool complete = ProcessAsyncResponseStreamResult(client, asyncResult);
                if (!complete) 
                    ReadAsyncResponseStream(client);
            }
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw;
                } 
                ProcessAsyncException(client, e, "ReadResponseAsyncCallback"); 
            }
        } 

        internal void NotifyClientCallOut(WebRequest request) {
            if (RemoteDebugger.IsClientCallOutEnabled()) {
                debugger = new RemoteDebugger(); 
                debugger.NotifyClientCallOut(request);
            } 
            else { 
                debugger = null;
            } 
        }

        /// 
        ///  
        ///    
        ///     Creates a new  instance for the given url. The base implementation creates a new 
        ///     instance using the WebRequest.Create() and then sets request related properties from 
        ///     the WebClientProtocol instance. Derived classes can override this method if additional
        ///     properties need to be set on the web request instance. 
        ///    
        /// 
        protected virtual WebRequest GetWebRequest(Uri uri) {
            if (uri == null) 
                throw new InvalidOperationException(Res.GetString(Res.WebMissingPath));
            WebRequest request = (WebRequest)WebRequest.Create(uri); 
            PendingSyncRequest = request; 
            request.Timeout = this.timeout;
            request.ConnectionGroupName = connectionGroupName; 
            request.Credentials = Credentials;
            request.PreAuthenticate = PreAuthenticate;
            request.CachePolicy = BypassCache;
            return request; 
        }
 
        ///  
        /// 
        ///     
        ///     Gets the  from the given request by calling
        ///     GetResponse(). Derived classes can override this method to do additional
        ///     processing on the response instance.
        ///     
        /// 
        protected virtual WebResponse GetWebResponse(WebRequest request) { 
            TraceMethod caller = Tracing.On ? new TraceMethod(this, "GetWebResponse") : null; 
            WebResponse response = null;
            try { 
                if (Tracing.On) Tracing.Enter("WebRequest.GetResponse", caller, new TraceMethod(request, "GetResponse"));
                response = request.GetResponse();
                if (Tracing.On) Tracing.Exit("WebRequest.GetResponse", caller);
            } 
            catch (WebException e) {
                if (e.Response == null) 
                    throw e; 
                else {
                    if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "GetWebResponse", e); 
                    response = e.Response;
                }
            }
            finally { 
                if (debugger != null)
                    debugger.NotifyClientCallReturn(response); 
            } 
            return response;
        } 

        /// 
        /// 
        ///     
        ///     Gets the  from the given request by calling
        ///     EndGetResponse(). Derived classes can override this method to do additional 
        ///     processing on the response instance. This method is only called during 
        ///     async request processing.
        ///     
        /// 
        protected virtual WebResponse GetWebResponse(WebRequest request, IAsyncResult result) {
            WebResponse response = request.EndGetResponse(result);
            if (response != null && debugger != null) 
                debugger.NotifyClientCallReturn(response);
            return response; 
        } 

        ///  
        ///    
        ///     Called during async request processing to give the derived class an opportunity
        ///     to modify the web request instance before the request stream is retrieved at which
        ///     point the request headers are sent and can no longer be modified. The base implementation 
        ///     does nothing.
        ///     
        ///  
        [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
        internal virtual void InitializeAsyncRequest(WebRequest request, object internalAsyncState) { 
            return;
        }

        [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")] 
        internal virtual void AsyncBufferedSerialize(WebRequest request, Stream requestStream, object internalAsyncState) {
            throw new NotSupportedException(Res.GetString(Res.ProtocolDoesNotAsyncSerialize)); 
        } 

        internal WebResponse EndSend(IAsyncResult asyncResult, ref object internalAsyncState, ref Stream responseStream) { 
            if (asyncResult == null) throw new ArgumentNullException(Res.GetString(Res.WebNullAsyncResultInEnd));

            WebClientAsyncResult client = (WebClientAsyncResult)asyncResult;
            if (client.EndSendCalled) 
                throw new InvalidOperationException(Res.GetString(Res.CanTCallTheEndMethodOfAnAsyncCallMoreThan));
            client.EndSendCalled = true; 
            WebResponse response = client.WaitForResponse(); 
            internalAsyncState = client.InternalAsyncState;
            responseStream = client.ResponseBufferedStream; 
            return response;
        }

        ///  
        /// 
        /// Returns an instance of a client protocol handler from the cache. 
        ///  
        protected static object GetFromCache(Type type) {
            return cache[type]; 
        }

        /// 
        ///  
        ///    
        ///       Add an instance of the client protocol handler to the cache. 
        ///     
        /// 
        protected static void AddToCache(Type type, object value) { 
            cache.Add(type, value);
        }

    } 

    ///  
    [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")] 
    public class WebClientAsyncResult : IAsyncResult {
        private object userAsyncState; 
        private bool completedSynchronously;
        private bool isCompleted;
        private ManualResetEvent manualResetEvent;
        private AsyncCallback userCallback; 

        internal WebClientProtocol ClientProtocol; 
        internal object InternalAsyncState; 
        internal Exception Exception;
        internal WebResponse Response; 
        internal WebRequest Request;
        internal Stream ResponseStream;
        internal Stream ResponseBufferedStream;
        internal byte[] Buffer; 
        internal bool EndSendCalled;
 
        internal WebClientAsyncResult(WebClientProtocol clientProtocol, 
            object internalAsyncState,
            WebRequest request, 
            AsyncCallback userCallback,
            object userAsyncState)
        {
            this.ClientProtocol = clientProtocol; 
            this.InternalAsyncState = internalAsyncState;
            this.userAsyncState = userAsyncState; 
            this.userCallback = userCallback; 
            this.Request = request;
            this.completedSynchronously = true; 
        }

        /// 
        public object AsyncState { get { return userAsyncState; } } 

        ///  
        public WaitHandle AsyncWaitHandle { 
            get {
                bool savedIsCompleted = isCompleted; 
                if (manualResetEvent == null) {
                    lock (this) {
                        if (manualResetEvent == null)
                            manualResetEvent = new ManualResetEvent(savedIsCompleted); 
                    }
                } 
                if (!savedIsCompleted && isCompleted) 
                    manualResetEvent.Set();
                return (WaitHandle)manualResetEvent; 
            }
        }

        ///  
        public bool CompletedSynchronously {
            get { return completedSynchronously; } 
        } 

        ///  
        public bool IsCompleted { get { return isCompleted; } }

        /// 
        public void Abort() { 
            WebRequest req = Request;
            if (req != null) 
                req.Abort(); 
        }
 

        internal void Complete() {
            Debug.Assert(!isCompleted, "Complete called more than once.");
 
            try {
                if (ResponseStream != null) { 
                    ResponseStream.Close(); 
                    ResponseStream = null;
                } 

                if (ResponseBufferedStream != null)
                    ResponseBufferedStream.Position = 0;
            } 
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw; 
                }
                if (this.Exception == null) 
                    this.Exception = e;
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "Complete", e);
            }
 
            isCompleted = true;
 
            try { 
                if (manualResetEvent != null)
                    manualResetEvent.Set(); 
            }
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                }
                if (this.Exception == null) 
                    this.Exception = e; 
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "Complete", e);
            } 

            // We want to let exceptions in user callback to bubble up to
            // threadpool so that AppDomain.UnhandledExceptionEventHandler
            // will get it if one is registered 
            if (userCallback != null)
                userCallback(this); 
        } 

        internal void Complete(Exception e) { 
            this.Exception = e;
            Complete();
        }
 
        internal WebResponse WaitForResponse() {
            if (!isCompleted) 
                AsyncWaitHandle.WaitOne(); 

            if (this.Exception != null) 
                throw this.Exception;

            return Response;
        } 

        internal void CombineCompletedSynchronously(bool innerCompletedSynchronously) { 
            completedSynchronously = completedSynchronously && innerCompletedSynchronously; 
        }
    } 

    /// 
    /// 
    ///    [To be supplied.] 
    /// 
    public delegate void InvokeCompletedEventHandler(object sender, InvokeCompletedEventArgs e); 
 
    /// 
    ///  
    ///    [To be supplied.]
    /// 
    public class InvokeCompletedEventArgs : AsyncCompletedEventArgs {
        object[] results; 

        internal InvokeCompletedEventArgs(object[] results, Exception exception, bool cancelled, object userState) : 
            base(exception, cancelled, userState) { 
            this.results = results;
        } 

        /// 
        /// 
        ///     
        ///       Gets or sets a value indicating whether the client should automatically follow server redirects.
        ///     
        ///  
        public object[] Results {
            get { 
                return results;
            }
        }
    } 

 
    internal class UserToken { 
        SendOrPostCallback callback;
        object userState; 

        internal UserToken(SendOrPostCallback callback, object userState) {
            this.callback = callback;
            this.userState = userState; 
        }
        internal SendOrPostCallback Callback { get { return callback; } } 
        internal object UserState { get { return userState; } } 
    }
 
    /// 
    /// 
    ///    [To be supplied.]
    ///  
    [ComVisible(true)]
    public abstract class HttpWebClientProtocol : WebClientProtocol { 
        private bool allowAutoRedirect; 
        private bool enableDecompression = false;
        private CookieContainer cookieJar = null; 
        private X509CertificateCollection clientCertificates;
        private IWebProxy proxy;
        private static string UserAgentDefault = "Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol " + System.Environment.Version.ToString() + ")";
        private string userAgent; 
        private bool unsafeAuthenticatedConnectionSharing;
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        protected HttpWebClientProtocol() : base() {
            this.allowAutoRedirect = false;
            this.userAgent = UserAgentDefault; 
            // the right thing to do, for NetClasses to pick up the default
            // GlobalProxySelection settings, is to leave proxy to null 
            // (which is the default initialization value) 
            // rather than picking up GlobalProxySelection.Select
            // which will never change. 
        }

        // used by SoapHttpClientProtocol.Discover
        internal HttpWebClientProtocol(HttpWebClientProtocol protocol) 
            : base(protocol) {
            this.allowAutoRedirect  = protocol.allowAutoRedirect; 
            this.enableDecompression  = protocol.enableDecompression; 
            this.cookieJar          = protocol.cookieJar;
            this.clientCertificates = protocol.clientCertificates; 
            this.proxy              = protocol.proxy;
            this.userAgent          = protocol.userAgent;
        }
 
        /// 
        ///  
        ///     
        ///       Gets or sets a value indicating whether the client should automatically follow server redirects.
        ///     
        /// 
        [DefaultValue(false), WebServicesDescription(Res.ClientProtocolAllowAutoRedirect)]
        public bool AllowAutoRedirect {
            get { 
                return allowAutoRedirect;
            } 
 
            set {
                allowAutoRedirect = value; 
            }
        }

 
        /// 
        [DefaultValue(null), WebServicesDescription(Res.ClientProtocolCookieContainer)] 
        public CookieContainer CookieContainer { 
            get {
                return cookieJar; 
            }
            set {
                cookieJar = value;
            } 
        }
 
        ///  
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), WebServicesDescription(Res.ClientProtocolClientCertificates)]
        public X509CertificateCollection ClientCertificates { 
            get {
                if (clientCertificates == null) {
                    clientCertificates = new X509CertificateCollection();
                } 
                return clientCertificates;
            } 
        } 

        ///  
        /// 
        ///    
        ///       Gets or sets a value indicating whether the client should automatically follow server redirects.
        ///     
        /// 
        [DefaultValue(false), WebServicesDescription(Res.ClientProtocolEnableDecompression)] 
        public bool EnableDecompression { 
            get {
                return enableDecompression; 
            }

            set {
                enableDecompression = value; 
            }
        } 
 
         /// 
         ///  
         ///    
         ///       Gets or sets the value for the user agent header that is
         ///       sent with each request.
         ///     
         /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), WebServicesDescription(Res.ClientProtocolUserAgent)] 
        public string UserAgent { 
            get { return (userAgent == null) ? string.Empty : userAgent; }
            set { userAgent = value; } 
        }

        /// 
        ///  
        ///    
        ///       Gets or sets the name of the proxy server to use for requests. 
        ///     
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public IWebProxy Proxy {
            get { return proxy; }
            set { proxy = value; }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        protected override WebRequest GetWebRequest(Uri uri) {
            WebRequest request = base.GetWebRequest(uri);
            HttpWebRequest httpRequest = request as HttpWebRequest;
            if (httpRequest != null) { 
                httpRequest.UserAgent = UserAgent;
                httpRequest.AllowAutoRedirect = allowAutoRedirect; 
                httpRequest.AutomaticDecompression = enableDecompression ? DecompressionMethods.GZip : DecompressionMethods.None; 
                httpRequest.AllowWriteStreamBuffering = true;
                httpRequest.SendChunked = false; 
                if (unsafeAuthenticatedConnectionSharing != httpRequest.UnsafeAuthenticatedConnectionSharing)
                    httpRequest.UnsafeAuthenticatedConnectionSharing = unsafeAuthenticatedConnectionSharing;
                // if the user has set a proxy explictly then we need to
                // propagate that to the WebRequest, otherwise we'll let NetClasses 
                // use their global setting (GlobalProxySelection.Select).
                if (proxy != null) { 
                    httpRequest.Proxy = proxy; 
                }
                if (clientCertificates != null && clientCertificates.Count > 0) { 
                    httpRequest.ClientCertificates.AddRange(clientCertificates);
                }
                httpRequest.CookieContainer = cookieJar;
            } 
            return request;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        protected override WebResponse GetWebResponse(WebRequest request) {
            WebResponse response = base.GetWebResponse(request); 
            return response;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result) {
            WebResponse response = base.GetWebResponse(request, result); 
            return response;
        } 
 
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public bool UnsafeAuthenticatedConnectionSharing {
            get { return unsafeAuthenticatedConnectionSharing; }
            set { unsafeAuthenticatedConnectionSharing = value; }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        protected void CancelAsync(object userState) {
            if (userState == null)
                userState = NullToken;
            WebClientAsyncResult result = OperationCompleted(userState, new object[] { null }, null, true); 
            if (result != null) {
                result.Abort(); 
            } 
        }
 
        internal WebClientAsyncResult OperationCompleted(object userState, object[] parameters, Exception e, bool canceled) {
            Debug.Assert(userState != null, "We should not call OperationCompleted with null user token.");
            WebClientAsyncResult result = (WebClientAsyncResult)AsyncInvokes[userState];
            if (result != null) { 
                AsyncOperation asyncOp = (AsyncOperation)result.AsyncState;
                UserToken token = (UserToken)asyncOp.UserSuppliedState; 
                InvokeCompletedEventArgs eventArgs = new InvokeCompletedEventArgs(parameters, e, canceled, userState); 
                AsyncInvokes.Remove(userState);
                asyncOp.PostOperationCompleted(token.Callback, eventArgs); 
            }
            return result;
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public static bool GenerateXmlMappings(Type type, ArrayList mappings) { 
            if (typeof(SoapHttpClientProtocol).IsAssignableFrom(type)) {
                WebServiceBindingAttribute binding = WebServiceBindingReflector.GetAttribute(type);
                if (binding == null)
                    throw new InvalidOperationException(Res.GetString(Res.WebClientBindingAttributeRequired)); 
                // Note: Service namespace is taken from WebserviceBindingAttribute and not WebserviceAttribute because
                // the generated proxy does not have a WebServiceAttribute; however all have a WebServiceBindingAttribute. 
                string serviceNamespace = binding.Namespace; 
                bool serviceDefaultIsEncoded = SoapReflector.ServiceDefaultIsEncoded(type);
                ArrayList soapMethodList = new ArrayList(); 
                SoapClientType.GenerateXmlMappings(type, soapMethodList, serviceNamespace, serviceDefaultIsEncoded, mappings);
                return true;
            }
            return false; 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public static Hashtable GenerateXmlMappings(Type[] types, ArrayList mappings) {
            if (types == null)
                throw new ArgumentNullException("types"); 

            Hashtable mappedTypes = new Hashtable(); 
            foreach (Type type in types) { 
                ArrayList typeMappings = new ArrayList();
                if (GenerateXmlMappings(type, mappings)) { 
                    mappedTypes.Add(type, typeMappings);
                    mappings.Add(typeMappings);
                }
            } 
            return mappedTypes;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK