Unverified Commit 2e9e1154 authored by honfika's avatar honfika Committed by GitHub

Merge pull request #678 from ByronAP/master

Adds ability to handle upstream proxy connect failures
parents 0366b348 69aa126c
......@@ -42,6 +42,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
proxyServer.ForwardToUpstreamGateway = true;
proxyServer.CertificateManager.SaveFakeCertificates = true;
// this is just to show the functionality, provided implementations use junk value
//proxyServer.GetCustomUpStreamProxyFunc = onGetCustomUpStreamProxyFunc;
//proxyServer.CustomUpStreamProxyFailureFunc = onCustomUpStreamProxyFailureFunc;
// optionally set the Certificate Engine
// Under Mono or Non-Windows runtimes only BouncyCastle will be supported
//proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle;
......@@ -116,6 +120,18 @@ namespace Titanium.Web.Proxy.Examples.Basic
//proxyServer.CertificateManager.RemoveTrustedRootCertificates();
}
private async Task<IExternalProxy> onGetCustomUpStreamProxyFunc(SessionEventArgsBase arg)
{
// this is just to show the functionality, provided values are junk
return new ExternalProxy() { BypassLocalhost = false, HostName = "127.0.0.9", Port = 9090, Password = "fake", UserName = "fake", UseDefaultCredentials = false };
}
private async Task<IExternalProxy> onCustomUpStreamProxyFailureFunc(SessionEventArgsBase arg)
{
// this is just to show the functionality, provided values are junk
return new ExternalProxy() { BypassLocalhost = false, HostName = "127.0.0.10", Port = 9191, Password = "fake2", UserName = "fake2", UseDefaultCredentials = false };
}
private async Task onBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{
string hostname = e.HttpClient.Request.RequestUri.Host;
......
......@@ -397,6 +397,16 @@ retry:
if (tcpClient == null)
{
if (session != null && proxyServer.CustomUpStreamProxyFailureFunc != null)
{
var newUpstreamProxy = await proxyServer.CustomUpStreamProxyFailureFunc(session);
if (newUpstreamProxy != null)
{
session.CustomUpStreamProxyUsed = newUpstreamProxy;
session.TimeLine["Retrying Upstream Proxy Connection"] = DateTime.Now;
return await createServerConnection(remoteHostName, remotePort, httpVersion, isHttps, sslProtocol, applicationProtocols, isConnect, proxyServer, session, upStreamEndPoint, externalProxy, cacheKey, cancellationToken);
}
}
throw new Exception($"Could not establish connection to {hostname}", lastException);
}
......
......@@ -283,6 +283,12 @@ namespace Titanium.Web.Proxy
/// </summary>
public Func<SessionEventArgsBase, Task<IExternalProxy?>>? GetCustomUpStreamProxyFunc { get; set; }
/// <summary>
/// A callback to provide a chance for an upstream proxy failure to be handled by a new upstream proxy.
/// User should return the ExternalProxy object with valid credentials or null.
/// </summary>
public Func<SessionEventArgsBase, Task<IExternalProxy?>>? CustomUpStreamProxyFailureFunc { get; set; }
/// <summary>
/// Callback for error events in this proxy instance.
/// </summary>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment