예제 #1
0
        //
        // IWebProxy implementation
        //

        // Get proxies can never return null in the case of ExecutionSuccess.
        private Uri GetProxyAuto(Uri destination, out AutoWebProxyState autoWebProxyState)
        {
            GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::GetProxyAuto() destination:" + ValidationHelper.ToString(destination));
            if (ScriptEngine == null)
            {
                autoWebProxyState = AutoWebProxyState.Uninitialized;
                return(null);
            }
            StringCollection proxies = ScriptEngine.GetProxies(destination, true, out autoWebProxyState);

            if (autoWebProxyState != AutoWebProxyState.ExecutionSuccess)
            {
                return(null);
            }
            if (proxies.Count == 0)
            {
                // Null here means, no proxy available (incl. DIRECT), the request is prohibited.
                return(null);
            }
            if (AreAllBypassed(proxies, true))
            {
                return(destination);
            }
            return(ProxyUri(proxies[0]));
        }
예제 #2
0
        internal Uri[] GetProxiesAuto(Uri destination, out AutoWebProxyState autoWebProxyState, ref int syncStatus)
        {
            GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::GetProxiesAuto() destination:" + ValidationHelper.ToString(destination));
            if (ScriptEngine == null)
            {
                autoWebProxyState = AutoWebProxyState.Uninitialized;
                return(null);
            }
            StringCollection proxies = ScriptEngine.GetProxies(destination, false, out autoWebProxyState, ref syncStatus);

            if (autoWebProxyState != AutoWebProxyState.ExecutionSuccess)
            {
                return(null);
            }
            if (proxies.Count == 0)
            {
                return(new Uri[] { });
            }
            if (AreAllBypassed(proxies, false))
            {
                return(new Uri[] { null });
            }
            Uri[] proxyUris = new Uri[proxies.Count];
            for (int i = 0; i < proxies.Count; i++)
            {
                proxyUris[i] = ProxyUri(proxies[i]);
            }
            return(proxyUris);
        }
        public bool GetAutoProxies(Uri destination, out IList <string>?proxyList)
        {
            proxyList = null;
            if (session == null || session.IsInvalid || state == AutoWebProxyState.UnrecognizedScheme)
            {
                return(false);
            }

            string?proxyListString = null;
            var    errorCode       = NativeMethods.WinHttp.ErrorCodes.AudodetectionFailed;

            if (AutomaticallyDetectSettings && !autoDetectFailed)
            {
                errorCode        = (NativeMethods.WinHttp.ErrorCodes)getAutoProxies(destination, null, out proxyListString);
                autoDetectFailed = isErrorFatalForAutoDetect(errorCode);
                if (errorCode == NativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme)
                {
                    state = AutoWebProxyState.UnrecognizedScheme;
                    return(false);
                }
            }

            if (AutomaticConfigurationScript != null && isRecoverableAutoProxyError(errorCode))
            {
                errorCode = (NativeMethods.WinHttp.ErrorCodes)getAutoProxies(destination, AutomaticConfigurationScript,
                                                                             out proxyListString);
            }

            state = getStateFromErrorCode(errorCode);
            if (state != AutoWebProxyState.Completed)
            {
                return(false);
            }

            if (!string.IsNullOrEmpty(proxyListString))
            {
                proxyListString = removeWhitespaces(proxyListString !);
                proxyList       = proxyListString.Split(';');
            }

            return(true);
        }
