From 80ed203258b8ffd01e7c06f2cf2ef6d4d174bd7c Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Sat, 13 Sep 2014 00:39:42 +0200 Subject: [PATCH] Updated HttpResponse to support binary content. --- src/NzbDrone.Common/Http/HttpClient.cs | 10 ++- src/NzbDrone.Common/Http/HttpResponse.cs | 69 ++++++++++++++++--- .../DownloadClientFixtureBase.cs | 4 +- .../IndexerTests/SeasonSearchFixture.cs | 4 +- .../CoverExistsSpecificationFixture.cs | 2 +- .../Download/UsenetClientBase.cs | 5 +- 6 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/NzbDrone.Common/Http/HttpClient.cs b/src/NzbDrone.Common/Http/HttpClient.cs index 708091f09..7aead3467 100644 --- a/src/NzbDrone.Common/Http/HttpClient.cs +++ b/src/NzbDrone.Common/Http/HttpClient.cs @@ -4,6 +4,7 @@ using System.IO; using System.Net; using NLog; using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Common.Extensions; namespace NzbDrone.Common.Http { @@ -73,22 +74,19 @@ namespace NzbDrone.Common.Http httpWebResponse = (HttpWebResponse)e.Response; } - string content = null; + Byte[] data = null; using (var responseStream = httpWebResponse.GetResponseStream()) { if (responseStream != null) { - using (var reader = new StreamReader(responseStream)) - { - content = reader.ReadToEnd(); - } + data = responseStream.ToBytes(); } } stopWatch.Stop(); - var response = new HttpResponse(request, new HttpHeader(httpWebResponse.Headers), content, httpWebResponse.StatusCode); + var response = new HttpResponse(request, new HttpHeader(httpWebResponse.Headers), data, httpWebResponse.StatusCode); _logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds); if (!RuntimeInfoBase.IsProduction && diff --git a/src/NzbDrone.Common/Http/HttpResponse.cs b/src/NzbDrone.Common/Http/HttpResponse.cs index dd75c22cb..f031b4080 100644 --- a/src/NzbDrone.Common/Http/HttpResponse.cs +++ b/src/NzbDrone.Common/Http/HttpResponse.cs @@ -1,24 +1,51 @@ using System; using System.IO; +using System.Linq; using System.Net; +using System.Text; using NzbDrone.Common.Serializer; namespace NzbDrone.Common.Http { public class HttpResponse { - public HttpResponse(HttpRequest request, HttpHeader headers, string content, HttpStatusCode statusCode) + public HttpResponse(HttpRequest request, HttpHeader headers, Byte[] binaryData, HttpStatusCode statusCode = HttpStatusCode.OK) { Request = request; Headers = headers; - Content = content; + ResponseData = binaryData; + StatusCode = statusCode; + } + + public HttpResponse(HttpRequest request, HttpHeader headers, String content, HttpStatusCode statusCode = HttpStatusCode.OK) + { + Request = request; + Headers = headers; + ResponseData = Encoding.UTF8.GetBytes(content); + _content = content; StatusCode = statusCode; } public HttpRequest Request { get; private set; } public HttpHeader Headers { get; private set; } public HttpStatusCode StatusCode { get; private set; } - public string Content { get; private set; } + public Byte[] ResponseData { get; private set; } + + private String _content; + + public String Content + { + get + { + if (_content == null) + { + _content = GetStringFromResponseData(); + } + + return _content; + } + } + public bool HasHttpError { @@ -40,14 +67,34 @@ namespace NzbDrone.Common.Http return result; } - public Stream GetStream() + protected virtual String GetStringFromResponseData() { - var stream = new MemoryStream(); - var writer = new StreamWriter(stream); - writer.Write(Content); - writer.Flush(); - stream.Position = 0; - return stream; + Encoding encoding = null; + + if (Headers.ContentType.IsNotNullOrWhiteSpace()) + { + var charset = Headers.ContentType.ToLowerInvariant() + .Split(';', '=', ' ') + .SkipWhile(v => v != "charset") + .Skip(1).FirstOrDefault(); + + if (charset.IsNotNullOrWhiteSpace()) + { + encoding = Encoding.GetEncoding(charset); + } + } + + if (encoding == null) + { + // TODO: Find encoding by Byte order mask. + } + + if (encoding == null) + { + encoding = Encoding.UTF8; + } + + return encoding.GetString(ResponseData); } } @@ -55,7 +102,7 @@ namespace NzbDrone.Common.Http public class HttpResponse : HttpResponse where T : new() { public HttpResponse(HttpResponse response) - : base(response.Request, response.Headers, response.Content, response.StatusCode) + : base(response.Request, response.Headers, response.ResponseData, response.StatusCode) { Resource = Json.Deserialize(response.Content); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs index 7f44406c8..8113a5012 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs @@ -33,8 +33,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests Mocker.GetMock() - .Setup(c => c.Get(It.IsAny())) - .Returns(new HttpResponse(null, null, "", HttpStatusCode.OK)); + .Setup(s => s.Get(It.IsAny())) + .Returns(r => new HttpResponse(r, new HttpHeader(), new Byte[0])); } diff --git a/src/NzbDrone.Core.Test/IndexerTests/SeasonSearchFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/SeasonSearchFixture.cs index 1d53b9051..1b71181d1 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/SeasonSearchFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/SeasonSearchFixture.cs @@ -24,9 +24,9 @@ namespace NzbDrone.Core.Test.IndexerTests { _series = Builder.CreateNew().Build(); - var response = new HttpResponse(null, new HttpHeader(), "", System.Net.HttpStatusCode.OK); Mocker.GetMock() - .Setup(s => s.Get(It.IsAny())).Returns(response); + .Setup(o => o.Get(It.IsAny())) + .Returns(r => new HttpResponse(r, new HttpHeader(), "")); } private IndexerBase WithIndexer(bool paging, int resultCount) diff --git a/src/NzbDrone.Core.Test/MediaCoverTests/CoverExistsSpecificationFixture.cs b/src/NzbDrone.Core.Test/MediaCoverTests/CoverExistsSpecificationFixture.cs index a839cae22..c5552bbf8 100644 --- a/src/NzbDrone.Core.Test/MediaCoverTests/CoverExistsSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/MediaCoverTests/CoverExistsSpecificationFixture.cs @@ -20,7 +20,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests [SetUp] public void Setup() { - _httpResponse = new HttpResponse(null, new HttpHeader(), null, HttpStatusCode.OK); + _httpResponse = new HttpResponse(null, new HttpHeader(), "", HttpStatusCode.OK); Mocker.GetMock().Setup(c => c.GetFileSize(It.IsAny())).Returns(100); Mocker.GetMock().Setup(c => c.Head(It.IsAny())).Returns(_httpResponse); diff --git a/src/NzbDrone.Core/Download/UsenetClientBase.cs b/src/NzbDrone.Core/Download/UsenetClientBase.cs index 24a79c328..eec17ec23 100644 --- a/src/NzbDrone.Core/Download/UsenetClientBase.cs +++ b/src/NzbDrone.Core/Download/UsenetClientBase.cs @@ -52,10 +52,7 @@ namespace NzbDrone.Core.Download try { - using (var nzb = _httpClient.Get(new HttpRequest(url)).GetStream()) - { - nzbData = nzb.ToBytes(); - } + nzbData = _httpClient.Get(new HttpRequest(url)).ResponseData; } catch (WebException ex) {