Version 2.x

This commit is contained in:
Stef Heyenrath
2025-08-30 10:24:07 +02:00
parent 358590918e
commit 034766a2d6
83 changed files with 1077 additions and 999 deletions

View File

@@ -1,6 +1,6 @@
// Copyright © WireMock.Net
#if NET451 || NET452 || NET46 || NET451 || NET461 || NETSTANDARD1_3 || NETSTANDARD2_0
#if NET451 || NET452 || NET46 || NET461 || NET48 || NETSTANDARD1_3 || NETSTANDARD2_0
using System.Text.RegularExpressions;
using WireMock.Constants;

View File

@@ -11,24 +11,18 @@ internal static class HttpClientBuilder
{
public static HttpClient Build(HttpClientSettings settings)
{
#if NETSTANDARD || NETCOREAPP3_1 || NET5_0_OR_GREATER
#if NET8_0_OR_GREATER
var handler = new HttpClientHandler
{
CheckCertificateRevocationList = false,
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
#elif NET46
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
#else
var handler = new WebRequestHandler
var handler = new HttpClientHandler
{
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
#endif

View File

@@ -1,6 +1,6 @@
// Copyright © WireMock.Net
#if NETCOREAPP3_1 || NET5_0_OR_GREATER
#if NET8_0
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using WireMock.Types;

View File

@@ -1,12 +1,11 @@
// Copyright © WireMock.Net
#if USE_ASPNETCORE && !NETSTANDARD1_3
//#if USE_ASPNETCORE && !NETSTANDARD1_3
using System;
using System.Collections.Generic;
using System.Net;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using CertificateLoader = WireMock.HttpsCertificate.CertificateLoader;
@@ -38,7 +37,7 @@ internal partial class AspNetCoreSelfHost
options.ServerCertificate = CertificateLoader.LoadCertificate(wireMockMiddlewareOptions, urlDetail.Host);
}
options.ClientCertificateMode = (ClientCertificateMode)wireMockMiddlewareOptions.ClientCertificateMode;
options.ClientCertificateMode = wireMockMiddlewareOptions.ClientCertificateMode;
if (wireMockMiddlewareOptions.AcceptAnyClientCertificate)
{
options.ClientCertificateValidation = (_, _, _) => true;
@@ -47,7 +46,7 @@ internal partial class AspNetCoreSelfHost
if (urlDetail.IsHttp2)
{
listenOptions.Protocols = HttpProtocols.Http2;
SetHttp2AsProtocolsOnListenOptions(listenOptions);
}
});
continue;
@@ -55,10 +54,7 @@ internal partial class AspNetCoreSelfHost
if (urlDetail.IsHttp2)
{
Listen(kestrelOptions, urlDetail, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
Listen(kestrelOptions, urlDetail, SetHttp2AsProtocolsOnListenOptions);
continue;
}
@@ -66,6 +62,15 @@ internal partial class AspNetCoreSelfHost
}
}
private static void SetHttp2AsProtocolsOnListenOptions(ListenOptions listenOptions)
{
#if NET8_0_OR_GREATER
listenOptions.Protocols = HttpProtocols.Http2;
#else
throw new NotSupportedException("HTTP/2 is only supported in .NET 8 or greater.");
#endif
}
private static void Listen(KestrelServerOptions kestrelOptions, HostUrlDetails urlDetail, Action<ListenOptions> configure)
{
// Listens on any IP with the given port.
@@ -112,4 +117,4 @@ internal static class IWebHostBuilderExtensions
});
}
}
#endif
//#endif

View File

@@ -1,57 +1,57 @@
// Copyright © WireMock.Net
#if USE_ASPNETCORE && NETSTANDARD1_3
using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WireMock.HttpsCertificate;
//#if USE_ASPNETCORE && NETSTANDARD1_3
//using System.Collections.Generic;
//using Microsoft.AspNetCore.Hosting;
//using Microsoft.AspNetCore.Server.Kestrel;
//using Microsoft.AspNetCore.Server.Kestrel.Https;
//using Microsoft.Extensions.Configuration;
//using Microsoft.Extensions.DependencyInjection;
//using WireMock.HttpsCertificate;
namespace WireMock.Owin;
//namespace WireMock.Owin;
internal partial class AspNetCoreSelfHost
{
private static void SetKestrelOptionsLimits(KestrelServerOptions options)
{
options.Limits.MaxRequestBufferSize = null;
options.Limits.MaxRequestHeaderCount = 100;
options.Limits.MaxResponseBufferSize = null;
}
//internal partial class AspNetCoreSelfHost
//{
// private static void SetKestrelOptionsLimits(KestrelServerOptions options)
// {
// options.Limits.MaxRequestBufferSize = null;
// options.Limits.MaxRequestHeaderCount = 100;
// options.Limits.MaxResponseBufferSize = null;
// }
private static void SetHttpsAndUrls(KestrelServerOptions options, IWireMockMiddlewareOptions wireMockMiddlewareOptions, IEnumerable<HostUrlDetails> urlDetails)
{
foreach (var urlDetail in urlDetails)
{
if (urlDetail.IsHttps)
{
options.UseHttps(new HttpsConnectionFilterOptions
{
ServerCertificate = wireMockMiddlewareOptions.CustomCertificateDefined ? CertificateLoader.LoadCertificate(wireMockMiddlewareOptions, urlDetail.Host) : PublicCertificateHelper.GetX509Certificate2(),
ClientCertificateMode = (ClientCertificateMode) wireMockMiddlewareOptions.ClientCertificateMode,
ClientCertificateValidation = wireMockMiddlewareOptions.AcceptAnyClientCertificate ? (_, _, _) => true : null
});
}
}
}
}
// private static void SetHttpsAndUrls(KestrelServerOptions options, IWireMockMiddlewareOptions wireMockMiddlewareOptions, IEnumerable<HostUrlDetails> urlDetails)
// {
// foreach (var urlDetail in urlDetails)
// {
// if (urlDetail.IsHttps)
// {
// options.UseHttps(new HttpsConnectionFilterOptions
// {
// ServerCertificate = wireMockMiddlewareOptions.CustomCertificateDefined ? CertificateLoader.LoadCertificate(wireMockMiddlewareOptions, urlDetail.Host) : PublicCertificateHelper.GetX509Certificate2(),
// ClientCertificateMode = (ClientCertificateMode) wireMockMiddlewareOptions.ClientCertificateMode,
// ClientCertificateValidation = wireMockMiddlewareOptions.AcceptAnyClientCertificate ? (_, _, _) => true : null
// });
// }
// }
// }
//}
internal static class IWebHostBuilderExtensions
{
internal static IWebHostBuilder ConfigureAppConfigurationUsingEnvironmentVariables(this IWebHostBuilder builder) => builder;
//internal static class IWebHostBuilderExtensions
//{
// internal static IWebHostBuilder ConfigureAppConfigurationUsingEnvironmentVariables(this IWebHostBuilder builder) => builder;
internal static IWebHostBuilder ConfigureKestrelServerOptions(this IWebHostBuilder builder)
{
var configuration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
// internal static IWebHostBuilder ConfigureKestrelServerOptions(this IWebHostBuilder builder)
// {
// var configuration = new ConfigurationBuilder()
// .AddEnvironmentVariables()
// .Build();
return builder.ConfigureServices(services =>
{
services.Configure<KestrelServerOptions>(configuration.GetSection("Kestrel"));
});
}
}
// return builder.ConfigureServices(services =>
// {
// services.Configure<KestrelServerOptions>(configuration.GetSection("Kestrel"));
// });
// }
//}
#endif
//#endif

View File

