diff --git a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs index 6c6a9d103..1ffbfd35a 100644 --- a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs +++ b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs @@ -17,7 +17,7 @@ namespace NzbDrone.Common.Http.Dispatchers webRequest.Method = request.Method.ToString(); webRequest.UserAgent = UserAgentBuilder.UserAgent; - webRequest.KeepAlive = false; + webRequest.KeepAlive = request.ConnectionKeepAlive; webRequest.AllowAutoRedirect = request.AllowAutoRedirect; webRequest.CookieContainer = cookies; diff --git a/src/NzbDrone.Common/Http/HttpRequest.cs b/src/NzbDrone.Common/Http/HttpRequest.cs index bd4af45e0..0a7bf0b51 100644 --- a/src/NzbDrone.Common/Http/HttpRequest.cs +++ b/src/NzbDrone.Common/Http/HttpRequest.cs @@ -35,6 +35,7 @@ namespace NzbDrone.Common.Http public string ContentSummary { get; set; } public bool SuppressHttpError { get; set; } public bool AllowAutoRedirect { get; set; } + public bool ConnectionKeepAlive { get; set; } public Dictionary Cookies { get; private set; } public bool StoreResponseCookie { get; set; } public TimeSpan RequestTimeout { get; set; } diff --git a/src/NzbDrone.Common/Http/HttpRequestBuilder.cs b/src/NzbDrone.Common/Http/HttpRequestBuilder.cs index d4b3b5c96..38cb24d7e 100644 --- a/src/NzbDrone.Common/Http/HttpRequestBuilder.cs +++ b/src/NzbDrone.Common/Http/HttpRequestBuilder.cs @@ -20,6 +20,7 @@ namespace NzbDrone.Common.Http public HttpHeader Headers { get; private set; } public bool SuppressHttpError { get; set; } public bool AllowAutoRedirect { get; set; } + public bool ConnectionKeepAlive { get; set; } public NetworkCredential NetworkCredential { get; set; } public Dictionary Cookies { get; private set; } public List FormData { get; private set; } @@ -98,6 +99,7 @@ namespace NzbDrone.Common.Http request.Method = Method; request.SuppressHttpError = SuppressHttpError; request.AllowAutoRedirect = AllowAutoRedirect; + request.ConnectionKeepAlive = ConnectionKeepAlive; if (NetworkCredential != null) { @@ -232,6 +234,13 @@ namespace NzbDrone.Common.Http return this; } + public virtual HttpRequestBuilder KeepAlive(bool keepAlive = true) + { + ConnectionKeepAlive = keepAlive; + + return this; + } + public virtual HttpRequestBuilder Post() { Method = HttpMethod.POST; @@ -253,6 +262,19 @@ namespace NzbDrone.Common.Http return this; } + public virtual HttpRequestBuilder AddPrefixQueryParam(string key, object value, bool replace = false) + { + if (replace) + { + QueryParams.RemoveAll(v => v.Key == key); + SuffixQueryParams.RemoveAll(v => v.Key == key); + } + + QueryParams.Insert(0, new KeyValuePair(key, value.ToString())); + + return this; + } + public virtual HttpRequestBuilder AddQueryParam(string key, object value, bool replace = false) { if (replace) diff --git a/src/NzbDrone.Common/Http/HttpResponse.cs b/src/NzbDrone.Common/Http/HttpResponse.cs index 65d9ff47a..1b64c76d7 100644 --- a/src/NzbDrone.Common/Http/HttpResponse.cs +++ b/src/NzbDrone.Common/Http/HttpResponse.cs @@ -61,12 +61,16 @@ namespace NzbDrone.Common.Http { var result = new Dictionary(); - foreach (var cookie in Headers.GetValues("Set-Cookie")) + var setCookieHeaders = Headers.GetValues("Set-Cookie"); + if (setCookieHeaders != null) { - var match = RegexSetCookie.Match(cookie); - if (match.Success) + foreach (var cookie in setCookieHeaders) { - result[match.Groups[1].Value] = match.Groups[2].Value; + var match = RegexSetCookie.Match(cookie); + if (match.Success) + { + result[match.Groups[1].Value] = match.Groups[2].Value; + } } } diff --git a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentProxy.cs b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentProxy.cs index 41d46c531..d23a9059d 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentProxy.cs @@ -158,6 +158,8 @@ namespace NzbDrone.Core.Download.Clients.UTorrent { var requestBuilder = new HttpRequestBuilder(false, settings.Host, settings.Port) .Resource("/gui/") + .KeepAlive() + .SetHeader("Cache-Control", "no-cache") .Accept(HttpAccept.Json); requestBuilder.NetworkCredential = new NetworkCredential(settings.Username, settings.Password); @@ -248,7 +250,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent } requestBuilder.SetCookies(cookies); - requestBuilder.AddQueryParam("token", authToken, true); + requestBuilder.AddPrefixQueryParam("token", authToken, true); } } }