mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-19 00:27:04 +01:00
Add support for Cors (#714)
This commit is contained in:
@@ -6,8 +6,6 @@ using System.Threading;
|
||||
using log4net;
|
||||
using log4net.Config;
|
||||
using log4net.Repository;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
@@ -35,33 +33,6 @@ namespace WireMock.Net.StandAlone.NETCoreApp
|
||||
|
||||
settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
|
||||
|
||||
/* https://stackoverflow.com/questions/31942037/how-to-enable-cors-in-asp-net-core */
|
||||
/* Enable Cors */
|
||||
var policyName = "MyPolicy";
|
||||
settings.AdditionalServiceRegistration = services =>
|
||||
{
|
||||
services.AddCors(corsOptions =>
|
||||
corsOptions.AddPolicy(policyName,
|
||||
corsPolicyBuilder =>
|
||||
{
|
||||
corsPolicyBuilder
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyOrigin();
|
||||
}));
|
||||
|
||||
settings.Logger.Debug("Enable Cors");
|
||||
};
|
||||
|
||||
/* Use Cors */
|
||||
settings.PreWireMockMiddlewareInit = app =>
|
||||
{
|
||||
var appBuilder = (IApplicationBuilder)app;
|
||||
appBuilder.UseCors(policyName);
|
||||
|
||||
settings.Logger.Debug("Use Cors");
|
||||
};
|
||||
|
||||
_server = WireMockServer.Start(settings);
|
||||
|
||||
_server.Given(Request.Create().WithPath("/api/sap")
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"profiles": {
|
||||
"WireMock.Net.StandAlone.NETCoreApp": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "--Urls http://localhost:9091 --WireMockLogger WireMockConsoleLogger"
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "--Urls http://localhost:9091 --CorsPolicyOptions AllowAll --WireMockLogger WireMockConsoleLogger"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Admin.Settings
|
||||
{
|
||||
@@ -53,5 +54,10 @@ namespace WireMock.Admin.Settings
|
||||
/// Save unmatched requests to a file using the <see cref="IFileSystemHandler"/>. (default set to false).
|
||||
/// </summary>
|
||||
public bool? SaveUnmatchedRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Policies to use when using CORS. By default CORS is disabled. [Optional]
|
||||
/// </summary>
|
||||
public string CorsPolicyOptions { get; set; }
|
||||
}
|
||||
}
|
||||
36
src/WireMock.Net.Abstractions/Types/CorsPolicyOptions.cs
Normal file
36
src/WireMock.Net.Abstractions/Types/CorsPolicyOptions.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace WireMock.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// Policies to use when using CORS.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum CorsPolicyOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Cors is disabled
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the policy allows any header.
|
||||
/// </summary>
|
||||
AllowAnyHeader = 0b00000001,
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the policy allows any method.
|
||||
/// </summary>
|
||||
AllowAnyMethod = 0b00000010,
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the policy allows any origin.
|
||||
/// </summary>
|
||||
AllowAnyOrigin = 0b00000100,
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the policy allows any header, method and origin.
|
||||
/// </summary>
|
||||
AllowAll = AllowAnyHeader | AllowAnyMethod | AllowAnyOrigin
|
||||
}
|
||||
}
|
||||
48
src/WireMock.Net/Owin/AspNetCoreSelfHost.NETCore.cs
Normal file
48
src/WireMock.Net/Owin/AspNetCoreSelfHost.NETCore.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
internal partial class AspNetCoreSelfHost
|
||||
{
|
||||
public void AddCors(IServiceCollection services)
|
||||
{
|
||||
if (_wireMockMiddlewareOptions.CorsPolicyOptions > CorsPolicyOptions.None)
|
||||
{
|
||||
/* https://stackoverflow.com/questions/31942037/how-to-enable-cors-in-asp-net-core */
|
||||
/* Enable Cors */
|
||||
services.AddCors(corsOptions => corsOptions
|
||||
.AddPolicy(CorsPolicyName,
|
||||
corsPolicyBuilder =>
|
||||
{
|
||||
if (_wireMockMiddlewareOptions.CorsPolicyOptions.Value.HasFlag(CorsPolicyOptions.AllowAnyHeader))
|
||||
{
|
||||
corsPolicyBuilder.AllowAnyHeader();
|
||||
}
|
||||
|
||||
if (_wireMockMiddlewareOptions.CorsPolicyOptions.Value.HasFlag(CorsPolicyOptions.AllowAnyMethod))
|
||||
{
|
||||
corsPolicyBuilder.AllowAnyMethod();
|
||||
}
|
||||
|
||||
if (_wireMockMiddlewareOptions.CorsPolicyOptions.Value.HasFlag(CorsPolicyOptions.AllowAnyOrigin))
|
||||
{
|
||||
corsPolicyBuilder.AllowAnyOrigin();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public void UseCors(IApplicationBuilder appBuilder)
|
||||
{
|
||||
if (_wireMockMiddlewareOptions.CorsPolicyOptions > CorsPolicyOptions.None)
|
||||
{
|
||||
/* Use Cors */
|
||||
appBuilder.UseCors(CorsPolicyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,10 +1,11 @@
|
||||
#if USE_ASPNETCORE && !NETSTANDARD1_3
|
||||
#if USE_ASPNETCORE && !NETSTANDARD1_3
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WireMock.HttpsCertificate;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace WireMock.Owin
|
||||
{
|
||||
internal partial class AspNetCoreSelfHost : IOwinSelfHost
|
||||
{
|
||||
private const string CorsPolicyName = "WireMock.Net - Policy";
|
||||
|
||||
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private readonly IWireMockMiddlewareOptions _wireMockMiddlewareOptions;
|
||||
private readonly IWireMockLogger _logger;
|
||||
@@ -68,12 +70,18 @@ namespace WireMock.Owin
|
||||
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
|
||||
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
|
||||
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
AddCors(services);
|
||||
#endif
|
||||
_wireMockMiddlewareOptions.AdditionalServiceRegistration?.Invoke(services);
|
||||
})
|
||||
.Configure(appBuilder =>
|
||||
{
|
||||
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
|
||||
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
UseCors(appBuilder);
|
||||
#endif
|
||||
_wireMockMiddlewareOptions.PreWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||
|
||||
appBuilder.UseMiddleware<WireMockMiddleware>();
|
||||
|
||||
@@ -4,6 +4,8 @@ using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Util;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Types;
|
||||
#if !USE_ASPNETCORE
|
||||
using Owin;
|
||||
#else
|
||||
@@ -39,6 +41,8 @@ namespace WireMock.Owin
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
|
||||
CorsPolicyOptions? CorsPolicyOptions { get; set; }
|
||||
#endif
|
||||
|
||||
IFileSystemHandler FileSystemHandler { get; set; }
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
#if !USE_ASPNETCORE
|
||||
using Owin;
|
||||
@@ -39,6 +40,8 @@ namespace WireMock.Owin
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
public Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
|
||||
public CorsPolicyOptions? CorsPolicyOptions { get; set; }
|
||||
#endif
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.FileSystemHandler"/>
|
||||
|
||||
@@ -293,7 +293,11 @@ namespace WireMock.Server
|
||||
HandleRequestsSynchronously = _settings.HandleRequestsSynchronously,
|
||||
ThrowExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails,
|
||||
UseRegexExtended = _settings.UseRegexExtended,
|
||||
SaveUnmatchedRequests = _settings.SaveUnmatchedRequests
|
||||
SaveUnmatchedRequests = _settings.SaveUnmatchedRequests,
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
CorsPolicyOptions = _settings.CorsPolicyOptions?.ToString()
|
||||
#endif
|
||||
};
|
||||
|
||||
return ToJson(model);
|
||||
@@ -315,6 +319,13 @@ namespace WireMock.Server
|
||||
_settings.UseRegexExtended = settings.UseRegexExtended;
|
||||
_settings.SaveUnmatchedRequests = settings.SaveUnmatchedRequests;
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
if (Enum.TryParse<CorsPolicyOptions>(settings.CorsPolicyOptions, true, out var corsPolicyOptions))
|
||||
{
|
||||
_settings.CorsPolicyOptions = corsPolicyOptions;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ResponseMessageBuilder.Create("Settings updated");
|
||||
}
|
||||
#endregion Settings
|
||||
|
||||
@@ -243,6 +243,8 @@ namespace WireMock.Server
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
_options.AdditionalServiceRegistration = _settings.AdditionalServiceRegistration;
|
||||
_options.CorsPolicyOptions = _settings.CorsPolicyOptions;
|
||||
|
||||
_httpServer = new AspNetCoreSelfHost(_options, urlOptions);
|
||||
#else
|
||||
_httpServer = new OwinSelfHost(_options, urlOptions);
|
||||
|
||||
@@ -11,6 +11,7 @@ using WireMock.Matchers;
|
||||
using WireMock.RegularExpressions;
|
||||
#if USE_ASPNETCORE
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WireMock.Types;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Settings
|
||||
@@ -135,6 +136,12 @@ namespace WireMock.Settings
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Policies to use when using CORS. By default CORS is disabled. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
CorsPolicyOptions? CorsPolicyOptions { get; set; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -7,6 +7,7 @@ using WireMock.Admin.Mappings;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Types;
|
||||
#if USE_ASPNETCORE
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
#endif
|
||||
@@ -97,6 +98,10 @@ namespace WireMock.Settings
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockServerSettings.CorsPolicyOptions"/>
|
||||
[PublicAPI]
|
||||
public CorsPolicyOptions? CorsPolicyOptions { get; set; }
|
||||
#endif
|
||||
|
||||
/// <inheritdoc cref="IWireMockServerSettings.Logger"/>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Logging;
|
||||
using Stef.Validation;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
@@ -50,9 +53,18 @@ namespace WireMock.Settings
|
||||
HandleRequestsSynchronously = parser.GetBoolValue("HandleRequestsSynchronously"),
|
||||
ThrowExceptionWhenMatcherFails = parser.GetBoolValue("ThrowExceptionWhenMatcherFails"),
|
||||
UseRegexExtended = parser.GetBoolValue(nameof(IWireMockServerSettings.UseRegexExtended), true),
|
||||
SaveUnmatchedRequests = parser.GetBoolValue(nameof(IWireMockServerSettings.SaveUnmatchedRequests))
|
||||
SaveUnmatchedRequests = parser.GetBoolValue(nameof(IWireMockServerSettings.SaveUnmatchedRequests)),
|
||||
};
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
settings.CorsPolicyOptions = parser.GetValue(
|
||||
nameof(IWireMockServerSettings.CorsPolicyOptions), values =>
|
||||
{
|
||||
var value = string.Join(string.Empty, values);
|
||||
return Enum.TryParse<CorsPolicyOptions>(value, true, out var corsPolicyOptions) ? corsPolicyOptions : CorsPolicyOptions.None;
|
||||
});
|
||||
#endif
|
||||
|
||||
if (logger != null)
|
||||
{
|
||||
settings.Logger = logger;
|
||||
|
||||
@@ -17,6 +17,7 @@ using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
@@ -97,6 +98,29 @@ namespace WireMock.Net.Tests
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
[Fact]
|
||||
public async Task WireMockServer_WithCorsPolicyOptions_Should_Work_Correct()
|
||||
{
|
||||
// Arrange
|
||||
var settings = new WireMockServerSettings
|
||||
{
|
||||
CorsPolicyOptions = CorsPolicyOptions.AllowAll
|
||||
};
|
||||
var server = WireMockServer.Start(settings);
|
||||
|
||||
server.Given(Request.Create().WithPath("/*")).RespondWith(Response.Create().WithBody("x"));
|
||||
|
||||
// Act
|
||||
var response = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + "/foo").ConfigureAwait(false);
|
||||
|
||||
// Asser.
|
||||
response.Should().Be("x");
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Should_delay_responses_for_a_given_route()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user