* Lower priority from Proxy mappings

* Fix codefactor

* extra tests

* #205

* Fix test for linux

* `c:\temp\x.json` fix

* Extra tests

* more tests

* more tests

* codefactor

* #200

* refactor

* refactor

* tests
This commit is contained in:
Stef Heyenrath
2018-09-22 08:41:24 +02:00
committed by GitHub
parent 0c25ab413d
commit f358f13c08
135 changed files with 11939 additions and 4506 deletions

View File

@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using JetBrains.Annotations;
using WireMock.Validation;
@@ -26,7 +27,7 @@ namespace WireMock.Matchers.Request
Check.NotNull(methods, nameof(methods));
_matchBehaviour = matchBehaviour;
Methods = methods.Select(v => v.ToLower()).ToArray();
Methods = methods;
}
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
@@ -38,7 +39,7 @@ namespace WireMock.Matchers.Request
private double IsMatch(RequestMessage requestMessage)
{
return MatchScores.ToScore(Methods.Contains(requestMessage.Method));
return MatchScores.ToScore(Methods.Contains(requestMessage.Method, StringComparer.OrdinalIgnoreCase));
}
}
}

View File

@@ -43,7 +43,7 @@ namespace WireMock.Owin
{
Urls.Add(uriPrefix);
PortUtils.TryExtractProtocolAndPort(uriPrefix, out string host, out int port);
PortUtils.TryExtract(uriPrefix, out string protocol, out string host, out int port);
Ports.Add(port);
}
@@ -75,13 +75,13 @@ namespace WireMock.Owin
// 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)))
{
PortUtils.TryExtractProtocolAndPort(url, out string host, out int port);
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.TryExtractProtocolAndPort(url, out string host, out int port);
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
options.Listen(System.Net.IPAddress.Any, port, listenOptions =>
{
listenOptions.UseHttps(PublicCertificateHelper.GetX509Certificate2());

View File

@@ -31,7 +31,7 @@ namespace WireMock.Owin
{
Urls.Add(uriPrefix);
PortUtils.TryExtractProtocolAndPort(uriPrefix, out string host, out int port);
PortUtils.TryExtract(uriPrefix, out string protocol, out string host, out int port);
Ports.Add(port);
}

View File

@@ -10,42 +10,42 @@ namespace WireMock.RequestBuilders
public interface IMethodRequestBuilder : IHeadersAndCookiesRequestBuilder
{
/// <summary>
/// UsingDelete: add HTTP Method matching on `delete` and matchBehaviour (optional).
/// UsingDelete: add HTTP Method matching on `DELETE` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingGet: add HTTP Method matching on `get` and matchBehaviour (optional).
/// UsingGet: add HTTP Method matching on `GET` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// 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>
IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingPost: add HTTP Method matching on `post` and matchBehaviour (optional).
/// UsingPost: add HTTP Method matching on `POST` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingPatch: add HTTP Method matching on `patch` and matchBehaviour (optional).
/// UsingPatch: add HTTP Method matching on `PATCH` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingPut: add HTTP Method matching on `put` and matchBehaviour (optional).
/// UsingPut: add HTTP Method matching on `PUT` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
@@ -68,21 +68,21 @@ namespace WireMock.RequestBuilders
/// UsingMethod: add HTTP Method matching on any methods and matchBehaviour.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="methods">The methods.</param>
/// <param name="methods">The method or methods.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, [NotNull] params string[] methods);
/// <summary>
/// UsingMethod: add HTTP Method matching on any methods.
/// </summary>
/// <param name="methods">The methods.</param>
/// <param name="methods">The method or methods.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingMethod([NotNull] params string[] methods);
/// <summary>
/// UsingVerb: add HTTP Method matching on any methods.
/// </summary>
/// <param name="verbs">The methods.</param>
/// <param name="verbs">The method or methods.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
[Obsolete("Use the method UsingMethod(...).")]
IRequestBuilder UsingVerb([NotNull] params string[] verbs);

View File

@@ -156,42 +156,42 @@ namespace WireMock.RequestBuilders
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "delete"));
_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"));
_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"));
_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"));
_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"));
_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"));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "PUT"));
return this;
}

View File

@@ -147,7 +147,7 @@ namespace WireMock
PathSegments = Path.Split('/').Skip(1).ToArray();
AbsolutePathSegments = AbsolutePath.Split('/').Skip(1).ToArray();
Method = method.ToLower();
Method = method;
ClientIP = clientIP;
Body = body?.BodyAsString;

View File

@@ -30,8 +30,10 @@ namespace WireMock.Server
/// </summary>
public partial class FluentMockServer
{
private const int EnhancedFileSystemWatcherTimeoutMs = 1000;
private const int AdminPriority = int.MinValue;
private const int ProxyPriority = 1000;
private const string ContentTypeJson = "application/json";
private const string AdminMappings = "/__admin/mappings";
private const string AdminRequests = "/__admin/requests";
private const string AdminSettings = "/__admin/settings";
@@ -56,48 +58,45 @@ namespace WireMock.Server
private void InitAdmin()
{
// __admin/settings
Given(Request.Create().WithPath(AdminSettings).UsingGet()).RespondWith(new DynamicResponseProvider(SettingsGet));
Given(Request.Create().WithPath(AdminSettings).UsingMethod("PUT", "POST").WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).RespondWith(new DynamicResponseProvider(SettingsUpdate));
Given(Request.Create().WithPath(AdminSettings).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(SettingsGet));
Given(Request.Create().WithPath(AdminSettings).UsingMethod("PUT", "POST").WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(SettingsUpdate));
// __admin/mappings
Given(Request.Create().WithPath(AdminMappings).UsingGet()).RespondWith(new DynamicResponseProvider(MappingsGet));
Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).RespondWith(new DynamicResponseProvider(MappingsPost));
Given(Request.Create().WithPath(AdminMappings).UsingDelete()).RespondWith(new DynamicResponseProvider(MappingsDelete));
Given(Request.Create().WithPath(AdminMappings).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsGet));
Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPost));
Given(Request.Create().WithPath(AdminMappings).UsingDelete()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsDelete));
// __admin/mappings/reset
Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).RespondWith(new DynamicResponseProvider(MappingsDelete));
Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsDelete));
// __admin/mappings/{guid}
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponseProvider(MappingGet));
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).RespondWith(new DynamicResponseProvider(MappingPut));
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicResponseProvider(MappingDelete));
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingGet));
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingPut));
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingDelete()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingDelete));
// __admin/mappings/save
Given(Request.Create().WithPath(AdminMappings + "/save").UsingPost()).RespondWith(new DynamicResponseProvider(MappingsSave));
Given(Request.Create().WithPath(AdminMappings + "/save").UsingPost()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsSave));
// __admin/requests
Given(Request.Create().WithPath(AdminRequests).UsingGet()).RespondWith(new DynamicResponseProvider(RequestsGet));
Given(Request.Create().WithPath(AdminRequests).UsingDelete()).RespondWith(new DynamicResponseProvider(RequestsDelete));
Given(Request.Create().WithPath(AdminRequests).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(RequestsGet));
Given(Request.Create().WithPath(AdminRequests).UsingDelete()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(RequestsDelete));
// __admin/requests/reset
Given(Request.Create().WithPath(AdminRequests + "/reset").UsingPost()).RespondWith(new DynamicResponseProvider(RequestsDelete));
Given(Request.Create().WithPath(AdminRequests + "/reset").UsingPost()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(RequestsDelete));
// __admin/request/{guid}
Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponseProvider(RequestGet));
Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicResponseProvider(RequestDelete));
Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(RequestGet));
Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingDelete()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(RequestDelete));
// __admin/requests/find
Given(Request.Create().WithPath(AdminRequests + "/find").UsingPost()).RespondWith(new DynamicResponseProvider(RequestsFind));
Given(Request.Create().WithPath(AdminRequests + "/find").UsingPost()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(RequestsFind));
// __admin/scenarios
Given(Request.Create().WithPath(AdminScenarios).UsingGet()).RespondWith(new DynamicResponseProvider(ScenariosGet));
Given(Request.Create().WithPath(AdminScenarios).UsingDelete()).RespondWith(new DynamicResponseProvider(ScenariosReset));
Given(Request.Create().WithPath(AdminScenarios).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(ScenariosGet));
Given(Request.Create().WithPath(AdminScenarios).UsingDelete()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(ScenariosReset));
// __admin/scenarios/reset
Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).RespondWith(new DynamicResponseProvider(ScenariosReset));
Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(ScenariosReset));
}
#endregion
@@ -167,7 +166,7 @@ namespace WireMock.Server
_logger.Info("Watching folder '{0}' for new, updated and deleted MappingFiles.", folder);
var watcher = new EnhancedFileSystemWatcher(folder, "*.json", 1000);
var watcher = new EnhancedFileSystemWatcher(folder, "*.json", EnhancedFileSystemWatcherTimeoutMs);
watcher.Created += (sender, args) =>
{
_logger.Info("New MappingFile created : '{0}'", args.FullPath);
@@ -222,10 +221,17 @@ namespace WireMock.Server
#region Proxy and Record
private HttpClient _httpClientForProxy;
private void InitProxyAndRecord(IProxyAndRecordSettings settings)
private void InitProxyAndRecord(IFluentMockServerSettings settings)
{
_httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ClientX509Certificate2ThumbprintOrSubjectName);
Given(Request.Create().WithPath("/*").UsingAnyMethod()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
_httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ProxyAndRecordSettings.ClientX509Certificate2ThumbprintOrSubjectName);
var respondProvider = Given(Request.Create().WithPath("/*").UsingAnyMethod());
if (settings.StartAdminInterface == true)
{
respondProvider.AtPriority(ProxyPriority);
}
respondProvider.RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings.ProxyAndRecordSettings));
}
private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, IProxyAndRecordSettings settings)

