New: Use native .NET socks proxy

This commit is contained in:
Qstick
2021-11-17 22:33:39 -06:00
parent c35e257a82
commit f5cb81951a
4 changed files with 47 additions and 109 deletions

View File

@@ -1,9 +1,5 @@
using System; using System;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets;
using com.LandonKey.SocksWebProxy;
using com.LandonKey.SocksWebProxy.Proxy;
using NzbDrone.Common.Cache; using NzbDrone.Common.Cache;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
@@ -33,54 +29,37 @@ namespace NzbDrone.Common.Http.Proxy
} }
private IWebProxy CreateWebProxy(HttpProxySettings proxySettings) private IWebProxy CreateWebProxy(HttpProxySettings proxySettings)
{
var uri = GetProxyUri(proxySettings);
if (uri == null)
{
return null;
}
if (proxySettings.Username.IsNotNullOrWhiteSpace() && proxySettings.Password.IsNotNullOrWhiteSpace())
{
return new WebProxy(uri, proxySettings.BypassLocalAddress, proxySettings.BypassListAsArray, new NetworkCredential(proxySettings.Username, proxySettings.Password));
}
else
{
return new WebProxy(uri, proxySettings.BypassLocalAddress, proxySettings.BypassListAsArray);
}
}
private Uri GetProxyUri(HttpProxySettings proxySettings)
{ {
switch (proxySettings.Type) switch (proxySettings.Type)
{ {
case ProxyType.Http: case ProxyType.Http:
if (proxySettings.Username.IsNotNullOrWhiteSpace() && proxySettings.Password.IsNotNullOrWhiteSpace()) return new Uri("http://" + proxySettings.Host + ":" + proxySettings.Port);
{
return new WebProxy(proxySettings.Host + ":" + proxySettings.Port, proxySettings.BypassLocalAddress, proxySettings.BypassListAsArray, new NetworkCredential(proxySettings.Username, proxySettings.Password));
}
else
{
return new WebProxy(proxySettings.Host + ":" + proxySettings.Port, proxySettings.BypassLocalAddress, proxySettings.BypassListAsArray);
}
case ProxyType.Socks4: case ProxyType.Socks4:
return new SocksWebProxy(new ProxyConfig(IPAddress.Loopback, GetNextFreePort(), GetProxyIpAddress(proxySettings.Host), proxySettings.Port, ProxyConfig.SocksVersion.Four, proxySettings.Username, proxySettings.Password), false); return new Uri("socks4://" + proxySettings.Host + ":" + proxySettings.Port);
case ProxyType.Socks5: case ProxyType.Socks5:
return new SocksWebProxy(new ProxyConfig(IPAddress.Loopback, GetNextFreePort(), GetProxyIpAddress(proxySettings.Host), proxySettings.Port, ProxyConfig.SocksVersion.Five, proxySettings.Username, proxySettings.Password), false); return new Uri("socks5://" + proxySettings.Host + ":" + proxySettings.Port);
default:
return null;
} }
return null;
}
private static IPAddress GetProxyIpAddress(string host)
{
IPAddress ipAddress;
if (!IPAddress.TryParse(host, out ipAddress))
{
try
{
ipAddress = Dns.GetHostEntry(host).AddressList.OrderByDescending(a => a.AddressFamily == AddressFamily.InterNetwork).First();
}
catch (Exception e)
{
throw new InvalidOperationException(string.Format("Unable to resolve proxy hostname '{0}' to a valid IP address.", host), e);
}
}
return ipAddress;
}
private static int GetNextFreePort()
{
var listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
} }
} }
} }

View File

@@ -4,7 +4,6 @@
<DefineConstants Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64'">ISMUSL</DefineConstants> <DefineConstants Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64'">ISMUSL</DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DotNet4.SocksProxy" Version="1.4.0.1" />
<PackageReference Include="DryIoc.dll" Version="4.8.1" /> <PackageReference Include="DryIoc.dll" Version="4.8.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.2" /> <PackageReference Include="NLog.Extensions.Logging" Version="1.7.2" />

View File

