diff --git a/Octokit.Tests.Integration/HttpClientAdapterTests.cs b/Octokit.Tests.Integration/HttpClientAdapterTests.cs index ead3b4f1..d721c752 100644 --- a/Octokit.Tests.Integration/HttpClientAdapterTests.cs +++ b/Octokit.Tests.Integration/HttpClientAdapterTests.cs @@ -26,7 +26,7 @@ public class HttpClientAdapterTests var response = await httpClient.Send(request, CancellationToken.None); // Spot check some of dem bytes. - var imageBytes = (byte[])response.BodyAsObject; + var imageBytes = (byte[])response.Body; Assert.Equal(137, imageBytes[0]); Assert.Equal(80, imageBytes[1]); Assert.Equal(78, imageBytes[2]); diff --git a/Octokit.Tests/Clients/BlobClientTests.cs b/Octokit.Tests/Clients/BlobClientTests.cs index 3e293ecf..a92bb08f 100644 --- a/Octokit.Tests/Clients/BlobClientTests.cs +++ b/Octokit.Tests/Clients/BlobClientTests.cs @@ -84,7 +84,7 @@ namespace Octokit.Tests.Clients var response = jsonPipeline.DeserializeResponse(httpResponse); Assert.NotNull(response.Body); - Assert.Equal(blobResponseJson, response.HttpResponse.Body); + Assert.Equal(blobResponseJson, (string)response.HttpResponse.Body); Assert.Equal(100, response.Body.Size); Assert.Equal(EncodingType.Utf8, response.Body.Encoding); } diff --git a/Octokit.Tests/Helpers/AssertEx.cs b/Octokit.Tests/Helpers/AssertEx.cs index e8a062d3..5796f7c5 100644 --- a/Octokit.Tests/Helpers/AssertEx.cs +++ b/Octokit.Tests/Helpers/AssertEx.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; using System.Threading.Tasks; using Xunit; -using Xunit.Sdk; namespace Octokit.Tests.Helpers { @@ -47,7 +45,7 @@ namespace Octokit.Tests.Helpers } } - public static void IsReadOnlyCollection(object instance) where T : class + public static void IsReadOnlyCollection(object instance) { var collection = instance as ICollection; // The collection == null case is for .NET 4.0 diff --git a/Octokit.Tests/Http/ApiConnectionTests.cs b/Octokit.Tests/Http/ApiConnectionTests.cs index d4a571a9..4b26c27e 100644 --- a/Octokit.Tests/Http/ApiConnectionTests.cs +++ b/Octokit.Tests/Http/ApiConnectionTests.cs @@ -19,7 +19,7 @@ namespace Octokit.Tests.Http public async Task MakesGetRequestForItem() { var getUri = new Uri("anything", UriKind.Relative); - IApiResponse response = new ApiResponse(new Response { BodyAsObject = new object() }); + IApiResponse response = new ApiResponse(new Response { Body = new object() }); var connection = Substitute.For(); connection.Get(Args.Uri, null, null).Returns(Task.FromResult(response)); var apiConnection = new ApiConnection(connection); @@ -35,7 +35,7 @@ namespace Octokit.Tests.Http { var getUri = new Uri("anything", UriKind.Relative); const string accepts = "custom/accepts"; - IApiResponse response = new ApiResponse(new Response { BodyAsObject = new object() }); + IApiResponse response = new ApiResponse(new Response { Body = new object() }); var connection = Substitute.For(); connection.Get(Args.Uri, null, Args.String).Returns(Task.FromResult(response)); var apiConnection = new ApiConnection(connection); @@ -147,7 +147,7 @@ namespace Octokit.Tests.Http var patchUri = new Uri("anything", UriKind.Relative); var sentData = new object(); var accepts = "custom/accepts"; - IApiResponse response = new ApiResponse(new Response { BodyAsObject = new object() }); + IApiResponse response = new ApiResponse(new Response { Body = new object() }); var connection = Substitute.For(); connection.Patch(Args.Uri, Args.Object, Args.String).Returns(Task.FromResult(response)); var apiConnection = new ApiConnection(connection); @@ -230,7 +230,7 @@ namespace Octokit.Tests.Http { var putUri = new Uri("anything", UriKind.Relative); var sentData = new object(); - IApiResponse response = new ApiResponse(new Response { BodyAsObject = new object() }); + IApiResponse response = new ApiResponse(new Response { Body = new object() }); var connection = Substitute.For(); connection.Put(Args.Uri, Args.Object).Returns(Task.FromResult(response)); var apiConnection = new ApiConnection(connection); @@ -246,7 +246,7 @@ namespace Octokit.Tests.Http { var putUri = new Uri("anything", UriKind.Relative); var sentData = new object(); - IApiResponse response = new ApiResponse(new Response { BodyAsObject = new object() }); + IApiResponse response = new ApiResponse(new Response { Body = new object() }); var connection = Substitute.For(); connection.Put(Args.Uri, Args.Object, "two-factor").Returns(Task.FromResult(response)); var apiConnection = new ApiConnection(connection); diff --git a/Octokit.Tests/Http/HttpClientAdapterTests.cs b/Octokit.Tests/Http/HttpClientAdapterTests.cs index 5dec9fea..e1c76c48 100644 --- a/Octokit.Tests/Http/HttpClientAdapterTests.cs +++ b/Octokit.Tests/Http/HttpClientAdapterTests.cs @@ -146,8 +146,7 @@ namespace Octokit.Tests.Http var response = await tester.BuildResponseTester(responseMessage); - Assert.Equal(new byte[] { 0, 1, 1, 0, 1 }, response.BodyAsObject); - Assert.Null(response.Body); + Assert.Equal(new byte[] { 0, 1, 1, 0, 1 }, response.Body); Assert.Equal("image/png", response.ContentType); } diff --git a/Octokit.Tests/Http/JsonHttpPipelineTests.cs b/Octokit.Tests/Http/JsonHttpPipelineTests.cs index 933bd61b..48f407d9 100644 --- a/Octokit.Tests/Http/JsonHttpPipelineTests.cs +++ b/Octokit.Tests/Http/JsonHttpPipelineTests.cs @@ -120,7 +120,7 @@ namespace Octokit.Tests.Http } [Fact] - public void IgnoresResponsesNotIdentifiedAsJson() + public void IgnoresResponsesNotIdentifiedAsJsonWhenNotDeserializingToString() { const string data = "works"; var httpResponse = new Response @@ -130,7 +130,7 @@ namespace Octokit.Tests.Http }; var jsonPipeline = new JsonHttpPipeline(); - var response = jsonPipeline.DeserializeResponse(httpResponse); + var response = jsonPipeline.DeserializeResponse(httpResponse); Assert.Null(response.Body); } @@ -139,12 +139,12 @@ namespace Octokit.Tests.Http public void DeserializesSingleObjectResponseIntoCollectionWithOneItem() { const string data = "{\"name\":\"Haack\"}"; + var jsonPipeline = new JsonHttpPipeline(); var httpResponse = new Response { Body = data, ContentType = "application/json" }; - var jsonPipeline = new JsonHttpPipeline(); var response = jsonPipeline.DeserializeResponse>(httpResponse); diff --git a/Octokit/Exceptions/ApiException.cs b/Octokit/Exceptions/ApiException.cs index 7185f63c..97c7a809 100644 --- a/Octokit/Exceptions/ApiException.cs +++ b/Octokit/Exceptions/ApiException.cs @@ -97,7 +97,7 @@ namespace Octokit static ApiError GetApiErrorFromExceptionMessage(IResponse response) { - string responseBody = response != null ? response.Body : null; + string responseBody = response != null ? response.Body as string : null; return GetApiErrorFromExceptionMessage(responseBody); } diff --git a/Octokit/Http/ApiResponse.cs b/Octokit/Http/ApiResponse.cs index 17d2c904..a83ba12b 100644 --- a/Octokit/Http/ApiResponse.cs +++ b/Octokit/Http/ApiResponse.cs @@ -11,21 +11,22 @@ namespace Octokit.Internal Headers = new Dictionary(); } - public ApiResponse(IResponse response) + public ApiResponse(IResponse response) : this(response, GetBodyAsObject(response)) + { + } + + public ApiResponse(IResponse response, T bodyAsObject) { Ensure.ArgumentNotNull(response, "response"); + var body = response.Body is T ? (T)response.Body : default(T); HttpResponse = response; Headers = response.Headers; - Body = (T)response.BodyAsObject; + Body = body; ResponseUri = response.ResponseUri; ApiInfo = response.ApiInfo; StatusCode = response.StatusCode; ContentType = response.ContentType; - } - - public ApiResponse(IResponse response, T bodyAsObject) : this(response) - { Body = bodyAsObject; } @@ -36,5 +37,12 @@ namespace Octokit.Internal public HttpStatusCode StatusCode { get; set; } public IResponse HttpResponse { get; private set; } public string ContentType { get; set; } + + static T GetBodyAsObject(IResponse response) + { + if (response == null) return default(T); + var body = response.Body; + return body is T ? (T)body : default(T); + } } } diff --git a/Octokit/Http/Connection.cs b/Octokit/Http/Connection.cs index 4bbe226d..b953c446 100644 --- a/Octokit/Http/Connection.cs +++ b/Octokit/Http/Connection.cs @@ -416,7 +416,7 @@ namespace Octokit { request.Headers.Add("Accept", "application/vnd.github.html"); var response = await RunRequest(request, CancellationToken.None); - return new ApiResponse(response, response.Body); + return new ApiResponse(response, response.Body as string); } async Task> Run(IRequest request, CancellationToken cancellationToken) @@ -471,7 +471,7 @@ namespace Octokit static Exception GetExceptionForForbidden(IResponse response) { - string body = response.Body ?? ""; + string body = response.Body as string ?? ""; return body.Contains("rate limit exceeded") ? new RateLimitExceededException(response) : body.Contains("number of login attempts exceeded") diff --git a/Octokit/Http/HttpClientAdapter.cs b/Octokit/Http/HttpClientAdapter.cs index 65aa3df9..0ea7f2da 100644 --- a/Octokit/Http/HttpClientAdapter.cs +++ b/Octokit/Http/HttpClientAdapter.cs @@ -68,8 +68,7 @@ namespace Octokit.Internal { Ensure.ArgumentNotNull(responseMessage, "responseMessage"); - string responseBody = null; - object bodyAsObject = null; + object responseBody = null; string contentType = null; using (var content = responseMessage.Content) { @@ -84,7 +83,7 @@ namespace Octokit.Internal } else { - bodyAsObject = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false); + responseBody = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false); } } } @@ -92,7 +91,6 @@ namespace Octokit.Internal var response = new Response { Body = responseBody, - BodyAsObject = bodyAsObject, StatusCode = responseMessage.StatusCode, ContentType = contentType }; diff --git a/Octokit/Http/IResponse.cs b/Octokit/Http/IResponse.cs index 5bba5564..c2e65f72 100644 --- a/Octokit/Http/IResponse.cs +++ b/Octokit/Http/IResponse.cs @@ -17,8 +17,7 @@ namespace Octokit public interface IResponse { - object BodyAsObject { get; set; } - string Body { get; set; } + object Body { get; } Dictionary Headers { get; } Uri ResponseUri { get; set; } ApiInfo ApiInfo { get; set; } diff --git a/Octokit/Http/JsonHttpPipeline.cs b/Octokit/Http/JsonHttpPipeline.cs index 735d742f..09e059ba 100644 --- a/Octokit/Http/JsonHttpPipeline.cs +++ b/Octokit/Http/JsonHttpPipeline.cs @@ -45,9 +45,9 @@ namespace Octokit.Internal if (response.ContentType != null && response.ContentType.Equals("application/json", StringComparison.Ordinal)) { - var body = response.Body; + var body = response.Body as string; // simple json does not support the root node being empty. Will submit a pr but in the mean time.... - if (body != "{}") + if (!String.IsNullOrEmpty(body) && body != "{}") { var typeIsDictionary = typeof(IDictionary).IsAssignableFrom(typeof(T)); var typeIsEnumerable = typeof(IEnumerable).IsAssignableFrom(typeof(T)); diff --git a/Octokit/Http/Response.cs b/Octokit/Http/Response.cs index b9221be5..397b13fe 100644 --- a/Octokit/Http/Response.cs +++ b/Octokit/Http/Response.cs @@ -11,8 +11,7 @@ namespace Octokit.Internal Headers = new Dictionary(); } - public object BodyAsObject { get; set; } - public string Body { get; set; } + public object Body { get; set; } public Dictionary Headers { get; private set; } public Uri ResponseUri { get; set; } public ApiInfo ApiInfo { get; set; }