View File

@@ -5,10 +5,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using WireMock.Handlers;
using WireMock.Http;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.Matchers.Request;
@@ -264,7 +262,7 @@ namespace WireMock.Server
if (settings.ProxyAndRecordSettings != null)
{
InitProxyAndRecord(settings.ProxyAndRecordSettings);
InitProxyAndRecord(settings);
}
if (settings.MaxRequestLogCount != null)

View File

@@ -22,8 +22,7 @@ namespace WireMock.Transformers
}
catch (JsonException)
{
// Ignore JsonException and return
return;
// Ignore JsonException
}
});
@@ -41,8 +40,7 @@ namespace WireMock.Transformers
}
catch (JsonException)
{
// Ignore JsonException and return
return;
// Ignore JsonException
}
});
}
@@ -69,7 +67,7 @@ namespace WireMock.Transformers
throw new NotSupportedException($"The value '{arguments[0]}' with type '{arguments[0]?.GetType()}' cannot be used in Handlebars JsonPath.");
}
return (valueToProcess, arguments[1] as string);
return (valueToProcess, (string) arguments[1]);
}
}
}

View File

@@ -24,8 +24,7 @@ namespace WireMock.Transformers
}
catch (ParseException)
{
// Ignore ParseException and return
return;
// Ignore ParseException
}
});
@@ -40,8 +39,7 @@ namespace WireMock.Transformers
}
catch (ParseException)
{
// Ignore ParseException and return
return;
// Ignore ParseException
}
});
}
@@ -82,7 +80,7 @@ namespace WireMock.Transformers
throw new NotSupportedException($"The value '{arguments[0]}' with type '{arguments[0]?.GetType()}' cannot be used in Handlebars Linq.");
}
return (valueToProcess, arguments[1] as string);
return (valueToProcess, (string) arguments[1]);
}
}
}