@@ -1,10 +1,9 @@
// Copyright © WireMock.Net
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
@@ -74,7 +73,7 @@ internal partial class AspNetCoreSelfHost : IOwinSelfHost
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
services.AddSingleton<IGuidUtils, GuidUtils>();
#if NETCOREAPP3_1 || NET5_0_OR_GREATER
#if NET8_0_OR_GREATER
AddCors(services);
#endif
_wireMockMiddlewareOptions.AdditionalServiceRegistration?.Invoke(services);
@@ -83,7 +82,7 @@ internal partial class AspNetCoreSelfHost : IOwinSelfHost
{
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
#if NETCOREAPP3_1 || NET5_0_OR_GREATER
#if NET8_0_OR_GREATER
UseCors(appBuilder);
#endif
_wireMockMiddlewareOptions.PreWireMockMiddlewareInit?.Invoke(appBuilder);
@@ -100,9 +99,9 @@ internal partial class AspNetCoreSelfHost : IOwinSelfHost
})
.ConfigureKestrelServerOptions()
#if NETSTANDARD1_3
.UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray())
#endif
//#if NETSTANDARD1_3
// .UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray())
//#endif
.Build();
return RunHost(_cts.Token);
@@ -112,7 +111,7 @@ internal partial class AspNetCoreSelfHost : IOwinSelfHost
{
try
{
#if NETCOREAPP3_1 || NET5_0_OR_GREATER
#if NET8_0_OR_GREATER
var appLifetime = _host.Services.GetRequiredService<Microsoft.Extensions.Hosting.IHostApplicationLifetime>();
#else
var appLifetime = _host.Services.GetRequiredService<IApplicationLifetime>();
@@ -134,23 +133,9 @@ internal partial class AspNetCoreSelfHost : IOwinSelfHost
IsStarted = true;
});
#if NETSTANDARD1_3
_logger.Info("Server using netstandard1.3");
#elif NETSTANDARD2_0
_logger.Info("Server using netstandard2.0");
#elif NETSTANDARD2_1
_logger.Info("Server using netstandard2.1");
#elif NETCOREAPP3_1
_logger.Info("Server using .NET Core App 3.1");
#elif NET5_0
_logger.Info("Server using .NET 5.0");
#elif NET6_0
_logger.Info("Server using .NET 6.0");
#elif NET7_0
_logger.Info("Server using .NET 7.0");
#elif NET8_0
#if NET8_0
_logger.Info("Server using .NET 8.0");
#elif NET46
#elif NET48
_logger.Info("Server using .NET Framework 4.6.1 or higher");
#endif
@@ -179,11 +164,11 @@ internal partial class AspNetCoreSelfHost : IOwinSelfHost
_cts.Cancel();
IsStarted = false;
#if NETSTANDARD1_3
return Task.CompletedTask;
#else
//#if NETSTANDARD1_3
// return Task.CompletedTask;
//#else
return _host.StopAsync();
#endif
//#endif
}
}
#endif
//#endif

View File

@@ -3,68 +3,69 @@
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
#if !USE_ASPNETCORE
using Microsoft.Owin;
using IContext = Microsoft.Owin.IOwinContext;
using OwinMiddleware = Microsoft.Owin.OwinMiddleware;
using Next = Microsoft.Owin.OwinMiddleware;
#else
using OwinMiddleware = System.Object;
using IContext = Microsoft.AspNetCore.Http.HttpContext;
using Next = Microsoft.AspNetCore.Http.RequestDelegate;
#endif
using WireMock.Owin.Mappers;
using Stef.Validation;
using Microsoft.AspNetCore.Http;
//#if !USE_ASPNETCORE
//using Microsoft.Owin;
//using IContext = Microsoft.Owin.IOwinContext;
//using OwinMiddleware = Microsoft.Owin.OwinMiddleware;
//using Next = Microsoft.Owin.OwinMiddleware;
//#else
//using OwinMiddleware = System.Object;
//using IContext = Microsoft.AspNetCore.Http.HttpContext;
//using Next = Microsoft.AspNetCore.Http.RequestDelegate;
//#endif
namespace WireMock.Owin
namespace WireMock.Owin;
internal class GlobalExceptionMiddleware //: OwinMiddleware
{
internal class GlobalExceptionMiddleware : OwinMiddleware
private readonly IWireMockMiddlewareOptions _options;
private readonly IOwinResponseMapper _responseMapper;
//#if !USE_ASPNETCORE
// public GlobalExceptionMiddleware(Next next, IWireMockMiddlewareOptions options, IOwinResponseMapper responseMapper) : base(next)
// {
// _options = Guard.NotNull(options);
// _responseMapper = Guard.NotNull(responseMapper);;
// }
//#else
public GlobalExceptionMiddleware(RequestDelegate next, IWireMockMiddlewareOptions options, IOwinResponseMapper responseMapper)
{
private readonly IWireMockMiddlewareOptions _options;
private readonly IOwinResponseMapper _responseMapper;
Next = next;
_options = Guard.NotNull(options);
_responseMapper = Guard.NotNull(responseMapper);
}
//#endif
#if !USE_ASPNETCORE
public GlobalExceptionMiddleware(Next next, IWireMockMiddlewareOptions options, IOwinResponseMapper responseMapper) : base(next)
{
_options = Guard.NotNull(options);
_responseMapper = Guard.NotNull(responseMapper);;
}
#else
public GlobalExceptionMiddleware(Next next, IWireMockMiddlewareOptions options, IOwinResponseMapper responseMapper)
{
Next = next;
_options = Guard.NotNull(options);
_responseMapper = Guard.NotNull(responseMapper);
}
#endif
//#if USE_ASPNETCORE
public RequestDelegate? Next { get; }
//#endif
#if USE_ASPNETCORE
public Next Next { get; }
#endif
//#if !USE_ASPNETCORE
// public override Task Invoke(IContext ctx)
//#else
public Task Invoke(HttpContext ctx)
//#endif
{
return InvokeInternalAsync(ctx);
}
#if !USE_ASPNETCORE
public override Task Invoke(IContext ctx)
#else
public Task Invoke(IContext ctx)
#endif
private async Task InvokeInternalAsync(HttpContext ctx)
{
try
{
return InvokeInternalAsync(ctx);
}
private async Task InvokeInternalAsync(IContext ctx)
{
try
if (Next != null)
{
if (Next != null)
{
await Next.Invoke(ctx).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_options.Logger.Error("HttpStatusCode set to 500 {0}", ex);
await _responseMapper.MapAsync(ResponseMessageBuilder.Create(500, JsonConvert.SerializeObject(ex)), ctx.Response).ConfigureAwait(false);
await Next.Invoke(ctx).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_options.Logger.Error("HttpStatusCode set to 500 {0}", ex);
await _responseMapper.MapAsync(ResponseMessageBuilder.Create(500, JsonConvert.SerializeObject(ex)), ctx.Response).ConfigureAwait(false);
}
}
}
}

View File

@@ -2,21 +2,22 @@
using System;
using System.Collections.Concurrent;
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using WireMock.Handlers;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.Types;
using WireMock.Util;
using System.Security.Cryptography.X509Certificates;
using ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode;
using JetBrains.Annotations;
#if !USE_ASPNETCORE
using Owin;
#else
using IAppBuilder = Microsoft.AspNetCore.Builder.IApplicationBuilder;
using Microsoft.Extensions.DependencyInjection;
#endif
//#if !USE_ASPNETCORE
//using Owin;
//#else
//using IAppBuilder = Microsoft.AspNetCore.Builder.IApplicationBuilder;
//using Microsoft.Extensions.DependencyInjection;
//#endif
namespace WireMock.Owin;
@@ -40,11 +41,11 @@ internal interface IWireMockMiddlewareOptions
int? MaxRequestLogCount { get; set; }
Action<IAppBuilder>? PreWireMockMiddlewareInit { get; set; }
Action<IApplicationBuilder>? PreWireMockMiddlewareInit { get; set; }
Action<IAppBuilder>? PostWireMockMiddlewareInit { get; set; }
Action<IApplicationBuilder>? PostWireMockMiddlewareInit { get; set; }
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
Action<IServiceCollection>? AdditionalServiceRegistration { get; set; }
CorsPolicyOptions? CorsPolicyOptions { get; set; }
@@ -52,7 +53,7 @@ internal interface IWireMockMiddlewareOptions
ClientCertificateMode ClientCertificateMode { get; set; }
bool AcceptAnyClientCertificate { get; set; }
#endif
//#endif
IFileSystemHandler? FileSystemHandler { get; set; }

View File

@@ -1,25 +1,25 @@
// Copyright © WireMock.Net
using System.Threading.Tasks;
#if !USE_ASPNETCORE
using IRequest = Microsoft.Owin.IOwinRequest;
#else
using IRequest = Microsoft.AspNetCore.Http.HttpRequest;
#endif
using Microsoft.AspNetCore.Http;
//#if !USE_ASPNETCORE
//using IRequest = Microsoft.Owin.IOwinRequest;
//#else
//using IRequest = Microsoft.AspNetCore.Http.HttpRequest;
//#endif
namespace WireMock.Owin.Mappers
namespace WireMock.Owin.Mappers;
/// <summary>
/// IOwinRequestMapper
/// </summary>
internal interface IOwinRequestMapper
{
/// <summary>
/// IOwinRequestMapper
/// MapAsync IRequest to RequestMessage
/// </summary>
internal interface IOwinRequestMapper
{
/// <summary>
/// MapAsync IRequest to RequestMessage
/// </summary>
/// <param name="request">The OwinRequest/HttpRequest</param>
/// <param name="options">The WireMockMiddlewareOptions</param>
/// <returns>RequestMessage</returns>
Task<RequestMessage> MapAsync(IRequest request, IWireMockMiddlewareOptions options);
}
/// <param name="request">The HttpRequest</param>
/// <param name="options">The WireMockMiddlewareOptions</param>
/// <returns>RequestMessage</returns>
Task<RequestMessage> MapAsync(HttpRequest request, IWireMockMiddlewareOptions options);
}

View File

@@ -1,11 +1,13 @@
// Copyright © WireMock.Net
using System.Threading.Tasks;
#if !USE_ASPNETCORE
using IResponse = Microsoft.Owin.IOwinResponse;
#else
using IResponse = Microsoft.AspNetCore.Http.HttpResponse;
#endif
using Microsoft.AspNetCore.Http;
//#if !USE_ASPNETCORE
//using IResponse = Microsoft.Owin.IOwinResponse;
//#else
//using IResponse = Microsoft.AspNetCore.Http.HttpResponse;
//#endif
namespace WireMock.Owin.Mappers;
@@ -18,6 +20,6 @@ internal interface IOwinResponseMapper
/// Map ResponseMessage to IResponse.
/// </summary>
/// <param name="responseMessage">The ResponseMessage</param>
/// <param name="response">The OwinResponse/HttpResponse</param>
Task MapAsync(IResponseMessage? responseMessage, IResponse response);
}
/// <param name="response">The HttpResponse</param>
Task MapAsync(IResponseMessage? responseMessage, HttpResponse response);
}

