allow proxy changes without restart

This commit is contained in:
kaso17 2017-11-17 16:46:58 +01:00
parent 01dec12909
commit 59388a8f80
6 changed files with 177 additions and 94 deletions

View File

@ -9,10 +9,14 @@ using System.Threading.Tasks;
namespace Jackett.Models.Config
{
public class ServerConfig
public class ServerConfig : IObservable<ServerConfig>
{
[JsonIgnore]
protected List<IObserver<ServerConfig>> observers;
public ServerConfig(RuntimeSettings runtimeSettings)
{
observers = new List<IObserver<ServerConfig>>();
Port = 9117;
AllowExternal = System.Environment.OSVersion.Platform == PlatformID.Unix;
RuntimeSettings = runtimeSettings;
@ -109,5 +113,42 @@ namespace Jackett.Models.Config
};
}
}
public IDisposable Subscribe(IObserver<ServerConfig> observer)
{
if (!observers.Contains(observer))
{
observers.Add(observer);
}
return new UnSubscriber(observers, observer);
}
private class UnSubscriber : IDisposable
{
private List<IObserver<ServerConfig>> lstObservers;
private IObserver<ServerConfig> observer;
public UnSubscriber(List<IObserver<ServerConfig>> ObserversCollection, IObserver<ServerConfig> observer)
{
this.lstObservers = ObserversCollection;
this.observer = observer;
}
public void Dispose()
{
if (this.observer != null)
{
lstObservers.Remove(this.observer);
}
}
}
public void ConfigChanged()
{
foreach (var obs in observers)
{
obs.OnNext(this);
}
}
}
}

View File

@ -136,6 +136,7 @@ namespace Jackett.Common.Plumbing
config.InstanceId = StringUtil.GenerateRandom(64);
configService.SaveConfig(config);
}
config.ConfigChanged();
return config;
}

View File