View File

@@ -2,7 +2,7 @@
using System.Linq;
using System.Text.RegularExpressions;
using HandlebarsDotNet;
using WireMock.Utils;
using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Transformers
@@ -52,7 +52,7 @@ namespace WireMock.Transformers
{
if (arg is string)
{
return arg as string;
return (string) arg;
}
else
{

View File

@@ -9,7 +9,7 @@ namespace WireMock.Util
/// </summary>
public static class PortUtils
{
private static readonly Regex UrlDetailsRegex = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>\d+)/?", RegexOptions.Compiled);
private static readonly Regex UrlDetailsRegex = new Regex(@"^((?<proto>\w+)://)(?<host>[^/]+?):(?<port>\d+)\/?$", RegexOptions.Compiled);
/// <summary>
/// Finds a free TCP port.
@@ -32,17 +32,19 @@ namespace WireMock.Util
}
/// <summary>
/// Extract a proto and port from a URL.
/// Extract the protocol, host and port from a URL.
/// </summary>
public static bool TryExtractProtocolAndPort(string url, out string proto, out int port)
public static bool TryExtract(string url, out string protocol, out string host, out int port)
{
proto = null;
port = 0;
protocol = null;
host = null;
port = default(int);
Match m = UrlDetailsRegex.Match(url);
if (m.Success)
{
proto = m.Groups["proto"].Value;
protocol = m.Groups["proto"].Value;
host = m.Groups["host"].Value;
return int.TryParse(m.Groups["port"].Value, out port);
}

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace WireMock.Utils
namespace WireMock.Util
{
internal static class RegexUtils
{