Option to disable JSON deserialization (#434)

* Option to disable JSON deserialization

* Fix build errors, add test case

* make new parameter optional

* set default for contentType as well
This commit is contained in:
Stef Heyenrath
2020-03-05 17:59:24 +01:00
committed by GitHub
parent 87c4344d65
commit 88dd1b9aa4
14 changed files with 53 additions and 22 deletions

View File

@@ -68,7 +68,7 @@ namespace WireMock.Http
return client; return client;
} }
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url) public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url, bool deserializeJson)
{ {
Check.NotNull(client, nameof(client)); Check.NotNull(client, nameof(client));
Check.NotNull(requestMessage, nameof(requestMessage)); Check.NotNull(requestMessage, nameof(requestMessage));
@@ -83,7 +83,7 @@ namespace WireMock.Http
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead); var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
// Create ResponseMessage // Create ResponseMessage
return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri); return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson);
} }
} }
} }

View File

@@ -9,7 +9,7 @@ namespace WireMock.Http
{ {
internal static class HttpResponseMessageHelper internal static class HttpResponseMessageHelper
{ {
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri) public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson)
{ {
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode }; var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
@@ -24,7 +24,7 @@ namespace WireMock.Http
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value; contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
} }
responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault()); responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault(), deserializeJson);
} }
foreach (var header in headers) foreach (var header in headers)

View File

@@ -41,5 +41,7 @@ namespace WireMock.Owin
bool? AllowBodyForAllHttpMethods { get; set; } bool? AllowBodyForAllHttpMethods { get; set; }
bool? AllowAnyHttpStatusCodeInResponse { get; set; } bool? AllowAnyHttpStatusCodeInResponse { get; set; }
bool? DisableJsonBodyParsing { get; set; }
} }
} }

View File

@@ -49,7 +49,7 @@ namespace WireMock.Owin.Mappers
BodyData body = null; BodyData body = null;
if (request.Body != null && BodyParser.ShouldParseBody(method, options.AllowBodyForAllHttpMethods == true)) if (request.Body != null && BodyParser.ShouldParseBody(method, options.AllowBodyForAllHttpMethods == true))
{ {
body = await BodyParser.Parse(request.Body, request.ContentType); body = await BodyParser.Parse(request.Body, request.ContentType, !options.DisableJsonBodyParsing.GetValueOrDefault(false));
} }
return new RequestMessage(urldetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow }; return new RequestMessage(urldetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow };

View File

@@ -45,5 +45,8 @@ namespace WireMock.Owin
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowAnyHttpStatusCodeInResponse"/> /// <inheritdoc cref="IWireMockMiddlewareOptions.AllowAnyHttpStatusCodeInResponse"/>
public bool? AllowAnyHttpStatusCodeInResponse { get; set; } public bool? AllowAnyHttpStatusCodeInResponse { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableResponseBodyParsing"/>
public bool? DisableJsonBodyParsing { get; set; }
} }
} }

View File

@@ -366,7 +366,7 @@ namespace WireMock.ResponseBuilders
var proxyUri = new Uri(ProxyUrl); var proxyUri = new Uri(ProxyUrl);
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery); var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri); return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri, !settings.DisableJsonBodyParsing.GetValueOrDefault(false));
} }
if (UseTransformer) if (UseTransformer)

View File

@@ -275,7 +275,7 @@ namespace WireMock.Server
var proxyUri = new Uri(settings.ProxyAndRecordSettings.Url); var proxyUri = new Uri(settings.ProxyAndRecordSettings.Url);
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery); var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri); var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri, !settings.DisableJsonBodyParsing.GetValueOrDefault(false));
if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) && if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
(settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile)) (settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile))

View File

@@ -213,9 +213,10 @@ namespace WireMock.Server
} }
_options.FileSystemHandler = _settings.FileSystemHandler; _options.FileSystemHandler = _settings.FileSystemHandler;
_options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit; _options.PreWireMockMiddlewareInit = _settings.PreWireMockMiddlewareInit;
_options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit; _options.PostWireMockMiddlewareInit = _settings.PostWireMockMiddlewareInit;
_options.Logger = _settings.Logger; _options.Logger = _settings.Logger;
_options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing;
_matcherMapper = new MatcherMapper(_settings); _matcherMapper = new MatcherMapper(_settings);
_mappingConverter = new MappingConverter(_matcherMapper); _mappingConverter = new MappingConverter(_matcherMapper);

View File

@@ -143,5 +143,11 @@ namespace WireMock.Settings
/// </summary> /// </summary>
/// [PublicAPI] /// [PublicAPI]
bool? AllowAnyHttpStatusCodeInResponse { get; set; } bool? AllowAnyHttpStatusCodeInResponse { get; set; }
/// <summary>
/// Set to true to disable Json deserialization when processing requests. (default set to false).
/// </summary>
[PublicAPI]
bool? DisableJsonBodyParsing { get; set; }
} }
} }

View File

@@ -104,5 +104,9 @@ namespace WireMock.Settings
/// <inheritdoc cref="IWireMockServerSettings.AllowAnyHttpStatusCodeInResponse"/> /// <inheritdoc cref="IWireMockServerSettings.AllowAnyHttpStatusCodeInResponse"/>
public bool? AllowAnyHttpStatusCodeInResponse { get; set; } public bool? AllowAnyHttpStatusCodeInResponse { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.DisableJsonBodyParsing"/>
[PublicAPI]
public bool? DisableJsonBodyParsing { get; set; }
} }
} }

