From fc1535210b355ff1ee922d728bad5e30b9be923e Mon Sep 17 00:00:00 2001 From: justcoding121 Date: Tue, 5 Mar 2019 11:33:21 -0500 Subject: [PATCH 1/6] #564 update error msg --- src/Titanium.Web.Proxy/ProxyServer.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Titanium.Web.Proxy/ProxyServer.cs b/src/Titanium.Web.Proxy/ProxyServer.cs index 180913245..d9c6ea5b4 100644 --- a/src/Titanium.Web.Proxy/ProxyServer.cs +++ b/src/Titanium.Web.Proxy/ProxyServer.cs @@ -417,9 +417,10 @@ public void SetAsSystemHttpsProxy(ExplicitProxyEndPoint endPoint) /// The proxy protocol type. public void SetAsSystemProxy(ExplicitProxyEndPoint endPoint, ProxyProtocolType protocolType) { - if (RunTime.IsRunningOnMono) + if (!RunTime.IsWindows) { - throw new Exception("Mono Runtime do not support system proxy settings."); + throw new NotSupportedException(@"Setting system proxy settings are only supported in Windows. + Please manually confugure you operating system to use this proxy's port and address."); } validateEndPointAsSystemProxy(endPoint); From d76e3c21612622f38bdb42cb014a1d4a2ba13ed2 Mon Sep 17 00:00:00 2001 From: buildbot121 Date: Tue, 5 Mar 2019 16:36:40 +0000 Subject: [PATCH 2/6] API documentation update by build server --- docs/api/Titanium.Web.Proxy.ProxyServer.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/api/Titanium.Web.Proxy.ProxyServer.html b/docs/api/Titanium.Web.Proxy.ProxyServer.html index 65245f5a1..07aa9740b 100644 --- a/docs/api/Titanium.Web.Proxy.ProxyServer.html +++ b/docs/api/Titanium.Web.Proxy.ProxyServer.html @@ -1178,7 +1178,7 @@
Parameters
Improve this Doc - View Source + View Source

DisableAllSystemProxies()

@@ -1194,7 +1194,7 @@
Declaration
Improve this Doc - View Source + View Source

DisableSystemHttpProxy()

@@ -1210,7 +1210,7 @@
Declaration
Improve this Doc - View Source + View Source

DisableSystemHttpsProxy()

@@ -1226,7 +1226,7 @@
Declaration
Improve this Doc - View Source + View Source

DisableSystemProxy(ProxyProtocolType)

@@ -1259,7 +1259,7 @@
Parameters
Improve this Doc - View Source + View Source

Dispose()

@@ -1418,7 +1418,7 @@
Parameters
Improve this Doc - View Source + View Source

Start()

@@ -1434,7 +1434,7 @@
Declaration
Improve this Doc - View Source + View Source

Stop()

