_ProxyChain.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Net / System / Net / _ProxyChain.cs / 1 / _ProxyChain.cs

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

namespace System.Net 
{ 
    using System.Collections;
    using System.Collections.Generic; 

    internal interface IAutoWebProxy : IWebProxy
    {
        ProxyChain GetProxies(Uri destination); 
    }
 
    internal abstract class ProxyChain : IEnumerable, IDisposable 
    {
        private List m_Cache = new List(); 
        private bool m_CacheComplete;
        private ProxyEnumerator m_MainEnumerator;
        private Uri m_Destination;
        private HttpAbortDelegate m_HttpAbortDelegate; 

        protected ProxyChain(Uri destination) 
        { 
            m_Destination = destination;
        } 

        public IEnumerator GetEnumerator()
        {
            ProxyEnumerator enumerator = new ProxyEnumerator(this); 
            if (m_MainEnumerator == null)
            { 
                m_MainEnumerator = enumerator; 
            }
            return enumerator; 
        }

        IEnumerator IEnumerable.GetEnumerator()
        { 
            return GetEnumerator();
        } 
 
        public virtual void Dispose() { }
 
        internal IEnumerator Enumerator
        {
            get
            { 
                return m_MainEnumerator == null ? GetEnumerator() : m_MainEnumerator;
            } 
        } 

        internal Uri Destination 
        {
            get
            {
                return m_Destination; 
            }
        } 
 
        // MoveNext can be time-consuming (download proxy script).  This lets you abort it.
        internal virtual void Abort() { } 

        internal bool HttpAbort(HttpWebRequest request, WebException webException)
        {
            Abort(); 
            return true;
        } 
 
        internal HttpAbortDelegate HttpAbortDelegate
        { 
            get
            {
                if (m_HttpAbortDelegate == null)
                { 
                    m_HttpAbortDelegate = new HttpAbortDelegate(HttpAbort);
                } 
                return m_HttpAbortDelegate; 
            }
        } 

        protected abstract bool GetNextProxy(out Uri proxy);

        // This implementation prevents DIRECT (null) from being returned more than once. 
        private class ProxyEnumerator : IEnumerator
        { 
            private ProxyChain m_Chain; 
            private bool m_Finished;
            private int m_CurrentIndex = -1; 
            private bool m_TriedDirect;

            internal ProxyEnumerator(ProxyChain chain)
            { 
                m_Chain = chain;
            } 
 
            public Uri Current
            { 
                get
                {
                    if (m_Finished || m_CurrentIndex < 0)
                    { 
                        throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_EnumOpCantHappen));
                    } 
 
                    GlobalLog.Assert(m_Chain.m_Cache.Count > m_CurrentIndex, "ProxyEnumerator::Current|Not all proxies made it to the cache.");
                    return m_Chain.m_Cache[m_CurrentIndex]; 
                }
            }

            object IEnumerator.Current 
            {
                get 
                { 
                    return Current;
                } 
            }

            public bool MoveNext()
            { 
                if (m_Finished)
                { 
                    return false; 
                }
 
                checked{m_CurrentIndex++;}
                if (m_Chain.m_Cache.Count > m_CurrentIndex)
                {
                    return true; 
                }
 
                if (m_Chain.m_CacheComplete) 
                {
                    m_Finished = true; 
                    return false;
                }

                lock (m_Chain.m_Cache) 
                {
                    if (m_Chain.m_Cache.Count > m_CurrentIndex) 
                    { 
                        return true;
                    } 

                    if (m_Chain.m_CacheComplete)
                    {
                        m_Finished = true; 
                        return false;
                    } 
 
                    Uri nextProxy;
                    while (true) 
                    {
                        if (!m_Chain.GetNextProxy(out nextProxy))
                        {
                            m_Finished = true; 
                            m_Chain.m_CacheComplete = true;
                            return false; 
                        } 

                        if (nextProxy == null) 
                        {
                            if (m_TriedDirect)
                            {
                                continue; 
                            }
                            m_TriedDirect = true; 
                        } 
                        break;
                    } 

                    m_Chain.m_Cache.Add(nextProxy);
                    GlobalLog.Assert(m_Chain.m_Cache.Count > m_CurrentIndex, "ProxyEnumerator::MoveNext|Not all proxies made it to the cache.");
                    return true; 
                }
            } 
 
            public void Reset()
            { 
                m_Finished = false;
                m_CurrentIndex = -1;
            }
 
