// // 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])); }
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); }
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 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)); }
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 void Reset() { state = AutoWebProxyState.Uninitialized; autoDetectFailed = false; }
// // 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]); }