diff --git a/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs index 1f9d3ed16..f7ffeb7b9 100644 --- a/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs +++ b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs @@ -207,6 +207,17 @@ private async Task onRequest(object sender, SessionEventArgs e) { e.GetState().PipelineInfo.AppendLine(nameof(onRequest) + ":" + e.HttpClient.Request.RequestUri); + var clientLocalIp = e.ClientLocalEndPoint.Address; + if (!clientLocalIp.Equals(IPAddress.Loopback) && !clientLocalIp.Equals(IPAddress.IPv6Loopback)) + { + e.HttpClient.UpStreamEndPoint = new IPEndPoint(clientLocalIp, 0); + } + + if (e.HttpClient.Request.Url.Contains("yahoo.com")) + { + e.CustomUpStreamProxy = new ExternalProxy("localhost", 8888); + } + await writeToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount); await writeToConsole(e.HttpClient.Request.Url); diff --git a/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs b/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs index 081ea4561..c362317ae 100644 --- a/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs +++ b/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs @@ -59,7 +59,7 @@ private protected SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoin ClientStream = clientStream; HttpClient = new HttpWebClient(connectRequest, request, new Lazy(() => clientStream.Connection.GetProcessId(endPoint))); - LocalEndPoint = endPoint; + ProxyEndPoint = endPoint; EnableWinAuth = server.EnableWinAuth && isWindowsAuthenticationSupported; } @@ -103,6 +103,9 @@ public bool EnableWinAuth /// public IPEndPoint ClientRemoteEndPoint => (IPEndPoint)ClientConnection.RemoteEndPoint; + [Obsolete("Use ClientRemoteEndPoint instead.")] + public IPEndPoint ClientEndPoint => ClientRemoteEndPoint; + /// /// The web client used to communicate with server for this session. /// @@ -111,6 +114,14 @@ public bool EnableWinAuth [Obsolete("Use HttpClient instead.")] public HttpWebClient WebSession => HttpClient; + /// + /// Gets or sets the custom up stream proxy. + /// + /// + /// The custom up stream proxy. + /// + public IExternalProxy? CustomUpStreamProxy { get; set; } + /// /// Are we using a custom upstream HTTP(S) proxy? /// @@ -119,12 +130,15 @@ public bool EnableWinAuth /// /// Local endpoint via which we make the request. /// - public ProxyEndPoint LocalEndPoint { get; } + public ProxyEndPoint ProxyEndPoint { get; } + + [Obsolete("Use ProxyEndPoint instead.")] + public ProxyEndPoint LocalEndPoint => ProxyEndPoint; /// /// Is this a transparent endpoint? /// - public bool IsTransparent => LocalEndPoint is TransparentProxyEndPoint; + public bool IsTransparent => ProxyEndPoint is TransparentProxyEndPoint; /// /// The last exception that happened. diff --git a/src/Titanium.Web.Proxy/Helpers/WinHttp/WinHttpWebProxyFinder.cs b/src/Titanium.Web.Proxy/Helpers/WinHttp/WinHttpWebProxyFinder.cs index 8b8ec3295..1aed46492 100644 --- a/src/Titanium.Web.Proxy/Helpers/WinHttp/WinHttpWebProxyFinder.cs +++ b/src/Titanium.Web.Proxy/Helpers/WinHttp/WinHttpWebProxyFinder.cs @@ -114,11 +114,7 @@ public bool GetAutoProxies(Uri destination, out IList? proxyList) } // TODO: Apply authorization - var systemProxy = new ExternalProxy - { - HostName = proxyStr, - Port = port - }; + var systemProxy = new ExternalProxy(proxyStr, port); return systemProxy; } @@ -134,12 +130,7 @@ public bool GetAutoProxies(Uri destination, out IList? proxyList) HttpSystemProxyValue? value = null; if (ProxyInfo?.Proxies?.TryGetValue(protocolType.Value, out value) == true) { - var systemProxy = new ExternalProxy - { - HostName = value!.HostName, - Port = value.Port - }; - + var systemProxy = new ExternalProxy(value!.HostName, value.Port); return systemProxy; } } diff --git a/src/Titanium.Web.Proxy/Models/ExternalProxy.cs b/src/Titanium.Web.Proxy/Models/ExternalProxy.cs index 931248233..70ae99caf 100644 --- a/src/Titanium.Web.Proxy/Models/ExternalProxy.cs +++ b/src/Titanium.Web.Proxy/Models/ExternalProxy.cs @@ -69,6 +69,39 @@ public string? Password /// public int Port { get; set; } + /// + /// Initializes a new instance of the class. + /// + public ExternalProxy() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the host. + /// The port. + public ExternalProxy(string hostName, int port) + { + HostName = hostName; + Port = port; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the host. + /// The port. + /// Name of the user. + /// The password. + public ExternalProxy(string hostName, int port, string userName, string password) + { + HostName = hostName; + Port = port; + UserName = userName; + Password = password; + } + /// /// returns data in Hostname:port format. /// @@ -77,6 +110,5 @@ public override string ToString() { return $"{HostName}:{Port}"; } - } } diff --git a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs index 1b507802f..62d9e935e 100644 --- a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs +++ b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs @@ -114,10 +114,10 @@ internal async Task GetConnectionCacheKey(ProxyServer server, SessionEve applicationProtocols = new List { applicationProtocol }; } - IExternalProxy? customUpStreamProxy = null; + IExternalProxy? customUpStreamProxy = session.CustomUpStreamProxy; bool isHttps = session.IsHttps; - if (server.GetCustomUpStreamProxyFunc != null) + if (customUpStreamProxy == null && server.GetCustomUpStreamProxyFunc != null) { customUpStreamProxy = await server.GetCustomUpStreamProxyFunc(session); } @@ -169,10 +169,10 @@ internal Task GetServerConnection(ProxyServer proxyServer, internal async Task GetServerConnection(ProxyServer proxyServer, SessionEventArgsBase session, bool isConnect, List? applicationProtocols, bool noCache, CancellationToken cancellationToken) { - IExternalProxy? customUpStreamProxy = null; + IExternalProxy? customUpStreamProxy = session.CustomUpStreamProxy; bool isHttps = session.IsHttps; - if (proxyServer.GetCustomUpStreamProxyFunc != null) + if (customUpStreamProxy == null && proxyServer.GetCustomUpStreamProxyFunc != null) { customUpStreamProxy = await proxyServer.GetCustomUpStreamProxyFunc(session); } diff --git a/src/Titanium.Web.Proxy/WinAuthHandler.cs b/src/Titanium.Web.Proxy/WinAuthHandler.cs index c72d333e1..4ea7bd073 100644 --- a/src/Titanium.Web.Proxy/WinAuthHandler.cs +++ b/src/Titanium.Web.Proxy/WinAuthHandler.cs @@ -175,7 +175,7 @@ private async Task rewriteUnauthorizedResponse(SessionEventArgs args) // Add custom div to body to clarify that the proxy (not the client browser) failed authentication string authErrorMessage = "