View File

@@ -4,15 +4,17 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using WireMock.Http;
using WireMock.Models;
using WireMock.Util;
#if !USE_ASPNETCORE
using IRequest = Microsoft.Owin.IOwinRequest;
#else
using Microsoft.AspNetCore.Http.Extensions;
using IRequest = Microsoft.AspNetCore.Http.HttpRequest;
#endif
//#if !USE_ASPNETCORE
//using IRequest = Microsoft.Owin.IOwinRequest;
//#else
//using Microsoft.AspNetCore.Http.Extensions;
//using IRequest = Microsoft.AspNetCore.Http.HttpRequest;
//#endif
namespace WireMock.Owin.Mappers;
@@ -22,7 +24,7 @@ namespace WireMock.Owin.Mappers;
internal class OwinRequestMapper : IOwinRequestMapper
{
/// <inheritdoc />
public async Task<RequestMessage> MapAsync(IRequest request, IWireMockMiddlewareOptions options)
public async Task<RequestMessage> MapAsync(HttpRequest request, IWireMockMiddlewareOptions options)
{
var (urlDetails, clientIP) = ParseRequest(request);
@@ -83,12 +85,12 @@ internal class OwinRequestMapper : IOwinRequestMapper
};
}
private static (UrlDetails UrlDetails, string ClientIP) ParseRequest(IRequest request)
private static (UrlDetails UrlDetails, string ClientIP) ParseRequest(HttpRequest request)
{
#if !USE_ASPNETCORE
var urlDetails = UrlUtils.Parse(request.Uri, request.PathBase);
var clientIP = request.RemoteIpAddress;
#else
//#if !USE_ASPNETCORE
// var urlDetails = UrlUtils.Parse(request.Uri, request.PathBase);
// var clientIP = request.RemoteIpAddress;
//#else
var urlDetails = UrlUtils.Parse(new Uri(request.GetEncodedUrl()), request.PathBase);
var connection = request.HttpContext.Connection;
@@ -105,7 +107,7 @@ internal class OwinRequestMapper : IOwinRequestMapper
{
clientIP = connection.RemoteIpAddress.ToString();
}
#endif
//#endif
return (urlDetails, clientIP);
}
}

View File

