Compare commits

..

1 Commits

Author SHA1 Message Date
Stef Heyenrath
3e6eb256f5 wip 2020-03-02 13:25:53 +00:00
32 changed files with 204 additions and 436 deletions

View File

@@ -1,16 +1,3 @@
# 1.2.0.0 (14 March 2020)
- [#417](https://github.com/WireMock-Net/WireMock.Net/pull/417) - Let the .NET core/standard WebHostBuilder use a random port [bug] contributed by [StefH](https://github.com/StefH)
- [#422](https://github.com/WireMock-Net/WireMock.Net/pull/422) - AllowOnlyDefinedHttpStatusCodeInResponse [bug] contributed by [StefH](https://github.com/StefH)
- [#379](https://github.com/WireMock-Net/WireMock.Net/issues/379) - Trusting the self signed certificate to enable SSL on dotnet core [bug]
- [#420](https://github.com/WireMock-Net/WireMock.Net/issues/420) - Updating to 1.1.6+ breaks tests because new AllowAnyHttpStatusCodeInResponse option defaults to false [bug]
# 1.1.10 (05 March 2020)
- [#427](https://github.com/WireMock-Net/WireMock.Net/pull/427) - Add UsingOptions, UsingConnect and UsingTrace [feature] contributed by [StefH](https://github.com/StefH)
- [#434](https://github.com/WireMock-Net/WireMock.Net/pull/434) - Option to disable JSON deserialization [feature] contributed by [sebastianmattar](https://github.com/sebastianmattar)
- [#435](https://github.com/WireMock-Net/WireMock.Net/pull/435) - Also call HandlebarsRegistrationCallback when using WithCallback(..) [feature] contributed by [StefH](https://github.com/StefH)
- [#408](https://github.com/WireMock-Net/WireMock.Net/issues/408) - Intermittent threading errors with FindLogEntries [bug]
- [#433](https://github.com/WireMock-Net/WireMock.Net/issues/433) - HandlebarsRegistrationCallback not fired [feature]
# 1.1.9.0 (25 February 2020)
- [#431](https://github.com/WireMock-Net/WireMock.Net/pull/431) - Fix LinqMatcher for JSON int64 [bug] contributed by [StefH](https://github.com/StefH)
- [#425](https://github.com/WireMock-Net/WireMock.Net/issues/425) - Allow 64 bit numbers in JSON [bug]

View File

@@ -4,7 +4,7 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.2.0</VersionPrefix>
<VersionPrefix>1.1.9</VersionPrefix>
</PropertyGroup>
<Choose>

View File

@@ -1,3 +1,3 @@
https://github.com/StefH/GitHubReleaseNotes
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.2.0.0
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.1.9.0

View File

@@ -61,6 +61,8 @@ namespace WireMock.Net.ConsoleApplication
handlebarsContext.RegisterHelper(transformer.Name, transformer.Render);
},
AllowAnyHttpStatusCodeInResponse = true
// Uncomment below if you want to use the CustomFileSystemFileHandler
// FileSystemHandler = new CustomFileSystemFileHandler()
});

View File

@@ -68,7 +68,7 @@ namespace WireMock.Http
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)
{
Check.NotNull(client, nameof(client));
Check.NotNull(requestMessage, nameof(requestMessage));
@@ -83,7 +83,7 @@ namespace WireMock.Http
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);
}
}
}

View File

@@ -1,18 +0,0 @@
namespace WireMock.Http
{
/// <summary>
/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
/// </summary>
internal static class HttpRequestMethods
{
public const string CONNECT = "CONNECT";
public const string DELETE = "DELETE";
public const string GET = "GET";
public const string HEAD = "HEAD";
public const string OPTIONS = "OPTIONS";
public const string PATCH = "PATCH";
public const string POST = "POST";
public const string PUT = "PUT";
public const string TRACE = "TRACE";
}
}

View File

@@ -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)
{
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;
}
responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault(), deserializeJson);
responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
}
foreach (var header in headers)

View File

@@ -20,10 +20,10 @@ namespace WireMock.Owin
{
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly IWireMockMiddlewareOptions _options;
private readonly string[] _urls;
private readonly IWireMockLogger _logger;
private readonly HostUrlOptions _urlOptions;
private Exception _runningException;
private IWebHost _host;
public bool IsStarted { get; private set; }
@@ -34,15 +34,23 @@ namespace WireMock.Owin
public Exception RunningException => _runningException;
public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions)
public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
{
Check.NotNull(options, nameof(options));
Check.NotNull(urlOptions, nameof(urlOptions));
Check.NotNullOrEmpty(uriPrefixes, nameof(uriPrefixes));
_logger = options.Logger ?? new WireMockConsoleLogger();
foreach (string uriPrefix in uriPrefixes)
{
Urls.Add(uriPrefix);
PortUtils.TryExtract(uriPrefix, out string protocol, out string host, out int port);
Ports.Add(port);
}
_options = options;
_urlOptions = urlOptions;
_urls = uriPrefixes;
}
public Task StartAsync()
@@ -78,35 +86,31 @@ namespace WireMock.Owin
})
.UseKestrel(options =>
{
var urlDetails = _urlOptions.GetDetails();
#if NETSTANDARD1_3
var urls = urlDetails.Select(u => u.Url);
if (urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
if (_urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
{
options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
}
#else
foreach (var detail in urlDetails)
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore2x
foreach (string url in _urls.Where(u => u.StartsWith("http://", StringComparison.OrdinalIgnoreCase)))
{
if (detail.Url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
options.Listen(System.Net.IPAddress.Any, port);
}
foreach (string url in _urls.Where(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
{
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
options.Listen(System.Net.IPAddress.Any, port, listenOptions =>
{
options.Listen(System.Net.IPAddress.Any, detail.Port, listenOptions =>
{
listenOptions.UseHttps(); // PublicCertificateHelper.GetX509Certificate2()
});
}
else
{
options.Listen(System.Net.IPAddress.Any, detail.Port);
}
listenOptions.UseHttps(); // PublicCertificateHelper.GetX509Certificate2()
});
}
#endif
})
#if NETSTANDARD1_3
.UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray())
.UseUrls(_urls)
#endif
.Build();
@@ -120,18 +124,6 @@ namespace WireMock.Owin
var appLifetime = (IApplicationLifetime)_host.Services.GetService(typeof(IApplicationLifetime));
appLifetime.ApplicationStarted.Register(() =>
{
var addresses = _host.ServerFeatures
.Get<Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>()
.Addresses;
foreach (string address in addresses)
{
Urls.Add(address.Replace("0.0.0.0", "localhost"));
PortUtils.TryExtract(address, out string protocol, out string host, out int port);
Ports.Add(port);
}
IsStarted = true;
});
@@ -174,5 +166,5 @@ namespace WireMock.Owin
#endif
}
}
}
}
#endif