NTLM authentication through Titanium.Web.Proxy (" + - args.ClientConnection.LocalEndPoint + + args.ClientLocalEndPoint + ") failed. Please check credentials.

"; string originalErrorMessage = "

Response from remote web server below.


"; diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/NestedProxyTests.cs b/tests/Titanium.Web.Proxy.IntegrationTests/NestedProxyTests.cs index 3f1f8a2ca..ef2c088a9 100644 --- a/tests/Titanium.Web.Proxy.IntegrationTests/NestedProxyTests.cs +++ b/tests/Titanium.Web.Proxy.IntegrationTests/NestedProxyTests.cs @@ -59,11 +59,7 @@ public async Task Smoke_Test_Nested_Proxy_UserData() { Assert.AreEqual("Test", session.UserData); - return await Task.FromResult(new Models.ExternalProxy - { - HostName = "localhost", - Port = proxy2.ProxyEndPoints[0].Port - }); + return await Task.FromResult(new Models.ExternalProxy("localhost", proxy2.ProxyEndPoints[0].Port)); }; var client = testSuite.GetClient(proxy1, true); diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestProxyServer.cs b/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestProxyServer.cs index 7a8d80c3d..d85ef4240 100644 --- a/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestProxyServer.cs +++ b/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestProxyServer.cs @@ -22,17 +22,8 @@ public TestProxyServer(bool isReverseProxy, ProxyServer upStreamProxy = null) if (upStreamProxy != null) { - ProxyServer.UpStreamHttpProxy = new ExternalProxy - { - HostName = "localhost", - Port = upStreamProxy.ProxyEndPoints[0].Port - }; - - ProxyServer.UpStreamHttpsProxy = new ExternalProxy - { - HostName = "localhost", - Port = upStreamProxy.ProxyEndPoints[0].Port - }; + ProxyServer.UpStreamHttpProxy = new ExternalProxy("localhost", upStreamProxy.ProxyEndPoints[0].Port); + ProxyServer.UpStreamHttpsProxy = new ExternalProxy("localhost", upStreamProxy.ProxyEndPoints[0].Port); } ProxyServer.Start();