@@ -8,21 +8,22 @@ using System.Net;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using RandomDataGenerator.FieldOptions;
using RandomDataGenerator.Randomizers;
using Stef.Validation;
using WireMock.Http;
using WireMock.ResponseBuilders;
using WireMock.Types;
using Stef.Validation;
using WireMock.Util;
#if !USE_ASPNETCORE
using IResponse = Microsoft.Owin.IOwinResponse;
#else
using Microsoft.AspNetCore.Http;
using IResponse = Microsoft.AspNetCore.Http.HttpResponse;
#endif
//#if !USE_ASPNETCORE
//using IResponse = Microsoft.Owin.IOwinResponse;
//#else
//using Microsoft.AspNetCore.Http;
//using IResponse = Microsoft.AspNetCore.Http.HttpResponse;
//#endif
namespace WireMock.Owin.Mappers
{
@@ -37,8 +38,8 @@ namespace WireMock.Owin.Mappers
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
// https://msdn.microsoft.com/en-us/library/78h415ay(v=vs.110).aspx
private static readonly IDictionary<string, Action<IResponse, bool, WireMockList<string>>> ResponseHeadersToFix =
new Dictionary<string, Action<IResponse, bool, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase)
private static readonly IDictionary<string, Action<HttpResponse, bool, WireMockList<string>>> ResponseHeadersToFix =
new Dictionary<string, Action<HttpResponse, bool, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase)
{
{ HttpKnownHeaderNames.ContentType, (r, _, v) => r.ContentType = v.FirstOrDefault() },
{ HttpKnownHeaderNames.ContentLength, (r, hasBody, v) =>
@@ -62,7 +63,7 @@ namespace WireMock.Owin.Mappers
}
/// <inheritdoc />
public async Task MapAsync(IResponseMessage? responseMessage, IResponse response)
public async Task MapAsync(IResponseMessage? responseMessage, HttpResponse response)
{
if (responseMessage == null)
{
@@ -128,7 +129,7 @@ namespace WireMock.Owin.Mappers
SetResponseTrailingHeaders(responseMessage, response);
}
private static async Task HandleSseStringAsync(IResponseMessage responseMessage, IResponse response, IBodyData bodyData)
private static async Task HandleSseStringAsync(IResponseMessage responseMessage, HttpResponse response, IBodyData bodyData)
{
if (bodyData.SseStringQueue == null)
{
@@ -199,7 +200,7 @@ namespace WireMock.Owin.Mappers
return null;
}
private static void SetResponseHeaders(IResponseMessage responseMessage, bool hasBody, IResponse response)
private static void SetResponseHeaders(IResponseMessage responseMessage, bool hasBody, HttpResponse response)
{
// Force setting the Date header (#577)
AppendResponseHeader(
@@ -215,7 +216,7 @@ namespace WireMock.Owin.Mappers
var value = item.Value;
if (ResponseHeadersToFix.TryGetValue(headerName, out var action))
{
action?.Invoke(response, hasBody, value);
action.Invoke(response, hasBody, value);
}
else
{
@@ -228,7 +229,7 @@ namespace WireMock.Owin.Mappers
}
}
private static void SetResponseTrailingHeaders(IResponseMessage responseMessage, IResponse response)
private static void SetResponseTrailingHeaders(IResponseMessage responseMessage, HttpResponse response)
{
if (responseMessage.TrailingHeaders == null)
{
@@ -236,13 +237,11 @@ namespace WireMock.Owin.Mappers
}
#if TRAILINGHEADERS
foreach (var item in responseMessage.TrailingHeaders)
foreach (var (headerName, value) in responseMessage.TrailingHeaders)
{
var headerName = item.Key;
var value = item.Value;
if (ResponseHeadersToFix.TryGetValue(headerName, out var action))
{
action?.Invoke(response, false, value);
action.Invoke(response, false, value);
}
else
{
@@ -256,13 +255,13 @@ namespace WireMock.Owin.Mappers
#endif
}
private static void AppendResponseHeader(IResponse response, string headerName, string[] values)
private static void AppendResponseHeader(HttpResponse response, string headerName, string[] values)
{
#if !USE_ASPNETCORE
response.Headers.AppendValues(headerName, values);
#else
//#if !USE_ASPNETCORE
// response.Headers.AppendValues(headerName, values);
//#else
response.Headers.Append(headerName, values);
#endif
//#endif
}
}
}

View File

@@ -1,114 +1,112 @@
// Copyright © WireMock.Net
#if !USE_ASPNETCORE
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;
using WireMock.Services;
using WireMock.Util;
//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;
//using WireMock.Services;
//using WireMock.Util;
namespace WireMock.Owin;
//namespace WireMock.Owin;
internal class OwinSelfHost : IOwinSelfHost
{
private readonly IWireMockMiddlewareOptions _options;
private readonly CancellationTokenSource _cts = new();
private readonly IWireMockLogger _logger;
//internal class OwinSelfHost : IOwinSelfHost
//{
// private readonly IWireMockMiddlewareOptions _options;
// private readonly CancellationTokenSource _cts = new();
// private readonly IWireMockLogger _logger;
private Exception? _runningException;
// private Exception? _runningException;
public OwinSelfHost(IWireMockMiddlewareOptions options, HostUrlOptions urlOptions)
{
Guard.NotNull(urlOptions);
// public OwinSelfHost(IWireMockMiddlewareOptions options, HostUrlOptions urlOptions)
// {
// Guard.NotNull(urlOptions);
_options = Guard.NotNull(options);
_logger = options.Logger ?? new WireMockConsoleLogger();
// _options = Guard.NotNull(options);
// _logger = options.Logger ?? new WireMockConsoleLogger();
foreach (var detail in urlOptions.GetDetails())
{
Urls.Add(detail.Url);
Ports.Add(detail.Port);
}
}
// foreach (var detail in urlOptions.GetDetails())
// {
// Urls.Add(detail.Url);
// Ports.Add(detail.Port);
// }
// }
public bool IsStarted { get; private set; }
// public bool IsStarted { get; private set; }
public List<string> Urls { get; } = new();
// public List<string> Urls { get; } = new();
public List<int> Ports { get; } = new();
// public List<int> Ports { get; } = new();
public Exception? RunningException => _runningException;
// public Exception? RunningException => _runningException;
[PublicAPI]
public Task StartAsync()
{
return Task.Run(StartServers, _cts.Token);
}
// [PublicAPI]
// public Task StartAsync()
// {
// return Task.Run(StartServers, _cts.Token);
// }
[PublicAPI]
public Task StopAsync()
{
_cts.Cancel();
// [PublicAPI]
// public Task StopAsync()
// {
// _cts.Cancel();
return Task.FromResult(true);
}
// return Task.FromResult(true);
// }
private void StartServers()
{
#if NET46
_logger.Info("Server using .net 4.6");
#else
_logger.Info("Server using .net 4.5.x");
#endif
var servers = new List<IDisposable>();
// private void StartServers()
// {
//#if NET46
// _logger.Info("Server using .net 4.6");
//#else
// _logger.Info("Server using .net 4.5.x");
//#endif
// var servers = new List<IDisposable>();
try
{
var requestMapper = new OwinRequestMapper();
var responseMapper = new OwinResponseMapper(_options);
var matcher = new MappingMatcher(_options, new RandomizerDoubleBetween0And1());
var guidUtils = new GuidUtils();
// try
// {
// var requestMapper = new OwinRequestMapper();
// var responseMapper = new OwinResponseMapper(_options);
// var matcher = new MappingMatcher(_options, new RandomizerDoubleBetween0And1());
// var guidUtils = new GuidUtils();
Action<IAppBuilder> startup = app =>
{
app.Use<GlobalExceptionMiddleware>(_options, responseMapper);
_options.PreWireMockMiddlewareInit?.Invoke(app);
app.Use<WireMockMiddleware>(_options, requestMapper, responseMapper, matcher, guidUtils);
_options.PostWireMockMiddlewareInit?.Invoke(app);
};
// Action<IAppBuilder> startup = app =>
// {
// app.Use<GlobalExceptionMiddleware>(_options, responseMapper);
// _options.PreWireMockMiddlewareInit?.Invoke(app);
// app.Use<WireMockMiddleware>(_options, requestMapper, responseMapper, matcher, guidUtils);
// _options.PostWireMockMiddlewareInit?.Invoke(app);
// };
foreach (var url in Urls)
{
servers.Add(WebApp.Start(url, startup));
}
// foreach (var url in Urls)
// {
// servers.Add(WebApp.Start(url, startup));
// }
IsStarted = true;
// IsStarted = true;
// WaitHandle is signaled when the token is cancelled,
// which will be more efficient than Thread.Sleep in while loop
_cts.Token.WaitHandle.WaitOne();
}
catch (Exception e)
{
// Expose exception of starting host, otherwise it's hard to be troubleshooting if keeping quiet
// For example, WebApp.Start will fail with System.MissingMemberException if Microsoft.Owin.Host.HttpListener.dll is being located
// https://stackoverflow.com/questions/25090211/owin-httplistener-not-located/31369857
_runningException = e;
_logger.Error(e.ToString());
}
finally
{
IsStarted = false;
// Dispose all servers in finally block to make sure clean up allocated resource on error happening
servers.ForEach(s => s.Dispose());
}
}
}
#endif
// // WaitHandle is signaled when the token is cancelled,
// // which will be more efficient than Thread.Sleep in while loop
// _cts.Token.WaitHandle.WaitOne();
// }
// catch (Exception e)
// {
// // Expose exception of starting host, otherwise it's hard to be troubleshooting if keeping quiet
// // For example, WebApp.Start will fail with System.MissingMemberException if Microsoft.Owin.Host.HttpListener.dll is being located
// // https://stackoverflow.com/questions/25090211/owin-httplistener-not-located/31369857
// _runningException = e;
// _logger.Error(e.ToString());
// }
// finally
// {
// IsStarted = false;
// // Dispose all servers in finally block to make sure clean up allocated resource on error happening
// servers.ForEach(s => s.Dispose());
// }
// }
//}

View File

@@ -1,368 +1,368 @@
// Copyright © WireMock.Net
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Stef.Validation;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.Http;
using WireMock.Owin.Mappers;
using WireMock.Serialization;
using WireMock.ResponseBuilders;
using WireMock.Settings;
using System.Collections.Generic;
using WireMock.Constants;
using WireMock.Exceptions;
using WireMock.Http;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.Owin.Mappers;
using WireMock.ResponseBuilders;
using WireMock.Serialization;
using WireMock.Settings;
using WireMock.Util;
#if !USE_ASPNETCORE
using IContext = Microsoft.Owin.IOwinContext;
using OwinMiddleware = Microsoft.Owin.OwinMiddleware;
using Next = Microsoft.Owin.OwinMiddleware;
#else
using OwinMiddleware = System.Object;
using IContext = Microsoft.AspNetCore.Http.HttpContext;
using Next = Microsoft.AspNetCore.Http.RequestDelegate;
#endif
//#if !USE_ASPNETCORE
//using IContext = Microsoft.Owin.IOwinContext;
//using OwinMiddleware = Microsoft.Owin.OwinMiddleware;
//using Next = Microsoft.Owin.OwinMiddleware;
//#else
//using OwinMiddleware = System.Object;
//using IContext = Microsoft.AspNetCore.Http.HttpContext;
//using Next = Microsoft.AspNetCore.Http.RequestDelegate;
//#endif
namespace WireMock.Owin
namespace WireMock.Owin;
internal class WireMockMiddleware //: OwinMiddleware
{
internal class WireMockMiddleware : OwinMiddleware
private readonly object _lock = new();
private static readonly Task CompletedTask = Task.FromResult(false);
private readonly IWireMockMiddlewareOptions _options;
private readonly IOwinRequestMapper _requestMapper;
private readonly IOwinResponseMapper _responseMapper;
private readonly IMappingMatcher _mappingMatcher;
private readonly LogEntryMapper _logEntryMapper;
private readonly IGuidUtils _guidUtils;
//#if !USE_ASPNETCORE
// public WireMockMiddleware(
// Next next,
// IWireMockMiddlewareOptions options,
// IOwinRequestMapper requestMapper,
// IOwinResponseMapper responseMapper,
// IMappingMatcher mappingMatcher,
// IGuidUtils guidUtils
// ) : base(next)
// {
// _options = Guard.NotNull(options);
// _requestMapper = Guard.NotNull(requestMapper);
// _responseMapper = Guard.NotNull(responseMapper);
// _mappingMatcher = Guard.NotNull(mappingMatcher);
// _logEntryMapper = new LogEntryMapper(options);
// _guidUtils = Guard.NotNull(guidUtils);
// }
//#else
public WireMockMiddleware(
RequestDelegate next,
IWireMockMiddlewareOptions options,
IOwinRequestMapper requestMapper,
IOwinResponseMapper responseMapper,
IMappingMatcher mappingMatcher,
IGuidUtils guidUtils
)
{
private readonly object _lock = new();
private static readonly Task CompletedTask = Task.FromResult(false);
_options = Guard.NotNull(options);
_requestMapper = Guard.NotNull(requestMapper);
_responseMapper = Guard.NotNull(responseMapper);
_mappingMatcher = Guard.NotNull(mappingMatcher);
_logEntryMapper = new LogEntryMapper(options);
_guidUtils = Guard.NotNull(guidUtils);
}
//#endif
private readonly IWireMockMiddlewareOptions _options;
private readonly IOwinRequestMapper _requestMapper;
private readonly IOwinResponseMapper _responseMapper;
private readonly IMappingMatcher _mappingMatcher;
private readonly LogEntryMapper _logEntryMapper;
private readonly IGuidUtils _guidUtils;
#if !USE_ASPNETCORE
public WireMockMiddleware(
Next next,
IWireMockMiddlewareOptions options,
IOwinRequestMapper requestMapper,
IOwinResponseMapper responseMapper,
IMappingMatcher mappingMatcher,
IGuidUtils guidUtils
) : base(next)
//#if !USE_ASPNETCORE
// public override Task Invoke(IContext ctx)
//#else
public Task Invoke(HttpContext ctx)
//#endif
{
if (_options.HandleRequestsSynchronously.GetValueOrDefault(false))
{
_options = Guard.NotNull(options);
_requestMapper = Guard.NotNull(requestMapper);
_responseMapper = Guard.NotNull(responseMapper);
_mappingMatcher = Guard.NotNull(mappingMatcher);
_logEntryMapper = new LogEntryMapper(options);
_guidUtils = Guard.NotNull(guidUtils);
}
#else
public WireMockMiddleware(
Next next,
IWireMockMiddlewareOptions options,
IOwinRequestMapper requestMapper,
IOwinResponseMapper responseMapper,
IMappingMatcher mappingMatcher,
IGuidUtils guidUtils
)
{
_options = Guard.NotNull(options);
_requestMapper = Guard.NotNull(requestMapper);
_responseMapper = Guard.NotNull(responseMapper);
_mappingMatcher = Guard.NotNull(mappingMatcher);
_logEntryMapper = new LogEntryMapper(options);
_guidUtils = Guard.NotNull(guidUtils);
}
#endif
#if !USE_ASPNETCORE
public override Task Invoke(IContext ctx)
#else
public Task Invoke(IContext ctx)
#endif
{
if (_options.HandleRequestsSynchronously.GetValueOrDefault(false))
lock (_lock)
{
lock (_lock)
return InvokeInternalAsync(ctx);
}
}
return InvokeInternalAsync(ctx);
}
private async Task InvokeInternalAsync(HttpContext ctx)
{
var request = await _requestMapper.MapAsync(ctx.Request, _options).ConfigureAwait(false);
var logRequest = false;
IResponseMessage? response = null;
(MappingMatcherResult? Match, MappingMatcherResult? Partial) result = (null, null);
try
{
foreach (var mapping in _options.Mappings.Values)
{
if (mapping.Scenario is null)
{
return InvokeInternalAsync(ctx);
continue;
}
// Set scenario start
if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)
{
_options.Scenarios.TryAdd(mapping.Scenario, new ScenarioState
{
Name = mapping.Scenario
});
}
}
return InvokeInternalAsync(ctx);
}
result = _mappingMatcher.FindBestMatch(request);
private async Task InvokeInternalAsync(IContext ctx)
{
var request = await _requestMapper.MapAsync(ctx.Request, _options).ConfigureAwait(false);
var logRequest = false;
IResponseMessage? response = null;
(MappingMatcherResult? Match, MappingMatcherResult? Partial) result = (null, null);
try
var targetMapping = result.Match?.Mapping;
if (targetMapping == null)
{
foreach (var mapping in _options.Mappings.Values)
logRequest = true;
_options.Logger.Warn("HttpStatusCode set to 404 : No matching mapping found");
response = ResponseMessageBuilder.Create(HttpStatusCode.NotFound, WireMockConstants.NoMatchingFound);
return;
}
logRequest = targetMapping.LogMapping;
if (targetMapping.IsAdminInterface && _options.AuthenticationMatcher != null && request.Headers != null)
{
var authorizationHeaderPresent = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out var authorization);
if (!authorizationHeaderPresent)
{
if (mapping.Scenario is null)
{
continue;
}
// Set scenario start
if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)
{
_options.Scenarios.TryAdd(mapping.Scenario, new ScenarioState
{
Name = mapping.Scenario
});
}
}
result = _mappingMatcher.FindBestMatch(request);
var targetMapping = result.Match?.Mapping;
if (targetMapping == null)
{
logRequest = true;
_options.Logger.Warn("HttpStatusCode set to 404 : No matching mapping found");
response = ResponseMessageBuilder.Create(HttpStatusCode.NotFound, WireMockConstants.NoMatchingFound);
_options.Logger.Error("HttpStatusCode set to 401, authorization header is missing.");
response = ResponseMessageBuilder.Create(HttpStatusCode.Unauthorized, null);
return;
}
logRequest = targetMapping.LogMapping;
if (targetMapping.IsAdminInterface && _options.AuthenticationMatcher != null && request.Headers != null)
var authorizationHeaderMatchResult = _options.AuthenticationMatcher.IsMatch(authorization!.ToString());
if (!MatchScores.IsPerfect(authorizationHeaderMatchResult.Score))
{
var authorizationHeaderPresent = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out var authorization);
if (!authorizationHeaderPresent)
{
_options.Logger.Error("HttpStatusCode set to 401, authorization header is missing.");
response = ResponseMessageBuilder.Create(HttpStatusCode.Unauthorized, null);
return;
}
_options.Logger.Error("HttpStatusCode set to 401, authentication failed.", authorizationHeaderMatchResult.Exception ?? throw new WireMockException("Authentication failed"));
response = ResponseMessageBuilder.Create(HttpStatusCode.Unauthorized, null);
return;
}
}
var authorizationHeaderMatchResult = _options.AuthenticationMatcher.IsMatch(authorization!.ToString());
if (!MatchScores.IsPerfect(authorizationHeaderMatchResult.Score))
{
_options.Logger.Error("HttpStatusCode set to 401, authentication failed.", authorizationHeaderMatchResult.Exception ?? throw new WireMockException("Authentication failed"));
response = ResponseMessageBuilder.Create(HttpStatusCode.Unauthorized, null);
return;
}
if (!targetMapping.IsAdminInterface && _options.RequestProcessingDelay > TimeSpan.Zero)
{
await Task.Delay(_options.RequestProcessingDelay.Value).ConfigureAwait(false);
}
var (theResponse, theOptionalNewMapping) = await targetMapping.ProvideResponseAsync(request).ConfigureAwait(false);
response = theResponse;
var responseBuilder = targetMapping.Provider as Response;
if (!targetMapping.IsAdminInterface && theOptionalNewMapping != null)
{
if (responseBuilder?.ProxyAndRecordSettings?.SaveMapping == true || targetMapping.Settings.ProxyAndRecordSettings?.SaveMapping == true)
{
_options.Mappings.TryAdd(theOptionalNewMapping.Guid, theOptionalNewMapping);
}
if (!targetMapping.IsAdminInterface && _options.RequestProcessingDelay > TimeSpan.Zero)
if (responseBuilder?.ProxyAndRecordSettings?.SaveMappingToFile == true || targetMapping.Settings.ProxyAndRecordSettings?.SaveMappingToFile == true)
{
await Task.Delay(_options.RequestProcessingDelay.Value).ConfigureAwait(false);
var matcherMapper = new MatcherMapper(targetMapping.Settings);
var mappingConverter = new MappingConverter(matcherMapper);
var mappingToFileSaver = new MappingToFileSaver(targetMapping.Settings, mappingConverter);
mappingToFileSaver.SaveMappingToFile(theOptionalNewMapping);
}
}
var (theResponse, theOptionalNewMapping) = await targetMapping.ProvideResponseAsync(request).ConfigureAwait(false);
response = theResponse;
if (targetMapping.Scenario != null)
{
UpdateScenarioState(targetMapping);
}
var responseBuilder = targetMapping.Provider as Response;
if (!targetMapping.IsAdminInterface && targetMapping.Webhooks?.Length > 0)
{
await SendToWebhooksAsync(targetMapping, request, response).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_options.Logger.Error($"Providing a Response for Mapping '{result.Match?.Mapping.Guid}' failed. HttpStatusCode set to 500. Exception: {ex}");
response = ResponseMessageBuilder.Create(500, ex.Message);
}
finally
{
var log = new LogEntry
{
Guid = _guidUtils.NewGuid(),
RequestMessage = request,
ResponseMessage = response,
if (!targetMapping.IsAdminInterface && theOptionalNewMapping != null)
MappingGuid = result.Match?.Mapping?.Guid,
MappingTitle = result.Match?.Mapping?.Title,
RequestMatchResult = result.Match?.RequestMatchResult,
PartialMappingGuid = result.Partial?.Mapping?.Guid,
PartialMappingTitle = result.Partial?.Mapping?.Title,
PartialMatchResult = result.Partial?.RequestMatchResult
};
LogRequest(log, logRequest);
try
{
if (_options.SaveUnmatchedRequests == true && result.Match?.RequestMatchResult is not { IsPerfectMatch: true })
{
if (responseBuilder?.ProxyAndRecordSettings?.SaveMapping == true || targetMapping.Settings.ProxyAndRecordSettings?.SaveMapping == true)
{
_options.Mappings.TryAdd(theOptionalNewMapping.Guid, theOptionalNewMapping);
}
if (responseBuilder?.ProxyAndRecordSettings?.SaveMappingToFile == true || targetMapping.Settings.ProxyAndRecordSettings?.SaveMappingToFile == true)
{
var matcherMapper = new MatcherMapper(targetMapping.Settings);
var mappingConverter = new MappingConverter(matcherMapper);
var mappingToFileSaver = new MappingToFileSaver(targetMapping.Settings, mappingConverter);
mappingToFileSaver.SaveMappingToFile(theOptionalNewMapping);
}
var filename = $"{log.Guid}.LogEntry.json";
_options.FileSystemHandler?.WriteUnmatchedRequest(filename, JsonUtils.Serialize(log));
}
}
catch
{
// Empty catch
}
if (targetMapping.Scenario != null)
{
UpdateScenarioState(targetMapping);
}
if (!targetMapping.IsAdminInterface && targetMapping.Webhooks?.Length > 0)
{
await SendToWebhooksAsync(targetMapping, request, response).ConfigureAwait(false);
}
try
{
await _responseMapper.MapAsync(response, ctx.Response).ConfigureAwait(false);
}
catch (Exception ex)
{
_options.Logger.Error($"Providing a Response for Mapping '{result.Match?.Mapping.Guid}' failed. HttpStatusCode set to 500. Exception: {ex}");
response = ResponseMessageBuilder.Create(500, ex.Message);
_options.Logger.Error("HttpStatusCode set to 404 : No matching mapping found", ex);
var notFoundResponse = ResponseMessageBuilder.Create(HttpStatusCode.NotFound, WireMockConstants.NoMatchingFound);
await _responseMapper.MapAsync(notFoundResponse, ctx.Response).ConfigureAwait(false);
}
finally
}
await CompletedTask.ConfigureAwait(false);
}
private async Task SendToWebhooksAsync(IMapping mapping, IRequestMessage request, IResponseMessage response)
{
var tasks = new List<Func<Task>>();
for (int index = 0; index < mapping.Webhooks?.Length; index++)
{
var httpClientForWebhook = HttpClientBuilder.Build(mapping.Settings.WebhookSettings ?? new WebhookSettings());
var webhookSender = new WebhookSender(mapping.Settings);
var webhookRequest = mapping.Webhooks[index].Request;
var webHookIndex = index;
tasks.Add(async () =>
{
var log = new LogEntry
{
Guid = _guidUtils.NewGuid(),
RequestMessage = request,
ResponseMessage = response,
MappingGuid = result.Match?.Mapping?.Guid,
MappingTitle = result.Match?.Mapping?.Title,
RequestMatchResult = result.Match?.RequestMatchResult,
PartialMappingGuid = result.Partial?.Mapping?.Guid,
PartialMappingTitle = result.Partial?.Mapping?.Title,
PartialMatchResult = result.Partial?.RequestMatchResult
};
LogRequest(log, logRequest);
try
{
if (_options.SaveUnmatchedRequests == true && result.Match?.RequestMatchResult is not { IsPerfectMatch: true })
var result = await webhookSender.SendAsync(httpClientForWebhook, mapping, webhookRequest, request, response).ConfigureAwait(false);
if (!result.IsSuccessStatusCode)
{
var filename = $"{log.Guid}.LogEntry.json";
_options.FileSystemHandler?.WriteUnmatchedRequest(filename, JsonUtils.Serialize(log));
var content = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
_options.Logger.Warn($"Sending message to Webhook [{webHookIndex}] from Mapping '{mapping.Guid}' failed. HttpStatusCode: {result.StatusCode} Content: {content}");
}
}
catch
{
// Empty catch
}
try
{
await _responseMapper.MapAsync(response, ctx.Response).ConfigureAwait(false);
}
catch (Exception ex)
{
_options.Logger.Error("HttpStatusCode set to 404 : No matching mapping found", ex);
var notFoundResponse = ResponseMessageBuilder.Create(HttpStatusCode.NotFound, WireMockConstants.NoMatchingFound);
await _responseMapper.MapAsync(notFoundResponse, ctx.Response).ConfigureAwait(false);
_options.Logger.Error($"Sending message to Webhook [{webHookIndex}] from Mapping '{mapping.Guid}' failed. Exception: {ex}");
}
}
await CompletedTask.ConfigureAwait(false);
});
}
private async Task SendToWebhooksAsync(IMapping mapping, IRequestMessage request, IResponseMessage response)
if (mapping.UseWebhooksFireAndForget == true)
{
var tasks = new List<Func<Task>>();
for (int index = 0; index < mapping.Webhooks?.Length; index++)
try
{
var httpClientForWebhook = HttpClientBuilder.Build(mapping.Settings.WebhookSettings ?? new WebhookSettings());
var webhookSender = new WebhookSender(mapping.Settings);
var webhookRequest = mapping.Webhooks[index].Request;
var webHookIndex = index;
tasks.Add(async () =>
// Do not wait
await Task.Run(() =>
{
try
{
var result = await webhookSender.SendAsync(httpClientForWebhook, mapping, webhookRequest, request, response).ConfigureAwait(false);
if (!result.IsSuccessStatusCode)
{
var content = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
_options.Logger.Warn($"Sending message to Webhook [{webHookIndex}] from Mapping '{mapping.Guid}' failed. HttpStatusCode: {result.StatusCode} Content: {content}");
}
}
catch (Exception ex)
{
_options.Logger.Error($"Sending message to Webhook [{webHookIndex}] from Mapping '{mapping.Guid}' failed. Exception: {ex}");
}
Task.WhenAll(tasks.Select(async task => await task.Invoke())).ConfigureAwait(false);
});
}
if (mapping.UseWebhooksFireAndForget == true)
{
try
{
// Do not wait
await Task.Run(() =>
{
Task.WhenAll(tasks.Select(async task => await task.Invoke())).ConfigureAwait(false);
});
}
catch
{
// Ignore
}
}
else
{
await Task.WhenAll(tasks.Select(async task => await task.Invoke())).ConfigureAwait(false);
}
}
private void UpdateScenarioState(IMapping mapping)
{
var scenario = _options.Scenarios[mapping.Scenario!];
// Increase the number of times this state has been executed
scenario.Counter++;
// Only if the number of times this state is executed equals the required StateTimes, proceed to next state and reset the counter to 0
if (scenario.Counter == (mapping.TimesInSameState ?? 1))
{
scenario.NextState = mapping.NextState;
scenario.Counter = 0;
}
// Else just update Started and Finished
scenario.Started = true;
scenario.Finished = mapping.NextState == null;
}
private void LogRequest(LogEntry entry, bool addRequest)
{
_options.Logger.DebugRequestResponse(_logEntryMapper.Map(entry), entry.RequestMessage.Path.StartsWith("/__admin/"));
// If addRequest is set to true and MaxRequestLogCount is null or does have a value greater than 0, try to add a new request log.
if (addRequest && _options.MaxRequestLogCount is null or > 0)
{
TryAddLogEntry(entry);
}
// In case MaxRequestLogCount has a value greater than 0, try to delete existing request logs based on the count.
if (_options.MaxRequestLogCount is > 0)
{
var logEntries = _options.LogEntries.ToList();
foreach (var logEntry in logEntries.OrderBy(le => le.RequestMessage.DateTime).Take(logEntries.Count - _options.MaxRequestLogCount.Value))
{
TryRemoveLogEntry(logEntry);
}
}
// In case RequestLogExpirationDuration has a value greater than 0, try to delete existing request logs based on the date.
if (_options.RequestLogExpirationDuration is > 0)
{
var checkTime = DateTime.UtcNow.AddHours(-_options.RequestLogExpirationDuration.Value);
foreach (var logEntry in _options.LogEntries.ToList().Where(le => le.RequestMessage.DateTime < checkTime))
{
TryRemoveLogEntry(logEntry);
}
}
}
private void TryAddLogEntry(LogEntry logEntry)
{
try
{
_options.LogEntries.Add(logEntry);
}
catch
{
// Ignore exception (can happen during stress testing)
// Ignore
}
}
else
{
await Task.WhenAll(tasks.Select(async task => await task.Invoke())).ConfigureAwait(false);
}
}
private void UpdateScenarioState(IMapping mapping)
{
var scenario = _options.Scenarios[mapping.Scenario!];
// Increase the number of times this state has been executed
scenario.Counter++;
// Only if the number of times this state is executed equals the required StateTimes, proceed to next state and reset the counter to 0
if (scenario.Counter == (mapping.TimesInSameState ?? 1))
{
scenario.NextState = mapping.NextState;
scenario.Counter = 0;
}
// Else just update Started and Finished
scenario.Started = true;
scenario.Finished = mapping.NextState == null;
}
private void LogRequest(LogEntry entry, bool addRequest)
{
_options.Logger.DebugRequestResponse(_logEntryMapper.Map(entry), entry.RequestMessage.Path.StartsWith("/__admin/"));
// If addRequest is set to true and MaxRequestLogCount is null or does have a value greater than 0, try to add a new request log.
if (addRequest && _options.MaxRequestLogCount is null or > 0)
{
TryAddLogEntry(entry);
}
// In case MaxRequestLogCount has a value greater than 0, try to delete existing request logs based on the count.
if (_options.MaxRequestLogCount is > 0)
{
var logEntries = _options.LogEntries.ToList();
foreach (var logEntry in logEntries.OrderBy(le => le.RequestMessage.DateTime).Take(logEntries.Count - _options.MaxRequestLogCount.Value))
{
TryRemoveLogEntry(logEntry);
}
}
private void TryRemoveLogEntry(LogEntry logEntry)
// In case RequestLogExpirationDuration has a value greater than 0, try to delete existing request logs based on the date.
if (_options.RequestLogExpirationDuration is > 0)
{
try
var checkTime = DateTime.UtcNow.AddHours(-_options.RequestLogExpirationDuration.Value);
foreach (var logEntry in _options.LogEntries.ToList().Where(le => le.RequestMessage.DateTime < checkTime))
{
_options.LogEntries.Remove(logEntry);
}
catch
{
// Ignore exception (can happen during stress testing)
TryRemoveLogEntry(logEntry);
}
}
}
}
private void TryAddLogEntry(LogEntry logEntry)
{
try
{
_options.LogEntries.Add(logEntry);
}
catch
{
// Ignore exception (can happen during stress testing)
}
}
private void TryRemoveLogEntry(LogEntry logEntry)
{
try
{
_options.LogEntries.Remove(logEntry);
}
catch
{
// Ignore exception (can happen during stress testing)
}
}
}

