Fix Proxying when StartAdminInterface=true (#778)

* ProxyHelper fixes

* .

* more reformat

* .
This commit is contained in:
Stef Heyenrath
2022-08-09 19:41:45 +02:00
committed by GitHub
parent be4b0addca
commit b1af37f044
39 changed files with 1962 additions and 1907 deletions
+1
View File
@@ -7,6 +7,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SSL/@EntryIndexedValue">SSL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TE/@EntryIndexedValue">TE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TSV/@EntryIndexedValue">TSV</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TTL/@EntryIndexedValue">TTL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WWW/@EntryIndexedValue">WWW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XMS/@EntryIndexedValue">XMS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XUA/@EntryIndexedValue">XUA</s:String>
@@ -30,12 +30,12 @@ public class LogEntryModel
/// <summary>
/// The mapping unique title.
/// </summary>
public string MappingTitle { get; set; }
public string? MappingTitle { get; set; }
/// <summary>
/// The request match result.
/// </summary>
public LogRequestMatchModel RequestMatchResult { get; set; }
public LogRequestMatchModel? RequestMatchResult { get; set; }
/// <summary>
/// The partial mapping unique identifier.
@@ -45,10 +45,10 @@ public class LogEntryModel
/// <summary>
/// The partial mapping unique title.
/// </summary>
public string PartialMappingTitle { get; set; }
public string? PartialMappingTitle { get; set; }
/// <summary>
/// The partial request match result.
/// </summary>
public LogRequestMatchModel PartialRequestMatchResult { get; set; }
public LogRequestMatchModel? PartialRequestMatchResult { get; set; }
}
@@ -63,12 +63,12 @@ public interface IRequestMessage
/// <summary>
/// Gets the headers.
/// </summary>
IDictionary<string, WireMockList<string>>? Headers { get; }
IDictionary<string, WireMockList<string>> Headers { get; }
/// <summary>
/// Gets the cookies.
/// </summary>
IDictionary<string, string>? Cookies { get; }
IDictionary<string, string> Cookies { get; }
/// <summary>
/// Gets the query.
@@ -1,7 +1,7 @@
using System;
namespace WireMock.Models
{
namespace WireMock.Models;
/// <summary>
/// TimeSettings: Start, End and TTL
/// </summary>
@@ -22,4 +22,3 @@ namespace WireMock.Models
/// </summary>
int? TTL { get; set; }
}
}
@@ -1,12 +1,11 @@
using System;
using JetBrains.Annotations;
using WireMock.Models;
namespace WireMock.Extensions
{
namespace WireMock.Extensions;
internal static class TimeSettingsExtensions
{
public static bool IsValid([CanBeNull] this ITimeSettings settings)
public static bool IsValid(this ITimeSettings? settings)
{
if (settings == null)
{
@@ -14,8 +13,9 @@ namespace WireMock.Extensions
}
var now = DateTime.Now;
var start = settings.Start != null ? settings.Start.Value : now;
var start = settings.Start ?? now;
DateTime end;
if (settings.End != null)
{
end = settings.End.Value;
@@ -32,4 +32,3 @@ namespace WireMock.Extensions
return now >= start && now <= end;
}
}
}
+4 -4
View File
@@ -20,22 +20,22 @@ public interface IMapping
/// <summary>
/// Gets the TimeSettings (Start, End and TTL).
/// </summary>
ITimeSettings TimeSettings { get; }
ITimeSettings? TimeSettings { get; }
/// <summary>
/// Gets the unique title.
/// </summary>
string Title { get; }
string? Title { get; }
/// <summary>
/// Gets the description.
/// </summary>
string Description { get; }
string? Description { get; }
/// <summary>
/// The full filename path for this mapping (only defined for static mappings).
/// </summary>
string Path { get; set; }
string? Path { get; set; }
/// <summary>
/// Gets the priority. (A low value means higher priority.)
+13 -15
View File
@@ -1,13 +1,12 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.ResponseProviders;
using WireMock.Settings;
namespace WireMock
{
namespace WireMock;
/// <summary>
/// The Mapping.
/// </summary>
@@ -17,25 +16,25 @@ namespace WireMock
public Guid Guid { get; }
/// <inheritdoc />
public string Title { get; }
public string? Title { get; }
/// <inheritdoc />
public string Description { get; }
public string? Description { get; }
/// <inheritdoc />
public string Path { get; set; }
public string? Path { get; set; }
/// <inheritdoc />
public int Priority { get; }
/// <inheritdoc />
public string Scenario { get; }
public string? Scenario { get; }
/// <inheritdoc />
public string ExecutionConditionState { get; }
public string? ExecutionConditionState { get; }
/// <inheritdoc />
public string NextState { get; }
public string? NextState { get; }
/// <inheritdoc />
public int? StateTimes { get; }
@@ -53,19 +52,19 @@ namespace WireMock
public bool IsStartState => Scenario == null || Scenario != null && NextState != null && ExecutionConditionState == null;
/// <inheritdoc />
public bool IsAdminInterface => Provider is DynamicResponseProvider || Provider is DynamicAsyncResponseProvider || Provider is ProxyAsyncResponseProvider;
public bool IsAdminInterface => Provider is DynamicResponseProvider or DynamicAsyncResponseProvider or ProxyAsyncResponseProvider;
/// <inheritdoc />
public bool IsProxy => Provider is ProxyAsyncResponseProvider;
/// <inheritdoc />
public bool LogMapping => !(Provider is DynamicResponseProvider || Provider is DynamicAsyncResponseProvider);
public bool LogMapping => Provider is not (DynamicResponseProvider or DynamicAsyncResponseProvider);
/// <inheritdoc />
public IWebhook[] Webhooks { get; }
public IWebhook[]? Webhooks { get; }
/// <inheritdoc />
public ITimeSettings TimeSettings { get; }
public ITimeSettings? TimeSettings { get; }
/// <summary>
/// Initializes a new instance of the <see cref="Mapping"/> class.
@@ -123,7 +122,7 @@ namespace WireMock
}
/// <inheritdoc cref="IMapping.GetRequestMatchResult" />
public IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string nextState)
public IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string? nextState)
{
var result = new RequestMatchResult();
@@ -146,4 +145,3 @@ namespace WireMock
return result;
}
}
}
@@ -1,7 +1,5 @@
using JetBrains.Annotations;
namespace WireMock.Matchers.Request;
namespace WireMock.Matchers.Request
{
/// <summary>
/// The scenario and state matcher.
/// </summary>
@@ -10,22 +8,20 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Execution state condition for the current mapping.
/// </summary>
[CanBeNull]
private readonly string _executionConditionState;
private readonly string? _executionConditionState;
/// <summary>
/// The next state which will be signaled after the current mapping execution.
/// In case the value is null state will not be changed.
/// </summary>
[CanBeNull]
private readonly string _nextState;
private readonly string? _nextState;
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageScenarioAndStateMatcher"/> class.
/// </summary>
/// <param name="nextState">The next state.</param>
/// <param name="executionConditionState">Execution state condition for the current mapping.</param>
public RequestMessageScenarioAndStateMatcher([CanBeNull] string nextState, [CanBeNull] string executionConditionState)
public RequestMessageScenarioAndStateMatcher(string? nextState, string? executionConditionState)
{
_nextState = nextState;
_executionConditionState = executionConditionState;
@@ -43,4 +39,3 @@ namespace WireMock.Matchers.Request
return Equals(_executionConditionState, _nextState) ? MatchScores.Perfect : MatchScores.Mismatch;
}
}
}
@@ -3,8 +3,8 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using WireMock.Types;
namespace WireMock.Owin
{
namespace WireMock.Owin;
internal partial class AspNetCoreSelfHost
{
public void AddCors(IServiceCollection services)
@@ -44,5 +44,4 @@ namespace WireMock.Owin
}
}
}
}
#endif
+4 -4
View File
@@ -36,10 +36,10 @@ namespace WireMock.Owin
public Exception RunningException => _runningException;
public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions wireMockMiddlewareOptions, [NotNull] HostUrlOptions urlOptions)
public AspNetCoreSelfHost(IWireMockMiddlewareOptions wireMockMiddlewareOptions, HostUrlOptions urlOptions)
{
Guard.NotNull(wireMockMiddlewareOptions, nameof(wireMockMiddlewareOptions));
Guard.NotNull(urlOptions, nameof(urlOptions));
Guard.NotNull(wireMockMiddlewareOptions);
Guard.NotNull(urlOptions);
_logger = wireMockMiddlewareOptions.Logger ?? new WireMockConsoleLogger();
@@ -119,7 +119,7 @@ namespace WireMock.Owin
{
Urls.Add(address.Replace("0.0.0.0", "localhost").Replace("[::]", "localhost"));
PortUtils.TryExtract(address, out bool isHttps, out string protocol, out string host, out int port);
PortUtils.TryExtract(address, out _, out _, out _, out int port);
Ports.Add(port);
}
+3 -4
View File
@@ -1,6 +1,6 @@
namespace WireMock.Owin
{
internal class HostUrlDetails
namespace WireMock.Owin;
internal struct HostUrlDetails
{
public bool IsHttps { get; set; }
@@ -12,4 +12,3 @@
public int Port { get; set; }
}
}
+8 -7
View File
@@ -1,13 +1,13 @@
using System.Collections.Generic;
using System.Collections.Generic;
using WireMock.Util;
namespace WireMock.Owin
{
namespace WireMock.Owin;
internal class HostUrlOptions
{
private const string LOCALHOST = "localhost";
public ICollection<string> Urls { get; set; }
public ICollection<string>? Urls { get; set; }
public int? Port { get; set; }
@@ -26,15 +26,17 @@ namespace WireMock.Owin
{
foreach (string url in Urls)
{
PortUtils.TryExtract(url, out bool isHttps, out string protocol, out string host, out int port);
if (PortUtils.TryExtract(url, out bool isHttps, out var protocol, out var host, out int port))
{
list.Add(new HostUrlDetails { IsHttps = isHttps, Url = url, Protocol = protocol, Host = host, Port = port });
}
}
}
return list;
}
private int FindFreeTcpPort()
private static int FindFreeTcpPort()
{
#if USE_ASPNETCORE || NETSTANDARD2_0 || NETSTANDARD2_1
return 0;
@@ -43,4 +45,3 @@ namespace WireMock.Owin
#endif
}
}
}
+3 -4
View File
@@ -1,7 +1,6 @@
namespace WireMock.Owin
{
namespace WireMock.Owin;
internal interface IMappingMatcher
{
(MappingMatcherResult Match, MappingMatcherResult Partial) FindBestMatch(RequestMessage request);
}
(MappingMatcherResult? Match, MappingMatcherResult? Partial) FindBestMatch(RequestMessage request);
}
+5 -6
View File
@@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
namespace WireMock.Owin
{
namespace WireMock.Owin;
interface IOwinSelfHost
{
/// <summary>
@@ -25,12 +25,11 @@ namespace WireMock.Owin
List<int> Ports { get; }
/// <summary>
/// The exception occurred when the host is running
/// The exception occurred when the host is running.
/// </summary>
Exception RunningException { get; }
Exception? RunningException { get; }
Task StartAsync();
Task StopAsync();
}
}
@@ -27,7 +27,7 @@ namespace WireMock.Owin.Mappers
string method = request.Method;
Dictionary<string, string[]>? headers = null;
var headers = new Dictionary<string, string[]>();
IEnumerable<string>? contentEncodingHeader = null;
if (request.Headers.Any())
{
@@ -43,7 +43,7 @@ namespace WireMock.Owin.Mappers
}
}
IDictionary<string, string>? cookies = null;
var cookies = new Dictionary<string, string>();
if (request.Cookies.Any())
{
cookies = new Dictionary<string, string>();
@@ -75,13 +75,24 @@ namespace WireMock.Owin.Mappers
{
#if !USE_ASPNETCORE
var urlDetails = UrlUtils.Parse(request.Uri, request.PathBase);
string clientIP = request.RemoteIpAddress;
var clientIP = request.RemoteIpAddress;
#else
var urlDetails = UrlUtils.Parse(new Uri(request.GetEncodedUrl()), request.PathBase);
var connection = request.HttpContext.Connection;
string clientIP = connection.RemoteIpAddress.IsIPv4MappedToIPv6
? connection.RemoteIpAddress.MapToIPv4().ToString()
: connection.RemoteIpAddress.ToString();
string clientIP;
if (connection.RemoteIpAddress is null)
{
clientIP = string.Empty;
}
else if (connection.RemoteIpAddress.IsIPv4MappedToIPv6)
{
clientIP = connection.RemoteIpAddress.MapToIPv4().ToString();
}
else
{
clientIP = connection.RemoteIpAddress.ToString();
}
#endif
return (urlDetails, clientIP);
}
+9 -10
View File
@@ -4,8 +4,8 @@ using System.Linq;
using WireMock.Extensions;
using Stef.Validation;
namespace WireMock.Owin
{
namespace WireMock.Owin;
internal class MappingMatcher : IMappingMatcher
{
private readonly IWireMockMiddlewareOptions _options;
@@ -17,17 +17,17 @@ namespace WireMock.Owin
_options = options;
}
public (MappingMatcherResult Match, MappingMatcherResult Partial) FindBestMatch(RequestMessage request)
public (MappingMatcherResult? Match, MappingMatcherResult? Partial) FindBestMatch(RequestMessage request)
{
var mappings = new List<MappingMatcherResult>();
var possibleMappings = new List<MappingMatcherResult>();
foreach (var mapping in _options.Mappings.Values.Where(m => m.TimeSettings.IsValid()))
{
try
{
string nextState = GetNextState(mapping);
var nextState = GetNextState(mapping);
mappings.Add(new MappingMatcherResult
possibleMappings.Add(new MappingMatcherResult
{
Mapping = mapping,
RequestMatchResult = mapping.GetRequestMatchResult(request, nextState)
@@ -39,7 +39,7 @@ namespace WireMock.Owin
}
}
var partialMappings = mappings
var partialMappings = possibleMappings
.Where(pm => (pm.Mapping.IsAdminInterface && pm.RequestMatchResult.IsPerfectMatch) || !pm.Mapping.IsAdminInterface)
.OrderBy(m => m.RequestMatchResult)
.ThenBy(m => m.Mapping.Priority)
@@ -51,7 +51,7 @@ namespace WireMock.Owin
return (partialMatch, partialMatch);
}
var match = mappings
var match = possibleMappings
.Where(m => m.RequestMatchResult.IsPerfectMatch)
.OrderBy(m => m.Mapping.Priority).ThenBy(m => m.RequestMatchResult)
.FirstOrDefault();
@@ -59,7 +59,7 @@ namespace WireMock.Owin
return (match, partialMatch);
}
private string GetNextState(IMapping mapping)
private string? GetNextState(IMapping mapping)
{
// If the mapping does not have a scenario or _options.Scenarios does not contain this scenario from the mapping,
// just return null to indicate that there is no next state.
@@ -72,4 +72,3 @@ namespace WireMock.Owin
return _options.Scenarios[mapping.Scenario].NextState;
}
}
}
@@ -1,11 +1,10 @@
using WireMock.Matchers.Request;
namespace WireMock.Owin
{
namespace WireMock.Owin;
internal class MappingMatcherResult
{
public IMapping Mapping { get; set; }
public IRequestMatchResult RequestMatchResult { get; set; }
}
}
+9 -10
View File
@@ -1,26 +1,26 @@
#if !USE_ASPNETCORE
using JetBrains.Annotations;
using Microsoft.Owin.Hosting;
using Owin;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Logging;
using WireMock.Owin.Mappers;
using Stef.Validation;
namespace WireMock.Owin
{
namespace WireMock.Owin;
internal class OwinSelfHost : IOwinSelfHost
{
private readonly IWireMockMiddlewareOptions _options;
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly CancellationTokenSource _cts = new();
private readonly IWireMockLogger _logger;
private Exception _runningException;
private Exception? _runningException;
public OwinSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions)
public OwinSelfHost(IWireMockMiddlewareOptions options, HostUrlOptions urlOptions)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(urlOptions, nameof(urlOptions));
@@ -37,11 +37,11 @@ namespace WireMock.Owin
public bool IsStarted { get; private set; }
public List<string> Urls { get; } = new List<string>();
public List<string> Urls { get; } = new();
public List<int> Ports { get; } = new List<int>();
public List<int> Ports { get; } = new();
public Exception RunningException => _runningException;
public Exception? RunningException => _runningException;
[PublicAPI]
public Task StartAsync()
@@ -107,5 +107,4 @@ namespace WireMock.Owin
}
}
}
}
#endif
+11 -4
View File
@@ -1,6 +1,7 @@
using System;
using System.Threading.Tasks;
using System.Linq;
using System.Net;
using Stef.Validation;
using WireMock.Logging;
using WireMock.Matchers;
@@ -74,10 +75,16 @@ namespace WireMock.Owin
var logRequest = false;
IResponseMessage? response = null;
(MappingMatcherResult? Match, MappingMatcherResult? Partial) result = (null, null);
try
{
foreach (var mapping in _options.Mappings.Values.Where(m => m?.Scenario != null))
foreach (var mapping in _options.Mappings.Values)
{
if (mapping.Scenario is null)
{
continue;
}
// Set scenario start
if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)
{
@@ -107,7 +114,7 @@ namespace WireMock.Owin
if (!present || _options.AuthenticationMatcher.IsMatch(authorization.ToString()) < MatchScores.Perfect)
{
_options.Logger.Error("HttpStatusCode set to 401");
response = ResponseMessageBuilder.Create(null, 401);
response = ResponseMessageBuilder.Create(null, HttpStatusCode.Unauthorized);
return;
}
}
@@ -194,7 +201,7 @@ namespace WireMock.Owin
private async Task SendToWebhooksAsync(IMapping mapping, IRequestMessage request, IResponseMessage response)
{
for (int index = 0; index < mapping.Webhooks.Length; index++)
for (int index = 0; index < mapping.Webhooks?.Length; index++)
{
var httpClientForWebhook = HttpClientBuilder.Build(mapping.Settings.WebhookSettings ?? new WebhookSettings());
var webhookSender = new WebhookSender(mapping.Settings);
@@ -212,7 +219,7 @@ namespace WireMock.Owin
private void UpdateScenarioState(IMapping mapping)
{
var scenario = _options.Scenarios[mapping.Scenario];
var scenario = _options.Scenarios[mapping.Scenario!];
// Increase the number of times this state has been executed
scenario.Counter++;
+21 -4
View File
@@ -4,6 +4,7 @@ using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Stef.Validation;
using WireMock.Constants;
using WireMock.Http;
using WireMock.Matchers;
using WireMock.RequestBuilders;
@@ -29,9 +30,9 @@ internal class ProxyHelper
IRequestMessage requestMessage,
string url)
{
Guard.NotNull(client, nameof(client));
Guard.NotNull(requestMessage, nameof(requestMessage));
Guard.NotNull(url, nameof(url));
Guard.NotNull(client);
Guard.NotNull(requestMessage);
Guard.NotNull(url);
var originalUri = new Uri(requestMessage.Url);
var requiredUri = new Uri(url);
@@ -103,6 +104,22 @@ internal class ProxyHelper
var response = Response.Create(responseMessage);
return new Mapping(Guid.NewGuid(), string.Empty, string.Empty, null, _settings, request, response, 0, null, null, null, null, null, null);
return new Mapping
(
guid: Guid.NewGuid(),
title: $"Proxy Mapping for {requestMessage.Method} {requestMessage.Path}",
description: string.Empty,
path: null,
settings: _settings,
request,
response,
priority: WireMockConstants.ProxyPriority, // This was 0
scenario: null,
executionConditionState: null,
nextState: null,
stateTimes: null,
webhooks: null,
timeSettings: null
);
}
}
+2 -2
View File
@@ -47,10 +47,10 @@ public class RequestMessage : IRequestMessage
public string Method { get; }
/// <inheritdoc cref="IRequestMessage.Headers" />
public IDictionary<string, WireMockList<string>>? Headers { get; }
public IDictionary<string, WireMockList<string>> Headers { get; }
/// <inheritdoc cref="IRequestMessage.Cookies" />
public IDictionary<string, string>? Cookies { get; }
public IDictionary<string, string> Cookies { get; }
/// <inheritdoc cref="IRequestMessage.Query" />
public IDictionary<string, WireMockList<string>>? Query { get; }
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net;
using WireMock.Admin.Mappings;
using WireMock.Constants;
using WireMock.Http;
@@ -15,6 +16,11 @@ internal static class ResponseMessageBuilder
{ HttpKnownHeaderNames.ContentType, new WireMockList<string> { WireMockConstants.ContentTypeJson } }
};
internal static ResponseMessage Create(string? message, HttpStatusCode statusCode, Guid? guid = null)
{
return Create(message, (int)statusCode, guid);
}
internal static ResponseMessage Create(string? message, int statusCode = 200, Guid? guid = null)
{
var response = new ResponseMessage
@@ -6,8 +6,8 @@ using WireMock.Matchers.Request;
using WireMock.ResponseBuilders;
using WireMock.Types;
namespace WireMock.Serialization
{
namespace WireMock.Serialization;
internal static class LogEntryMapper
{
public static LogEntryModel Map(ILogEntry logEntry)
@@ -124,7 +124,7 @@ namespace WireMock.Serialization
};
}
private static LogRequestMatchModel Map(IRequestMatchResult matchResult)
private static LogRequestMatchModel? Map(IRequestMatchResult? matchResult)
{
if (matchResult == null)
{
@@ -145,4 +145,3 @@ namespace WireMock.Serialization
};
}
}
}
@@ -1,10 +1,10 @@
using WireMock.Models;
namespace WireMock.Serialization
{
namespace WireMock.Serialization;
internal static class TimeSettingsMapper
{
public static TimeSettingsModel Map(ITimeSettings settings)
public static TimeSettingsModel? Map(ITimeSettings? settings)
{
return settings != null ? new TimeSettingsModel
{
@@ -14,7 +14,7 @@ namespace WireMock.Serialization
} : null;
}
public static ITimeSettings Map(TimeSettingsModel settings)
public static ITimeSettings? Map(TimeSettingsModel? settings)
{
return settings != null ? new TimeSettings
{
@@ -24,4 +24,3 @@ namespace WireMock.Serialization
} : null;
}
}
}
+19 -20
View File
@@ -20,7 +20,6 @@ using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Proxy;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.ResponseProviders;
using WireMock.Serialization;
using WireMock.Settings;
@@ -43,10 +42,10 @@ public partial class WireMockServer
private const string AdminScenarios = "/__admin/scenarios";
private const string QueryParamReloadStaticMappings = "reloadStaticMappings";
private readonly Guid _proxyMappingGuid = new("e59914fd-782e-428e-91c1-4810ffb86567");
private readonly RegexMatcher _adminRequestContentTypeJson = new ContentTypeMatcher(WireMockConstants.ContentTypeJson, true);
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new(@"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new(@"^\/__admin\/requests\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private static readonly Guid ProxyMappingGuid = new("e59914fd-782e-428e-91c1-4810ffb86567");
private static readonly RegexMatcher AdminRequestContentTypeJson = new ContentTypeMatcher(WireMockConstants.ContentTypeJson, true);
private static readonly RegexMatcher AdminMappingsGuidPathMatcher = new(@"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private static readonly RegexMatcher AdminRequestsGuidPathMatcher = new(@"^\/__admin\/requests\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private EnhancedFileSystemWatcher? _enhancedFileSystemWatcher;
@@ -55,21 +54,21 @@ public partial class WireMockServer
{
// __admin/settings
Given(Request.Create().WithPath(AdminSettings).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(SettingsGet));
Given(Request.Create().WithPath(AdminSettings).UsingMethod("PUT", "POST").WithHeader(HttpKnownHeaderNames.ContentType, _adminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(SettingsUpdate));
Given(Request.Create().WithPath(AdminSettings).UsingMethod("PUT", "POST").WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(SettingsUpdate));
// __admin/mappings
Given(Request.Create().WithPath(AdminMappings).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsGet));
Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, _adminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPost));
Given(Request.Create().WithPath(AdminMappingsWireMockOrg).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, _adminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPostWireMockOrg));
Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPost));
Given(Request.Create().WithPath(AdminMappingsWireMockOrg).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPostWireMockOrg));
Given(Request.Create().WithPath(AdminMappings).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsDelete));
// __admin/mappings/reset
Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsReset));
// __admin/mappings/{guid}
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingGet));
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.ContentType, _adminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingPut));
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingDelete));
Given(Request.Create().WithPath(AdminMappingsGuidPathMatcher).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingGet));
Given(Request.Create().WithPath(AdminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingPut));
Given(Request.Create().WithPath(AdminMappingsGuidPathMatcher).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingDelete));
// __admin/mappings/save
Given(Request.Create().WithPath($"{AdminMappings}/save").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsSave));
@@ -85,8 +84,8 @@ public partial class WireMockServer
Given(Request.Create().WithPath(AdminRequests + "/reset").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestsDelete));
// __admin/request/{guid}
Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestGet));
Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestDelete));
Given(Request.Create().WithPath(AdminRequestsGuidPathMatcher).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestGet));
Given(Request.Create().WithPath(AdminRequestsGuidPathMatcher).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestDelete));
// __admin/requests/find
Given(Request.Create().WithPath(AdminRequests + "/find").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestsFind));
@@ -186,7 +185,7 @@ public partial class WireMockServer
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);
if (FileHelper.TryReadMappingFileWithRetryAndDelay(_settings.FileSystemHandler, path, out string value))
if (FileHelper.TryReadMappingFileWithRetryAndDelay(_settings.FileSystemHandler, path, out var value))
{
var mappingModels = DeserializeJsonToArray<MappingModel>(value);
foreach (var mappingModel in mappingModels)
@@ -216,13 +215,13 @@ public partial class WireMockServer
if (settings.ProxyAndRecordSettings == null)
{
_httpClientForProxy = null;
DeleteMapping(_proxyMappingGuid);
DeleteMapping(ProxyMappingGuid);
return;
}
_httpClientForProxy = HttpClientBuilder.Build(settings.ProxyAndRecordSettings);
var proxyRespondProvider = Given(Request.Create().WithPath("/*").UsingAnyMethod()).WithGuid(_proxyMappingGuid);
var proxyRespondProvider = Given(Request.Create().WithPath("/*").UsingAnyMethod()).WithGuid(ProxyMappingGuid).WithTitle("Default Proxy Mapping on /*");
if (settings.StartAdminInterface == true)
{
proxyRespondProvider.AtPriority(WireMockConstants.ProxyPriority);
@@ -359,7 +358,7 @@ public partial class WireMockServer
var mappingModel = DeserializeObject<MappingModel>(requestMessage);
Guid? guidFromPut = ConvertMappingAndRegisterAsRespondProvider(mappingModel, guid);
return ResponseMessageBuilder.Create("Mapping added or updated", 200, guidFromPut);
return ResponseMessageBuilder.Create("Mapping added or updated", HttpStatusCode.OK, guidFromPut);
}
private IResponseMessage MappingDelete(IRequestMessage requestMessage)
@@ -368,13 +367,13 @@ public partial class WireMockServer
if (DeleteMapping(guid))
{
return ResponseMessageBuilder.Create("Mapping removed", 200, guid);
return ResponseMessageBuilder.Create("Mapping removed", HttpStatusCode.OK, guid);
}
return ResponseMessageBuilder.Create("Mapping not found", 404);
return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound);
}
private Guid ParseGuidFromRequestMessage(IRequestMessage requestMessage)
private static Guid ParseGuidFromRequestMessage(IRequestMessage requestMessage)
{
return Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
}
@@ -27,7 +27,7 @@ public partial class WireMockServer
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);
if (FileHelper.TryReadMappingFileWithRetryAndDelay(_settings.FileSystemHandler, path, out string value))
if (FileHelper.TryReadMappingFileWithRetryAndDelay(_settings.FileSystemHandler, path, out var value))
{
var mappings = DeserializeJsonToArray<OrgMappings>(value);
foreach (var mapping in mappings)
+8 -8
View File
@@ -80,7 +80,7 @@ public partial class WireMockServer : IWireMockServer
/// Gets the scenarios.
/// </summary>
[PublicAPI]
public ConcurrentDictionary<string, ScenarioState> Scenarios => new ConcurrentDictionary<string, ScenarioState>(_options.Scenarios);
public ConcurrentDictionary<string, ScenarioState> Scenarios => new(_options.Scenarios);
#region IDisposable Members
/// <summary>
@@ -414,10 +414,10 @@ public partial class WireMockServer : IWireMockServer
/// <inheritdoc cref="IWireMockServer.SetAzureADAuthentication(string, string)" />
[PublicAPI]
public void SetAzureADAuthentication([NotNull] string tenant, [NotNull] string audience)
public void SetAzureADAuthentication(string tenant, string audience)
{
Guard.NotNull(tenant, nameof(tenant));
Guard.NotNull(audience, nameof(audience));
Guard.NotNull(tenant);
Guard.NotNull(audience);
#if NETSTANDARD1_3
throw new NotSupportedException("AzureADAuthentication is not supported for NETStandard 1.3");
@@ -445,14 +445,14 @@ public partial class WireMockServer : IWireMockServer
/// <inheritdoc cref="IWireMockServer.SetMaxRequestLogCount" />
[PublicAPI]
public void SetMaxRequestLogCount([CanBeNull] int? maxRequestLogCount)
public void SetMaxRequestLogCount(int? maxRequestLogCount)
{
_options.MaxRequestLogCount = maxRequestLogCount;
}
/// <inheritdoc cref="IWireMockServer.SetRequestLogExpirationDuration" />
[PublicAPI]
public void SetRequestLogExpirationDuration([CanBeNull] int? requestLogExpirationDuration)
public void SetRequestLogExpirationDuration(int? requestLogExpirationDuration)
{
_options.RequestLogExpirationDuration = requestLogExpirationDuration;
}
@@ -542,12 +542,12 @@ public partial class WireMockServer : IWireMockServer
{
if (!string.IsNullOrEmpty(settings.AdminUsername) && !string.IsNullOrEmpty(settings.AdminPassword))
{
SetBasicAuthentication(settings.AdminUsername, settings.AdminPassword);
SetBasicAuthentication(settings.AdminUsername!, settings.AdminPassword!);
}
if (!string.IsNullOrEmpty(settings.AdminAzureADTenant) && !string.IsNullOrEmpty(settings.AdminAzureADAudience))
{
SetAzureADAuthentication(settings.AdminAzureADTenant, settings.AdminAzureADAudience);
SetAzureADAuthentication(settings.AdminAzureADTenant!, settings.AdminAzureADAudience!);
}
InitAdmin();
+5 -5
View File
@@ -1,10 +1,11 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
namespace WireMock.Util
{
namespace WireMock.Util;
/// <summary>
/// Based on:
/// http://utf8checker.codeplex.com
@@ -23,7 +24,7 @@ namespace WireMock.Util
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="encoding">The output encoding.</param>
public static bool TryGetEncoding(byte[] bytes, out Encoding encoding)
public static bool TryGetEncoding(byte[] bytes, [NotNullWhen(true)] out Encoding? encoding)
{
encoding = null;
if (bytes.All(b => b < 80))
@@ -227,4 +228,3 @@ namespace WireMock.Util
}
}
#pragma warning restore S3776 // Cognitive Complexity of methods should not be too high
}
+13 -23
View File
@@ -1,16 +1,15 @@
using System;
using System;
using System.IO;
using System.IO.Compression;
namespace WireMock.Util
{
namespace WireMock.Util;
internal static class CompressionUtils
{
public static byte[] Compress(string contentEncoding, byte[] data)
{
using (var compressedStream = new MemoryStream())
using (var zipStream = Create(contentEncoding, compressedStream, CompressionMode.Compress))
{
using var compressedStream = new MemoryStream();
using var zipStream = Create(contentEncoding, compressedStream, CompressionMode.Compress);
zipStream.Write(data, 0, data.Length);
#if !NETSTANDARD1_3
@@ -18,32 +17,23 @@ namespace WireMock.Util
#endif
return compressedStream.ToArray();
}
}
public static byte[] Decompress(string contentEncoding, byte[] data)
{
using (var compressedStream = new MemoryStream(data))
using (var zipStream = Create(contentEncoding, compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{
using var compressedStream = new MemoryStream(data);
using var zipStream = Create(contentEncoding, compressedStream, CompressionMode.Decompress);
using var resultStream = new MemoryStream();
zipStream.CopyTo(resultStream);
return resultStream.ToArray();
}
}
private static Stream Create(string contentEncoding, Stream stream, CompressionMode mode)
{
switch (contentEncoding)
return contentEncoding switch
{
case "gzip":
return new GZipStream(stream, mode);
case "deflate":
return new DeflateStream(stream, mode);
default:
throw new NotSupportedException($"ContentEncoding '{contentEncoding}' is not supported.");
}
}
"gzip" => new GZipStream(stream, mode),
"deflate" => new DeflateStream(stream, mode),
_ => throw new NotSupportedException($"ContentEncoding '{contentEncoding}' is not supported.")
};
}
}
@@ -1,10 +1,9 @@
using System;
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Stef.Validation;
namespace WireMock.Util
{
namespace WireMock.Util;
/// <summary>
/// Some IDictionary Extensions
/// </summary>
@@ -17,9 +16,9 @@ namespace WireMock.Util
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="dictionary">The dictionary to loop (can be null).</param>
/// <param name="action">The action.</param>
public static void Loop<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, [NotNull] Action<TKey, TValue> action)
public static void Loop<TKey, TValue>(this IDictionary<TKey, TValue>? dictionary, Action<TKey, TValue> action)
{
Guard.NotNull(action, nameof(action));
Guard.NotNull(action);
if (dictionary != null)
{
@@ -30,4 +29,3 @@ namespace WireMock.Util
}
}
}
}
+7 -8
View File
@@ -1,19 +1,19 @@
using JetBrains.Annotations;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using WireMock.Handlers;
using Stef.Validation;
using WireMock.Handlers;
namespace WireMock.Util;
namespace WireMock.Util
{
internal static class FileHelper
{
private const int NumberOfRetries = 3;
private const int DelayOnRetry = 500;
public static bool TryReadMappingFileWithRetryAndDelay([NotNull] IFileSystemHandler handler, [NotNull] string path, out string value)
public static bool TryReadMappingFileWithRetryAndDelay(IFileSystemHandler handler, string path, [NotNullWhen(true)] out string? value)
{
Guard.NotNull(handler, nameof(handler));
Guard.NotNullOrEmpty(path, nameof(path));
Guard.NotNull(handler);
Guard.NotNullOrEmpty(path);
value = null;
@@ -33,4 +33,3 @@ namespace WireMock.Util
return false;
}
}
}
@@ -1,10 +1,10 @@
using System;
using System;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
namespace WireMock.Util
{
namespace WireMock.Util;
/// <summary>
/// Based on https://github.com/tmenier/Flurl/blob/129565361e135e639f1d44a35a78aea4302ac6ca/src/Flurl.Http/HttpStatusRangeParser.cs
/// </summary>
@@ -47,7 +47,7 @@ namespace WireMock.Util
/// <param name="pattern">The pattern. (Can be null, in that case it's allowed.)</param>
/// <param name="httpStatusCode">The value.</param>
/// <exception cref="ArgumentException"><paramref name="pattern"/> is invalid.</exception>
public static bool IsMatch(string pattern, int httpStatusCode)
public static bool IsMatch(string? pattern, int httpStatusCode)
{
if (pattern == null)
{
@@ -88,4 +88,3 @@ namespace WireMock.Util
return false;
}
}
}
+7 -7
View File
@@ -1,16 +1,17 @@
using System;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;
namespace WireMock.Util
{
namespace WireMock.Util;
/// <summary>
/// Port Utility class
/// </summary>
public static class PortUtils
{
private static readonly Regex UrlDetailsRegex = new Regex(@"^((?<proto>\w+)://)(?<host>[^/]+?):(?<port>\d+)\/?$", RegexOptions.Compiled);
private static readonly Regex UrlDetailsRegex = new(@"^((?<proto>\w+)://)(?<host>[^/]+?):(?<port>\d+)\/?$", RegexOptions.Compiled);
/// <summary>
/// Finds a free TCP port.
@@ -18,7 +19,7 @@ namespace WireMock.Util
/// <remarks>see http://stackoverflow.com/questions/138043/find-the-next-tcp-port-in-net.</remarks>
public static int FindFreeTcpPort()
{
TcpListener tcpListener = null;
TcpListener? tcpListener = null;
try
{
tcpListener = new TcpListener(IPAddress.Loopback, 0);
@@ -35,7 +36,7 @@ namespace WireMock.Util
/// <summary>
/// Extract the if-isHttps, protocol, host and port from a URL.
/// </summary>
public static bool TryExtract(string url, out bool isHttps, out string protocol, out string host, out int port)
public static bool TryExtract(string url, out bool isHttps, [NotNullWhen(true)] out string? protocol, [NotNullWhen(true)] out string? host, out int port)
{
isHttps = false;
protocol = null;
@@ -55,4 +56,3 @@ namespace WireMock.Util
return false;
}
}
}
+3 -4
View File
@@ -1,11 +1,11 @@
using System;
using System;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using WireMock.Types;
namespace WireMock.Util
{
namespace WireMock.Util;
/// <summary>
/// Based on https://stackoverflow.com/questions/659887/get-url-parameters-from-a-string-in-net
/// </summary>
@@ -35,4 +35,3 @@ namespace WireMock.Util
.ToDictionary(grouping => grouping.Key, grouping => new WireMockList<string>(grouping.SelectMany(x => x).Select(WebUtility.UrlDecode)));
}
}
}
+2 -2
View File
@@ -14,8 +14,8 @@ internal static class TypeBuilderUtils
{
private static readonly ConcurrentDictionary<IDictionary<string, Type>, Type> Types = new();
private static readonly ModuleBuilder ModuleBuilder =
AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("WireMock.Net.Reflection"), AssemblyBuilderAccess.Run)
private static readonly ModuleBuilder ModuleBuilder = AssemblyBuilder
.DefineDynamicAssembly(new AssemblyName("WireMock.Net.Reflection"), AssemblyBuilderAccess.Run)
.DefineDynamicModule("WireMock.Net.Reflection.Module");
public static Type BuildType(IDictionary<string, Type> properties, string? name = null)
+5 -7
View File
@@ -1,5 +1,4 @@
using System;
using JetBrains.Annotations;
using System;
using WireMock.Models;
using Stef.Validation;
#if !USE_ASPNETCORE
@@ -8,13 +7,13 @@ using Microsoft.Owin;
using Microsoft.AspNetCore.Http;
#endif
namespace WireMock.Util
{
namespace WireMock.Util;
internal static class UrlUtils
{
public static UrlDetails Parse([NotNull] Uri uri, PathString pathBase)
public static UrlDetails Parse(Uri uri, PathString pathBase)
{
Guard.NotNull(uri, nameof(uri));
Guard.NotNull(uri);
if (!pathBase.HasValue)
{
@@ -38,4 +37,3 @@ namespace WireMock.Util
return text.Substring(0, pos) + text.Substring(pos + search.Length);
}
}
}
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using FluentAssertions;
using Moq;
@@ -9,8 +9,8 @@ using WireMock.Owin;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests.Owin
{
namespace WireMock.Net.Tests.Owin;
public class MappingMatcherTests
{
private readonly Mock<IWireMockMiddlewareOptions> _optionsMock;
@@ -74,7 +74,8 @@ namespace WireMock.Net.Tests.Owin
// Assign
var guid1 = Guid.Parse("00000000-0000-0000-0000-000000000001");
var guid2 = Guid.Parse("00000000-0000-0000-0000-000000000002");
var mappings = InitMappings(
var mappings = InitMappings
(
(guid1, new[] { 0.1 }),
(guid2, new[] { 1.0 })
);
@@ -86,19 +87,23 @@ namespace WireMock.Net.Tests.Owin
var result = _sut.FindBestMatch(request);
// Assert
result.Match.Mapping.Guid.Should().Be(guid2);
result.Match.Should().NotBeNull();
result.Match!.Mapping.Guid.Should().Be(guid2);
result.Match.RequestMatchResult.AverageTotalScore.Should().Be(1.0);
result.Partial.Mapping.Guid.Should().Be(guid2);
result.Partial.Should().NotBeNull();
result.Partial!.Mapping.Guid.Should().Be(guid2);
result.Partial.RequestMatchResult.AverageTotalScore.Should().Be(1.0);
}
[Fact]
public void MappingMatcher_FindBestMatch_WhenAllowPartialMappingIsFalse_AndNoExactmatch_ShouldReturnNullExactMatch_And_PartialMatch()
public void MappingMatcher_FindBestMatch_WhenAllowPartialMappingIsFalse_AndNoExactMatch_ShouldReturnNullExactMatch_And_PartialMatch()
{
// Assign
var guid1 = Guid.Parse("00000000-0000-0000-0000-000000000001");
var guid2 = Guid.Parse("00000000-0000-0000-0000-000000000002");
var mappings = InitMappings(
var mappings = InitMappings
(
(guid1, new[] { 0.1 }),
(guid2, new[] { 0.9 })
);
@@ -111,7 +116,9 @@ namespace WireMock.Net.Tests.Owin
// Assert
result.Match.Should().BeNull();
result.Partial.Mapping.Guid.Should().Be(guid2);
result.Partial.Should().NotBeNull();
result.Partial!.Mapping.Guid.Should().Be(guid2);
result.Partial.RequestMatchResult.AverageTotalScore.Should().Be(0.9);
}
@@ -135,9 +142,12 @@ namespace WireMock.Net.Tests.Owin
var result = _sut.FindBestMatch(request);
// Assert
result.Match.Mapping.Guid.Should().Be(guid2);
result.Match.Should().NotBeNull();
result.Match!.Mapping.Guid.Should().Be(guid2);
result.Match.RequestMatchResult.AverageTotalScore.Should().Be(0.9);
result.Partial.Mapping.Guid.Should().Be(guid2);
result.Partial.Should().NotBeNull();
result.Partial!.Mapping.Guid.Should().Be(guid2);
result.Partial.RequestMatchResult.AverageTotalScore.Should().Be(0.9);
}
@@ -159,13 +169,16 @@ namespace WireMock.Net.Tests.Owin
var result = _sut.FindBestMatch(request);
// Assert and Verify
result.Match.Mapping.Guid.Should().Be(guid2);
result.Match.Should().NotBeNull();
result.Match!.Mapping.Guid.Should().Be(guid2);
result.Match.RequestMatchResult.AverageTotalScore.Should().Be(1.0);
result.Partial.Mapping.Guid.Should().Be(guid2);
result.Partial.Should().NotBeNull();
result.Partial!.Mapping.Guid.Should().Be(guid2);
result.Partial.RequestMatchResult.AverageTotalScore.Should().Be(1.0);
}
private ConcurrentDictionary<Guid, IMapping> InitMappings(params (Guid guid, double[] scores)[] matches)
private static ConcurrentDictionary<Guid, IMapping> InitMappings(params (Guid guid, double[] scores)[] matches)
{
var mappings = new ConcurrentDictionary<Guid, IMapping>();
@@ -188,4 +201,3 @@ namespace WireMock.Net.Tests.Owin
return mappings;
}
}
}
@@ -1,12 +1,12 @@
using FluentAssertions;
using FluentAssertions;
using Moq;
using System;
using WireMock.Handlers;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests.Util
{
namespace WireMock.Net.Tests.Util;
public class FileHelperTests
{
[Fact]
@@ -17,7 +17,7 @@ namespace WireMock.Net.Tests.Util
staticMappingHandlerMock.Setup(m => m.ReadMappingFile(It.IsAny<string>())).Returns("text");
// Act
bool result = FileHelper.TryReadMappingFileWithRetryAndDelay(staticMappingHandlerMock.Object, @"c:\temp", out string value);
bool result = FileHelper.TryReadMappingFileWithRetryAndDelay(staticMappingHandlerMock.Object, @"c:\temp", out var value);
// Assert
result.Should().BeTrue();
@@ -35,7 +35,7 @@ namespace WireMock.Net.Tests.Util
staticMappingHandlerMock.Setup(m => m.ReadMappingFile(It.IsAny<string>())).Throws<NotSupportedException>();
// Act
bool result = FileHelper.TryReadMappingFileWithRetryAndDelay(staticMappingHandlerMock.Object, @"c:\temp", out string value);
bool result = FileHelper.TryReadMappingFileWithRetryAndDelay(staticMappingHandlerMock.Object, @"c:\temp", out var value);
// Assert
result.Should().BeFalse();
@@ -45,4 +45,3 @@ namespace WireMock.Net.Tests.Util
staticMappingHandlerMock.Verify(m => m.ReadMappingFile(@"c:\temp"), Times.Exactly(3));
}
}
}
+47 -10
View File
@@ -18,8 +18,8 @@ using WireMock.Settings;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests
{
namespace WireMock.Net.Tests;
public class WireMockServerProxyTests
{
[Fact(Skip = "Fails in Linux CI")]
@@ -54,7 +54,7 @@ namespace WireMock.Net.Tests
}
[Fact]
public async Task WireMockServer_Proxy_With_SaveMapping_Is_True_And_SaveMappingToFile_Is_False_Should_AddInternalMappingOnly()
public async Task WireMockServer_Proxy_AdminFalse_With_SaveMapping_Is_True_And_SaveMappingToFile_Is_False_Should_AddInternalMappingOnly()
{
// Assign
var settings = new WireMockServerSettings
@@ -63,24 +63,62 @@ namespace WireMock.Net.Tests
{
Url = "http://www.google.com",
SaveMapping = true,
SaveMappingToFile = false
SaveMappingToFile = false,
ExcludedHeaders = new[] { "Connection" } // Needed for .NET 4.5.x and 4.6.x
}
};
var server = WireMockServer.Start(settings);
// Act
var httpClientHandler = new HttpClientHandler { AllowAutoRedirect = false };
var client = new HttpClient(httpClientHandler);
for (int i = 0; i < 5; i++)
{
var requestMessage = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(server.Urls[0])
RequestUri = new Uri(server.Url!)
};
var httpClientHandler = new HttpClientHandler { AllowAutoRedirect = false };
await new HttpClient(httpClientHandler).SendAsync(requestMessage).ConfigureAwait(false);
await client.SendAsync(requestMessage).ConfigureAwait(false);
}
// Assert
server.Mappings.Should().HaveCount(2);
}
[Fact]
public async Task WireMockServer_Proxy_AdminTrue_With_SaveMapping_Is_True_And_SaveMappingToFile_Is_False_Should_AddInternalMappingOnly()
{
// Assign
var settings = new WireMockServerSettings
{
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
Url = "http://www.google.com",
SaveMapping = true,
SaveMappingToFile = false,
ExcludedHeaders = new[] { "Connection" } // Needed for .NET 4.5.x and 4.6.x
},
StartAdminInterface = true
};
var server = WireMockServer.Start(settings);
// Act
for (int i = 0; i < 5; i++)
{
var requestMessage = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(server.Url!)
};
var httpClientHandler = new HttpClientHandler { AllowAutoRedirect = false };
await new HttpClient(httpClientHandler).SendAsync(requestMessage).ConfigureAwait(false);
}
// Assert
server.Mappings.Should().HaveCount(28);
}
[Fact]
public async Task WireMockServer_Proxy_With_SaveMapping_Is_False_And_SaveMappingToFile_Is_True_ShouldSaveMappingToFile()
{
@@ -264,7 +302,7 @@ namespace WireMock.Net.Tests
{
BodyData = new BodyData
{
BodyAsString = x.Headers["Authorization"].ToString(),
BodyAsString = x.Headers!["Authorization"].ToString(),
DetectedBodyType = Types.BodyType.String
}
}));
@@ -294,7 +332,7 @@ namespace WireMock.Net.Tests
(await result.Content.ReadAsStringAsync().ConfigureAwait(false)).Should().Be("BASIC test-A");
var receivedRequest = serverForProxyForwarding.LogEntries.First().RequestMessage;
var authorizationHeader = receivedRequest.Headers["Authorization"].ToString().Should().Be("BASIC test-A");
receivedRequest.Headers!["Authorization"].ToString().Should().Be("BASIC test-A");
server.Mappings.Should().HaveCount(2);
var authorizationRequestMessageHeaderMatcher = ((Request)server.Mappings.Single(m => !m.IsAdminInterface).RequestMatcher)
@@ -702,4 +740,3 @@ namespace WireMock.Net.Tests
server.Stop();
}
}
}