protected virtual IActualProxy GetSystemActualProxy(SystemSettings systemSettings) { // argument checks Debug.Assert(systemSettings != null); // detect the system web proxy by try to give external urls // Note this implementation simply detect a possible typical proxy. IWebProxy systemProxy = WebRequest.GetSystemWebProxy(); Func <string, IActualProxy> detect = (sampleExternalUrl) => { Uri sampleUri = new Uri(sampleExternalUrl); IActualProxy value = null; if (systemProxy.IsBypassed(sampleUri) == false) { Uri uri = systemProxy.GetProxy(sampleUri); if (uri != sampleUri) { // uri seems to be a proxy value = new StaticActualProxy(new DnsEndPoint(uri.Host, uri.Port)); } } return(value); }; // try with google's URL IActualProxy actualProxy = detect("http://www.google.com/"); if (actualProxy == null) { // try with Microsoft's URL actualProxy = detect("http://www.microsoft.com/"); } return(actualProxy); // note that it may be null }
protected override IActualProxy GetSystemActualProxy(SystemSettings systemSettings) { // argument checks Debug.Assert(systemSettings != null); SystemSettingsForWindows actualSystemSettings = systemSettings as SystemSettingsForWindows; if (actualSystemSettings == null) { return(base.GetSystemActualProxy(systemSettings)); } // detect actual proxy IActualProxy actualProxy = null; if ((actualSystemSettings.ProxyEnable ?? 0) == 0) { // proxy is not explicitly specified bool autoDetect = actualSystemSettings.AutoDetect; string autoConfigURL = actualSystemSettings.AutoConfigURL; if (autoDetect || string.IsNullOrEmpty(autoConfigURL) == false) { actualProxy = new AutoConfigActualProxy(autoDetect, autoConfigURL); } } else { // proxy is explicitly specified // detect actually effective proxy by the base class implementation // Note that the explicitly specified proxy setting is not used // in some case such as dialup or VPN connection. ; } return((actualProxy != null) ? actualProxy : base.GetSystemActualProxy(systemSettings)); }
public SetupContext(CommandSettings settings, SystemSettingsSwitcher switcher) { // argument checks if (settings == null) { throw new ArgumentNullException(nameof(settings)); } if (switcher == null) { throw new ArgumentNullException(nameof(switcher)); } // initialize members this.Settings = settings; // ActualProxy this.DefaultActualProxyHostName = SystemSettingsSwitcher.GetDefaultActualProxyHostName(); this.DefaultActualProxyPort = SystemSettingsSwitcher.GetDefaultActualProxyPort(); this.DefaultActualProxyConfigurationScript = SystemSettingsSwitcher.GetDefaultActualProxyConfigurationScript(); IActualProxy actualProxy = switcher.DetectSystemActualProxy(); if (actualProxy != null) { this.ProxyDetected = true; DisposableUtil.ClearDisposableObject(ref actualProxy); } if (this.ProxyDetected == false && settings.SystemSettingsSwitcher.ActualProxy == null) { // The authentication proxy cannot be detected automatically. // User must set its information explicitly. this.NeedActualProxy = true; } return; }
public virtual bool TestWebProxy(IActualProxy actualProxy) { // get test url specified in application config file // (not in the settings file because this information is supposed to be set for site) string targetUrl = SystemSettingsSwitcher.GetProxyTestUrl(); Debug.Assert(string.IsNullOrEmpty(targetUrl) == false); Uri target = new Uri(targetUrl); DnsEndPoint targetEndPoint = new DnsEndPoint(target.Host, target.Port); WebClientForTest webClient = new WebClientForTest(); webClient.Timeout = 10 * 1000; // 10 seconds // test each proxy candidate CommandBase owner = this.Owner; bool result = false; IReadOnlyCollection <DnsEndPoint> endPoints = actualProxy.GetProxyEndPoints(target); if (endPoints != null) { foreach (DnsEndPoint endPoint in endPoints) { owner.LogVerbose($"ActualProxy check: to {endPoint.Host}:{endPoint.Port}"); try { webClient.Proxy = new WebProxy(endPoint.Host, endPoint.Port); webClient.DownloadData(targetUrl); // an exception is thrown on error result = true; } catch (WebException exception) { // Note that a protocol error indicates that the end point exists result = (exception.Status == WebExceptionStatus.ProtocolError); if (result) { owner.LogVerbose($"ActualProxy check: {exception.Status} -> OK"); } else { owner.LogError($"ActualProxy check: {exception.Status} -> NG"); } } if (result) { // a valid proxy is found break; } } } if (result) { owner.LogVerbose("ActualProxy check: OK - there is a valid actual proxy."); } else { owner.LogError("ActualProxy check: NG - no valid proxy."); } return(result); }
public Proxy(IServerComponentFactory componentFactory, ProxySettings settings) { // argument checks if (componentFactory == null) { throw new ArgumentNullException(nameof(componentFactory)); } if (settings == null) { throw new ArgumentNullException(nameof(settings)); } // initialize members this.ComponentName = ObjectBaseName; this.componentFactory = componentFactory; // listeners // ToDo: can be Listener[]? this.listeners = new List <Listener>(settings.GetListeners().Select( s => this.componentFactory.CreateListener(this, s) )); // actualProxy this.actualProxy = null; // retryCount this.retryCount = settings.RetryCount; // ToDo: value checks // misc. this.connections = null; this.serverBasicCredentialCache = new Dictionary <string, BasicCredential>(); this.Runner = null; return; }
bool ICommunicationOwner.OnCommunicate(int repeatCount, Request request, Response response) { // argument checks if (request == null) { throw new ArgumentNullException(nameof(request)); } if (request.HostEndPoint == null) { throw new HttpException(HttpStatusCode.BadRequest); } if (response == null && repeatCount != 0) { throw new ArgumentNullException(nameof(response)); } // preparations bool logVerbose = ShouldLog(TraceEventType.Verbose); bool retry = false; bool connectingToProxy; lock (this.instanceLocker) { connectingToProxy = this.connectingToProxy; } if (response == null) { // on before requesting to the server firstly // detect the server to be connected IActualProxy actualProxy = this.Proxy.ActualProxy; IReadOnlyCollection <DnsEndPoint> remoteEndPoints = null; if (actualProxy != null) { if (request.TargetUri != null) { remoteEndPoints = actualProxy.GetProxyEndPoints(request.TargetUri); } else { remoteEndPoints = actualProxy.GetProxyEndPoints(request.HostEndPoint); } } if (remoteEndPoints != null) { connectingToProxy = true; LogVerbose($"Connecting to proxy '{actualProxy.Description}'"); } else { DnsEndPoint endPoint = request.HostEndPoint; remoteEndPoints = new DnsEndPoint[] { endPoint }; connectingToProxy = false; LogVerbose($"Connecting directly to '{endPoint.Host}:{endPoint.Port}'"); } // connect to the server try { EnsureConnectToServer(remoteEndPoints); Debug.Assert(this.server.IsConnecting); lock (this.instanceLocker) { this.connectingToProxy = connectingToProxy; } } catch (Exception exception) { // the case that server connection is not available lock (this.instanceLocker) { this.connectingToProxy = false; } LogError($"Cannot connect to the server: {exception.Message}"); throw new HttpException(HttpStatusCode.BadGateway, "Cannot connect to the server."); } LogVerbose($"Connected to '{this.server.EndPoint}'"); } // retry check and get modifications if (repeatCount <= this.retryCount) { // set modifications on the request retry = SetModifications(request, response); if (retry == false && connectingToProxy == false && request.IsConnectMethod) { // ToDo: can be more smart? LogDirectTunnelingResult(request); } } else { LogWarning("Overruns the retry count. Responding the current response."); Debug.Assert(retry == false); } if (response != null) { // on after responded from the server // log the round trip result LogRoundTripResult(request, response, retry); } return(retry); }
public void Start(CommandSettings commandSettings, bool saveCredentials, bool checkPreviousBackup) { // argument checks if (commandSettings == null) { throw new ArgumentNullException(nameof(commandSettings)); } SystemSettingsSwitcherSettings systemSettingsSwitcherSettings = commandSettings.SystemSettingsSwitcher; if (systemSettingsSwitcherSettings == null) { throw new ArgumentNullException(nameof(commandSettings.SystemSettingsSwitcher)); } ProxySettings proxySettings = commandSettings.Proxy; if (proxySettings == null) { throw new ArgumentNullException(nameof(commandSettings.Proxy)); } // state checks if (this.proxy != null) { throw new InvalidOperationException("The proxy is already started."); } Debug.Assert(this.switcher == null); Debug.Assert(this.backup == null); try { ComponentFactory componentFactory = this.Owner.ComponentFactory; // check the state of previous backup if (checkPreviousBackup) { this.Owner.CheckPreviousBackup(); } // create a system settings swither SystemSettingsSwitcher switcher = componentFactory.CreateSystemSettingsSwitcher(this.Owner, systemSettingsSwitcherSettings); this.switcher = switcher; // setup credential dictionary lock (this.credentialsLocker) { IEnumerable <CredentialSettings> credentials = commandSettings.Credentials; this.dictionary = (credentials == null)? new Dictionary <string, CredentialSettings>(): credentials.ToDictionary(c => c.EndPoint); this.isCredentialsDirty = false; } // create a proxy Proxy proxy = componentFactory.CreateProxy(proxySettings); this.proxy = proxy; // detect the current proxy IActualProxy actualProxy = switcher.GetActualProxy(); if (actualProxy == null) { // no actual proxy to which it connects throw new Exception(Resources.CommandBase_Message_NoActualProxy); } try { // log CommandBase owner = this.Owner; if (owner.ShouldLog(TraceEventType.Verbose)) { // log the actual proxy owner.LogVerbose($"ActualProxy is '{actualProxy.Description}'"); // log whether system settings is being switched string label = switcher.Enabled ? "enabled" : "disabled"; owner.LogVerbose($"SystemSettingsSwitch: {label}"); } // test actual proxy if (switcher.TestWebProxy(actualProxy) == false) { string message = string.Format(Resources.SystemSettingsSwitcher_Message_ProxyIsNotConnectable, actualProxy.Description); throw new Exception(message); } // start the proxy proxy.ActualProxy = actualProxy; actualProxy = null; // its ownership has been moved to the proxy object. proxy.Start(this); this.saveCredentials = saveCredentials; // switch system settings this.backup = switcher.Switch(proxy); if (this.backup != null) { // save backup settings owner.SaveSystemSettingsBackup(this.backup); } this.commandSettings = commandSettings; } catch { DisposableUtil.ClearDisposableObject(ref actualProxy); throw; } } catch { Stop(systemSessionEnding: false); throw; } return; }