View File

@@ -8,13 +8,17 @@ using WireMock.Matchers;
using WireMock.Types;
using WireMock.Util;
using System.Security.Cryptography.X509Certificates;
#if !USE_ASPNETCORE
using Owin;
#else
using IAppBuilder = Microsoft.AspNetCore.Builder.IApplicationBuilder;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.DependencyInjection;
#endif
using ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode;
//#if !USE_ASPNETCORE
//using Owin;
//#else
//using IAppBuilder = Microsoft.AspNetCore.Builder.IApplicationBuilder;
//using Microsoft.Extensions.DependencyInjection;
//#endif
namespace WireMock.Owin;
@@ -38,11 +42,11 @@ internal class WireMockMiddlewareOptions : IWireMockMiddlewareOptions
public int? MaxRequestLogCount { get; set; }
public Action<IAppBuilder>? PreWireMockMiddlewareInit { get; set; }
public Action<IApplicationBuilder>? PreWireMockMiddlewareInit { get; set; }
public Action<IAppBuilder>? PostWireMockMiddlewareInit { get; set; }
public Action<IApplicationBuilder>? PostWireMockMiddlewareInit { get; set; }
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
public Action<IServiceCollection>? AdditionalServiceRegistration { get; set; }
public CorsPolicyOptions? CorsPolicyOptions { get; set; }
@@ -51,7 +55,7 @@ internal class WireMockMiddlewareOptions : IWireMockMiddlewareOptions
/// <inheritdoc />
public bool AcceptAnyClientCertificate { get; set; }
#endif
//#endif
/// <inheritdoc cref="IWireMockMiddlewareOptions.FileSystemHandler"/>
public IFileSystemHandler? FileSystemHandler { get; set; }

