Fixed: RestClient does not use global proxy settings

This commit is contained in:
Петр Шургалин 2020-01-16 13:38:26 +03:00 committed by Taloth
parent 10dc884fa8
commit b19d665817
11 changed files with 88 additions and 33 deletions

View File

@ -3,5 +3,6 @@ namespace NzbDrone.Common.Http.Proxy
public interface IHttpProxySettingsProvider public interface IHttpProxySettingsProvider
{ {
HttpProxySettings GetProxySettings(HttpRequest request); HttpProxySettings GetProxySettings(HttpRequest request);
HttpProxySettings GetProxySettings();
} }
} }

View File

@ -17,18 +17,9 @@ namespace NzbDrone.Core.Http
public HttpProxySettings GetProxySettings(HttpRequest request) public HttpProxySettings GetProxySettings(HttpRequest request)
{ {
if (!_configService.ProxyEnabled) var proxySettings = GetProxySettings();
{ if (proxySettings == null)
return null; return null;
}
var proxySettings = new HttpProxySettings(_configService.ProxyType,
_configService.ProxyHostname,
_configService.ProxyPort,
_configService.ProxyBypassFilter,
_configService.ProxyBypassLocalAddresses,
_configService.ProxyUsername,
_configService.ProxyPassword);
if (ShouldProxyBeBypassed(proxySettings, request.Url)) if (ShouldProxyBeBypassed(proxySettings, request.Url))
{ {
@ -38,6 +29,22 @@ namespace NzbDrone.Core.Http
return proxySettings; return proxySettings;
} }
public HttpProxySettings GetProxySettings()
{
if (!_configService.ProxyEnabled)
{
return null;
}
return new HttpProxySettings(_configService.ProxyType,
_configService.ProxyHostname,
_configService.ProxyPort,
_configService.ProxyBypassFilter,
_configService.ProxyBypassLocalAddresses,
_configService.ProxyUsername,
_configService.ProxyPassword);
}
public bool ShouldProxyBeBypassed(HttpProxySettings proxySettings, HttpUri url) public bool ShouldProxyBeBypassed(HttpProxySettings proxySettings, HttpUri url)
{ {
//We are utilising the WebProxy implementation here to save us having to reimplement it. This way we use Microsofts implementation //We are utilising the WebProxy implementation here to save us having to reimplement it. This way we use Microsofts implementation

View File

@ -16,11 +16,13 @@ namespace NzbDrone.Core.Notifications.Boxcar
public class BoxcarProxy : IBoxcarProxy public class BoxcarProxy : IBoxcarProxy
{ {
private readonly IRestClientFactory _restClientFactory;
private readonly Logger _logger; private readonly Logger _logger;
private const string URL = "https://new.boxcar.io/api/notifications"; private const string URL = "https://new.boxcar.io/api/notifications";
public BoxcarProxy(Logger logger) public BoxcarProxy(IRestClientFactory restClientFactory, Logger logger)
{ {
_restClientFactory = restClientFactory;
_logger = logger; _logger = logger;
} }
@ -71,7 +73,7 @@ namespace NzbDrone.Core.Notifications.Boxcar
{ {
try try
{ {
var client = RestClientFactory.BuildClient(URL); var client = _restClientFactory.BuildClient(URL);
request.AddParameter("user_credentials", settings.Token); request.AddParameter("user_credentials", settings.Token);
request.AddParameter("notification[title]", title); request.AddParameter("notification[title]", title);

View File

@ -10,9 +10,16 @@ namespace NzbDrone.Core.Notifications.Gotify
public class GotifyProxy : IGotifyProxy public class GotifyProxy : IGotifyProxy
{ {
private readonly IRestClientFactory _restClientFactory;
public GotifyProxy(IRestClientFactory restClientFactory)
{
_restClientFactory = restClientFactory;
}
public void SendNotification(string title, string message, GotifySettings settings) public void SendNotification(string title, string message, GotifySettings settings)
{ {
var client = RestClientFactory.BuildClient(settings.Server); var client = _restClientFactory.BuildClient(settings.Server);
var request = new RestRequest("message", Method.POST); var request = new RestRequest("message", Method.POST);
request.AddQueryParameter("token", settings.AppToken); request.AddQueryParameter("token", settings.AppToken);

View File

@ -16,11 +16,13 @@ namespace NzbDrone.Core.Notifications.Join
public class JoinProxy : IJoinProxy public class JoinProxy : IJoinProxy
{ {
private readonly IRestClientFactory _restClientFactory;
private readonly Logger _logger; private readonly Logger _logger;
private const string URL = "https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush?"; private const string URL = "https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush?";
public JoinProxy(Logger logger) public JoinProxy(IRestClientFactory restClientFactory, Logger logger)
{ {
_restClientFactory = restClientFactory;
_logger = logger; _logger = logger;
} }
@ -49,7 +51,7 @@ namespace NzbDrone.Core.Notifications.Join
SendNotification(title, body, settings); SendNotification(title, body, settings);
return null; return null;
} }
catch(JoinInvalidDeviceException ex) catch (JoinInvalidDeviceException ex)
{ {
_logger.Error(ex, "Unable to send test Join message. Invalid Device IDs supplied."); _logger.Error(ex, "Unable to send test Join message. Invalid Device IDs supplied.");
return new ValidationFailure("DeviceIds", "Device IDs appear invalid."); return new ValidationFailure("DeviceIds", "Device IDs appear invalid.");
@ -59,7 +61,7 @@ namespace NzbDrone.Core.Notifications.Join
_logger.Error(ex, "Unable to send test Join message."); _logger.Error(ex, "Unable to send test Join message.");
return new ValidationFailure("ApiKey", ex.Message); return new ValidationFailure("ApiKey", ex.Message);
} }
catch(RestException ex) catch (RestException ex)
{ {
_logger.Error(ex, "Unable to send test Join message. Server connection failed."); _logger.Error(ex, "Unable to send test Join message. Server connection failed.");
return new ValidationFailure("ApiKey", "Unable to connect to Join API. Please try again later."); return new ValidationFailure("ApiKey", "Unable to connect to Join API. Please try again later.");
@ -74,7 +76,7 @@ namespace NzbDrone.Core.Notifications.Join
private void SendNotification(string title, string message, RestRequest request, JoinSettings settings) private void SendNotification(string title, string message, RestRequest request, JoinSettings settings)
{ {
var client = RestClientFactory.BuildClient(URL); var client = _restClientFactory.BuildClient(URL);
if (settings.DeviceNames.IsNotNullOrWhiteSpace()) if (settings.DeviceNames.IsNotNullOrWhiteSpace())
{ {
@ -88,7 +90,7 @@ namespace NzbDrone.Core.Notifications.Join
{ {
request.AddParameter("deviceId", "group.all"); request.AddParameter("deviceId", "group.all");
} }
request.AddParameter("apikey", settings.ApiKey); request.AddParameter("apikey", settings.ApiKey);
request.AddParameter("title", title); request.AddParameter("title", title);
request.AddParameter("text", message); request.AddParameter("text", message);

View File

@ -21,12 +21,14 @@ namespace NzbDrone.Core.Notifications.PushBullet
public class PushBulletProxy : IPushBulletProxy public class PushBulletProxy : IPushBulletProxy
{ {
private readonly IRestClientFactory _restClientFactory;
private readonly Logger _logger; private readonly Logger _logger;
private const string PUSH_URL = "https://api.pushbullet.com/v2/pushes"; private const string PUSH_URL = "https://api.pushbullet.com/v2/pushes";
private const string DEVICE_URL = "https://api.pushbullet.com/v2/devices"; private const string DEVICE_URL = "https://api.pushbullet.com/v2/devices";
public PushBulletProxy(Logger logger) public PushBulletProxy(IRestClientFactory restClientFactory, Logger logger)
{ {
_restClientFactory = restClientFactory;
_logger = logger; _logger = logger;
} }
@ -96,7 +98,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
{ {
try try
{ {
var client = RestClientFactory.BuildClient(DEVICE_URL); var client = _restClientFactory.BuildClient(DEVICE_URL);
var request = new RestRequest(Method.GET); var request = new RestRequest(Method.GET);
client.Authenticator = new HttpBasicAuthenticator(settings.ApiKey, string.Empty); client.Authenticator = new HttpBasicAuthenticator(settings.ApiKey, string.Empty);
@ -175,7 +177,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
{ {
try try
{ {
var client = RestClientFactory.BuildClient(PUSH_URL); var client = _restClientFactory.BuildClient(PUSH_URL);
request.AddParameter("type", "note"); request.AddParameter("type", "note");
request.AddParameter("title", title); request.AddParameter("title", title);

View File

@ -15,17 +15,19 @@ namespace NzbDrone.Core.Notifications.Pushover
public class PushoverProxy : IPushoverProxy public class PushoverProxy : IPushoverProxy
{ {
private readonly IRestClientFactory _restClientFactory;
private readonly Logger _logger; private readonly Logger _logger;
private const string URL = "https://api.pushover.net/1/messages.json"; private const string URL = "https://api.pushover.net/1/messages.json";
public PushoverProxy(Logger logger) public PushoverProxy(IRestClientFactory restClientFactory, Logger logger)
{ {
_restClientFactory = restClientFactory;
_logger = logger; _logger = logger;
} }
public void SendNotification(string title, string message, PushoverSettings settings) public void SendNotification(string title, string message, PushoverSettings settings)
{ {
var client = RestClientFactory.BuildClient(URL); var client = _restClientFactory.BuildClient(URL);
var request = new RestRequest(Method.POST); var request = new RestRequest(Method.POST);
request.AddParameter("token", settings.ApiKey); request.AddParameter("token", settings.ApiKey);
request.AddParameter("user", settings.UserKey); request.AddParameter("user", settings.UserKey);

View File

@ -4,6 +4,7 @@ using FluentValidation.Results;
using NLog; using NLog;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
using NzbDrone.Common.Http.Proxy;
using RestSharp; using RestSharp;
using NzbDrone.Core.Rest; using NzbDrone.Core.Rest;
using System.Web; using System.Web;
@ -18,11 +19,13 @@ namespace NzbDrone.Core.Notifications.Telegram
public class TelegramProxy : ITelegramProxy public class TelegramProxy : ITelegramProxy
{ {
private readonly IRestClientFactory _restClientFactory;
private readonly Logger _logger; private readonly Logger _logger;
private const string URL = "https://api.telegram.org"; private const string URL = "https://api.telegram.org";
public TelegramProxy(Logger logger) public TelegramProxy(IRestClientFactory restClientFactory, Logger logger)
{ {
_restClientFactory = restClientFactory;
_logger = logger; _logger = logger;
} }
@ -30,7 +33,8 @@ namespace NzbDrone.Core.Notifications.Telegram
{ {
//Format text to add the title before and bold using markdown //Format text to add the title before and bold using markdown
var text = $"<b>{HttpUtility.HtmlEncode(title)}</b>\n{HttpUtility.HtmlEncode(message)}"; var text = $"<b>{HttpUtility.HtmlEncode(title)}</b>\n{HttpUtility.HtmlEncode(message)}";
var client = RestClientFactory.BuildClient(URL); var client = _restClientFactory.BuildClient(URL);
var request = new RestRequest("bot{token}/sendmessage", Method.POST); var request = new RestRequest("bot{token}/sendmessage", Method.POST);
request.AddUrlSegment("token", settings.BotToken); request.AddUrlSegment("token", settings.BotToken);
@ -54,9 +58,11 @@ namespace NzbDrone.Core.Notifications.Telegram
{ {
_logger.Error(ex, "Unable to send test message"); _logger.Error(ex, "Unable to send test message");
var restException = ex as RestException; if (ex is WebException webException)
{
if (restException != null && restException.Response.StatusCode == HttpStatusCode.BadRequest) return new ValidationFailure("Connection", $"{webException.Status.ToString()}: {webException.Message}");
}
else if (ex is RestException restException && restException.Response.StatusCode == HttpStatusCode.BadRequest)
{ {
var error = Json.Deserialize<TelegramError>(restException.Response.Content); var error = Json.Deserialize<TelegramError>(restException.Response.Content);
var property = error.Description.ContainsIgnoreCase("chat not found") ? "ChatId" : "BotToken"; var property = error.Description.ContainsIgnoreCase("chat not found") ? "ChatId" : "BotToken";

View File

@ -21,10 +21,12 @@ namespace NzbDrone.Core.Notifications.Xbmc
public class XbmcJsonApiProxy : IXbmcJsonApiProxy public class XbmcJsonApiProxy : IXbmcJsonApiProxy
{ {
private readonly IRestClientFactory _restClientFactory;
private readonly Logger _logger; private readonly Logger _logger;
public XbmcJsonApiProxy(Logger logger) public XbmcJsonApiProxy(IRestClientFactory restClientFactory, Logger logger)
{ {
_restClientFactory = restClientFactory;
_logger = logger; _logger = logger;
} }
@ -110,7 +112,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
private IRestClient BuildClient(XbmcSettings settings) private IRestClient BuildClient(XbmcSettings settings)
{ {
var url = string.Format(@"http://{0}/jsonrpc", settings.Address); var url = string.Format(@"http://{0}/jsonrpc", settings.Address);
var client = RestClientFactory.BuildClient(url); var client = _restClientFactory.BuildClient(url);
if (!settings.Username.IsNullOrWhiteSpace()) if (!settings.Username.IsNullOrWhiteSpace())
{ {

View File

@ -0,0 +1,9 @@
using RestSharp;
namespace NzbDrone.Core.Rest
{
public interface IRestClientFactory
{
RestClient BuildClient(string baseUrl);
}
}

View File

@ -1,17 +1,32 @@
using RestSharp; using RestSharp;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Http.Proxy;
namespace NzbDrone.Core.Rest namespace NzbDrone.Core.Rest
{ {
public static class RestClientFactory public class RestClientFactory : IRestClientFactory
{ {
public static RestClient BuildClient(string baseUrl) private readonly IHttpProxySettingsProvider _httpProxySettingsProvider;
private readonly ICreateManagedWebProxy _createManagedWebProxy;
public RestClientFactory(IHttpProxySettingsProvider httpProxySettingsProvider, ICreateManagedWebProxy createManagedWebProxy)
{
_httpProxySettingsProvider = httpProxySettingsProvider;
_createManagedWebProxy = createManagedWebProxy;
}
public RestClient BuildClient(string baseUrl)
{ {
var restClient = new RestClient(baseUrl) var restClient = new RestClient(baseUrl)
{ {
UserAgent = $"{BuildInfo.AppName}/{BuildInfo.Version} ({OsInfo.Os})" UserAgent = $"{BuildInfo.AppName}/{BuildInfo.Version} ({OsInfo.Os})"
}; };
var proxySettings = _httpProxySettingsProvider.GetProxySettings();
if (proxySettings != null)
{
restClient.Proxy = _createManagedWebProxy.GetWebProxy(proxySettings);
}
return restClient; return restClient;
} }