Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

beta #650

Merged
merged 6 commits into from
Oct 16, 2019
Merged

beta #650

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public abstract class SessionEventArgsBase : EventArgs, IDisposable
{
private static bool isWindowsAuthenticationSupported => RunTime.IsWindows;

internal readonly CancellationTokenSource CancellationTokenSource;
internal readonly CancellationTokenSource? CancellationTokenSource;

internal TcpServerConnection ServerConnection => HttpClient.Connection;

Expand Down
60 changes: 59 additions & 1 deletion src/Titanium.Web.Proxy/Helpers/RunTime.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System;
using System.Reflection;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

namespace Titanium.Web.Proxy.Helpers
{
Expand Down Expand Up @@ -41,6 +43,62 @@ public static class RunTime
public static bool IsUwpOnWindows => IsWindows && UwpHelper.IsRunningAsUwp();

public static bool IsMac => isRunningOnMac;

/// <summary>
/// Is socket reuse available to use?
/// </summary>
public static bool IsSocketReuseAvailable => isSocketReuseAvailable();

private static bool? _isSocketReuseAvailable;

private static bool isSocketReuseAvailable()
{
// use the cached value if we have one
if (_isSocketReuseAvailable != null)
return _isSocketReuseAvailable.Value;

try
{
if (IsWindows)
{
// since we are on windows just return true
// store the result in our static object so we don't have to be bothered going through all this more than once
_isSocketReuseAvailable = true;
return true;
}

// get the currently running framework name and version (EX: .NETFramework,Version=v4.5.1) (Ex: .NETCoreApp,Version=v2.0)
string ver = Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;

if (ver == null)
return false; // play it safe if we can not figure out what the framework is

// make sure we are on .NETCoreApp
ver = ver.ToLower(); // make everything lowercase to simplify comparison
if (ver.Contains(".netcoreapp"))
{
var versionString = ver.Replace(".netcoreapp,version=v", "");
var versionArr = versionString.Split('.');
var majorVersion = Convert.ToInt32(versionArr[0]);

var result = majorVersion >= 3; // version 3 and up supports socket reuse

// store the result in our static object so we don't have to be bothered going through all this more than once
_isSocketReuseAvailable = result;
return result;
}

// store the result in our static object so we don't have to be bothered going through all this more than once
_isSocketReuseAvailable = false;
return false;
}
catch
{
// store the result in our static object so we don't have to be bothered going through all this more than once
_isSocketReuseAvailable = false;
return false;
}
}

// https://github.com/qmatteoq/DesktopBridgeHelpers/blob/master/DesktopBridge.Helpers/Helpers.cs
private class UwpHelper
Expand Down
7 changes: 2 additions & 5 deletions src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,7 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
tcpClient.SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000;
tcpClient.LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds);

// linux has a bug with socket reuse in .net core.
if (proxyServer.ReuseSocket && RunTime.IsWindows)
if (proxyServer.ReuseSocket && RunTime.IsSocketReuseAvailable)
{
tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
Expand Down Expand Up @@ -417,7 +416,7 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
throw;
}

return new TcpServerConnection(proxyServer, tcpClient)
return new TcpServerConnection(proxyServer, tcpClient, stream)
{
UpStreamProxy = externalProxy,
UpStreamEndPoint = upStreamEndPoint,
Expand All @@ -426,8 +425,6 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
IsHttps = isHttps,
NegotiatedApplicationProtocol = negotiatedApplicationProtocol,
UseUpstreamProxy = useUpstreamProxy,
StreamWriter = new HttpRequestWriter(stream, proxyServer.BufferPool),
Stream = stream,
Version = httpVersion
};
}
Expand Down
8 changes: 5 additions & 3 deletions src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// </summary>
internal class TcpServerConnection : IDisposable
{
internal TcpServerConnection(ProxyServer proxyServer, TcpClient tcpClient)
internal TcpServerConnection(ProxyServer proxyServer, TcpClient tcpClient, CustomBufferedStream stream)
{
this.tcpClient = tcpClient;
LastAccess = DateTime.Now;
this.proxyServer = proxyServer;
this.proxyServer.UpdateServerConnectionCount(true);
StreamWriter = new HttpRequestWriter(stream, proxyServer.BufferPool);
Stream = stream;
}

private ProxyServer proxyServer { get; }
Expand Down Expand Up @@ -59,12 +61,12 @@ internal TcpServerConnection(ProxyServer proxyServer, TcpClient tcpClient)
/// <summary>
/// Used to write lines to server
/// </summary>
internal HttpRequestWriter? StreamWriter { get; set; }
internal HttpRequestWriter StreamWriter { get; }

/// <summary>
/// Server stream
/// </summary>
internal CustomBufferedStream? Stream { get; set; }
internal CustomBufferedStream Stream { get; }

/// <summary>
/// Last time this connection was used
Expand Down
15 changes: 7 additions & 8 deletions src/Titanium.Web.Proxy/ProxyServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public partial class ProxyServer : IDisposable
/// <summary>
/// Upstream proxy manager.
/// </summary>
private WinHttpWebProxyFinder systemProxyResolver;
private WinHttpWebProxyFinder? systemProxyResolver;


/// <inheritdoc />
Expand Down Expand Up @@ -421,7 +421,7 @@ public void SetAsSystemHttpsProxy(ExplicitProxyEndPoint endPoint)
/// <param name="protocolType">The proxy protocol type.</param>
public void SetAsSystemProxy(ExplicitProxyEndPoint endPoint, ProxyProtocolType protocolType)
{
if (!RunTime.IsWindows)
if (systemProxySettingsManager == null)
{
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.");
Expand Down Expand Up @@ -515,7 +515,7 @@ public void DisableSystemHttpsProxy()
/// </summary>
public void RestoreOriginalProxySettings()
{
if (!RunTime.IsWindows)
if (systemProxySettingsManager == null)
{
throw new NotSupportedException(@"Setting system proxy settings are only supported in Windows.
Please manually configure your operating system to use this proxy's port and address.");
Expand All @@ -529,7 +529,7 @@ public void RestoreOriginalProxySettings()
/// </summary>
public void DisableSystemProxy(ProxyProtocolType protocolType)
{
if (!RunTime.IsWindows)
if (systemProxySettingsManager == null)
{
throw new NotSupportedException(@"Setting system proxy settings are only supported in Windows.
Please manually configure your operating system to use this proxy's port and address.");
Expand All @@ -543,7 +543,7 @@ public void DisableSystemProxy(ProxyProtocolType protocolType)
/// </summary>
public void DisableAllSystemProxies()
{
if (!RunTime.IsWindows)
if (systemProxySettingsManager == null)
{
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.");
Expand Down Expand Up @@ -622,7 +622,7 @@ public void Stop()
throw new Exception("Proxy is not running.");
}

if (RunTime.IsWindows && !RunTime.IsUwpOnWindows)
if (systemProxySettingsManager != null)
{
bool setAsSystemProxy = ProxyEndPoints.OfType<ExplicitProxyEndPoint>()
.Any(x => x.IsSystemHttpProxy || x.IsSystemHttpsProxy);
Expand Down Expand Up @@ -654,8 +654,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)
if (ReuseSocket && RunTime.IsSocketReuseAvailable)
{
endPoint.Listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
Expand Down