From 5c485c119ec1d862661633f95ec1f5154326a7e9 Mon Sep 17 00:00:00 2001 From: Atif Aziz Date: Tue, 11 Jun 2019 12:36:18 +0200 Subject: [PATCH] Change to work with non-text HTTP requests & responses (#24) --- src/Cassette/Cassette.cs | 18 +++++++++++------- src/Cassette/Helpers.cs | 28 +++++++++++++++++----------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/Cassette/Cassette.cs b/src/Cassette/Cassette.cs index 19ce721..286d99c 100644 --- a/src/Cassette/Cassette.cs +++ b/src/Cassette/Cassette.cs @@ -83,16 +83,20 @@ public static string GetKey(Request request, CassetteOptions options) string requestMethod = request.Method; string requestUri = request.Headers.ContainsKey(CassetteOptions.ExcludeLastUriSegment) ? request.GetUriWithoutLastSegment() : request.Uri; - string requestBody = request.Headers.ContainsKey(CassetteOptions.ExcludeRequestBody) ? string.Empty : request.Body; - var bytes = Encoding.UTF8.GetBytes(requestMethod + requestUri + requestBody); - using (var sha1 = new SHA1Managed()) + using (var hasher = IncrementalHash.CreateHash(HashAlgorithmName.SHA1)) { - var hash = sha1.ComputeHash(bytes); + hasher.AppendData(Encoding.UTF8.GetBytes(requestMethod + requestUri)); + + if (request.Body != null && !request.Headers.ContainsKey(CassetteOptions.ExcludeRequestBody)) + { + hasher.AppendData(request.Body); + } + return options.KeyPrefix is null ? "" : options.KeyPrefix + options.KeySeparator + requestMethod + options.KeySeparator + requestUri.Replace("http://", "http//").Replace("https://", "https//") + options.KeySeparator - + Convert.ToBase64String(hash); + + Convert.ToBase64String(hasher.GetHashAndReset()); } } } @@ -104,7 +108,7 @@ internal class Request public string Uri { get; set; } public Dictionary> Headers { get; set; } public Dictionary> ContentHeaders { get; set; } - public string Body { get; set; } + public byte[] Body { get; set; } public Version Version { get; set; } } @@ -115,7 +119,7 @@ internal class Response public string ReasonPhrase { get; set; } public Dictionary> Headers { get; set; } public Dictionary> ContentHeaders { get; set; } - public string Body { get; set; } + public byte[] Body { get; set; } public Version Version { get; set; } } } diff --git a/src/Cassette/Helpers.cs b/src/Cassette/Helpers.cs index 1d11ee4..e4241a2 100644 --- a/src/Cassette/Helpers.cs +++ b/src/Cassette/Helpers.cs @@ -18,18 +18,19 @@ public static async Task GetCassetteKey(this HttpRequestMessage httpRequ public static async Task ToRequest(this HttpRequestMessage httpRequest) { - string requestBody = await httpRequest.Content.ToStringAsync(); var request = new Request { Method = httpRequest.Method.ToString(), Uri = httpRequest.RequestUri.ToString(), Version = httpRequest.Version, Headers = httpRequest.Headers.ToDictionary(x => x.Key, v => v.Value), - Body = requestBody }; + if (httpRequest.Content != null) { request.ContentHeaders = httpRequest.Content.Headers.ToDictionary(x => x.Key, v => v.Value); + await httpRequest.Content.LoadIntoBufferAsync(); + request.Body = await httpRequest.Content.ReadAsByteArrayAsync(); } return request; @@ -37,17 +38,22 @@ public static async Task ToRequest(this HttpRequestMessage httpRequest) public static async Task ToResponse(this HttpResponseMessage httpResponse) { - string responseBody = await httpResponse.Content.ToStringAsync(); - - return new Response + var response = new Response { Status = httpResponse.StatusCode, ReasonPhrase = httpResponse.ReasonPhrase, Version = httpResponse.Version, Headers = httpResponse.Headers.ToDictionary(x => x.Key, v => v.Value), - ContentHeaders = httpResponse.Content.Headers.ToDictionary(x => x.Key, v => v.Value), - Body = responseBody }; + + if (httpResponse.Content != null) + { + response.ContentHeaders = httpResponse.Content.Headers.ToDictionary(x => x.Key, v => v.Value); + await httpResponse.Content.LoadIntoBufferAsync(); + response.Body = await httpResponse.Content.ReadAsByteArrayAsync(); + } + + return response; } public static HttpResponseMessage Replay(this byte[] bytes) => bytes.ToCassette().Replay(); @@ -78,14 +84,14 @@ public static HttpRequestMessage ToHttpRequestMessage(this Request request) return httpRequest; } - public static HttpContent ToHttpContent(this string body) + public static HttpContent ToHttpContent(this byte[] body) { - if (!string.IsNullOrEmpty(body)) + if (body is null) { - return new ByteArrayContent(Encoding.UTF8.GetBytes(body)); + return null; } - return null; + return new ByteArrayContent(body); } public static string GetUriWithoutLastSegment(this Request request)