mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-18 07:24:34 +01:00
Added some more tests for JsonMatcher + refactored some code to use nullable (#770)
This commit is contained in:
@@ -15,24 +15,24 @@ namespace WireMock.Admin.Mappings
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The methods
|
||||
/// The method
|
||||
/// </summary>
|
||||
public string Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the headers.
|
||||
/// </summary>
|
||||
public IDictionary<string, string> Headers { get; set; }
|
||||
public IDictionary<string, string>? Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body.
|
||||
/// </summary>
|
||||
public string Body { get; set; }
|
||||
public string? Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body (as JSON object).
|
||||
/// </summary>
|
||||
public object BodyAsJson { get; set; }
|
||||
public object? BodyAsJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use ResponseMessage Transformer.
|
||||
|
||||
@@ -5,60 +5,64 @@ using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Http
|
||||
namespace WireMock.Http;
|
||||
|
||||
internal static class HttpResponseMessageHelper
|
||||
{
|
||||
internal static class HttpResponseMessageHelper
|
||||
public static async Task<ResponseMessage> CreateAsync(
|
||||
HttpResponseMessage httpResponseMessage,
|
||||
Uri requiredUri,
|
||||
Uri originalUri,
|
||||
bool deserializeJson,
|
||||
bool decompressGzipAndDeflate)
|
||||
{
|
||||
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson, bool decompressGzipAndDeflate)
|
||||
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
|
||||
|
||||
// Set both content and response headers, replacing URLs in values
|
||||
var headers = (httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers) ?? Enumerable.Empty<KeyValuePair<string, IEnumerable<string>>>()).ToArray();
|
||||
if (httpResponseMessage.Content != null)
|
||||
{
|
||||
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
|
||||
|
||||
// Set both content and response headers, replacing URLs in values
|
||||
var headers = (httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers) ?? Enumerable.Empty<KeyValuePair<string, IEnumerable<string>>>()).ToArray();
|
||||
if (httpResponseMessage.Content != null)
|
||||
var stream = await httpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
IEnumerable<string>? contentTypeHeader = null;
|
||||
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var stream = await httpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
IEnumerable<string> contentTypeHeader = null;
|
||||
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
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.ParseAsync(bodyParserSettings).ConfigureAwait(false);
|
||||
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
foreach (var header in headers)
|
||||
IEnumerable<string>? contentEncodingHeader = null;
|
||||
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
// If Location header contains absolute redirect URL, and base URL is one that we proxy to,
|
||||
// we need to replace it to original one.
|
||||
if (string.Equals(header.Key, HttpKnownHeaderNames.Location, StringComparison.OrdinalIgnoreCase)
|
||||
&& Uri.TryCreate(header.Value.First(), UriKind.Absolute, out Uri absoluteLocationUri)
|
||||
&& string.Equals(absoluteLocationUri.Host, requiredUri.Host, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var replacedLocationUri = new Uri(originalUri, absoluteLocationUri.PathAndQuery);
|
||||
responseMessage.AddHeader(header.Key, replacedLocationUri.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
responseMessage.AddHeader(header.Key, header.Value.ToArray());
|
||||
}
|
||||
contentEncodingHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = stream,
|
||||
ContentType = contentTypeHeader?.FirstOrDefault(),
|
||||
DeserializeJson = deserializeJson,
|
||||
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
|
||||
DecompressGZipAndDeflate = decompressGzipAndDeflate
|
||||
};
|
||||
responseMessage.BodyData = await BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
foreach (var header in headers)
|
||||
{
|
||||
// If Location header contains absolute redirect URL, and base URL is one that we proxy to,
|
||||
// we need to replace it to original one.
|
||||
if (string.Equals(header.Key, HttpKnownHeaderNames.Location, StringComparison.OrdinalIgnoreCase)
|
||||
&& Uri.TryCreate(header.Value.First(), UriKind.Absolute, out Uri absoluteLocationUri)
|
||||
&& string.Equals(absoluteLocationUri.Host, requiredUri.Host, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var replacedLocationUri = new Uri(originalUri, absoluteLocationUri.PathAndQuery);
|
||||
responseMessage.AddHeader(header.Key, replacedLocationUri.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
responseMessage.AddHeader(header.Key, header.Value.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
@@ -68,9 +68,7 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
|
||||
|
||||
Value = value;
|
||||
_valueAsJToken = ConvertValueToJToken(value);
|
||||
_jTokenConverter = ignoreCase
|
||||
? (Func<JToken, JToken>)Rename
|
||||
: jToken => jToken;
|
||||
_jTokenConverter = ignoreCase ? Rename : jToken => jToken;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace WireMock.Owin.Mappers
|
||||
|
||||
string method = request.Method;
|
||||
|
||||
Dictionary<string, string[]> headers = null;
|
||||
IEnumerable<string> contentEncodingHeader = null;
|
||||
Dictionary<string, string[]>? headers = null;
|
||||
IEnumerable<string>? contentEncodingHeader = null;
|
||||
if (request.Headers.Any())
|
||||
{
|
||||
headers = new Dictionary<string, string[]>();
|
||||
@@ -43,7 +43,7 @@ namespace WireMock.Owin.Mappers
|
||||
}
|
||||
}
|
||||
|
||||
IDictionary<string, string> cookies = null;
|
||||
IDictionary<string, string>? cookies = null;
|
||||
if (request.Cookies.Any())
|
||||
{
|
||||
cookies = new Dictionary<string, string>();
|
||||
@@ -53,7 +53,7 @@ namespace WireMock.Owin.Mappers
|
||||
}
|
||||
}
|
||||
|
||||
IBodyData body = null;
|
||||
IBodyData? body = null;
|
||||
if (request.Body != null && BodyParser.ShouldParseBody(method, options.AllowBodyForAllHttpMethods == true))
|
||||
{
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
|
||||
@@ -4,180 +4,176 @@ using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
using WireMock.Http;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Types;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Util
|
||||
namespace WireMock.Util;
|
||||
|
||||
internal static class BodyParser
|
||||
{
|
||||
internal static class BodyParser
|
||||
private static readonly Encoding DefaultEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
|
||||
private static readonly Encoding[] SupportedBodyAsStringEncodingForMultipart = { DefaultEncoding, Encoding.ASCII };
|
||||
|
||||
/*
|
||||
HEAD - No defined body semantics.
|
||||
GET - No defined body semantics.
|
||||
PUT - Body supported.
|
||||
POST - Body supported.
|
||||
DELETE - No defined body semantics.
|
||||
TRACE - Body not supported.
|
||||
OPTIONS - Body supported but no semantics on usage (maybe in the future).
|
||||
CONNECT - No defined body semantics
|
||||
PATCH - Body supported.
|
||||
*/
|
||||
private static readonly IDictionary<string, bool> BodyAllowedForMethods = new Dictionary<string, bool>
|
||||
{
|
||||
private static readonly Encoding DefaultEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
|
||||
private static readonly Encoding[] SupportedBodyAsStringEncodingForMultipart = { DefaultEncoding, Encoding.ASCII };
|
||||
{ HttpRequestMethods.HEAD, false },
|
||||
{ HttpRequestMethods.GET, false },
|
||||
{ HttpRequestMethods.PUT, true },
|
||||
{ HttpRequestMethods.POST, true },
|
||||
{ HttpRequestMethods.DELETE, true },
|
||||
{ HttpRequestMethods.TRACE, false },
|
||||
{ HttpRequestMethods.OPTIONS, true },
|
||||
{ HttpRequestMethods.CONNECT, false },
|
||||
{ HttpRequestMethods.PATCH, true }
|
||||
};
|
||||
|
||||
/*
|
||||
HEAD - No defined body semantics.
|
||||
GET - No defined body semantics.
|
||||
PUT - Body supported.
|
||||
POST - Body supported.
|
||||
DELETE - No defined body semantics.
|
||||
TRACE - Body not supported.
|
||||
OPTIONS - Body supported but no semantics on usage (maybe in the future).
|
||||
CONNECT - No defined body semantics
|
||||
PATCH - Body supported.
|
||||
*/
|
||||
private static readonly IDictionary<string, bool> BodyAllowedForMethods = new Dictionary<string, bool>
|
||||
private static readonly IStringMatcher[] MultipartContentTypesMatchers = {
|
||||
new WildcardMatcher("multipart/*", true)
|
||||
};
|
||||
|
||||
private static readonly IStringMatcher[] JsonContentTypesMatchers = {
|
||||
new WildcardMatcher("application/json", true),
|
||||
new WildcardMatcher("application/vnd.*+json", true)
|
||||
};
|
||||
|
||||
private static readonly IStringMatcher[] TextContentTypeMatchers =
|
||||
{
|
||||
new WildcardMatcher("text/*", true),
|
||||
new RegexMatcher("^application\\/(java|type)script$", true),
|
||||
new WildcardMatcher("application/*xml", true),
|
||||
new WildcardMatcher("application/x-www-form-urlencoded", true)
|
||||
};
|
||||
|
||||
public static bool ShouldParseBody(string? httpMethod, bool allowBodyForAllHttpMethods)
|
||||
{
|
||||
if (string.IsNullOrEmpty(httpMethod))
|
||||
{
|
||||
{ HttpRequestMethods.HEAD, false },
|
||||
{ HttpRequestMethods.GET, false },
|
||||
{ HttpRequestMethods.PUT, true },
|
||||
{ HttpRequestMethods.POST, true },
|
||||
{ HttpRequestMethods.DELETE, true },
|
||||
{ HttpRequestMethods.TRACE, false },
|
||||
{ HttpRequestMethods.OPTIONS, true },
|
||||
{ HttpRequestMethods.CONNECT, false },
|
||||
{ HttpRequestMethods.PATCH, true }
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
private static readonly IStringMatcher[] MultipartContentTypesMatchers = {
|
||||
new WildcardMatcher("multipart/*", true)
|
||||
};
|
||||
|
||||
private static readonly IStringMatcher[] JsonContentTypesMatchers = {
|
||||
new WildcardMatcher("application/json", true),
|
||||
new WildcardMatcher("application/vnd.*+json", true)
|
||||
};
|
||||
|
||||
private static readonly IStringMatcher[] TextContentTypeMatchers =
|
||||
if (allowBodyForAllHttpMethods)
|
||||
{
|
||||
new WildcardMatcher("text/*", true),
|
||||
new RegexMatcher("^application\\/(java|type)script$", true),
|
||||
new WildcardMatcher("application/*xml", true),
|
||||
new WildcardMatcher("application/x-www-form-urlencoded", true)
|
||||
};
|
||||
|
||||
public static bool ShouldParseBody([CanBeNull] string httpMethod, bool allowBodyForAllHttpMethods)
|
||||
{
|
||||
if (string.IsNullOrEmpty(httpMethod))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (allowBodyForAllHttpMethods)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (BodyAllowedForMethods.TryGetValue(httpMethod.ToUpper(), out bool allowed))
|
||||
{
|
||||
return allowed;
|
||||
}
|
||||
|
||||
// If we don't have any knowledge of this method, we should assume that a body *may*
|
||||
// be present, so we should parse it if it is. Therefore, if a new method is added to
|
||||
// the HTTP Method Registry, we only really need to add it to BodyAllowedForMethods if
|
||||
// we want to make it clear that a body is *not* allowed.
|
||||
return true;
|
||||
}
|
||||
|
||||
public static BodyType DetectBodyTypeFromContentType([CanBeNull] string contentTypeValue)
|
||||
if (BodyAllowedForMethods.TryGetValue(httpMethod!.ToUpper(), out bool allowed))
|
||||
{
|
||||
if (string.IsNullOrEmpty(contentTypeValue) || !MediaTypeHeaderValue.TryParse(contentTypeValue, out MediaTypeHeaderValue contentType))
|
||||
{
|
||||
return BodyType.Bytes;
|
||||
}
|
||||
return allowed;
|
||||
}
|
||||
|
||||
if (TextContentTypeMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
|
||||
{
|
||||
return BodyType.String;
|
||||
}
|
||||
|
||||
if (JsonContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
|
||||
{
|
||||
return BodyType.Json;
|
||||
}
|
||||
|
||||
if (MultipartContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
|
||||
{
|
||||
return BodyType.MultiPart;
|
||||
}
|
||||
// If we don't have any knowledge of this method, we should assume that a body *may*
|
||||
// be present, so we should parse it if it is. Therefore, if a new method is added to
|
||||
// the HTTP Method Registry, we only really need to add it to BodyAllowedForMethods if
|
||||
// we want to make it clear that a body is *not* allowed.
|
||||
return true;
|
||||
}
|
||||
|
||||
public static BodyType DetectBodyTypeFromContentType(string? contentTypeValue)
|
||||
{
|
||||
if (string.IsNullOrEmpty(contentTypeValue) || !MediaTypeHeaderValue.TryParse(contentTypeValue, out MediaTypeHeaderValue contentType))
|
||||
{
|
||||
return BodyType.Bytes;
|
||||
}
|
||||
|
||||
public static async Task<BodyData> ParseAsync([NotNull] BodyParserSettings settings)
|
||||
if (TextContentTypeMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
|
||||
{
|
||||
Guard.NotNull(settings, nameof(settings));
|
||||
return BodyType.String;
|
||||
}
|
||||
|
||||
var bodyWithContentEncoding = await ReadBytesAsync(settings.Stream, settings.ContentEncoding, settings.DecompressGZipAndDeflate).ConfigureAwait(false);
|
||||
var data = new BodyData
|
||||
{
|
||||
BodyAsBytes = bodyWithContentEncoding.Bytes,
|
||||
DetectedCompression = bodyWithContentEncoding.ContentType,
|
||||
DetectedBodyType = BodyType.Bytes,
|
||||
DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(settings.ContentType)
|
||||
};
|
||||
if (JsonContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
|
||||
{
|
||||
return BodyType.Json;
|
||||
}
|
||||
|
||||
// In case of MultiPart: check if the BodyAsBytes is a valid UTF8 or ASCII string, in that case read as String else keep as-is
|
||||
if (data.DetectedBodyTypeFromContentType == BodyType.MultiPart)
|
||||
{
|
||||
if (BytesEncodingUtils.TryGetEncoding(data.BodyAsBytes, out Encoding encoding) &&
|
||||
SupportedBodyAsStringEncodingForMultipart.Select(x => x.Equals(encoding)).Any())
|
||||
{
|
||||
data.BodyAsString = encoding.GetString(data.BodyAsBytes);
|
||||
data.Encoding = encoding;
|
||||
data.DetectedBodyType = BodyType.String;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
if (MultipartContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
|
||||
{
|
||||
return BodyType.MultiPart;
|
||||
}
|
||||
|
||||
// Try to get the body as String
|
||||
try
|
||||
return BodyType.Bytes;
|
||||
}
|
||||
|
||||
public static async Task<BodyData> ParseAsync(BodyParserSettings settings)
|
||||
{
|
||||
Guard.NotNull(settings);
|
||||
|
||||
var bodyWithContentEncoding = await ReadBytesAsync(settings.Stream, settings.ContentEncoding, settings.DecompressGZipAndDeflate).ConfigureAwait(false);
|
||||
var data = new BodyData
|
||||
{
|
||||
BodyAsBytes = bodyWithContentEncoding.Bytes,
|
||||
DetectedCompression = bodyWithContentEncoding.ContentType,
|
||||
DetectedBodyType = BodyType.Bytes,
|
||||
DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(settings.ContentType)
|
||||
};
|
||||
|
||||
// In case of MultiPart: check if the BodyAsBytes is a valid UTF8 or ASCII string, in that case read as String else keep as-is
|
||||
if (data.DetectedBodyTypeFromContentType == BodyType.MultiPart)
|
||||
{
|
||||
if (BytesEncodingUtils.TryGetEncoding(data.BodyAsBytes, out Encoding encoding) &&
|
||||
SupportedBodyAsStringEncodingForMultipart.Select(x => x.Equals(encoding)).Any())
|
||||
{
|
||||
data.BodyAsString = DefaultEncoding.GetString(data.BodyAsBytes);
|
||||
data.Encoding = DefaultEncoding;
|
||||
data.BodyAsString = encoding.GetString(data.BodyAsBytes);
|
||||
data.Encoding = encoding;
|
||||
data.DetectedBodyType = BodyType.String;
|
||||
|
||||
// If string is not null or empty, try to deserialize the string to a JObject
|
||||
if (settings.DeserializeJson && !string.IsNullOrEmpty(data.BodyAsString))
|
||||
{
|
||||
try
|
||||
{
|
||||
data.BodyAsJson = JsonUtils.DeserializeObject(data.BodyAsString);
|
||||
data.DetectedBodyType = BodyType.Json;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// JsonConvert failed, just ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Reading as string failed, just ignore
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static async Task<(string ContentType, byte[] Bytes)> ReadBytesAsync(Stream stream, string contentEncoding = null, bool decompressGZipAndDeflate = true)
|
||||
// Try to get the body as String or Json
|
||||
try
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
data.BodyAsString = DefaultEncoding.GetString(data.BodyAsBytes);
|
||||
data.Encoding = DefaultEncoding;
|
||||
data.DetectedBodyType = BodyType.String;
|
||||
|
||||
// If string is not null or empty, try to deserialize the string to a JObject
|
||||
if (settings.DeserializeJson && !string.IsNullOrEmpty(data.BodyAsString))
|
||||
{
|
||||
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
||||
byte[] data = memoryStream.ToArray();
|
||||
|
||||
string type = contentEncoding?.ToLowerInvariant();
|
||||
if (decompressGZipAndDeflate && (type == "gzip" || type == "deflate"))
|
||||
try
|
||||
{
|
||||
return (type, CompressionUtils.Decompress(type, data));
|
||||
data.BodyAsJson = JsonUtils.DeserializeObject(data.BodyAsString);
|
||||
data.DetectedBodyType = BodyType.Json;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// JsonConvert failed, just ignore.
|
||||
}
|
||||
|
||||
return (null, data);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Reading as string failed, just ignore
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static async Task<(string? ContentType, byte[] Bytes)> ReadBytesAsync(Stream stream, string? contentEncoding = null, bool decompressGZipAndDeflate = true)
|
||||
{
|
||||
using var memoryStream = new MemoryStream();
|
||||
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
||||
byte[] data = memoryStream.ToArray();
|
||||
|
||||
var type = contentEncoding?.ToLowerInvariant();
|
||||
if (decompressGZipAndDeflate && type is "gzip" or "deflate")
|
||||
{
|
||||
return (type, CompressionUtils.Decompress(type, data));
|
||||
}
|
||||
|
||||
return (null, data);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
|
||||
namespace WireMock.Util
|
||||
namespace WireMock.Util;
|
||||
|
||||
internal class BodyParserSettings
|
||||
{
|
||||
internal class BodyParserSettings
|
||||
{
|
||||
public Stream Stream { get; set; }
|
||||
public Stream Stream { get; set; } = null!;
|
||||
|
||||
public string ContentType { get; set; }
|
||||
public string? ContentType { get; set; }
|
||||
|
||||
public string ContentEncoding { get; set; }
|
||||
public string? ContentEncoding { get; set; }
|
||||
|
||||
public bool DecompressGZipAndDeflate { get; set; } = true;
|
||||
public bool DecompressGZipAndDeflate { get; set; } = true;
|
||||
|
||||
public bool DeserializeJson { get; set; } = true;
|
||||
}
|
||||
public bool DeserializeJson { get; set; } = true;
|
||||
}
|
||||
Reference in New Issue
Block a user