View File

@@ -6,9 +6,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
#if USE_ASPNETCORE
using System.Security.Cryptography.X509Certificates;
#endif
//#if USE_ASPNETCORE
//using System.Security.Cryptography.X509Certificates;
//#endif
using Stef.Validation;
using WireMock.Models;
using WireMock.Owin;
@@ -82,11 +83,11 @@ public class RequestMessage : IRequestMessage
/// <inheritdoc />
public byte[]? BodyAsBytes { get; }
#if MIMEKIT
//#if MIMEKIT
/// <inheritdoc />
[Newtonsoft.Json.JsonIgnore] // Issue 1001
public Models.Mime.IMimeMessageData? BodyAsMimeMessage { get; }
#endif
//#endif
/// <inheritdoc />
public string? DetectedBodyType { get; }
@@ -109,10 +110,10 @@ public class RequestMessage : IRequestMessage
/// <inheritdoc />
public string Origin { get; }
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
/// <inheritdoc />
public X509Certificate2? ClientCertificate { get; }
#endif
//#endif
/// <summary>
/// Used for Unit Testing
@@ -136,9 +137,9 @@ public class RequestMessage : IRequestMessage
IDictionary<string, string[]>? headers = null,
IDictionary<string, string>? cookies = null,
string httpVersion = "1.1"
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
, X509Certificate2? clientCertificate = null
#endif
//#endif
)
{
Guard.NotNull(urlDetails);
@@ -178,9 +179,9 @@ public class RequestMessage : IRequestMessage
Query = QueryStringParser.Parse(RawQuery, options?.QueryParameterMultipleValueSupport);
QueryIgnoreCase = new Dictionary<string, WireMockList<string>>(Query, StringComparer.OrdinalIgnoreCase);
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
ClientCertificate = clientCertificate;
#endif
//#endif
#if MIMEKIT
try
@@ -206,7 +207,6 @@ public class RequestMessage : IRequestMessage
}
var query = !ignoreCase ? Query : new Dictionary<string, WireMockList<string>>(Query, StringComparer.OrdinalIgnoreCase);
return query.ContainsKey(key) ? query[key] : null;
return query.TryGetValue(key, out var value) ? value : null;
}
}

