This commit is contained in:
Stef Heyenrath
2020-03-25 16:00:15 +00:00
committed by GitHub
parent 8a295e806c
commit 5809fae602
4 changed files with 186 additions and 183 deletions

View File

@@ -1,8 +1,8 @@
{ {
"profiles": { "profiles": {
"WireMock.Net.StandAlone.NETCoreApp": { "WireMock.Net.StandAlone.NETCoreApp": {
"commandName": "Project", "commandName": "Project",
"commandLineArgs": "--Urls http://*:9091 --WireMockLogger WireMockConsoleLogger" "commandLineArgs": "--Port 9091 --WireMockLogger WireMockConsoleLogger"
} }
} }
} }

View File

@@ -1,178 +1,178 @@
#if USE_ASPNETCORE #if USE_ASPNETCORE
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using WireMock.HttpsCertificate; using WireMock.HttpsCertificate;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Owin.Mappers; using WireMock.Owin.Mappers;
using WireMock.Util; using WireMock.Util;
using WireMock.Validation; using WireMock.Validation;
namespace WireMock.Owin namespace WireMock.Owin
{ {
internal class AspNetCoreSelfHost : IOwinSelfHost internal class AspNetCoreSelfHost : IOwinSelfHost
{ {
private readonly CancellationTokenSource _cts = new CancellationTokenSource(); private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly IWireMockMiddlewareOptions _options; private readonly IWireMockMiddlewareOptions _options;
private readonly IWireMockLogger _logger; private readonly IWireMockLogger _logger;
private readonly HostUrlOptions _urlOptions; private readonly HostUrlOptions _urlOptions;
private Exception _runningException; private Exception _runningException;
private IWebHost _host; private IWebHost _host;
public bool IsStarted { get; private set; } public bool IsStarted { get; private set; }
public List<string> Urls { get; } = new List<string>(); public List<string> Urls { get; } = new List<string>();
public List<int> Ports { get; } = new List<int>(); public List<int> Ports { get; } = new List<int>();
public Exception RunningException => _runningException; public Exception RunningException => _runningException;
public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions) public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions)
{ {
Check.NotNull(options, nameof(options)); Check.NotNull(options, nameof(options));
Check.NotNull(urlOptions, nameof(urlOptions)); Check.NotNull(urlOptions, nameof(urlOptions));
_logger = options.Logger ?? new WireMockConsoleLogger(); _logger = options.Logger ?? new WireMockConsoleLogger();
_options = options; _options = options;
_urlOptions = urlOptions; _urlOptions = urlOptions;
} }
public Task StartAsync() public Task StartAsync()
{ {
var builder = new WebHostBuilder(); var builder = new WebHostBuilder();
// Workaround for https://github.com/WireMock-Net/WireMock.Net/issues/292 // Workaround for https://github.com/WireMock-Net/WireMock.Net/issues/292
// On some platforms, AppContext.BaseDirectory is null, which causes WebHostBuilder to fail if ContentRoot is not // On some platforms, AppContext.BaseDirectory is null, which causes WebHostBuilder to fail if ContentRoot is not
// specified (even though we don't actually use that base path mechanism, since we have our own way of configuring // specified (even though we don't actually use that base path mechanism, since we have our own way of configuring
// a filesystem handler). // a filesystem handler).
if (string.IsNullOrEmpty(AppContext.BaseDirectory)) if (string.IsNullOrEmpty(AppContext.BaseDirectory))
{ {
builder.UseContentRoot(System.IO.Directory.GetCurrentDirectory()); builder.UseContentRoot(System.IO.Directory.GetCurrentDirectory());
} }
_host = builder _host = builder
.ConfigureServices(services => .ConfigureServices(services =>
{ {
services.AddSingleton(_options); services.AddSingleton(_options);
services.AddSingleton<IMappingMatcher, MappingMatcher>(); services.AddSingleton<IMappingMatcher, MappingMatcher>();
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>(); services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>(); services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
}) })
.Configure(appBuilder => .Configure(appBuilder =>
{ {
appBuilder.UseMiddleware<GlobalExceptionMiddleware>(); appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder); _options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
appBuilder.UseMiddleware<WireMockMiddleware>(); appBuilder.UseMiddleware<WireMockMiddleware>();
_options.PostWireMockMiddlewareInit?.Invoke(appBuilder); _options.PostWireMockMiddlewareInit?.Invoke(appBuilder);
}) })
.UseKestrel(options => .UseKestrel(options =>
{ {
var urlDetails = _urlOptions.GetDetails(); var urlDetails = _urlOptions.GetDetails();
#if NETSTANDARD1_3 #if NETSTANDARD1_3
var urls = urlDetails.Select(u => u.Url); var urls = urlDetails.Select(u => u.Url);
if (urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase))) if (urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
{ {
options.UseHttps(PublicCertificateHelper.GetX509Certificate2()); options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
} }
#else #else
foreach (var detail in urlDetails) foreach (var detail in urlDetails)
{ {
if (detail.Url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) if (detail.Url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
{ {
options.Listen(System.Net.IPAddress.Any, detail.Port, listenOptions => options.Listen(System.Net.IPAddress.Any, detail.Port, listenOptions =>
{ {
listenOptions.UseHttps(); // PublicCertificateHelper.GetX509Certificate2() listenOptions.UseHttps(); // PublicCertificateHelper.GetX509Certificate2()
}); });
} }
else else
{ {
options.Listen(System.Net.IPAddress.Any, detail.Port); options.Listen(System.Net.IPAddress.Any, detail.Port);
} }
} }
#endif #endif
}) })
#if NETSTANDARD1_3 #if NETSTANDARD1_3
.UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray()) .UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray())
#endif #endif
.Build(); .Build();
return RunHost(_cts.Token); return RunHost(_cts.Token);
} }
private Task RunHost(CancellationToken token) private Task RunHost(CancellationToken token)
{ {
try try
{ {
var appLifetime = (IApplicationLifetime)_host.Services.GetService(typeof(IApplicationLifetime)); var appLifetime = (IApplicationLifetime)_host.Services.GetService(typeof(IApplicationLifetime));
appLifetime.ApplicationStarted.Register(() => appLifetime.ApplicationStarted.Register(() =>
{ {
var addresses = _host.ServerFeatures var addresses = _host.ServerFeatures
.Get<Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>() .Get<Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>()
.Addresses; .Addresses;
foreach (string address in addresses) foreach (string address in addresses)
{ {
Urls.Add(address.Replace("0.0.0.0", "localhost")); Urls.Add(address.Replace("0.0.0.0", "localhost"));
PortUtils.TryExtract(address, out string protocol, out string host, out int port); PortUtils.TryExtract(address, out string protocol, out string host, out int port);
Ports.Add(port); Ports.Add(port);
} }
IsStarted = true; IsStarted = true;
}); });
#if NETSTANDARD1_3 #if NETSTANDARD1_3
_logger.Info("WireMock.Net server using netstandard1.3"); _logger.Info("WireMock.Net server using netstandard1.3");
#elif NETSTANDARD2_0 #elif NETSTANDARD2_0
_logger.Info("WireMock.Net server using netstandard2.0"); _logger.Info("WireMock.Net server using netstandard2.0");
#elif NET46 #elif NET46
_logger.Info("WireMock.Net server using .net 4.6.1 or higher"); _logger.Info("WireMock.Net server using .net 4.6.1 or higher");
#endif #endif
#if NETSTANDARD1_3 #if NETSTANDARD1_3
return Task.Run(() => return Task.Run(() =>
{ {
_host.Run(token); _host.Run(token);
}); });
#else #else
return _host.RunAsync(token); return _host.RunAsync(token);
#endif #endif
} }
catch (Exception e) catch (Exception e)
{ {
_runningException = e; _runningException = e;
_logger.Error(e.ToString()); _logger.Error(e.ToString());
IsStarted = false; IsStarted = false;
return Task.CompletedTask; return Task.CompletedTask;
} }
} }
public Task StopAsync() public Task StopAsync()
{ {
_cts.Cancel(); _cts.Cancel();
IsStarted = false; IsStarted = false;
#if NETSTANDARD1_3 #if NETSTANDARD1_3
return Task.FromResult(true); return Task.FromResult(true);
#else #else
return _host.StopAsync(); return _host.StopAsync();
#endif #endif
} }
} }
} }
#endif #endif

View File

@@ -7,6 +7,8 @@ namespace WireMock.Owin
{ {
public ICollection<string> Urls { get; set; } public ICollection<string> Urls { get; set; }
public int? Port { get; set; }
public bool UseSSL { get; set; } public bool UseSSL { get; set; }
public ICollection<(string Url, int Port)> GetDetails() public ICollection<(string Url, int Port)> GetDetails()
@@ -14,7 +16,7 @@ namespace WireMock.Owin
var list = new List<(string Url, int Port)>(); var list = new List<(string Url, int Port)>();
if (Urls == null) if (Urls == null)
{ {
int port = FindFreeTcpPort(); int port = Port ?? FindFreeTcpPort();
list.Add(($"{(UseSSL ? "https" : "http")}://localhost:{port}", port)); list.Add(($"{(UseSSL ? "https" : "http")}://localhost:{port}", port));
} }
else else

View File

@@ -214,7 +214,8 @@ namespace WireMock.Server
{ {
urlOptions = new HostUrlOptions urlOptions = new HostUrlOptions
{ {
UseSSL = settings.UseSSL == true UseSSL = settings.UseSSL == true,
Port = settings.Port
}; };
} }