@@ -1,9 +1,5 @@
using System; using System;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets;
using com.LandonKey.SocksWebProxy;
using com.LandonKey.SocksWebProxy.Proxy;
using NLog; using NLog;
using NzbDrone.Common.Cloud; using NzbDrone.Common.Cloud;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
@@ -22,13 +18,20 @@ namespace NzbDrone.Core.IndexerProxies.Socks4
public override string Name => "Socks4"; public override string Name => "Socks4";
public override HttpRequest PreRequest(HttpRequest request) public override HttpRequest PreRequest(HttpRequest request)
{ {
var uri = GetProxyUri(Settings);
if (uri == null)
{
return null;
}
if (Settings.Username.IsNotNullOrWhiteSpace() && Settings.Password.IsNotNullOrWhiteSpace()) if (Settings.Username.IsNotNullOrWhiteSpace() && Settings.Password.IsNotNullOrWhiteSpace())
{ {
request.Proxy = new SocksWebProxy(new ProxyConfig(IPAddress.Loopback, GetNextFreePort(), GetProxyIpAddress(Settings.Host), Settings.Port, ProxyConfig.SocksVersion.Four, Settings.Username, Settings.Password), false); request.Proxy = new WebProxy(uri, false, null, new NetworkCredential(Settings.Username, Settings.Password));
} }
else else
{ {
request.Proxy = new SocksWebProxy(new ProxyConfig(IPAddress.Loopback, GetNextFreePort(), GetProxyIpAddress(Settings.Host), Settings.Port, ProxyConfig.SocksVersion.Four), false); request.Proxy = new WebProxy(uri);
} }
_logger.Debug("Applying Socks4 Proxy {0} to request {1}", Name, request.Url); _logger.Debug("Applying Socks4 Proxy {0} to request {1}", Name, request.Url);
@@ -36,32 +39,9 @@ namespace NzbDrone.Core.IndexerProxies.Socks4
return request; return request;
} }
private static int GetNextFreePort() private Uri GetProxyUri(Socks4Settings proxySettings)
{ {
var listener = new TcpListener(IPAddress.Loopback, 0); return new Uri("socks4://" + proxySettings.Host + ":" + proxySettings.Port);
listener.Start();
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
}
private static IPAddress GetProxyIpAddress(string host)
{
IPAddress ipAddress;
if (!IPAddress.TryParse(host, out ipAddress))
{
try
{
ipAddress = Dns.GetHostEntry(host).AddressList.OrderByDescending(a => a.AddressFamily == AddressFamily.InterNetwork).First();
}
catch (Exception e)
{
throw new InvalidOperationException(string.Format("Unable to resolve proxy hostname '{0}' to a valid IP address.", host), e);
}
}
return ipAddress;
} }
} }
} }

View File

@@ -1,9 +1,5 @@
using System; using System;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets;
using com.LandonKey.SocksWebProxy;
using com.LandonKey.SocksWebProxy.Proxy;
using NLog; using NLog;
using NzbDrone.Common.Cloud; using NzbDrone.Common.Cloud;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
@@ -23,13 +19,20 @@ namespace NzbDrone.Core.IndexerProxies.Socks5
public override HttpRequest PreRequest(HttpRequest request) public override HttpRequest PreRequest(HttpRequest request)
{ {
var uri = GetProxyUri(Settings);
if (uri == null)
{
return null;
}
if (Settings.Username.IsNotNullOrWhiteSpace() && Settings.Password.IsNotNullOrWhiteSpace()) if (Settings.Username.IsNotNullOrWhiteSpace() && Settings.Password.IsNotNullOrWhiteSpace())
{ {
request.Proxy = new SocksWebProxy(new ProxyConfig(IPAddress.Loopback, GetNextFreePort(), GetProxyIpAddress(Settings.Host), Settings.Port, ProxyConfig.SocksVersion.Five, Settings.Username, Settings.Password), false); request.Proxy = new WebProxy(uri, false, null, new NetworkCredential(Settings.Username, Settings.Password));
} }
else else
{ {
request.Proxy = new SocksWebProxy(new ProxyConfig(IPAddress.Loopback, GetNextFreePort(), GetProxyIpAddress(Settings.Host), Settings.Port, ProxyConfig.SocksVersion.Five), false); request.Proxy = new WebProxy(uri);
} }
_logger.Debug("Applying Socks5 Proxy {0} to request {1}", Name, request.Url); _logger.Debug("Applying Socks5 Proxy {0} to request {1}", Name, request.Url);
@@ -37,32 +40,9 @@ namespace NzbDrone.Core.IndexerProxies.Socks5
return request; return request;
} }
private static int GetNextFreePort() private Uri GetProxyUri(Socks5Settings proxySettings)
{ {
var listener = new TcpListener(IPAddress.Loopback, 0); return new Uri("socks5://" + proxySettings.Host + ":" + proxySettings.Port);
listener.Start();
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
}
private static IPAddress GetProxyIpAddress(string host)
{
IPAddress ipAddress;
if (!IPAddress.TryParse(host, out ipAddress))
{
try
{
ipAddress = Dns.GetHostEntry(host).AddressList.OrderByDescending(a => a.AddressFamily == AddressFamily.InterNetwork).First();
}
catch (Exception e)
{
throw new InvalidOperationException(string.Format("Unable to resolve proxy hostname '{0}' to a valid IP address.", host), e);
}
}
return ipAddress;
} }
} }
} }