View File

@@ -295,11 +295,11 @@ public partial class WireMockServer
WatchStaticMappings = _settings.WatchStaticMappings,
WatchStaticMappingsInSubdirectories = _settings.WatchStaticMappingsInSubdirectories,
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
AcceptAnyClientCertificate = _settings.AcceptAnyClientCertificate,
ClientCertificateMode = _settings.ClientCertificateMode,
CorsPolicyOptions = _settings.CorsPolicyOptions?.ToString()
#endif
//#endif
};
model.ProxyAndRecordSettings = TinyMapperUtils.Instance.Map(_settings.ProxyAndRecordSettings);
@@ -333,12 +333,12 @@ public partial class WireMockServer
InitSettings(_settings);
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
if (Enum.TryParse<CorsPolicyOptions>(settings.CorsPolicyOptions, true, out var corsPolicyOptions))
{
_settings.CorsPolicyOptions = corsPolicyOptions;
}
#endif
//#endif
WireMockMiddlewareOptionsHelper.InitFromSettings(_settings, _options, o =>
{
@@ -347,11 +347,11 @@ public partial class WireMockServer
o.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);
}
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
o.CorsPolicyOptions = corsPolicyOptions;
o.ClientCertificateMode = _settings.ClientCertificateMode;
o.ClientCertificateMode = (Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode) _settings.ClientCertificateMode;
o.AcceptAnyClientCertificate = _settings.AcceptAnyClientCertificate;
#endif
//#endif
});
return ResponseMessageBuilder.Create(200, "Settings updated");
@@ -900,6 +900,6 @@ public partial class WireMockServer
}
var singleResult = ((JObject)value).ToObject<T>();
return new[] { singleResult! };
return [singleResult!];
}
}