@ -21,32 +21,54 @@ namespace Jackett.Utils.Clients
public class HttpWebClient : WebClient
{
static protected Dictionary<string, ICollection<string>> trustedCertificates = new Dictionary<string, ICollection<string>>();
static protected SocksWebProxy socksWebProxy;
static protected string webProxyUrl;
static protected IWebProxy webProxy;
static public void InitSocksWebProxy(ServerConfig serverConfig)
static public void InitProxy(ServerConfig serverConfig)
{
if (socksWebProxy != null)
// dispose old SocksWebProxy
if (webProxy != null && webProxy is SocksWebProxy)
{
socksWebProxy.Dispose();
((SocksWebProxy)webProxy).Dispose();
webProxy = null;
}
if (serverConfig.ProxyType != ProxyType.Http)
webProxyUrl = serverConfig.GetProxyUrl();
if (!string.IsNullOrWhiteSpace(webProxyUrl))
{
var addresses = Dns.GetHostAddressesAsync(serverConfig.ProxyUrl).Result;
var socksConfig = new ProxyConfig
if (serverConfig.ProxyType != ProxyType.Http)
{
SocksAddress = addresses.FirstOrDefault(),
Username = serverConfig.ProxyUsername,
Password = serverConfig.ProxyPassword,
Version = serverConfig.ProxyType == ProxyType.Socks4 ?
ProxyConfig.SocksVersion.Four :
ProxyConfig.SocksVersion.Five
};
if (serverConfig.ProxyPort.HasValue)
{
socksConfig.SocksPort = serverConfig.ProxyPort.Value;
var addresses = Dns.GetHostAddressesAsync(serverConfig.ProxyUrl).Result;
var socksConfig = new ProxyConfig
{
SocksAddress = addresses.FirstOrDefault(),
Username = serverConfig.ProxyUsername,
Password = serverConfig.ProxyPassword,
Version = serverConfig.ProxyType == ProxyType.Socks4 ?
ProxyConfig.SocksVersion.Four :
ProxyConfig.SocksVersion.Five
};
if (serverConfig.ProxyPort.HasValue)
{
socksConfig.SocksPort = serverConfig.ProxyPort.Value;
}
webProxy = new SocksWebProxy(socksConfig, false);
}
else
{
NetworkCredential creds = null;
if (!serverConfig.ProxyIsAnonymous)
{
var username = serverConfig.ProxyUsername;
var password = serverConfig.ProxyPassword;
creds = new NetworkCredential(username, password);
}
webProxy = new WebProxy(webProxyUrl)
{
BypassProxyOnLocal = false,
Credentials = creds
};
}
socksWebProxy = new SocksWebProxy(socksConfig, false);
}
}
@ -56,8 +78,16 @@ namespace Jackett.Utils.Clients
c: c,
sc: sc)
{
if (socksWebProxy == null)
InitSocksWebProxy(sc);
if (webProxyUrl == null)
InitProxy(sc);
}
// Called everytime the ServerConfig changes
public override void OnNext(ServerConfig value)
{
var newProxyUrl = serverConfig.GetProxyUrl();
if (webProxyUrl != newProxyUrl) // if proxy URL changed
InitProxy(serverConfig);
}
override public void Init()
@ -112,42 +142,16 @@ namespace Jackett.Utils.Clients
}
}
}
var useProxy = false;
using (ClearanceHandler clearanceHandlr = new ClearanceHandler())
{
IWebProxy proxyServer = null;
var proxyUrl = serverConfig.GetProxyUrl();
if (!string.IsNullOrWhiteSpace(proxyUrl))
{
useProxy = true;
if (serverConfig.ProxyType != ProxyType.Http)
{
proxyServer = socksWebProxy;
}
else
{
NetworkCredential creds = null;
if (!serverConfig.ProxyIsAnonymous)
{
var username = serverConfig.ProxyUsername;
var password = serverConfig.ProxyPassword;
creds = new NetworkCredential(username, password);
}
proxyServer = new WebProxy(proxyUrl)
{
BypassProxyOnLocal = false,
Credentials = creds
};
}
}
using (HttpClientHandler clientHandlr = new HttpClientHandler
{
CookieContainer = cookies,
AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
UseCookies = true,
Proxy = proxyServer,
UseProxy = useProxy,
Proxy = webProxy,
UseProxy = (webProxy != null),
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
})
{

View File

@ -33,54 +33,38 @@ namespace Jackett.Utils.Clients
HttpClient client;
static protected Dictionary<string, ICollection<string>> trustedCertificates = new Dictionary<string, ICollection<string>>();
static protected SocksWebProxy socksWebProxy;
static protected string webProxyUrl;
static protected IWebProxy webProxy;
static public void InitSocksWebProxy(ServerConfig serverConfig)
static public void InitProxy(ServerConfig serverConfig)
{
if (socksWebProxy != null)
// dispose old SocksWebProxy
if (webProxy != null && webProxy is SocksWebProxy)
{
socksWebProxy.Dispose();
((SocksWebProxy)webProxy).Dispose();
webProxy = null;
}
if (serverConfig.ProxyType != ProxyType.Http)
webProxyUrl = serverConfig.GetProxyUrl();
if (!string.IsNullOrWhiteSpace(webProxyUrl))
{
var addresses = Dns.GetHostAddressesAsync(serverConfig.ProxyUrl).Result;
var socksConfig = new ProxyConfig
{
SocksAddress = addresses.FirstOrDefault(),
Username = serverConfig.ProxyUsername,
Password = serverConfig.ProxyPassword,
Version = serverConfig.ProxyType == ProxyType.Socks4 ?
ProxyConfig.SocksVersion.Four :
ProxyConfig.SocksVersion.Five
};
if (serverConfig.ProxyPort.HasValue)
{
socksConfig.SocksPort = serverConfig.ProxyPort.Value;
}
socksWebProxy = new SocksWebProxy(socksConfig, false);
}
}
public HttpWebClient2(IProcessService p, Logger l, IConfigurationService c, ServerConfig sc)
: base(p: p,
l: l,
c: c,
sc: sc)
{
if (socksWebProxy == null)
InitSocksWebProxy(sc);
cookies = new CookieContainer();
var useProxy = false;
IWebProxy proxyServer = null;
var proxyUrl = serverConfig.GetProxyUrl();
if (!string.IsNullOrWhiteSpace(proxyUrl))
{
useProxy = true;
if (serverConfig.ProxyType != ProxyType.Http)
{
proxyServer = socksWebProxy;
var addresses = Dns.GetHostAddressesAsync(serverConfig.ProxyUrl).Result;
var socksConfig = new ProxyConfig
{
SocksAddress = addresses.FirstOrDefault(),
Username = serverConfig.ProxyUsername,
Password = serverConfig.ProxyPassword,
Version = serverConfig.ProxyType == ProxyType.Socks4 ?
ProxyConfig.SocksVersion.Four :
ProxyConfig.SocksVersion.Five
};
if (serverConfig.ProxyPort.HasValue)
{
socksConfig.SocksPort = serverConfig.ProxyPort.Value;
}
webProxy = new SocksWebProxy(socksConfig, false);
}
else
{
@ -91,22 +75,38 @@ namespace Jackett.Utils.Clients
var password = serverConfig.ProxyPassword;
creds = new NetworkCredential(username, password);
}
proxyServer = new WebProxy(proxyUrl)
webProxy = new WebProxy(webProxyUrl)
{
BypassProxyOnLocal = false,
Credentials = creds
};
}
}
}
public HttpWebClient2(IProcessService p, Logger l, IConfigurationService c, ServerConfig sc)
: base(p: p,
l: l,
c: c,
sc: sc)
{
if (webProxyUrl == null)
InitProxy(sc);
cookies = new CookieContainer();
CreateClient();
}
public void CreateClient()
{
clearanceHandlr = new ClearanceHandler();
clientHandlr = new HttpClientHandler
{
CookieContainer = cookies,
AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
UseCookies = true,
Proxy = proxyServer,
UseProxy = useProxy,
Proxy = webProxy,
UseProxy = (webProxy != null),
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
@ -114,6 +114,20 @@ namespace Jackett.Utils.Clients
client = new HttpClient(clearanceHandlr);
}
// Called everytime the ServerConfig changes
public override void OnNext(ServerConfig value)
{
var newProxyUrl = serverConfig.GetProxyUrl();
if (webProxyUrl != newProxyUrl) // if proxy URL changed
InitProxy(serverConfig);
// recreate client if needed (can't just change the proxy attribute)
if (!ReferenceEquals(clientHandlr.Proxy, webProxy))
{
CreateClient();
}
}
override public void Init()
{
if (serverConfig.RuntimeSettings.IgnoreSslErrors == true)

View File

@ -13,8 +13,9 @@ using Jackett.Models.Config;
namespace Jackett.Utils.Clients
{
public abstract class WebClient
public abstract class WebClient : IObserver<ServerConfig>
{
protected IDisposable ServerConfigUnsubscriber;
protected Logger logger;
protected IConfigurationService configService;
protected readonly ServerConfig serverConfig;
@ -32,6 +33,10 @@ namespace Jackett.Utils.Clients
}
}
virtual protected void OnConfigChange()
{
}
virtual public void AddTrustedCertificate(string host, string hash)
{
// not implemented by default
@ -44,6 +49,7 @@ namespace Jackett.Utils.Clients
configService = c;
serverConfig = sc;
ClientType = GetType().Name;
ServerConfigUnsubscriber = serverConfig.Subscribe(this);
}
async protected Task DelayRequest(WebRequest request)
@ -165,5 +171,20 @@ namespace Jackett.Utils.Clients
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
abstract public void Init();
public virtual void OnCompleted()
{
throw new NotImplementedException();
}
public virtual void OnError(Exception error)
{
throw new NotImplementedException();
}
public virtual void OnNext(ServerConfig value)
{
// nothing by default
}
}
}

View File

@ -187,6 +187,8 @@ namespace Jackett.Controllers.V20
serverConfig.BlackholeDir = saveDir;
configService.SaveConfig(serverConfig);
}
serverConfig.ConfigChanged();
}
[HttpGet]
@ -195,6 +197,6 @@ namespace Jackett.Controllers.V20
return logCache.Logs;
}
}
}