예제 #4
0
        private bool IsBypassedAuto(Uri destination, out AutoWebProxyState autoWebProxyState)
        {
            GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::IsBypassedAuto() destination:" + ValidationHelper.ToString(destination));
            if (ScriptEngine == null)
            {
                autoWebProxyState = AutoWebProxyState.Uninitialized;
                return(true);
            }
            StringCollection proxies = ScriptEngine.GetProxies(destination, true, out autoWebProxyState);

            if (autoWebProxyState != AutoWebProxyState.ExecutionSuccess)
            {
                return(true);
            }
            if (proxies.Count == 0)
            {
                return(false);
            }
            return(AreAllBypassed(proxies, true));
        }
 private void ExitLock(ref int syncStatus)
 {
     if (syncStatus != SyncStatus.Unlocked && syncStatus != SyncStatus.Aborted)
     {
         lock (this)
         {
             if (syncStatus == SyncStatus.RequestOwner)
             {
                 m_LockedRequest = null;
             }
             m_LockHeld = false;
             if (syncStatus == SyncStatus.AbortedLocked)
             {
                 state      = AutoWebProxyState.Uninitialized;
                 syncStatus = SyncStatus.Aborted;
             }
             else
             {
                 syncStatus = SyncStatus.Unlocked;
             }
             Monitor.Pulse(this);
         }
     }
 }
        // Downloads and compiles the script from a given Uri.
        // This code can be called by config for a downloaded control, we need to assert.
        // This code is called holding the lock.
        private AutoWebProxyState DownloadAndCompile(Uri location)
        {
            GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() location:" + ValidationHelper.ToString(location));
            AutoWebProxyState newState = AutoWebProxyState.DownloadFailure;
            WebResponse       response = null;

            TimerThread.Timer         timer             = null;
            AutoWebProxyScriptWrapper newScriptInstance = null;

            // Can't assert this in declarative form (DCR?). This Assert() is needed to be able to create the request to download the proxy script.
            ExceptionHelper.WebPermissionUnrestricted.Assert();
            try
            {
                lock (lockObject)
                {
                    if (aborted)
                    {
                        throw new WebException(NetRes.GetWebStatusString("net_requestaborted",
                                                                         WebExceptionStatus.RequestCanceled), WebExceptionStatus.RequestCanceled);
                    }

                    request = WebRequest.Create(location);
                }

                request.Timeout             = Timeout.Infinite;
                request.CachePolicy         = new RequestCachePolicy(RequestCacheLevel.Default);
                request.ConnectionGroupName = "__WebProxyScript";

                // We have an opportunity here, if caching is disabled AppDomain-wide, to override it with a
                // custom, trivial cache-provider to get a similar semantic.
                //
                // We also want to have a backup caching key in the case when IE has locked an expired script response
                //
                if (request.CacheProtocol != null)
                {
                    GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Using backup caching.");
                    request.CacheProtocol = new RequestCacheProtocol(backupCache, request.CacheProtocol.Validator);
                }

                HttpWebRequest httpWebRequest = request as HttpWebRequest;
                if (httpWebRequest != null)
                {
                    httpWebRequest.Accept    = "*/*";
                    httpWebRequest.UserAgent = this.GetType().FullName + "/" + Environment.Version;
                    httpWebRequest.KeepAlive = false;
                    httpWebRequest.Pipelined = false;
                    httpWebRequest.InternalConnectionGroup = true;
                }
                else
                {
                    FtpWebRequest ftpWebRequest = request as FtpWebRequest;
                    if (ftpWebRequest != null)
                    {
                        ftpWebRequest.KeepAlive = false;
                    }
                }

                // Use no proxy, default cache - initiate the download.
                request.Proxy       = null;
                request.Credentials = Engine.Credentials;

                // Use our own timeout timer so that it can encompass the whole request, not just the headers.
                if (timerQueue == null)
                {
                    timerQueue = TimerThread.GetOrCreateQueue(SettingsSectionInternal.Section.DownloadTimeout);
                }
                timer    = timerQueue.CreateTimer(timerCallback, request);
                response = request.GetResponse();

                // Check Last Modified.
                DateTime        lastModified = DateTime.MinValue;
                HttpWebResponse httpResponse = response as HttpWebResponse;
                if (httpResponse != null)
                {
                    lastModified = httpResponse.LastModified;
                }
                else
                {
                    FtpWebResponse ftpResponse = response as FtpWebResponse;
                    if (ftpResponse != null)
                    {
                        lastModified = ftpResponse.LastModified;
                    }
                }
                GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() lastModified:" + lastModified.ToString() + " (script):" + (scriptInstance == null ? "(null)" : scriptInstance.LastModified.ToString()));
                if (scriptInstance != null && lastModified != DateTime.MinValue && scriptInstance.LastModified == lastModified)
                {
                    newScriptInstance = scriptInstance;
                    newState          = AutoWebProxyState.Completed;
                }
                else
                {
                    string scriptBody   = null;
                    byte[] scriptBuffer = null;
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        SingleItemRequestCache.ReadOnlyStream ros = responseStream as SingleItemRequestCache.ReadOnlyStream;
                        if (ros != null)
                        {
                            scriptBuffer = ros.Buffer;
                        }
                        if (scriptInstance != null && scriptBuffer != null && scriptBuffer == scriptInstance.Buffer)
                        {
                            scriptInstance.LastModified = lastModified;
                            newScriptInstance           = scriptInstance;
                            newState = AutoWebProxyState.Completed;
                            GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Buffer matched - reusing Engine.");
                        }
                        else
                        {
                            using (StreamReader streamReader = new StreamReader(responseStream))
                            {
                                scriptBody = streamReader.ReadToEnd();
                            }
                        }
                    }

                    WebResponse tempResponse = response;
                    response = null;
                    tempResponse.Close();
                    timer.Cancel();
                    timer = null;

                    if (newState != AutoWebProxyState.Completed)
                    {
                        GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() IsFromCache:" + tempResponse.IsFromCache.ToString() + " scriptInstance:" + ValidationHelper.HashString(scriptInstance));
                        if (scriptInstance != null && scriptBody == scriptInstance.ScriptBody)
                        {
                            GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Script matched - using existing Engine.");
                            scriptInstance.LastModified = lastModified;
                            if (scriptBuffer != null)
                            {
                                scriptInstance.Buffer = scriptBuffer;
                            }
                            newScriptInstance = scriptInstance;
                            newState          = AutoWebProxyState.Completed;
                        }
                        else
                        {
                            GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Creating AutoWebProxyScriptWrapper.");
                            newScriptInstance = new AutoWebProxyScriptWrapper();
                            newScriptInstance.LastModified = lastModified;

                            if (newScriptInstance.Compile(location, scriptBody, scriptBuffer))
                            {
                                newState = AutoWebProxyState.Completed;
                            }
                            else
                            {
                                newState = AutoWebProxyState.CompilationFailure;
                            }
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                if (Logging.On)
                {
                    Logging.PrintWarning(Logging.Web, SR.GetString(SR.net_log_proxy_script_download_compile_error, exception));
                }
                GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Download() threw:" + ValidationHelper.ToString(exception));
            }
            finally
            {
                if (timer != null)
                {
                    timer.Cancel();
                }

                //
                try
                {
                    if (response != null)
                    {
                        response.Close();
                    }
                }
                finally
                {
                    WebPermission.RevertAssert();

                    // The request is not needed anymore. Set it to null, so if Abort() gets called,
                    // after this point, it will result in a no-op.
                    request = null;
                }
            }

            if ((newState == AutoWebProxyState.Completed) && (scriptInstance != newScriptInstance))
            {
                if (scriptInstance != null)
                {
                    scriptInstance.Close();
                }

                scriptInstance = newScriptInstance;
            }

            GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() retuning newState:" + ValidationHelper.ToString(newState));
            return(newState);
        }
        // Ensures that (if state is AutoWebProxyState.CompilationSuccess) there is an engine available to execute script.
        // Figures out the script location (might discover if needed).
        // Calls DownloadAndCompile().
        private void EnsureEngineAvailable()
        {
            GlobalLog.Enter("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable");

            if (State == AutoWebProxyState.Uninitialized || engineScriptLocation == null)
            {
#if !FEATURE_PAL
                if (Engine.AutomaticallyDetectSettings)
                {
                    GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() Attempting auto-detection.");
                    DetectScriptLocation();
                    if (scriptLocation != null)
                    {
                        //
                        // Successfully detected or user has flipped the automaticallyDetectSettings bit.
                        // Attempt a non conclusive DownloadAndCompile() so we can fallback
                        //
                        GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() discovered:" + ValidationHelper.ToString(scriptLocation) + " engineScriptLocation:" + ValidationHelper.ToString(engineScriptLocation));
                        if (scriptLocation.Equals(engineScriptLocation))
                        {
                            State = AutoWebProxyState.Completed;
                            GlobalLog.Leave("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(State));
                            return;
                        }
                        AutoWebProxyState newState = DownloadAndCompile(scriptLocation);
                        if (newState == AutoWebProxyState.Completed)
                        {
                            State = AutoWebProxyState.Completed;
                            engineScriptLocation = scriptLocation;
                            GlobalLog.Leave("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(State));
                            return;
                        }
                    }
                }
#endif // !FEATURE_PAL

                // Either Auto-Detect wasn't enabled or something failed with it.  Try the manual script location.
                if ((Engine.AutomaticConfigurationScript != null) && !aborted)
                {
                    GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() using automaticConfigurationScript:" + ValidationHelper.ToString(Engine.AutomaticConfigurationScript) + " engineScriptLocation:" + ValidationHelper.ToString(engineScriptLocation));
                    if (Engine.AutomaticConfigurationScript.Equals(engineScriptLocation))
                    {
                        State = AutoWebProxyState.Completed;
                        GlobalLog.Leave("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(State));
                        return;
                    }
                    State = DownloadAndCompile(Engine.AutomaticConfigurationScript);
                    if (State == AutoWebProxyState.Completed)
                    {
                        engineScriptLocation = Engine.AutomaticConfigurationScript;
                        GlobalLog.Leave("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(State));
                        return;
                    }
                }
            }
            else
            {
                // We always want to call DownloadAndCompile to check the expiration.
                GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() State:" + State + " engineScriptLocation:" + ValidationHelper.ToString(engineScriptLocation));
                State = DownloadAndCompile(engineScriptLocation);
                if (State == AutoWebProxyState.Completed)
                {
                    GlobalLog.Leave("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(State));
                    return;
                }

                // There's still an opportunity to fail over to the automaticConfigurationScript.
                if (!engineScriptLocation.Equals(Engine.AutomaticConfigurationScript) && !aborted)
                {
                    GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() Update failed.  Falling back to automaticConfigurationScript:" + ValidationHelper.ToString(Engine.AutomaticConfigurationScript));
                    State = DownloadAndCompile(Engine.AutomaticConfigurationScript);
                    if (State == AutoWebProxyState.Completed)
                    {
                        engineScriptLocation = Engine.AutomaticConfigurationScript;
                        GlobalLog.Leave("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(State));
                        return;
                    }
                }
            }

            // Everything failed.  Set this instance to mostly-dead.  It will wake up again if there's a reg/connectoid change.
            GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() All failed.");
            State = AutoWebProxyState.DiscoveryFailure;

            if (scriptInstance != null)
            {
                scriptInstance.Close();
                scriptInstance = null;
            }

            engineScriptLocation = null;

            GlobalLog.Leave("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(State));
        }
        /// <devdoc>
        ///     <para>
        ///         Ensures that (if state is AutoWebProxyState.CompilationSuccess) there is an engine available to execute script.
        ///         Figures out the script location (might discover if needed).
        ///         Calls DownloadAndCompile().
        ///     </para>
        /// </devdoc>
        private AutoWebProxyState EnsureEngineAvailable(ref int syncStatus)
        {
            GlobalLog.Enter("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable");
            AutoWebProxyScriptWrapper newScriptInstance;

            if (state == AutoWebProxyState.Uninitialized || engineScriptLocation == null)
            {

                // Either Auto-Detect wasn't enabled or something failed with it.  Try the manual script location.
                if (automaticConfigurationScript != null)
                {
                    GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() using automaticConfigurationScript:" + ValidationHelper.ToString(automaticConfigurationScript) + " engineScriptLocation:" + ValidationHelper.ToString(engineScriptLocation));
                    state = AutoWebProxyState.DiscoverySuccess;
                    if (automaticConfigurationScript.Equals(engineScriptLocation))
                    {
                        state = AutoWebProxyState.CompilationSuccess;
                        GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
                        return state;
                    }
                    state = DownloadAndCompile(automaticConfigurationScript, out newScriptInstance, ref syncStatus);
                    if (state == AutoWebProxyState.CompilationSuccess)
                    {
                        UpdateScriptInstance(newScriptInstance);
                        engineScriptLocation = automaticConfigurationScript;
                        GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
                        return state;
                    }
                }
            }
            else
            {
                // We always want to call DownloadAndCompile to check the expiration.
                GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() state:" + state + " engineScriptLocation:" + ValidationHelper.ToString(engineScriptLocation));
                state = AutoWebProxyState.DiscoverySuccess;
                state = DownloadAndCompile(engineScriptLocation, out newScriptInstance, ref syncStatus);
                if (state == AutoWebProxyState.CompilationSuccess)
                {
                    UpdateScriptInstance(newScriptInstance);
                    GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
                    return state;
                }

                // There's still an opportunity to fail over to the automaticConfigurationScript.
                if (!engineScriptLocation.Equals(automaticConfigurationScript))
                {
                    GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() Update failed.  Falling back to automaticConfigurationScript:" + ValidationHelper.ToString(automaticConfigurationScript));
                    state = AutoWebProxyState.DiscoverySuccess;
                    state = DownloadAndCompile(automaticConfigurationScript, out newScriptInstance, ref syncStatus);
                    if (state == AutoWebProxyState.CompilationSuccess)
                    {
                        UpdateScriptInstance(newScriptInstance);
                        engineScriptLocation = automaticConfigurationScript;
                        GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
                        return state;
                    }
                }
            }

            // Everything failed.  Set this instance to mostly-dead.  It will wake up again if there's a reg/connectoid change.
            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() All failed.");
            state = AutoWebProxyState.DiscoveryFailure;
            UpdateScriptInstance(null);
            engineScriptLocation = null;

            GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
            return state;
        }
        internal StringCollection GetProxies(Uri destination, bool returnFirstOnly, out AutoWebProxyState autoWebProxyState, ref int syncStatus)
        {
            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::GetProxies() state:" + ValidationHelper.ToString(state));


            if (state==AutoWebProxyState.DiscoveryFailure) {
                // No engine will be available anyway, shortcut the call.
                autoWebProxyState = state;
                return null;
            }

            // This whole thing has to be locked, both to prevent simultaneous downloading / compilation, and
            // because the script isn't threadsafe.
            string scriptReturn = null;
            try
            {
                EnterLock(ref syncStatus);
                if (syncStatus != SyncStatus.LockOwner)
                {
                    // This is typically because a download got aborted.
                    autoWebProxyState = AutoWebProxyState.DownloadFailure;
                    return null;
                }

                autoWebProxyState = EnsureEngineAvailable(ref syncStatus);
                if (autoWebProxyState != AutoWebProxyState.CompilationSuccess)
                {
                    // the script can't run, say we're not ready and bypass
                    return null;
                }
                autoWebProxyState = AutoWebProxyState.ExecutionFailure;
                try {
                    scriptReturn = scriptInstance.FindProxyForURL(destination.ToString(), destination.Host);
                    autoWebProxyState = AutoWebProxyState.ExecutionSuccess;
                    GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::GetProxies() calling ExecuteFindProxyForURL() for destination:" + ValidationHelper.ToString(destination) + " returned scriptReturn:" + ValidationHelper.ToString(scriptReturn));
                }
                catch (Exception exception) {
                    if (NclUtilities.IsFatal(exception)) throw;
                    if(Logging.On)Logging.PrintWarning(Logging.Web, SR.GetString(SR.net_log_proxy_script_execution_error, exception));
                    GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::GetProxies() calling ExecuteFindProxyForURL() for destination:" + ValidationHelper.ToString(destination) + " threw:" + ValidationHelper.ToString(exception));
                }
            }
            finally
            {
                ExitLock(ref syncStatus);
            }

            if (autoWebProxyState==AutoWebProxyState.ExecutionFailure) {
                // the script failed at runtime, say we're not ready and bypass
                return null;
            }
            StringCollection proxies = ParseScriptReturn(scriptReturn, destination, returnFirstOnly);
            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::GetProxies() proxies:" + ValidationHelper.ToString(proxies));
            return proxies;
        }
 internal StringCollection GetProxies(Uri destination, bool returnFirstOnly, out AutoWebProxyState autoWebProxyState)
 {
     int syncStatus = SyncStatus.Unlocked;
     return GetProxies(destination, returnFirstOnly, out autoWebProxyState, ref syncStatus);
 }
 private void ExitLock(ref int syncStatus)
 {
     if (syncStatus != SyncStatus.Unlocked && syncStatus != SyncStatus.Aborted)
     {
         lock (this)
         {
             if (syncStatus == SyncStatus.RequestOwner)
             {
                 m_LockedRequest = null;
             }
             m_LockHeld = false;
             if (syncStatus == SyncStatus.AbortedLocked)
             {
                 state = AutoWebProxyState.Uninitialized;
                 syncStatus = SyncStatus.Aborted;
             }
             else
             {
                 syncStatus = SyncStatus.Unlocked;
             }
             Monitor.Pulse(this);
         }
     }
 }
예제 #12
0
 private bool IsBypassedAuto(Uri destination, out AutoWebProxyState autoWebProxyState) {
     GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::IsBypassedAuto() destination:" + ValidationHelper.ToString(destination));
     if (ScriptEngine == null) {
         autoWebProxyState = AutoWebProxyState.Uninitialized;
         return true;
     }
     StringCollection proxies = ScriptEngine.GetProxies(destination, true, out autoWebProxyState);
     if (autoWebProxyState!=AutoWebProxyState.ExecutionSuccess) {
         return true;
     }
     if (proxies.Count == 0)
     {
         return false;
     }
     return AreAllBypassed(proxies, true);
 }
        /// <devdoc>
        ///     <para>
        ///         Ensures that (if state is AutoWebProxyState.CompilationSuccess) there is an engine available to execute script.
        ///         Figures out the script location (might discover if needed).
        ///         Calls DownloadAndCompile().
        ///     </para>
        /// </devdoc>
        private AutoWebProxyState EnsureEngineAvailable(ref int syncStatus)
        {
            GlobalLog.Enter("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable");
            AutoWebProxyScriptWrapper newScriptInstance;

            if (state == AutoWebProxyState.Uninitialized || engineScriptLocation == null)
            {
                // Either Auto-Detect wasn't enabled or something failed with it.  Try the manual script location.
                if (automaticConfigurationScript != null)
                {
                    GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() using automaticConfigurationScript:" + ValidationHelper.ToString(automaticConfigurationScript) + " engineScriptLocation:" + ValidationHelper.ToString(engineScriptLocation));
                    state = AutoWebProxyState.DiscoverySuccess;
                    if (automaticConfigurationScript.Equals(engineScriptLocation))
                    {
                        state = AutoWebProxyState.CompilationSuccess;
                        GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
                        return(state);
                    }
                    state = DownloadAndCompile(automaticConfigurationScript, out newScriptInstance, ref syncStatus);
                    if (state == AutoWebProxyState.CompilationSuccess)
                    {
                        UpdateScriptInstance(newScriptInstance);
                        engineScriptLocation = automaticConfigurationScript;
                        GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
                        return(state);
                    }
                }
            }
            else
            {
                // We always want to call DownloadAndCompile to check the expiration.
                GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() state:" + state + " engineScriptLocation:" + ValidationHelper.ToString(engineScriptLocation));
                state = AutoWebProxyState.DiscoverySuccess;
                state = DownloadAndCompile(engineScriptLocation, out newScriptInstance, ref syncStatus);
                if (state == AutoWebProxyState.CompilationSuccess)
                {
                    UpdateScriptInstance(newScriptInstance);
                    GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
                    return(state);
                }

                // There's still an opportunity to fail over to the automaticConfigurationScript.
                if (!engineScriptLocation.Equals(automaticConfigurationScript))
                {
                    GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() Update failed.  Falling back to automaticConfigurationScript:" + ValidationHelper.ToString(automaticConfigurationScript));
                    state = AutoWebProxyState.DiscoverySuccess;
                    state = DownloadAndCompile(automaticConfigurationScript, out newScriptInstance, ref syncStatus);
                    if (state == AutoWebProxyState.CompilationSuccess)
                    {
                        UpdateScriptInstance(newScriptInstance);
                        engineScriptLocation = automaticConfigurationScript;
                        GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
                        return(state);
                    }
                }
            }

            // Everything failed.  Set this instance to mostly-dead.  It will wake up again if there's a reg/connectoid change.
            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable() All failed.");
            state = AutoWebProxyState.DiscoveryFailure;
            UpdateScriptInstance(null);
            engineScriptLocation = null;

            GlobalLog.Leave("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::EnsureEngineAvailable", ValidationHelper.ToString(state));
            return(state);
        }
        internal StringCollection GetProxies(Uri destination, bool returnFirstOnly, out AutoWebProxyState autoWebProxyState, ref int syncStatus)
        {
            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::GetProxies() state:" + ValidationHelper.ToString(state));


            if (state == AutoWebProxyState.DiscoveryFailure)
            {
                // No engine will be available anyway, shortcut the call.
                autoWebProxyState = state;
                return(null);
            }

            // This whole thing has to be locked, both to prevent simultaneous downloading / compilation, and
            // because the script isn't threadsafe.
            string scriptReturn = null;

            try
            {
                EnterLock(ref syncStatus);
                if (syncStatus != SyncStatus.LockOwner)
                {
                    // This is typically because a download got aborted.
                    autoWebProxyState = AutoWebProxyState.DownloadFailure;
                    return(null);
                }

                autoWebProxyState = EnsureEngineAvailable(ref syncStatus);
                if (autoWebProxyState != AutoWebProxyState.CompilationSuccess)
                {
                    // the script can't run, say we're not ready and bypass
                    return(null);
                }
                autoWebProxyState = AutoWebProxyState.ExecutionFailure;
                try {
                    scriptReturn      = scriptInstance.FindProxyForURL(destination.ToString(), destination.Host);
                    autoWebProxyState = AutoWebProxyState.ExecutionSuccess;
                    GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::GetProxies() calling ExecuteFindProxyForURL() for destination:" + ValidationHelper.ToString(destination) + " returned scriptReturn:" + ValidationHelper.ToString(scriptReturn));
                }
                catch (Exception exception) {
                    if (NclUtilities.IsFatal(exception))
                    {
                        throw;
                    }
                    if (Logging.On)
                    {
                        Logging.PrintWarning(Logging.Web, SR.GetString(SR.net_log_proxy_script_execution_error, exception));
                    }
                    GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::GetProxies() calling ExecuteFindProxyForURL() for destination:" + ValidationHelper.ToString(destination) + " threw:" + ValidationHelper.ToString(exception));
                }
            }
            finally
            {
                ExitLock(ref syncStatus);
            }

            if (autoWebProxyState == AutoWebProxyState.ExecutionFailure)
            {
                // the script failed at runtime, say we're not ready and bypass
                return(null);
            }
            StringCollection proxies = ParseScriptReturn(scriptReturn, destination, returnFirstOnly);

            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::GetProxies() proxies:" + ValidationHelper.ToString(proxies));
            return(proxies);
        }
        internal StringCollection GetProxies(Uri destination, bool returnFirstOnly, out AutoWebProxyState autoWebProxyState)
        {
            int syncStatus = SyncStatus.Unlocked;

            return(GetProxies(destination, returnFirstOnly, out autoWebProxyState, ref syncStatus));
        }
예제 #16
0
 internal Uri[] GetProxiesAuto(Uri destination, out AutoWebProxyState autoWebProxyState, ref int syncStatus)
 {
     GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::GetProxiesAuto() destination:" + ValidationHelper.ToString(destination));
     if (ScriptEngine == null) {
         autoWebProxyState = AutoWebProxyState.Uninitialized;
         return null;
     }
     StringCollection proxies = ScriptEngine.GetProxies(destination, false, out autoWebProxyState, ref syncStatus);
     if (autoWebProxyState!=AutoWebProxyState.ExecutionSuccess) {
         return null;
     }
     if (proxies.Count == 0)
     {
         return new Uri[] { };
     }
     if (AreAllBypassed(proxies, false))
     {
         return new Uri[] { null };
     }
     Uri[] proxyUris = new Uri[proxies.Count];
     for (int i=0; i<proxies.Count; i++) {
         proxyUris[i] = ProxyUri(proxies[i]);
     }
     return proxyUris;
 }
예제 #17
0
 public void Reset()
 {
     state            = AutoWebProxyState.Uninitialized;
     autoDetectFailed = false;
 }
예제 #18
0
        //
        // IWebProxy implementation
        //

        // Get proxies can never return null in the case of ExecutionSuccess.
        private Uri GetProxyAuto(Uri destination, out AutoWebProxyState autoWebProxyState) {
            GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::GetProxyAuto() destination:" + ValidationHelper.ToString(destination));
            if (ScriptEngine == null) {
                autoWebProxyState = AutoWebProxyState.Uninitialized;
                return null;
            }
            StringCollection proxies = ScriptEngine.GetProxies(destination, true, out autoWebProxyState);
            if (autoWebProxyState!=AutoWebProxyState.ExecutionSuccess) {
                return null;
            }
            if (proxies.Count == 0)
            {
                // Null here means, no proxy available (incl. DIRECT), the request is prohibited.
                return null;
            }
            if (AreAllBypassed(proxies, true)) {
                return destination;
            }
            return ProxyUri(proxies[0]);
        }