Add option to run the server on http & https (#818)

* HostingProtocol.HttpAndHttps

* .

* .

* .

* HostingScheme
This commit is contained in:
Stef Heyenrath
2022-09-26 14:24:45 +02:00
committed by GitHub
parent fd996ab4ed
commit c0b18631a3
9 changed files with 118 additions and 28 deletions

View File

@@ -40,6 +40,19 @@ namespace WireMock.Net.ConsoleApplication
var s = WireMockServer.Start(); var s = WireMockServer.Start();
s.Stop(); s.Stop();
var httpAndHttpsWithPort = WireMockServer.Start(new WireMockServerSettings
{
HostingScheme = HostingScheme.HttpAndHttps,
Port = 12399
});
httpAndHttpsWithPort.Stop();
var httpAndHttpsFree = WireMockServer.Start(new WireMockServerSettings
{
HostingScheme = HostingScheme.HttpAndHttps
});
httpAndHttpsFree.Stop();
string url1 = "http://localhost:9091/"; string url1 = "http://localhost:9091/";
string url2 = "http://localhost:9092/"; string url2 = "http://localhost:9092/";
string url3 = "https://localhost:9443/"; string url3 = "https://localhost:9443/";

View File

@@ -1,8 +1,16 @@
{ {
"profiles": { "profiles": {
"WireMock.Net.StandAlone.NETCoreApp": { "WireMock.Net.StandAlone.NETCoreApp": {
"commandName": "Project", "commandName": "Project",
"commandLineArgs": "--Urls http://localhost:9091 --CorsPolicyOptions AllowAll --WireMockLogger WireMockConsoleLogger" "commandLineArgs": "--Urls http://localhost:9091 --CorsPolicyOptions AllowAll --WireMockLogger WireMockConsoleLogger"
},
"WireMock.Net.StandAlone.NETCoreAppNoPort": {
"commandName": "Project",
"commandLineArgs": "--CorsPolicyOptions AllowAll --WireMockLogger WireMockConsoleLogger"
},
"WireMock.Net.StandAlone.NETCoreAppWithHostingProtocol": {
"commandName": "Project",
"commandLineArgs": "--HostingProtocol HttpAndHttps --CorsPolicyOptions AllowAll --WireMockLogger WireMockConsoleLogger"
}
} }
}
} }

View File

@@ -0,0 +1,15 @@
using System;
namespace WireMock.Types;
[Flags]
public enum HostingScheme
{
None = 0x0,
Http = 0x1,
Https = 0x2,
HttpAndHttps = Http | Https
}

View File

@@ -1,12 +1,15 @@
namespace WireMock.Owin; namespace WireMock.Owin;
/// <summary>
/// https://en.wikipedia.org/wiki/Uniform_Resource_Identifier
/// </summary>
internal struct HostUrlDetails internal struct HostUrlDetails
{ {
public bool IsHttps { get; set; } public bool IsHttps { get; set; }
public string Url { get; set; } public string Url { get; set; }
public string Protocol { get; set; } public string Scheme { get; set; }
public string Host { get; set; } public string Host { get; set; }

View File

@@ -1,34 +1,49 @@
using System.Collections.Generic; using System.Collections.Generic;
using WireMock.Types;
using WireMock.Util; using WireMock.Util;
namespace WireMock.Owin; namespace WireMock.Owin;
internal class HostUrlOptions internal class HostUrlOptions
{ {
private const string LOCALHOST = "localhost"; private const string Localhost = "localhost";
public ICollection<string>? Urls { get; set; } public ICollection<string>? Urls { get; set; }
public int? Port { get; set; } public int? Port { get; set; }
public bool UseSSL { get; set; } public int? HttpsPort { get; set; }
public ICollection<HostUrlDetails> GetDetails() public HostingScheme HostingScheme { get; set; }
public IReadOnlyList<HostUrlDetails> GetDetails()
{ {
var list = new List<HostUrlDetails>(); var list = new List<HostUrlDetails>();
if (Urls == null) if (Urls == null)
{ {
int port = Port > 0 ? Port.Value : FindFreeTcpPort(); if (HostingScheme is HostingScheme.Http or HostingScheme.Https)
string protocol = UseSSL ? "https" : "http"; {
list.Add(new HostUrlDetails { IsHttps = UseSSL, Url = $"{protocol}://{LOCALHOST}:{port}", Protocol = protocol, Host = LOCALHOST, Port = port }); var port = Port > 0 ? Port.Value : FindFreeTcpPort();
var scheme = HostingScheme == HostingScheme.Https ? "https" : "http";
list.Add(new HostUrlDetails { IsHttps = HostingScheme == HostingScheme.Https, Url = $"{scheme}://{Localhost}:{port}", Scheme = scheme, Host = Localhost, Port = port });
}
if (HostingScheme == HostingScheme.HttpAndHttps)
{
var httpPort = Port > 0 ? Port.Value : FindFreeTcpPort();
list.Add(new HostUrlDetails { IsHttps = false, Url = $"http://{Localhost}:{httpPort}", Scheme = "http", Host = Localhost, Port = httpPort });
var httpsPort = FindFreeTcpPort(); // In this scenario, always get a free port for https.
list.Add(new HostUrlDetails { IsHttps = true, Url = $"https://{Localhost}:{httpsPort}", Scheme = "https", Host = Localhost, Port = httpsPort });
}
} }
else else
{ {
foreach (string url in Urls) foreach (string url in Urls)
{ {
if (PortUtils.TryExtract(url, out bool isHttps, out var protocol, out var host, out int port)) if (PortUtils.TryExtract(url, out var isHttps, out var protocol, out var host, out var port))
{ {
list.Add(new HostUrlDetails { IsHttps = isHttps, Url = url, Protocol = protocol, Host = host, Port = port }); list.Add(new HostUrlDetails { IsHttps = isHttps, Url = url, Scheme = protocol, Host = host, Port = port });
} }
} }
} }

View File

@@ -21,6 +21,7 @@ using WireMock.RequestBuilders;
using WireMock.ResponseProviders; using WireMock.ResponseProviders;
using WireMock.Serialization; using WireMock.Serialization;
using WireMock.Settings; using WireMock.Settings;
using WireMock.Types;
namespace WireMock.Server; namespace WireMock.Server;
@@ -48,7 +49,7 @@ public partial class WireMockServer : IWireMockServer
/// <inheritdoc /> /// <inheritdoc />
[PublicAPI] [PublicAPI]
public int Port => Ports?.FirstOrDefault() ?? default(int); public int Port => Ports?.FirstOrDefault() ?? default;
/// <inheritdoc /> /// <inheritdoc />
[PublicAPI] [PublicAPI]
@@ -269,11 +270,22 @@ public partial class WireMockServer : IWireMockServer
} }
else else
{ {
urlOptions = new HostUrlOptions if (settings.HostingScheme is not null)
{ {
UseSSL = settings.UseSSL == true, urlOptions = new HostUrlOptions
Port = settings.Port {
}; HostingScheme = settings.HostingScheme.Value,
Port = settings.Port
};
}
else
{
urlOptions = new HostUrlOptions
{
HostingScheme = settings.UseSSL == true ? HostingScheme.Https : HostingScheme.Http,
Port = settings.Port
};
}
} }
_options.FileSystemHandler = _settings.FileSystemHandler; _options.FileSystemHandler = _settings.FileSystemHandler;

View File

@@ -94,6 +94,26 @@ internal class SimpleCommandLineParser
}, defaultValue); }, defaultValue);
} }
public TEnum? GetEnumValue<TEnum>(string name)
where TEnum : struct
{
return GetValue(name, values =>
{
var value = values.FirstOrDefault();
return Enum.TryParse<TEnum>(value, true, out var enumValue) ? enumValue : (TEnum?)null;
});
}
public TEnum GetEnumValue<TEnum>(string name, TEnum defaultValue)
where TEnum : struct
{
return GetValue(name, values =>
{
var value = values.FirstOrDefault();
return Enum.TryParse<TEnum>(value, true, out var enumValue) ? enumValue : defaultValue;
}, defaultValue);
}
public string GetStringValue(string name, string defaultValue) public string GetStringValue(string name, string defaultValue)
{ {
return GetValue(name, values => values.FirstOrDefault() ?? defaultValue, defaultValue); return GetValue(name, values => values.FirstOrDefault() ?? defaultValue, defaultValue);

View File

@@ -9,6 +9,7 @@ using WireMock.Handlers;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Matchers; using WireMock.Matchers;
using WireMock.RegularExpressions; using WireMock.RegularExpressions;
using WireMock.Types;
#if USE_ASPNETCORE #if USE_ASPNETCORE
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using WireMock.Types; using WireMock.Types;
@@ -22,7 +23,7 @@ namespace WireMock.Settings
public class WireMockServerSettings public class WireMockServerSettings
{ {
/// <summary> /// <summary>
/// Gets or sets the port. /// Gets or sets the http port.
/// </summary> /// </summary>
[PublicAPI] [PublicAPI]
public int? Port { get; set; } public int? Port { get; set; }
@@ -34,6 +35,12 @@ namespace WireMock.Settings
[PublicAPI] [PublicAPI]
public bool? UseSSL { get; set; } public bool? UseSSL { get; set; }
/// <summary>
/// Defines on which scheme (http/https) to host. (This overrides the <c>UseSSL</c> value).
/// </summary>
[PublicAPI]
public HostingScheme? HostingScheme { get; set; }
/// <summary> /// <summary>
/// Gets or sets whether to start admin interface. /// Gets or sets whether to start admin interface.
/// </summary> /// </summary>

View File

@@ -54,14 +54,11 @@ public static class WireMockServerSettingsParser
UseRegexExtended = parser.GetBoolValue(nameof(WireMockServerSettings.UseRegexExtended), true), UseRegexExtended = parser.GetBoolValue(nameof(WireMockServerSettings.UseRegexExtended), true),
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"), WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
WatchStaticMappingsInSubdirectories = parser.GetBoolValue("WatchStaticMappingsInSubdirectories"), WatchStaticMappingsInSubdirectories = parser.GetBoolValue("WatchStaticMappingsInSubdirectories"),
HostingScheme = parser.GetEnumValue<HostingScheme>(nameof(WireMockServerSettings.HostingScheme))
}; };
#if USE_ASPNETCORE #if USE_ASPNETCORE
settings.CorsPolicyOptions = parser.GetValue(nameof(WireMockServerSettings.CorsPolicyOptions), values => settings.CorsPolicyOptions = parser.GetEnumValue(nameof(WireMockServerSettings.CorsPolicyOptions), CorsPolicyOptions.None);
{
var value = string.Join(string.Empty, values);
return Enum.TryParse<CorsPolicyOptions>(value, true, out var corsPolicyOptions) ? corsPolicyOptions : CorsPolicyOptions.None;
});
#endif #endif
if (logger != null) if (logger != null)
@@ -77,7 +74,7 @@ public static class WireMockServerSettingsParser
{ {
settings.Port = parser.GetIntValue(nameof(WireMockServerSettings.Port)); settings.Port = parser.GetIntValue(nameof(WireMockServerSettings.Port));
} }
else else if (settings.HostingScheme is null)
{ {
settings.Urls = parser.GetValues("Urls", new[] { "http://*:9091/" }); settings.Urls = parser.GetValues("Urls", new[] { "http://*:9091/" });
} }
@@ -95,7 +92,7 @@ public static class WireMockServerSettingsParser
SaveMapping = parser.GetBoolValue("SaveMapping"), SaveMapping = parser.GetBoolValue("SaveMapping"),
SaveMappingForStatusCodePattern = parser.GetStringValue("SaveMappingForStatusCodePattern", "*"), SaveMappingForStatusCodePattern = parser.GetStringValue("SaveMappingForStatusCodePattern", "*"),
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"), SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
Url = proxyUrl Url = proxyUrl!
}; };
string? proxyAddress = parser.GetStringValue("WebProxyAddress"); string? proxyAddress = parser.GetStringValue("WebProxyAddress");
@@ -103,7 +100,7 @@ public static class WireMockServerSettingsParser
{ {
settings.ProxyAndRecordSettings.WebProxySettings = new WebProxySettings settings.ProxyAndRecordSettings.WebProxySettings = new WebProxySettings
{ {
Address = proxyAddress, Address = proxyAddress!,
UserName = parser.GetStringValue("WebProxyUserName"), UserName = parser.GetStringValue("WebProxyUserName"),
Password = parser.GetStringValue("WebProxyPassword") Password = parser.GetStringValue("WebProxyPassword")
}; };