View File

@@ -1,41 +0,0 @@
using System.Collections.Generic;
using WireMock.Util;
namespace WireMock.Owin
{
internal class HostUrlOptions
{
public ICollection<string> Urls { get; set; }
public bool UseSSL { get; set; }
public ICollection<(string Url, int Port)> GetDetails()
{
var list = new List<(string Url, int Port)>();
if (Urls == null)
{
int port = FindFreeTcpPort();
list.Add(($"{(UseSSL ? "https" : "http")}://localhost:{port}", port));
}
else
{
foreach (string url in Urls)
{
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
list.Add((url, port));
}
}
return list;
}
private int FindFreeTcpPort()
{
#if USE_ASPNETCORE || NETSTANDARD2_0
return 0;
#else
return PortUtils.FindFreeTcpPort();
#endif
}
}
}

View File

@@ -40,8 +40,6 @@ namespace WireMock.Owin
bool? AllowBodyForAllHttpMethods { get; set; }
bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
bool? DisableJsonBodyParsing { get; set; }
bool? AllowAnyHttpStatusCodeInResponse { get; set; }
}
}

View File

@@ -49,7 +49,7 @@ namespace WireMock.Owin.Mappers
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));
body = await BodyParser.Parse(request.Body, request.ContentType);
}
return new RequestMessage(urldetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow };

