Skip to content

Commit

Permalink
Add support for GZip and Deflate (#439)
Browse files Browse the repository at this point in the history
* gzip - wip

* wip

* tests

* fix gzip and deflate

* CheckIfShouldKillVBCSCompiler

* DisableRequestBodyDecompressing
  • Loading branch information
StefH authored Apr 10, 2020
1 parent a9974a4 commit e91be0a
Show file tree
Hide file tree
Showing 22 changed files with 504 additions and 366 deletions.
31 changes: 10 additions & 21 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (WireMock.Net.StandAlone.NETCoreApp)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build_WireMock.Net.StandAlone.NETCoreApp",
"program": "${workspaceRoot}/examples/WireMock.Net.StandAlone.NETCoreApp/bin/Debug/netcoreapp2.0/WireMock.Net.StandAlone.NETCoreApp.dll",
"args": [],
"cwd": "${workspaceRoot}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}
4 changes: 2 additions & 2 deletions src/WireMock.Net/Http/HttpClientHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static HttpClient CreateHttpClient(IProxyAndRecordSettings settings)
return client;
}

public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url, bool deserializeJson)
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url, bool deserializeJson, bool decompressGzipAndDeflate)
{
Check.NotNull(client, nameof(client));
Check.NotNull(requestMessage, nameof(requestMessage));
Expand All @@ -83,7 +83,7 @@ public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client,
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);

// Create ResponseMessage
return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson);
return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate);
}
}
}
18 changes: 16 additions & 2 deletions src/WireMock.Net/Http/HttpResponseMessageHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace WireMock.Http
{
internal static class HttpResponseMessageHelper
{
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson)
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson, bool decompressGzipAndDeflate)
{
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };

Expand All @@ -24,7 +24,21 @@ public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpRe
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
}

responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault(), deserializeJson);
IEnumerable<string> contentEncodingHeader = null;
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)))
{
contentEncodingHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)).Value;
}

var bodyParserSettings = new BodyParserSettings
{
Stream = stream,
ContentType = contentTypeHeader?.FirstOrDefault(),
DeserializeJson = deserializeJson,
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
DecompressGZipAndDeflate = decompressGzipAndDeflate
};
responseMessage.BodyData = await BodyParser.Parse(bodyParserSettings);
}

foreach (var header in headers)
Expand Down
2 changes: 2 additions & 0 deletions src/WireMock.Net/Owin/IWireMockMiddlewareOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,7 @@ internal interface IWireMockMiddlewareOptions
bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }

bool? DisableJsonBodyParsing { get; set; }

bool? DisableRequestBodyDecompressing { get; set; }
}
}
17 changes: 16 additions & 1 deletion src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WireMock.Http;
using WireMock.Models;
using WireMock.Util;
#if !USE_ASPNETCORE
Expand All @@ -27,12 +28,18 @@ public async Task<RequestMessage> MapAsync(IRequest request, IWireMockMiddleware
string method = request.Method;

Dictionary<string, string[]> headers = null;
IEnumerable<string> contentEncodingHeader = null;
if (request.Headers.Any())
{
headers = new Dictionary<string, string[]>();
foreach (var header in request.Headers)
{
headers.Add(header.Key, header.Value);

if (string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase))
{
contentEncodingHeader = header.Value;
}
}
}

Expand All @@ -49,7 +56,15 @@ public async Task<RequestMessage> MapAsync(IRequest request, IWireMockMiddleware
BodyData body = null;
if (request.Body != null && BodyParser.ShouldParseBody(method, options.AllowBodyForAllHttpMethods == true))
{
body = await BodyParser.Parse(request.Body, request.ContentType, !options.DisableJsonBodyParsing.GetValueOrDefault(false));
var bodyParserSettings = new BodyParserSettings
{
Stream = request.Body,
ContentType = request.ContentType,
DeserializeJson = !options.DisableJsonBodyParsing.GetValueOrDefault(false),
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
DecompressGZipAndDeflate = !options.DisableRequestBodyDecompressing.GetValueOrDefault(false)
};
body = await BodyParser.Parse(bodyParserSettings);
}

return new RequestMessage(urldetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow };
Expand Down
5 changes: 4 additions & 1 deletion src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ internal class WireMockMiddlewareOptions : IWireMockMiddlewareOptions
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowOnlyDefinedHttpStatusCodeInResponse"/>
public bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }

/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableResponseBodyParsing"/>
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableJsonBodyParsing"/>
public bool? DisableJsonBodyParsing { get; set; }

/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableRequestBodyDecompressing"/>
public bool? DisableRequestBodyDecompressing { get; set; }
}
}
6 changes: 6 additions & 0 deletions src/WireMock.Net/RequestMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ public class RequestMessage
/// </summary>
public string DetectedBodyTypeFromContentType { get; }

/// <summary>
/// The detected compression from the Content-Encoding header. Convenience getter for Handlebars.
/// </summary>
public string DetectedCompression { get; }

/// <summary>
/// Gets the Host
/// </summary>
Expand Down Expand Up @@ -170,6 +175,7 @@ public RequestMessage([NotNull] UrlDetails urlDetails, [NotNull] string method,
BodyAsBytes = BodyData?.BodyAsBytes;
DetectedBodyType = BodyData?.DetectedBodyType.ToString();
DetectedBodyTypeFromContentType = BodyData?.DetectedBodyTypeFromContentType.ToString();
DetectedCompression = BodyData?.DetectedCompression;

Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
Cookies = cookies;
Expand Down
8 changes: 7 additions & 1 deletion src/WireMock.Net/ResponseBuilders/Response.cs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,13 @@ public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMe
var proxyUri = new Uri(ProxyUrl);
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);

return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri, !settings.DisableJsonBodyParsing.GetValueOrDefault(false));
return await HttpClientHelper.SendAsync(
_httpClientForProxy,
requestMessage,
proxyUriWithRequestPathAndQuery.AbsoluteUri,
!settings.DisableJsonBodyParsing.GetValueOrDefault(false),
!settings.DisableRequestBodyDecompressing.GetValueOrDefault(false)
);
}

ResponseMessage responseMessage;
Expand Down
8 changes: 7 additions & 1 deletion src/WireMock.Net/Server/WireMockServer.Admin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,13 @@ private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMe
var proxyUri = new Uri(settings.ProxyAndRecordSettings.Url);
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);

var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri, !settings.DisableJsonBodyParsing.GetValueOrDefault(false));
var responseMessage = await HttpClientHelper.SendAsync(
_httpClientForProxy,
requestMessage,
proxyUriWithRequestPathAndQuery.AbsoluteUri,
!settings.DisableJsonBodyParsing.GetValueOrDefault(false),
!settings.DisableRequestBodyDecompressing.GetValueOrDefault(false)
);

if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
(settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile))
Expand Down
Loading

0 comments on commit e91be0a

Please sign in to comment.