View File

@@ -35,7 +35,8 @@ namespace WireMock.Settings
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"), RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
AllowCSharpCodeMatcher = parser.GetBoolValue("AllowCSharpCodeMatcher"), AllowCSharpCodeMatcher = parser.GetBoolValue("AllowCSharpCodeMatcher"),
AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods"), AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods"),
AllowAnyHttpStatusCodeInResponse = parser.GetBoolValue("AllowAnyHttpStatusCodeInResponse") AllowAnyHttpStatusCodeInResponse = parser.GetBoolValue("AllowAnyHttpStatusCodeInResponse"),
DisableJsonBodyParsing = parser.GetBoolValue("DisableJsonBodyParsing")
}; };
if (logger != null) if (logger != null)

View File

@@ -108,7 +108,7 @@ namespace WireMock.Util
return BodyType.Bytes; return BodyType.Bytes;
} }
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType) public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType = null, bool deserializeJson = true)
{ {
Check.NotNull(stream, nameof(stream)); Check.NotNull(stream, nameof(stream));
@@ -128,8 +128,6 @@ namespace WireMock.Util
data.BodyAsString = encoding.GetString(data.BodyAsBytes); data.BodyAsString = encoding.GetString(data.BodyAsBytes);
data.Encoding = encoding; data.Encoding = encoding;
data.DetectedBodyType = BodyType.String; data.DetectedBodyType = BodyType.String;
return data;
} }
return data; return data;
@@ -143,7 +141,7 @@ namespace WireMock.Util
data.DetectedBodyType = BodyType.String; data.DetectedBodyType = BodyType.String;
// If string is not null or empty, try to deserialize the string to a JObject // If string is not null or empty, try to deserialize the string to a JObject
if (!string.IsNullOrEmpty(data.BodyAsString)) if (deserializeJson && !string.IsNullOrEmpty(data.BodyAsString))
{ {
try try
{ {

View File

@@ -243,9 +243,9 @@ namespace WireMock.Net.Tests.RequestMatchers
// assign // assign
BodyData bodyData; BodyData bodyData;
if (body is byte[] b) if (body is byte[] b)
bodyData = await BodyParser.Parse(new MemoryStream(b), null); bodyData = await BodyParser.Parse(new MemoryStream(b), null, true);
else if (body is string s) else if (body is string s)
bodyData = await BodyParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(s)), null); bodyData = await BodyParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(s)), null, true);
else else
throw new Exception(); throw new Exception();

View File

@@ -22,7 +22,7 @@ namespace WireMock.Net.Tests.Util
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson)); var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson));
// Act // Act
var body = await BodyParser.Parse(memoryStream, contentType); var body = await BodyParser.Parse(memoryStream, contentType, true);
// Assert // Assert
Check.That(body.BodyAsBytes).IsNotNull(); Check.That(body.BodyAsBytes).IsNotNull();
@@ -41,7 +41,7 @@ namespace WireMock.Net.Tests.Util
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString)); var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
// Act // Act
var body = await BodyParser.Parse(memoryStream, contentType); var body = await BodyParser.Parse(memoryStream, contentType, true);
// Assert // Assert
Check.That(body.BodyAsBytes).IsNotNull(); Check.That(body.BodyAsBytes).IsNotNull();
@@ -61,7 +61,23 @@ namespace WireMock.Net.Tests.Util
var memoryStream = new MemoryStream(content); var memoryStream = new MemoryStream(content);
// act // act
var body = await BodyParser.Parse(memoryStream, null); var body = await BodyParser.Parse(memoryStream, null, true);
// assert
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
}
[Theory]
[InlineData(new byte[] { 34, 97, 34 }, BodyType.String)]
[InlineData(new byte[] { 97 }, BodyType.String)]
[InlineData(new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 }, BodyType.Bytes)]
public async Task BodyParser_Parse_DetectedBodyTypeNoJsonParsing(byte[] content, BodyType detectedBodyType)
{
// arrange
var memoryStream = new MemoryStream(content);
// act
var body = await BodyParser.Parse(memoryStream, null, false);
// assert // assert
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType); Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
@@ -95,7 +111,7 @@ Content-Type: text/html
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body)); var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
// Act // Act
var result = await BodyParser.Parse(memoryStream, contentType); var result = await BodyParser.Parse(memoryStream, contentType, true);
// Assert // Assert
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.String); Check.That(result.DetectedBodyType).IsEqualTo(BodyType.String);
@@ -115,7 +131,7 @@ Content-Type: text/html
var memoryStream = new MemoryStream(Encoding.UTF32.GetBytes(body)); var memoryStream = new MemoryStream(Encoding.UTF32.GetBytes(body));
// Act // Act
var result = await BodyParser.Parse(memoryStream, contentType); var result = await BodyParser.Parse(memoryStream, contentType, true);
// Assert // Assert
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.Bytes); Check.That(result.DetectedBodyType).IsEqualTo(BodyType.Bytes);
@@ -133,7 +149,7 @@ Content-Type: text/html
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString)); var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
// Act // Act
var body = await BodyParser.Parse(memoryStream, contentType); var body = await BodyParser.Parse(memoryStream, contentType, true);
// Assert // Assert
Check.That(body.BodyAsBytes).IsNotNull(); Check.That(body.BodyAsBytes).IsNotNull();