View File

@@ -104,12 +104,12 @@ namespace WireMock.Owin.Mappers
private int MapStatusCode(int code)
{
if (_options.AllowOnlyDefinedHttpStatusCodeInResponse == true && !Enum.IsDefined(typeof(HttpStatusCode), code))
if (_options.AllowAnyHttpStatusCodeInResponse == true || Enum.IsDefined(typeof(HttpStatusCode), code))
{
return (int)HttpStatusCode.OK;
return code;
}
return code;
return (int)HttpStatusCode.OK;
}
private bool IsFault(ResponseMessage responseMessage)

View File

@@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using WireMock.Logging;
using WireMock.Owin.Mappers;
using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Owin
@@ -17,22 +18,24 @@ namespace WireMock.Owin
private readonly IWireMockMiddlewareOptions _options;
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly IWireMockLogger _logger;
private Exception _runningException;
public OwinSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions)
public OwinSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
{
Check.NotNull(options, nameof(options));
Check.NotNull(urlOptions, nameof(urlOptions));
Check.NotNullOrEmpty(uriPrefixes, nameof(uriPrefixes));
_options = options;
_logger = options.Logger ?? new WireMockConsoleLogger();
foreach (var detail in urlOptions.GetDetails())
foreach (string uriPrefix in uriPrefixes)
{
Urls.Add(detail.Url);
Ports.Add(detail.Port);
Urls.Add(uriPrefix);
PortUtils.TryExtract(uriPrefix, out string protocol, out string host, out int port);
Ports.Add(port);
}
_options = options;
}
public bool IsStarted { get; private set; }

View File

@@ -43,10 +43,7 @@ namespace WireMock.Owin
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowBodyForAllHttpMethods"/>
public bool? AllowBodyForAllHttpMethods { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowOnlyDefinedHttpStatusCodeInResponse"/>
public bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableResponseBodyParsing"/>
public bool? DisableJsonBodyParsing { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowAnyHttpStatusCodeInResponse"/>
public bool? AllowAnyHttpStatusCodeInResponse { get; set; }
}
}

View File

