mirror of https://github.com/Jackett/Jackett
allow proxy changes without restart
This commit is contained in:
parent
01dec12909
commit
59388a8f80
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,6 +136,7 @@ namespace Jackett.Common.Plumbing
|
|||
config.InstanceId = StringUtil.GenerateRandom(64);
|
||||
configService.SaveConfig(config);
|
||||
}
|
||||
config.ConfigChanged();
|
||||
return config;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
})
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,6 +187,8 @@ namespace Jackett.Controllers.V20
|
|||
serverConfig.BlackholeDir = saveDir;
|
||||
configService.SaveConfig(serverConfig);
|
||||
}
|
||||
|
||||
serverConfig.ConfigChanged();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
|
Loading…
Reference in New Issue