View File

@@ -62,7 +62,7 @@ public partial class WireMockServer : IWireMockServer
/// <inheritdoc />
[PublicAPI]
public int Port => Ports?.FirstOrDefault() ?? default;
public int Port => Ports?.FirstOrDefault() ?? 0;
/// <inheritdoc />
[PublicAPI]
@@ -411,16 +411,16 @@ public partial class WireMockServer : IWireMockServer
_dateTimeUtils
);
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
_options.AdditionalServiceRegistration = _settings.AdditionalServiceRegistration;
_options.CorsPolicyOptions = _settings.CorsPolicyOptions;
_options.ClientCertificateMode = _settings.ClientCertificateMode;
_options.ClientCertificateMode = (Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode)_settings.ClientCertificateMode;
_options.AcceptAnyClientCertificate = _settings.AcceptAnyClientCertificate;
_httpServer = new AspNetCoreSelfHost(_options, urlOptions);
#else
_httpServer = new OwinSelfHost(_options, urlOptions);
#endif
//#else
// _httpServer = new OwinSelfHost(_options, urlOptions);
//#endif
var startTask = _httpServer.StartAsync();
using (var ctsStartTimeout = new CancellationTokenSource(settings.StartTimeout))

View File

@@ -1,13 +1,14 @@
// Copyright © WireMock.Net
using System;
using Microsoft.AspNetCore.Http;
using WireMock.Models;
using Stef.Validation;
#if !USE_ASPNETCORE
using Microsoft.Owin;
#else
using Microsoft.AspNetCore.Http;
#endif
//#if !USE_ASPNETCORE
//using Microsoft.Owin;
//#else
//using Microsoft.AspNetCore.Http;
//#endif
namespace WireMock.Util;

View File

@@ -3,7 +3,8 @@
<Description>Minimal version from the lightweight Http Mocking Server for .NET</Description>
<AssemblyTitle>WireMock.Net.Minimal</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<!--<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>-->
<TargetFrameworks>net48;net8.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net.Minimal</AssemblyName>
<PackageId>WireMock.Net.Minimal</PackageId>
@@ -28,7 +29,7 @@
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'">
<!--<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'">
<DefineConstants>$(DefineConstants);NETSTANDARD;USE_ASPNETCORE</DefineConstants>
</PropertyGroup>
@@ -46,9 +47,9 @@
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT;PROTOBUF</DefineConstants>
</PropertyGroup>
</PropertyGroup>-->
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' ">
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0' ">
<DefineConstants>$(DefineConstants);TRAILINGHEADERS</DefineConstants>
</PropertyGroup>
@@ -57,34 +58,55 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="JsonConverter.Abstractions" Version="0.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<!--<PackageReference Include="JsonConverter.Abstractions" Version="0.7.0" />-->
<!--<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />-->
<PackageReference Include="NJsonSchema.Extensions" Version="0.1.0" />
<PackageReference Include="NSwag.Core" Version="13.16.1" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
<PackageReference Include="JmesPath.Net" Version="1.0.330" />
<PackageReference Include="AnyOf" Version="0.4.0" />
<!--<PackageReference Include="AnyOf" Version="0.4.0" />-->
<PackageReference Include="TinyMapper.Signed" Version="4.0.0" />
<PackageReference Include="Nullable" Version="1.3.1">
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.34.0" />
<!--<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</PackageReference>-->
<PackageReference Include="Scriban.Signed" Version="5.5.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard1.3' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net48'">
<!--<PackageReference Include="Polyfill" Version="8.8.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>-->
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.3.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
</ItemGroup>
<!--<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard1.3' ">
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.34.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' or '$(TargetFramework)' == 'net452' ">
<!-- Required for WebRequestHandler -->
--><!-- Required for WebRequestHandler --><!--
<Reference Include="System.Net.Http.WebRequest" />
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.6" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="Scriban.Signed" Version="2.1.4" />
</ItemGroup>
</ItemGroup>-->
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<!--<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.6" />
<PackageReference Include="Microsoft.Owin" Version="4.2.2" />
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="4.0.0" />
@@ -92,17 +114,17 @@
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="Scriban.Signed" Version="2.1.4" />
</ItemGroup>
</ItemGroup>-->
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<!--<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<PackageReference Include="Scriban.Signed" Version="2.1.4" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<!-- https://github.com/wiremock/WireMock.Net/issues/507 -->
--><!-- https://github.com/wiremock/WireMock.Net/issues/507 --><!--
<PackageReference Include="Microsoft.AspNetCore.Server.IIS" Version="2.2.6" />
</ItemGroup>
</ItemGroup>-->
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<!--<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<PackageReference Include="System.Collections.Specialized" Version="4.3.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.7" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="1.1.3" />
@@ -110,24 +132,24 @@
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="Scriban.Signed" Version="2.1.4" />
</ItemGroup>
</ItemGroup>-->
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' ">
<!--<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' ">
<PackageReference Include="Scriban.Signed" Version="5.5.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<!-- https://github.com/wiremock/WireMock.Net/issues/507 -->
--><!-- https://github.com/wiremock/WireMock.Net/issues/507 --><!--
<PackageReference Include="Microsoft.AspNetCore.Server.IIS" Version="2.2.6" />
</ItemGroup>
</ItemGroup>-->
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net5.0' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net8.0'">
<!--<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net5.0' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net8.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Scriban.Signed" Version="5.5.0" />
</ItemGroup>
</ItemGroup>-->
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
<!--<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
<PackageReference Include="System.ComponentModel" Version="4.3.0" />
</ItemGroup>
</ItemGroup>-->
<ItemGroup>
<Compile Update="Server\WireMockServer.*.cs">
@@ -147,9 +169,9 @@
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' ">
<!--<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' ">
<PackageReference Include="Handlebars.Net.Helpers.Xslt" Version="2.5.2" />
</ItemGroup>
</ItemGroup>-->
<!--<ItemGroup>
--><!-- CVE-2021-26701 and https://github.com/wiremock/WireMock.Net/issues/697 --><!--
@@ -159,9 +181,10 @@
<ItemGroup>
<ProjectReference Include="..\WireMock.Net.Shared\WireMock.Net.Shared.csproj" />
<ProjectReference Include="..\WireMock.Org.Abstractions\WireMock.Org.Abstractions.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46'">
<ProjectReference Include="..\WireMock.Net.OpenApiParser\WireMock.Net.OpenApiParser.csproj" />
</ItemGroup>
<!--<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46'">
<ProjectReference Include="..\WireMock.Net.OpenApiParser\WireMock.Net.OpenApiParser.csproj" />
</ItemGroup>-->
</Project>