@@ -9,13 +9,6 @@ namespace WireMock.RequestBuilders
/// </summary>
public interface IMethodRequestBuilder : IHeadersRequestBuilder
{
/// <summary>
/// UsingConnect: add HTTP Method matching on `CONNECT` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingDelete: add HTTP Method matching on `DELETE` and matchBehaviour (optional).
/// </summary>
@@ -31,7 +24,7 @@ namespace WireMock.RequestBuilders
IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingHead: Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
/// Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
@@ -51,13 +44,6 @@ namespace WireMock.RequestBuilders
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingPut: add HTTP Method matching on `OPTIONS` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingPut: add HTTP Method matching on `PUT` and matchBehaviour (optional).
/// </summary>
@@ -65,13 +51,6 @@ namespace WireMock.RequestBuilders
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingTrace: add HTTP Method matching on `TRACE` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingAnyMethod: add HTTP Method matching on any method.
/// </summary>

View File

@@ -1,113 +0,0 @@
using System.Linq;
using WireMock.Http;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Validation;
namespace WireMock.RequestBuilders
{
public partial class Request
{
/// <inheritdoc cref="IMethodRequestBuilder.UsingConnect(MatchBehaviour)"/>
public IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.CONNECT));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.DELETE));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.GET));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.HEAD));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingOptions(MatchBehaviour)"/>
public IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.OPTIONS));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.POST));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PATCH));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PUT));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingTrace(MatchBehaviour)"/>
public IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.TRACE));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
public IRequestBuilder UsingAnyMethod()
{
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
foreach (var matcher in matchers)
{
_requestMatchers.Remove(matcher);
}
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
public IRequestBuilder UsingAnyVerb()
{
return UsingAnyMethod();
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
public IRequestBuilder UsingMethod(params string[] methods)
{
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
public IRequestBuilder UsingVerb(params string[] verbs)
{
return UsingMethod(verbs);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
{
Check.NotNullOrEmpty(methods, nameof(methods));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
return this;
}
}
}

View File

@@ -151,5 +151,86 @@ namespace WireMock.RequestBuilders
_requestMatchers.Add(new RequestMessageUrlMatcher(funcs));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "DELETE"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "GET"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "HEAD"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "POST"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "PATCH"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "PUT"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
public IRequestBuilder UsingAnyMethod()
{
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
foreach (var matcher in matchers)
{
_requestMatchers.Remove(matcher);
}
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
public IRequestBuilder UsingAnyVerb()
{
return UsingAnyMethod();
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
public IRequestBuilder UsingMethod(params string[] methods)
{
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
public IRequestBuilder UsingVerb(params string[] verbs)
{
return UsingMethod(verbs);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
{
Check.NotNullOrEmpty(methods, nameof(methods));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
return this;
}
}
}

View File

@@ -1,5 +1,4 @@
using System.Net;
using WireMock.Settings;
namespace WireMock.ResponseBuilders
{
@@ -10,7 +9,6 @@ namespace WireMock.ResponseBuilders
{
/// <summary>
/// The with status code.
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
@@ -18,7 +16,6 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// The with status code.
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
@@ -26,7 +23,6 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// The with status code.
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>

View File

@@ -345,7 +345,7 @@ namespace WireMock.ResponseBuilders
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);
}
ResponseMessage responseMessage;

View File

@@ -275,7 +275,7 @@ namespace WireMock.Server
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);
if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
(settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile))

View File

@@ -202,36 +202,31 @@ namespace WireMock.Server
_settings.Logger.Info("WireMock.Net by Stef Heyenrath (https://github.com/WireMock-Net/WireMock.Net)");
_settings.Logger.Debug("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
HostUrlOptions urlOptions;
if (settings.Urls != null)
{
urlOptions = new HostUrlOptions
{
Urls = settings.Urls
};
Urls = settings.Urls.ToArray();
}
else
{
urlOptions = new HostUrlOptions
{
UseSSL = settings.UseSSL == true
};
int port = settings.Port > 0 ? settings.Port.Value : PortUtils.FindFreeTcpPort();
Urls = new[] { $"{(settings.UseSSL == true ? "https" : "http")}://localhost:{port}" };
}
_options.FileSystemHandler = _settings.FileSystemHandler;
_options.PreWireMockMiddlewareInit = _settings.PreWireMockMiddlewareInit;
_options.PostWireMockMiddlewareInit = _settings.PostWireMockMiddlewareInit;
_options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
_options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
_options.Logger = _settings.Logger;
_options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing;
_matcherMapper = new MatcherMapper(_settings);
_mappingConverter = new MappingConverter(_matcherMapper);
#if USE_ASPNETCORE
_httpServer = new AspNetCoreSelfHost(_options, urlOptions);
_httpServer = new AspNetCoreSelfHost(_options, Urls);
#else
_httpServer = new OwinSelfHost(_options, urlOptions);
_httpServer = new OwinSelfHost(_options, Urls);
#endif
Ports = _httpServer.Ports;
var startTask = _httpServer.StartAsync();
using (var ctsStartTimeout = new CancellationTokenSource(settings.StartTimeout))
@@ -258,9 +253,6 @@ namespace WireMock.Server
ctsStartTimeout.Token.WaitHandle.WaitOne(ServerStartDelayInMs);
}
Urls = _httpServer.Urls.ToArray();
Ports = _httpServer.Ports;
}
if (settings.AllowBodyForAllHttpMethods == true)
@@ -269,10 +261,10 @@ namespace WireMock.Server
_settings.Logger.Info("AllowBodyForAllHttpMethods is set to True");
}
if (settings.AllowOnlyDefinedHttpStatusCodeInResponse == true)
if (settings.AllowAnyHttpStatusCodeInResponse == true)
{
_options.AllowOnlyDefinedHttpStatusCodeInResponse = _settings.AllowOnlyDefinedHttpStatusCodeInResponse;
_settings.Logger.Info("AllowOnlyDefinedHttpStatusCodeInResponse is set to True");
_options.AllowAnyHttpStatusCodeInResponse = _settings.AllowAnyHttpStatusCodeInResponse;
_settings.Logger.Info("AllowAnyHttpStatusCodeInResponse is set to True");
}
if (settings.AllowPartialMapping == true)

