From affd351fdfa2eda27fb5d8b2fb5b25a931c1db25 Mon Sep 17 00:00:00 2001 From: Qstick Date: Mon, 7 Sep 2020 01:10:39 -0400 Subject: [PATCH] Fixed: RestClient does not use global proxy settings --- .../Http/HttpProxySettingsProvider.cs | 4 ++-- .../Notifications/Boxcar/BoxcarProxy.cs | 8 ++++--- .../Notifications/Gotify/GotifyProxy.cs | 9 +++++++- .../Notifications/Join/JoinProxy.cs | 6 +++-- .../PushBullet/PushBulletProxy.cs | 8 ++++--- .../Notifications/Pushover/PushoverProxy.cs | 6 +++-- .../Subsonic/SubsonicServerProxy.cs | 6 +++-- .../Notifications/Telegram/TelegramService.cs | 15 ++++++++----- .../Notifications/Xbmc/XbmcJsonApiProxy.cs | 6 +++-- src/NzbDrone.Core/Rest/IRestClientFactory.cs | 9 ++++++++ src/NzbDrone.Core/Rest/RestClientFactory.cs | 22 ++++++++++++++++--- 11 files changed, 74 insertions(+), 25 deletions(-) create mode 100644 src/NzbDrone.Core/Rest/IRestClientFactory.cs diff --git a/src/NzbDrone.Core/Http/HttpProxySettingsProvider.cs b/src/NzbDrone.Core/Http/HttpProxySettingsProvider.cs index a24370c98..a56bcf2e6 100644 --- a/src/NzbDrone.Core/Http/HttpProxySettingsProvider.cs +++ b/src/NzbDrone.Core/Http/HttpProxySettingsProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net; using NzbDrone.Common.Http; using NzbDrone.Common.Http.Proxy; @@ -49,7 +49,7 @@ namespace NzbDrone.Core.Http 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 utilizing the WebProxy implementation here to save us having to re-implement it. This way we use Microsofts implementation var proxy = new WebProxy(proxySettings.Host + ":" + proxySettings.Port, proxySettings.BypassLocalAddress, proxySettings.BypassListAsArray); return proxy.IsBypassed((Uri)url); diff --git a/src/NzbDrone.Core/Notifications/Boxcar/BoxcarProxy.cs b/src/NzbDrone.Core/Notifications/Boxcar/BoxcarProxy.cs index 9ec8c48dc..deb9d02d2 100644 --- a/src/NzbDrone.Core/Notifications/Boxcar/BoxcarProxy.cs +++ b/src/NzbDrone.Core/Notifications/Boxcar/BoxcarProxy.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net; using FluentValidation.Results; using NLog; @@ -17,10 +17,12 @@ namespace NzbDrone.Core.Notifications.Boxcar public class BoxcarProxy : IBoxcarProxy { private const string URL = "https://new.boxcar.io/api/notifications"; + private readonly IRestClientFactory _restClientFactory; private readonly Logger _logger; - public BoxcarProxy(Logger logger) + public BoxcarProxy(IRestClientFactory restClientFactory, Logger logger) { + _restClientFactory = restClientFactory; _logger = logger; } @@ -71,7 +73,7 @@ namespace NzbDrone.Core.Notifications.Boxcar { try { - var client = RestClientFactory.BuildClient(URL); + var client = _restClientFactory.BuildClient(URL); request.AddParameter("user_credentials", settings.Token); request.AddParameter("notification[title]", title); diff --git a/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs b/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs index a6e711516..15a1c40d4 100644 --- a/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs +++ b/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs @@ -10,9 +10,16 @@ namespace NzbDrone.Core.Notifications.Gotify public class GotifyProxy : IGotifyProxy { + private readonly IRestClientFactory _restClientFactory; + + public GotifyProxy(IRestClientFactory restClientFactory) + { + _restClientFactory = restClientFactory; + } + 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); request.AddQueryParameter("token", settings.AppToken); diff --git a/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs b/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs index 43cc73945..7ba3b467d 100644 --- a/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs +++ b/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs @@ -17,10 +17,12 @@ namespace NzbDrone.Core.Notifications.Join public class JoinProxy : IJoinProxy { private const string URL = "https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush?"; + private readonly IRestClientFactory _restClientFactory; private readonly Logger _logger; - public JoinProxy(Logger logger) + public JoinProxy(IRestClientFactory restClientFactory, Logger logger) { + _restClientFactory = restClientFactory; _logger = logger; } @@ -73,7 +75,7 @@ namespace NzbDrone.Core.Notifications.Join 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()) { diff --git a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs index 0bce61c61..fae2b2324 100644 --- a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs +++ b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs @@ -23,10 +23,12 @@ namespace NzbDrone.Core.Notifications.PushBullet { private const string PUSH_URL = "https://api.pushbullet.com/v2/pushes"; private const string DEVICE_URL = "https://api.pushbullet.com/v2/devices"; + private readonly IRestClientFactory _restClientFactory; private readonly Logger _logger; - public PushBulletProxy(Logger logger) + public PushBulletProxy(IRestClientFactory restClientFactory, Logger logger) { + _restClientFactory = restClientFactory; _logger = logger; } @@ -96,7 +98,7 @@ namespace NzbDrone.Core.Notifications.PushBullet { try { - var client = RestClientFactory.BuildClient(DEVICE_URL); + var client = _restClientFactory.BuildClient(DEVICE_URL); var request = new RestRequest(Method.GET); client.Authenticator = new HttpBasicAuthenticator(settings.ApiKey, string.Empty); @@ -174,7 +176,7 @@ namespace NzbDrone.Core.Notifications.PushBullet { try { - var client = RestClientFactory.BuildClient(PUSH_URL); + var client = _restClientFactory.BuildClient(PUSH_URL); request.AddParameter("type", "note"); request.AddParameter("title", title); diff --git a/src/NzbDrone.Core/Notifications/Pushover/PushoverProxy.cs b/src/NzbDrone.Core/Notifications/Pushover/PushoverProxy.cs index 8fcfc45bf..0b57684e1 100644 --- a/src/NzbDrone.Core/Notifications/Pushover/PushoverProxy.cs +++ b/src/NzbDrone.Core/Notifications/Pushover/PushoverProxy.cs @@ -16,16 +16,18 @@ namespace NzbDrone.Core.Notifications.Pushover public class PushoverProxy : IPushoverProxy { private const string URL = "https://api.pushover.net/1/messages.json"; + private readonly IRestClientFactory _restClientFactory; private readonly Logger _logger; - public PushoverProxy(Logger logger) + public PushoverProxy(IRestClientFactory restClientFactory, Logger logger) { + _restClientFactory = restClientFactory; _logger = logger; } 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); request.AddParameter("token", settings.ApiKey); request.AddParameter("user", settings.UserKey); diff --git a/src/NzbDrone.Core/Notifications/Subsonic/SubsonicServerProxy.cs b/src/NzbDrone.Core/Notifications/Subsonic/SubsonicServerProxy.cs index 7b0a71632..f285b4a73 100644 --- a/src/NzbDrone.Core/Notifications/Subsonic/SubsonicServerProxy.cs +++ b/src/NzbDrone.Core/Notifications/Subsonic/SubsonicServerProxy.cs @@ -18,10 +18,12 @@ namespace NzbDrone.Core.Notifications.Subsonic public class SubsonicServerProxy : ISubsonicServerProxy { + private readonly IRestClientFactory _restClientFactory; private readonly Logger _logger; - public SubsonicServerProxy(Logger logger) + public SubsonicServerProxy(IRestClientFactory restClientFactory, Logger logger) { + _restClientFactory = restClientFactory; _logger = logger; } @@ -78,7 +80,7 @@ namespace NzbDrone.Core.Notifications.Subsonic private RestClient GetSubsonicServerClient(SubsonicSettings settings) { - return RestClientFactory.BuildClient(GetBaseUrl(settings, "rest")); + return _restClientFactory.BuildClient(GetBaseUrl(settings, "rest")); } private RestRequest GetSubsonicServerRequest(string resource, Method method, SubsonicSettings settings) diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramService.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramService.cs index 7436d852a..15f3f5fca 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/TelegramService.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramService.cs @@ -19,10 +19,12 @@ namespace NzbDrone.Core.Notifications.Telegram public class TelegramProxy : ITelegramProxy { private const string URL = "https://api.telegram.org"; + private readonly IRestClientFactory _restClientFactory; private readonly Logger _logger; - public TelegramProxy(Logger logger) + public TelegramProxy(IRestClientFactory restClientFactory, Logger logger) { + _restClientFactory = restClientFactory; _logger = logger; } @@ -30,7 +32,8 @@ namespace NzbDrone.Core.Notifications.Telegram { //Format text to add the title before and bold using markdown var text = $"{HttpUtility.HtmlEncode(title)}\n{HttpUtility.HtmlEncode(message)}"; - var client = RestClientFactory.BuildClient(URL); + var client = _restClientFactory.BuildClient(URL); + var request = new RestRequest("bot{token}/sendmessage", Method.POST); request.AddUrlSegment("token", settings.BotToken); @@ -55,9 +58,11 @@ namespace NzbDrone.Core.Notifications.Telegram { _logger.Error(ex, "Unable to send test message"); - var restException = ex as RestException; - - if (restException != null && restException.Response.StatusCode == HttpStatusCode.BadRequest) + if (ex is WebException webException) + { + return new ValidationFailure("Connection", $"{webException.Status.ToString()}: {webException.Message}"); + } + else if (ex is RestException restException && restException.Response.StatusCode == HttpStatusCode.BadRequest) { var error = Json.Deserialize(restException.Response.Content); var property = error.Description.ContainsIgnoreCase("chat not found") ? "ChatId" : "BotToken"; diff --git a/src/NzbDrone.Core/Notifications/Xbmc/XbmcJsonApiProxy.cs b/src/NzbDrone.Core/Notifications/Xbmc/XbmcJsonApiProxy.cs index 3b238e600..5735aee7a 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/XbmcJsonApiProxy.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/XbmcJsonApiProxy.cs @@ -21,10 +21,12 @@ namespace NzbDrone.Core.Notifications.Xbmc public class XbmcJsonApiProxy : IXbmcJsonApiProxy { + private readonly IRestClientFactory _restClientFactory; private readonly Logger _logger; - public XbmcJsonApiProxy(Logger logger) + public XbmcJsonApiProxy(IRestClientFactory restClientFactory, Logger logger) { + _restClientFactory = restClientFactory; _logger = logger; } @@ -110,7 +112,7 @@ namespace NzbDrone.Core.Notifications.Xbmc private IRestClient BuildClient(XbmcSettings settings) { var url = string.Format(@"http://{0}/jsonrpc", settings.Address); - var client = RestClientFactory.BuildClient(url); + var client = _restClientFactory.BuildClient(url); if (!settings.Username.IsNullOrWhiteSpace()) { diff --git a/src/NzbDrone.Core/Rest/IRestClientFactory.cs b/src/NzbDrone.Core/Rest/IRestClientFactory.cs new file mode 100644 index 000000000..84547fab1 --- /dev/null +++ b/src/NzbDrone.Core/Rest/IRestClientFactory.cs @@ -0,0 +1,9 @@ +using RestSharp; + +namespace NzbDrone.Core.Rest +{ + public interface IRestClientFactory + { + RestClient BuildClient(string baseUrl); + } +} diff --git a/src/NzbDrone.Core/Rest/RestClientFactory.cs b/src/NzbDrone.Core/Rest/RestClientFactory.cs index 6990fb8fb..2614840c8 100644 --- a/src/NzbDrone.Core/Rest/RestClientFactory.cs +++ b/src/NzbDrone.Core/Rest/RestClientFactory.cs @@ -1,17 +1,33 @@ -using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Common.Http.Proxy; using RestSharp; 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) { UserAgent = $"{BuildInfo.AppName}/{BuildInfo.Version} ({OsInfo.Os})" }; + var proxySettings = _httpProxySettingsProvider.GetProxySettings(); + if (proxySettings != null) + { + restClient.Proxy = _createManagedWebProxy.GetWebProxy(proxySettings); + } + return restClient; } }