            public void Dispose() { }
        } 
    } 

 
    // This class implements failover logic for proxy scripts.
    internal class ProxyScriptChain : ProxyChain
    {
        private WebProxy m_Proxy; 
        private Uri[] m_ScriptProxies;
        private int m_CurrentIndex; 
        private int m_SyncStatus; 

        internal ProxyScriptChain(WebProxy proxy, Uri destination) : 
            base(destination)
        {
            m_Proxy = proxy;
        } 

        protected override bool GetNextProxy(out Uri proxy) 
        { 
            if (m_CurrentIndex < 0)
            { 
                proxy = null;
                return false;
            }
 
            if (m_CurrentIndex == 0)
            { 
                AutoWebProxyState state; 
                m_ScriptProxies = m_Proxy.GetProxiesAuto(Destination, out state, ref m_SyncStatus);
                if (state != AutoWebProxyState.ExecutionSuccess) 
                {
                    m_ScriptProxies = null;
                }
            } 

            if (m_ScriptProxies == null || m_CurrentIndex >= m_ScriptProxies.Length) 
            { 
                proxy = m_Proxy.GetProxyAutoFailover(Destination);
                m_CurrentIndex = -1; 
                return true;
            }

            proxy = m_ScriptProxies[m_CurrentIndex++]; 
            return true;
        } 
 
        internal override void Abort()
        { 
            m_Proxy.AbortGetProxiesAuto(ref m_SyncStatus);
        }
    }
 
    // This class says to use no proxy.
    internal class DirectProxy : ProxyChain 
    { 
        private bool m_ProxyRetrieved;
 
        internal DirectProxy(Uri destination) : base(destination) { }

        protected override bool GetNextProxy(out Uri proxy)
        { 
            proxy = null;
            if (m_ProxyRetrieved) 
            { 
                return false;
            } 
            m_ProxyRetrieved = true;
            return true;
        }
    } 

    // This class says to use a single fixed proxy. 
    internal class StaticProxy : ProxyChain 
    {
        private Uri m_Proxy; 

        internal StaticProxy(Uri destination, Uri proxy) :
            base(destination)
        { 
            if (proxy == null)
            { 
                throw new ArgumentNullException("proxy"); 
            }
            m_Proxy = proxy; 
        }

        protected override bool GetNextProxy(out Uri proxy)
        { 
            proxy = m_Proxy;
            if (proxy == null) 
            { 
                return false;
            } 
            m_Proxy = null;
            return true;
        }
    } 
}

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

namespace System.Net 
{ 
    using System.Collections;
    using System.Collections.Generic; 

    internal interface IAutoWebProxy : IWebProxy
    {
        ProxyChain GetProxies(Uri destination); 
    }
 
    internal abstract class ProxyChain : IEnumerable, IDisposable 
    {
        private List m_Cache = new List(); 
        private bool m_CacheComplete;
        private ProxyEnumerator m_MainEnumerator;
        private Uri m_Destination;
        private HttpAbortDelegate m_HttpAbortDelegate; 

        protected ProxyChain(Uri destination) 
        { 
            m_Destination = destination;
        } 

        public IEnumerator GetEnumerator()
        {
            ProxyEnumerator enumerator = new ProxyEnumerator(this); 
            if (m_MainEnumerator == null)
            { 
                m_MainEnumerator = enumerator; 
            }
            return enumerator; 
        }

        IEnumerator IEnumerable.GetEnumerator()
        { 
            return GetEnumerator();
        } 
 
        public virtual void Dispose() { }
 
        internal IEnumerator Enumerator
        {
            get
            { 
                return m_MainEnumerator == null ? GetEnumerator() : m_MainEnumerator;
            } 
        } 

        internal Uri Destination 
        {
            get
            {
                return m_Destination; 
            }
        } 
 
        // MoveNext can be time-consuming (download proxy script).  This lets you abort it.
        internal virtual void Abort() { } 

        internal bool HttpAbort(HttpWebRequest request, WebException webException)
        {
            Abort(); 
            return true;
        } 
 
        internal HttpAbortDelegate HttpAbortDelegate
        { 
            get
            {
                if (m_HttpAbortDelegate == null)
                { 
                    m_HttpAbortDelegate = new HttpAbortDelegate(HttpAbort);
                } 
                return m_HttpAbortDelegate; 
            }
        } 

        protected abstract bool GetNextProxy(out Uri proxy);

        // This implementation prevents DIRECT (null) from being returned more than once. 
        private class ProxyEnumerator : IEnumerator
        { 
            private ProxyChain m_Chain; 
            private bool m_Finished;
            private int m_CurrentIndex = -1; 
            private bool m_TriedDirect;