View File

@@ -139,17 +139,9 @@ namespace WireMock.Settings
bool? AllowBodyForAllHttpMethods { get; set; }
/// <summary>
/// Allow only a HttpStatus Code in the response which is defined. (default set to false).
/// - false : also null, 0, empty or invalid HttpStatus codes are allowed.
/// - true : only codes defined in <see cref="System.Net.HttpStatusCode"/> are allowed.
/// Allow any HttpStatusCode in the response. Also null, 0, empty or invalid. (default set to false).
/// </summary>
/// [PublicAPI]
bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
/// <summary>
/// Set to true to disable Json deserialization when processing requests. (default set to false).
/// </summary>
[PublicAPI]
bool? DisableJsonBodyParsing { get; set; }
bool? AllowAnyHttpStatusCodeInResponse { get; set; }
}
}

View File

@@ -102,11 +102,7 @@ namespace WireMock.Settings
[PublicAPI]
public bool? AllowBodyForAllHttpMethods { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>
public bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.DisableJsonBodyParsing"/>
[PublicAPI]
public bool? DisableJsonBodyParsing { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.AllowAnyHttpStatusCodeInResponse"/>
public bool? AllowAnyHttpStatusCodeInResponse { get; set; }
}
}

View File

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

View File

@@ -6,7 +6,6 @@ using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Newtonsoft.Json;
using WireMock.Http;
using WireMock.Matchers;
using WireMock.Types;
using WireMock.Validation;
@@ -31,15 +30,15 @@ namespace WireMock.Util
*/
private static readonly IDictionary<string, bool> BodyAllowedForMethods = new Dictionary<string, bool>
{
{ 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", false },
{ "GET", false },
{ "PUT", true },
{ "POST", true },
{ "DELETE", true },
{ "TRACE", false },
{ "OPTIONS", true },
{ "CONNECT", false },
{ "PATCH", true }
};
private static readonly IStringMatcher[] MultipartContentTypesMatchers = {
@@ -108,7 +107,7 @@ namespace WireMock.Util
return BodyType.Bytes;
}
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType = null, bool deserializeJson = true)
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType)
{
Check.NotNull(stream, nameof(stream));
@@ -128,6 +127,8 @@ namespace WireMock.Util
data.BodyAsString = encoding.GetString(data.BodyAsBytes);
data.Encoding = encoding;
data.DetectedBodyType = BodyType.String;
return data;
}
return data;
@@ -141,7 +142,7 @@ namespace WireMock.Util
data.DetectedBodyType = BodyType.String;
// If string is not null or empty, try to deserialize the string to a JObject
if (deserializeJson && !string.IsNullOrEmpty(data.BodyAsString))
if (!string.IsNullOrEmpty(data.BodyAsString))
{
try
{

View File

@@ -96,7 +96,7 @@ namespace WireMock.Net.Tests
var listOfTasks = new List<Task<HttpResponseMessage>>();
for (var i = 0; i < expectedCount; i++)
{
Thread.Sleep(50);
Thread.Sleep(10);
listOfTasks.Add(http.GetAsync($"{server.Urls[0]}{path}"));
}
var responses = await Task.WhenAll(listOfTasks);

View File

@@ -69,33 +69,14 @@ namespace WireMock.Net.Tests.Owin.Mappers
await _sut.MapAsync(null, _responseMock.Object);
}
[Theory]
[InlineData(300, 300)]
[InlineData(500, 500)]
public async Task OwinResponseMapper_MapAsync_Valid_StatusCode(object code, int expected)
{
// Arrange
var responseMessage = new ResponseMessage
{
StatusCode = code
};
// Act
await _sut.MapAsync(responseMessage, _responseMock.Object);
// Assert
_responseMock.VerifySet(r => r.StatusCode = expected, Times.Once);
}
[Theory]
[InlineData(0, 200)]
[InlineData(-1, 200)]
[InlineData(10000, 200)]
[InlineData(300, 300)]
public async Task OwinResponseMapper_MapAsync_Invalid_StatusCode_When_AllowOnlyDefinedHttpStatusCodeInResponseSet_Is_True(object code, int expected)
public async Task OwinResponseMapper_MapAsync_StatusCode(object code, int expected)
{
// Arrange
_optionsMock.SetupGet(o => o.AllowOnlyDefinedHttpStatusCodeInResponse).Returns(true);
var responseMessage = new ResponseMessage
{
StatusCode = code
@@ -109,24 +90,7 @@ namespace WireMock.Net.Tests.Owin.Mappers
}
[Fact]
public async Task OwinResponseMapper_MapAsync_Null_StatusCode_When_AllowOnlyDefinedHttpStatusCodeInResponseSet_Is_True()
{
// Arrange
_optionsMock.SetupGet(o => o.AllowOnlyDefinedHttpStatusCodeInResponse).Returns(true);
var responseMessage = new ResponseMessage
{
StatusCode = null
};
// Act
await _sut.MapAsync(responseMessage, _responseMock.Object);
// Assert
_responseMock.VerifyNoOtherCalls();
}
[Fact]
public async Task OwinResponseMapper_MapAsync_StatusCode_Is_Null()
public async Task OwinResponseMapper_MapAsync_StatusCodeNull()
{
// Arrange
var responseMessage = new ResponseMessage
@@ -146,9 +110,10 @@ namespace WireMock.Net.Tests.Owin.Mappers
[InlineData(-1, -1)]
[InlineData(10000, 10000)]
[InlineData(300, 300)]
public async Task OwinResponseMapper_MapAsync_StatusCode_Is_NotInEnumRange(object code, int expected)
public async Task OwinResponseMapper_MapAsync_StatusCode_WithAllowAll(object code, int expected)
{
// Arrange
_optionsMock.SetupGet(o => o.AllowAnyHttpStatusCodeInResponse).Returns(true);
var responseMessage = new ResponseMessage
{
StatusCode = code
@@ -161,6 +126,23 @@ namespace WireMock.Net.Tests.Owin.Mappers
_responseMock.VerifySet(r => r.StatusCode = expected, Times.Once);
}
[Fact]
public async Task OwinResponseMapper_MapAsync_StatusCode_WithAllowAll_Null()
{
// Arrange
_optionsMock.SetupGet(o => o.AllowAnyHttpStatusCodeInResponse).Returns(true);
var responseMessage = new ResponseMessage
{
StatusCode = null
};
// Act
await _sut.MapAsync(responseMessage, _responseMock.Object);
// Assert
_responseMock.VerifyNoOtherCalls();
}
[Fact]
public async Task OwinResponseMapper_MapAsync_NoBody()
{

View File

@@ -8,54 +8,18 @@ namespace WireMock.Net.Tests.RequestBuilders
{
public class RequestBuilderUsingMethodTests
{
[Fact]
public void RequestBuilder_UsingConnect()
{
// Act
var requestBuilder = (Request)Request.Create().UsingConnect();
// Assert
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
Check.That(matchers.Count).IsEqualTo(1);
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("CONNECT");
}
[Fact]
public void RequestBuilder_UsingOptions()
{
// Act
var requestBuilder = (Request)Request.Create().UsingOptions();
// Assert
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
Check.That(matchers.Count).IsEqualTo(1);
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("OPTIONS");
}
[Fact]
public void RequestBuilder_UsingPatch()
{
// Act
var requestBuilder = (Request)Request.Create().UsingPatch();
// Assert
// Assert 1
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
Check.That(matchers.Count).IsEqualTo(1);
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("PATCH");
}
[Fact]
public void RequestBuilder_UsingTrace()
{
// Act
var requestBuilder = (Request)Request.Create().UsingTrace();
// Assert
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
Check.That(matchers.Count).IsEqualTo(1);
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("TRACE");
}
[Fact]
public void RequestBuilder_UsingAnyMethod_ClearsAllOtherMatches()
{

View File

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

View File

@@ -22,7 +22,7 @@ namespace WireMock.Net.Tests.Util
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson));
// Act
var body = await BodyParser.Parse(memoryStream, contentType, true);
var body = await BodyParser.Parse(memoryStream, contentType);
// Assert
Check.That(body.BodyAsBytes).IsNotNull();
@@ -41,7 +41,7 @@ namespace WireMock.Net.Tests.Util
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
// Act
var body = await BodyParser.Parse(memoryStream, contentType, true);
var body = await BodyParser.Parse(memoryStream, contentType);
// Assert
Check.That(body.BodyAsBytes).IsNotNull();
@@ -61,23 +61,7 @@ namespace WireMock.Net.Tests.Util
var memoryStream = new MemoryStream(content);
// act
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);
var body = await BodyParser.Parse(memoryStream, null);
// assert
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
@@ -111,7 +95,7 @@ Content-Type: text/html
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
// Act
var result = await BodyParser.Parse(memoryStream, contentType, true);
var result = await BodyParser.Parse(memoryStream, contentType);
// Assert
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.String);
@@ -131,7 +115,7 @@ Content-Type: text/html
var memoryStream = new MemoryStream(Encoding.UTF32.GetBytes(body));
// Act
var result = await BodyParser.Parse(memoryStream, contentType, true);
var result = await BodyParser.Parse(memoryStream, contentType);
// Assert
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.Bytes);
@@ -149,7 +133,7 @@ Content-Type: text/html
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
// Act
var body = await BodyParser.Parse(memoryStream, contentType, true);
var body = await BodyParser.Parse(memoryStream, contentType);
// Assert
Check.That(body.BodyAsBytes).IsNotNull();

View File

@@ -2,8 +2,8 @@
<PropertyGroup>
<Authors>Stef Heyenrath</Authors>
<!--<TargetFrameworks>net452;netcoreapp2.1</TargetFrameworks>-->
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFrameworks>net452;netcoreapp2.1</TargetFrameworks>
<!--<TargetFramework>netcoreapp2.1</TargetFramework>-->
<DebugType>full</DebugType>
<AssemblyName>WireMock.Net.Tests</AssemblyName>
<PackageId>WireMock.Net.Tests</PackageId>
@@ -19,10 +19,6 @@
<AssemblyOriginatorKeyFile>../../src/WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<!--<DelaySign>true</DelaySign>-->
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<!--https://developercommunity.visualstudio.com/content/problem/26347/unit-tests-fail-with-fileloadexception-newtonsoftj-1.html-->
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
@@ -62,7 +58,6 @@
<ItemGroup Condition="'$(TargetFramework)' == 'net452'">
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="3.1.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">

View File

@@ -141,21 +141,21 @@ namespace WireMock.Net.Tests
}
[Fact]
public void WireMockServer_WireMockServerSettings_AllowOnlyDefinedHttpStatusCodeInResponse()
public void WireMockServer_WireMockServerSettings_AllowAnyHttpStatusCodeInResponse()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{
Logger = _loggerMock.Object,
AllowOnlyDefinedHttpStatusCodeInResponse = true
AllowAnyHttpStatusCodeInResponse = true
});
// Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AllowOnlyDefinedHttpStatusCodeInResponse).Equals(true);
Check.That(options.AllowAnyHttpStatusCodeInResponse).Equals(true);
// Verify
_loggerMock.Verify(l => l.Info(It.Is<string>(s => s.Contains("AllowOnlyDefinedHttpStatusCodeInResponse") && s.Contains("True"))));
_loggerMock.Verify(l => l.Info(It.Is<string>(s => s.Contains("AllowAnyHttpStatusCodeInResponse") && s.Contains("True"))));
}
[Fact]