From c2994bc748daa8543eae86a972938a97ed9251de Mon Sep 17 00:00:00 2001 From: justcoding121 Date: Tue, 5 Mar 2019 11:39:30 -0500 Subject: [PATCH 3/6] system proxy do not support non-windows env --- .../Network/CertificateManager.cs | 8 ++++---- .../Network/Tcp/TcpConnectionFactory.cs | 2 +- src/Titanium.Web.Proxy/ProxyServer.cs | 16 +++++++++------- src/Titanium.Web.Proxy/RequestHandler.cs | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/Titanium.Web.Proxy/Network/CertificateManager.cs b/src/Titanium.Web.Proxy/Network/CertificateManager.cs index d7b2164c9..c7ee521e0 100644 --- a/src/Titanium.Web.Proxy/Network/CertificateManager.cs +++ b/src/Titanium.Web.Proxy/Network/CertificateManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; @@ -149,7 +149,7 @@ public CertificateEngine CertificateEngine set { // For Mono (or Non-Windows) only Bouncy Castle is supported - if (!RunTime.IsWindows || RunTime.IsRunningOnMono) + if (!RunTime.IsWindows) { value = CertificateEngine.BouncyCastle; } @@ -662,7 +662,7 @@ public void TrustRootCertificate(bool machineTrusted = false) /// True if success. public bool TrustRootCertificateAsAdmin(bool machineTrusted = false) { - if (!RunTime.IsWindows || RunTime.IsRunningOnMono) + if (!RunTime.IsWindows) { return false; } @@ -805,7 +805,7 @@ public void RemoveTrustedRootCertificate(bool machineTrusted = false) /// Should also remove from machine store? public bool RemoveTrustedRootCertificateAsAdmin(bool machineTrusted = false) { - if (!RunTime.IsWindows || RunTime.IsRunningOnMono) + if (!RunTime.IsWindows) { return false; } diff --git a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs index 9da4b2c65..13457bcf4 100644 --- a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs +++ b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs @@ -280,7 +280,7 @@ private async Task createServerConnection(string remoteHost }; //linux has a bug with socket reuse in .net core. - if (proxyServer.ReuseSocket && (RunTime.IsWindows || RunTime.IsRunningOnMono)) + if (proxyServer.ReuseSocket && RunTime.IsWindows) { tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } diff --git a/src/Titanium.Web.Proxy/ProxyServer.cs b/src/Titanium.Web.Proxy/ProxyServer.cs index d9c6ea5b4..dd198a16b 100644 --- a/src/Titanium.Web.Proxy/ProxyServer.cs +++ b/src/Titanium.Web.Proxy/ProxyServer.cs @@ -102,7 +102,7 @@ public ProxyServer(string rootCertificateName, string rootCertificateIssuerName, ProxyEndPoints = new List(); tcpConnectionFactory = new TcpConnectionFactory(this); - if (!RunTime.IsRunningOnMono && RunTime.IsWindows && !RunTime.IsUwpOnWindows) + if (RunTime.IsWindows && !RunTime.IsUwpOnWindows) { systemProxySettingsManager = new SystemProxyManager(); } @@ -511,9 +511,10 @@ public void DisableSystemHttpsProxy() /// public void DisableSystemProxy(ProxyProtocolType protocolType) { - if (RunTime.IsRunningOnMono) + if (!RunTime.IsWindows) { - throw new Exception("Mono Runtime do not support system proxy settings."); + throw new NotSupportedException(@"Setting system proxy settings are only supported in Windows. + Please manually confugure you operating system to use this proxy's port and address."); } systemProxySettingsManager.RemoveProxy(protocolType); @@ -524,9 +525,10 @@ public void DisableSystemProxy(ProxyProtocolType protocolType) /// public void DisableAllSystemProxies() { - if (RunTime.IsRunningOnMono) + if (!RunTime.IsWindows) { - throw new Exception("Mono Runtime do not support system proxy settings."); + throw new NotSupportedException(@"Setting system proxy settings are only supported in Windows. + Please manually confugure you operating system to use this proxy's port and address."); } systemProxySettingsManager.DisableAllProxy(); @@ -600,7 +602,7 @@ public void Stop() throw new Exception("Proxy is not running."); } - if (!RunTime.IsRunningOnMono && RunTime.IsWindows && !RunTime.IsUwpOnWindows) + if (RunTime.IsWindows && !RunTime.IsUwpOnWindows) { bool setAsSystemProxy = ProxyEndPoints.OfType() .Any(x => x.IsSystemHttpProxy || x.IsSystemHttpsProxy); @@ -633,7 +635,7 @@ private void listen(ProxyEndPoint endPoint) endPoint.Listener = new TcpListener(endPoint.IpAddress, endPoint.Port); //linux/macOS has a bug with socket reuse in .net core. - if (ReuseSocket && (RunTime.IsWindows || RunTime.IsRunningOnMono)) + if (ReuseSocket && RunTime.IsWindows) { endPoint.Listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } diff --git a/src/Titanium.Web.Proxy/RequestHandler.cs b/src/Titanium.Web.Proxy/RequestHandler.cs index 2cdce381b..79b2cbf11 100644 --- a/src/Titanium.Web.Proxy/RequestHandler.cs +++ b/src/Titanium.Web.Proxy/RequestHandler.cs @@ -27,7 +27,7 @@ namespace Titanium.Web.Proxy public partial class ProxyServer { private bool isWindowsAuthenticationEnabledAndSupported => - EnableWinAuth && RunTime.IsWindows && !RunTime.IsRunningOnMono; + EnableWinAuth && RunTime.IsWindows; /// /// This is the core request handler method for a particular connection from client. From 10c923e3f4ea1f75d8a9776bcd0a92a8df77c3cf Mon Sep 17 00:00:00 2001 From: buildbot121 Date: Tue, 5 Mar 2019 16:44:08 +0000 Subject: [PATCH 4/6] API documentation update by build server --- docs/api/Titanium.Web.Proxy.ProxyServer.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api/Titanium.Web.Proxy.ProxyServer.html b/docs/api/Titanium.Web.Proxy.ProxyServer.html index 07aa9740b..8da337748 100644 --- a/docs/api/Titanium.Web.Proxy.ProxyServer.html +++ b/docs/api/Titanium.Web.Proxy.ProxyServer.html @@ -1178,7 +1178,7 @@
Parameters
Improve this Doc - View Source + View Source

DisableAllSystemProxies()

@@ -1259,7 +1259,7 @@
Parameters
Improve this Doc - View Source + View Source

Dispose()

@@ -1418,7 +1418,7 @@
Parameters
Improve this Doc - View Source + View Source

Start()

@@ -1434,7 +1434,7 @@
Declaration
Improve this Doc - View Source + View Source

Stop()

From 48c041e6534f9906e057e419a330e7d24d9f5674 Mon Sep 17 00:00:00 2001 From: justcoding121 Date: Sat, 30 Mar 2019 20:40:53 -0400 Subject: [PATCH 5/6] #565 Verify hostname before prefetching connection --- .../ExplicitClientHandler.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs index e31f51def..6d8347fb7 100644 --- a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs +++ b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs @@ -47,7 +47,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect { string connectHostname = null; TunnelConnectSessionEventArgs connectArgs = null; - + // Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request) if (await HttpHelper.IsConnectMethod(clientStream) == 1) @@ -154,11 +154,17 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response, if (EnableTcpServerConnectionPrefetch) { - //don't pass cancellation token here - //it could cause floating server connections when client exits - prefetchConnectionTask = tcpConnectionFactory.GetServerConnection(this, connectArgs, - isConnect: true, applicationProtocols: null, noCache: false, - cancellationToken: CancellationToken.None); + //make sure the host can be resolved before creating the prefetch task + var ipAddresses = await Dns.GetHostAddressesAsync(connectArgs.HttpClient.Request.RequestUri.Host); + + if (ipAddresses != null && ipAddresses.Length > 0) + { + //don't pass cancellation token here + //it could cause floating server connections when client exits + prefetchConnectionTask = tcpConnectionFactory.GetServerConnection(this, connectArgs, + isConnect: true, applicationProtocols: null, noCache: false, + cancellationToken: CancellationToken.None); + } } X509Certificate2 certificate = null; From ac02c68baeca8dc53bf0b0287fde6c30143a4869 Mon Sep 17 00:00:00 2001 From: justcoding121 Date: Sat, 30 Mar 2019 20:58:27 -0400 Subject: [PATCH 6/6] Fix fake tunnel failure --- src/Titanium.Web.Proxy/RequestHandler.cs | 15 +++++++++- .../HttpsTests.cs | 29 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Titanium.Web.Proxy/RequestHandler.cs b/src/Titanium.Web.Proxy/RequestHandler.cs index 79b2cbf11..1800cc2aa 100644 --- a/src/Titanium.Web.Proxy/RequestHandler.cs +++ b/src/Titanium.Web.Proxy/RequestHandler.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Net.Sockets; #if NETCOREAPP2_1 using System.Net.Security; #endif @@ -188,8 +189,20 @@ await clientStreamWriter.WriteResponseAsync(args.HttpClient.Response, //If prefetch task is available. if (connection == null && prefetchTask != null) { - connection = await prefetchTask; + try + { + connection = await prefetchTask; + } + catch (SocketException e) + { + if(e.SocketErrorCode != SocketError.HostNotFound) + { + throw; + } + } + prefetchTask = null; + } // create a new connection if cache key changes. diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/HttpsTests.cs b/tests/Titanium.Web.Proxy.IntegrationTests/HttpsTests.cs index cb1621bef..56e260268 100644 --- a/tests/Titanium.Web.Proxy.IntegrationTests/HttpsTests.cs +++ b/tests/Titanium.Web.Proxy.IntegrationTests/HttpsTests.cs @@ -33,5 +33,34 @@ public async Task Can_Handle_Https_Request() Assert.AreEqual("I am server. I received your greetings.", body); } + [TestMethod] + public async Task Can_Handle_Https_Fake_Tunnel_Request() + { + var testSuite = new TestSuite(); + + var server = testSuite.GetServer(); + server.HandleRequest((context) => + { + return context.Response.WriteAsync("I am server. I received your greetings."); + }); + + var proxy = testSuite.GetProxy(); + proxy.BeforeRequest += async (sender, e) => + { + e.HttpClient.Request.RequestUri = new Uri(server.ListeningHttpUrl); + await Task.FromResult(0); + }; + + var client = testSuite.GetClient(proxy); + + var response = await client.PostAsync(new Uri($"https://{Guid.NewGuid().ToString()}.com"), + new StringContent("hello server. I am a client.")); + + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + var body = await response.Content.ReadAsStringAsync(); + + Assert.AreEqual("I am server. I received your greetings.", body); + } + } }