            internal ProxyEnumerator(ProxyChain chain)
            { 
                m_Chain = chain;
            } 
 
            public Uri Current
            { 
                get
                {
                    if (m_Finished || m_CurrentIndex < 0)
                    { 
                        throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_EnumOpCantHappen));
                    } 
 
                    GlobalLog.Assert(m_Chain.m_Cache.Count > m_CurrentIndex, "ProxyEnumerator::Current|Not all proxies made it to the cache.");
                    return m_Chain.m_Cache[m_CurrentIndex]; 
                }
            }

            object IEnumerator.Current 
            {
                get 
                { 
                    return Current;
                } 
            }

            public bool MoveNext()
            { 
                if (m_Finished)
                { 
                    return false; 
                }
 
                checked{m_CurrentIndex++;}
                if (m_Chain.m_Cache.Count > m_CurrentIndex)
                {
                    return true; 
                }
 
                if (m_Chain.m_CacheComplete) 
                {
                    m_Finished = true; 
                    return false;
                }

                lock (m_Chain.m_Cache) 
                {
                    if (m_Chain.m_Cache.Count > m_CurrentIndex) 
                    { 
                        return true;
                    } 

                    if (m_Chain.m_CacheComplete)
                    {
                        m_Finished = true; 
                        return false;
                    } 
 
                    Uri nextProxy;
                    while (true) 
                    {
                        if (!m_Chain.GetNextProxy(out nextProxy))
                        {
                            m_Finished = true; 
                            m_Chain.m_CacheComplete = true;
                            return false; 
                        } 

                        if (nextProxy == null) 
                        {
                            if (m_TriedDirect)
                            {
                                continue; 
                            }
                            m_TriedDirect = true; 
                        } 
                        break;
                    } 

                    m_Chain.m_Cache.Add(nextProxy);
                    GlobalLog.Assert(m_Chain.m_Cache.Count > m_CurrentIndex, "ProxyEnumerator::MoveNext|Not all proxies made it to the cache.");
                    return true; 
                }
            } 
 
            public void Reset()
            { 
                m_Finished = false;
                m_CurrentIndex = -1;
            }
 
            public void Dispose() { }
        } 
    } 

 
    // This class implements failover logic for proxy scripts.
    internal class ProxyScriptChain : ProxyChain
    {
        private WebProxy m_Proxy; 
        private Uri[] m_ScriptProxies;
        private int m_CurrentIndex; 
        private int m_SyncStatus; 

        internal ProxyScriptChain(WebProxy proxy, Uri destination) : 
            base(destination)
        {
            m_Proxy = proxy;
        } 

        protected override bool GetNextProxy(out Uri proxy) 
        { 
            if (m_CurrentIndex < 0)
            { 
                proxy = null;
                return false;
            }
 
            if (m_CurrentIndex == 0)
            { 
                AutoWebProxyState state; 
                m_ScriptProxies = m_Proxy.GetProxiesAuto(Destination, out state, ref m_SyncStatus);
                if (state != AutoWebProxyState.ExecutionSuccess) 
                {
                    m_ScriptProxies = null;
                }
            } 

            if (m_ScriptProxies == null || m_CurrentIndex >= m_ScriptProxies.Length) 
            { 
                proxy = m_Proxy.GetProxyAutoFailover(Destination);
                m_CurrentIndex = -1; 
                return true;
            }

            proxy = m_ScriptProxies[m_CurrentIndex++]; 
            return true;
        } 
 
        internal override void Abort()
        { 
            m_Proxy.AbortGetProxiesAuto(ref m_SyncStatus);
        }
    }
 
    // This class says to use no proxy.
    internal class DirectProxy : ProxyChain 
    { 
        private bool m_ProxyRetrieved;
 
        internal DirectProxy(Uri destination) : base(destination) { }

        protected override bool GetNextProxy(out Uri proxy)
        { 
            proxy = null;
            if (m_ProxyRetrieved) 
            { 
                return false;
            } 
            m_ProxyRetrieved = true;
            return true;
        }
    } 

    // This class says to use a single fixed proxy. 
    internal class StaticProxy : ProxyChain 
    {
        private Uri m_Proxy; 

        internal StaticProxy(Uri destination, Uri proxy) :
            base(destination)
        { 
            if (proxy == null)
            { 
                throw new ArgumentNullException("proxy"); 
            }
            m_Proxy = proxy; 
        }

        protected override bool GetNextProxy(out Uri proxy)
        { 
            proxy = m_Proxy;
            if (proxy == null) 
            { 
                return false;
            } 
            m_Proxy = null;
            return true;
        }
    } 
}

// 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