diff --git a/WireMock.Net Solution.sln b/WireMock.Net Solution.sln index 66ad324b..9c41a64c 100644 --- a/WireMock.Net Solution.sln +++ b/WireMock.Net Solution.sln @@ -99,6 +99,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Org.Abstractions", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NET6", "examples\WireMock.Net.Console.NET6\WireMock.Net.Console.NET6.csproj", "{2215055B-594E-4C2F-99B2-6DF337F02893}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.WebApplication.NET6", "examples\WireMock.Net.WebApplication.NET6\WireMock.Net.WebApplication.NET6.csproj", "{3F7AA023-6833-4856-A08A-4B5717B592B8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -233,6 +235,10 @@ Global {2215055B-594E-4C2F-99B2-6DF337F02893}.Debug|Any CPU.Build.0 = Debug|Any CPU {2215055B-594E-4C2F-99B2-6DF337F02893}.Release|Any CPU.ActiveCfg = Release|Any CPU {2215055B-594E-4C2F-99B2-6DF337F02893}.Release|Any CPU.Build.0 = Release|Any CPU + {3F7AA023-6833-4856-A08A-4B5717B592B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F7AA023-6833-4856-A08A-4B5717B592B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F7AA023-6833-4856-A08A-4B5717B592B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F7AA023-6833-4856-A08A-4B5717B592B8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -272,6 +278,7 @@ Global {08B29DB1-FEFE-408A-AD0A-6BA6DDC8D70F} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2} {3BA5109E-5F30-4CC2-B699-02EC82560AA6} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2} {2215055B-594E-4C2F-99B2-6DF337F02893} = {985E0ADB-D4B4-473A-AA40-567E279B7946} + {3F7AA023-6833-4856-A08A-4B5717B592B8} = {985E0ADB-D4B4-473A-AA40-567E279B7946} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458} diff --git a/examples/WireMock.Net.WebApplication.NET6/App.cs b/examples/WireMock.Net.WebApplication.NET6/App.cs new file mode 100644 index 00000000..1274605b --- /dev/null +++ b/examples/WireMock.Net.WebApplication.NET6/App.cs @@ -0,0 +1,28 @@ +using Microsoft.Extensions.Hosting; +using System.Threading; +using System.Threading.Tasks; + +namespace WireMock.Net.WebApplication +{ + public class App : IHostedService + { + private readonly IWireMockService _service; + + public App(IWireMockService service) + { + _service = service; + } + + public Task StartAsync(CancellationToken cancellationToken) + { + _service.Start(); + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + _service.Stop(); + return Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/examples/WireMock.Net.WebApplication.NET6/IWireMockService.cs b/examples/WireMock.Net.WebApplication.NET6/IWireMockService.cs new file mode 100644 index 00000000..02e489d3 --- /dev/null +++ b/examples/WireMock.Net.WebApplication.NET6/IWireMockService.cs @@ -0,0 +1,9 @@ +namespace WireMock.Net.WebApplication +{ + public interface IWireMockService + { + void Start(); + + void Stop(); + } +} \ No newline at end of file diff --git a/examples/WireMock.Net.WebApplication.NET6/Program.cs b/examples/WireMock.Net.WebApplication.NET6/Program.cs new file mode 100644 index 00000000..1effb357 --- /dev/null +++ b/examples/WireMock.Net.WebApplication.NET6/Program.cs @@ -0,0 +1,30 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using WireMock.Settings; + +namespace WireMock.Net.WebApplication +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + private static IHostBuilder CreateHostBuilder(string[] args) + => Host.CreateDefaultBuilder(args) + .ConfigureServices((host, services) => ConfigureServices(services, host.Configuration)); + + private static void ConfigureServices(IServiceCollection services, IConfiguration configuration) + { + services.AddLogging(logging => logging.AddConsole().AddDebug()); + + services.AddTransient(); + services.Configure(configuration.GetSection("WireMockServerSettings")); + + services.AddHostedService(); + } + } +} \ No newline at end of file diff --git a/examples/WireMock.Net.WebApplication.NET6/WireMock.Net.WebApplication.NET6.csproj b/examples/WireMock.Net.WebApplication.NET6/WireMock.Net.WebApplication.NET6.csproj new file mode 100644 index 00000000..36017217 --- /dev/null +++ b/examples/WireMock.Net.WebApplication.NET6/WireMock.Net.WebApplication.NET6.csproj @@ -0,0 +1,33 @@ + + + + net6 + win10-x64 + WireMock.Net.WebApplication.Program + WireMock.Net.WebApplication + WireMock.Net.WebApplication + efcf4a18-fd7c-4622-1111-336d65290599 + OutOfProcess + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + \ No newline at end of file diff --git a/examples/WireMock.Net.WebApplication.NET6/WireMockService.cs b/examples/WireMock.Net.WebApplication.NET6/WireMockService.cs new file mode 100644 index 00000000..1bbe763c --- /dev/null +++ b/examples/WireMock.Net.WebApplication.NET6/WireMockService.cs @@ -0,0 +1,83 @@ +using System; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; + +using WireMock.Admin.Requests; +using WireMock.Logging; +using WireMock.Server; +using WireMock.Settings; + +namespace WireMock.Net.WebApplication +{ + public class WireMockService : IWireMockService + { + private WireMockServer _server; + private readonly ILogger _logger; + private readonly WireMockServerSettings _settings; + + private class Logger : IWireMockLogger + { + private readonly ILogger _logger; + + public Logger(ILogger logger) + { + _logger = logger; + } + + public void Debug(string formatString, params object[] args) + { + _logger.LogDebug(formatString, args); + } + + public void Info(string formatString, params object[] args) + { + _logger.LogInformation(formatString, args); + } + + public void Warn(string formatString, params object[] args) + { + _logger.LogWarning(formatString, args); + } + + public void Error(string formatString, params object[] args) + { + _logger.LogError(formatString, args); + } + + public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminrequest) + { + string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented); + _logger.LogDebug("Admin[{0}] {1}", isAdminrequest, message); + } + + public void Error(string formatString, Exception exception) + { + _logger.LogError(formatString, exception.Message); + } + } + + public WireMockService(ILogger logger, IOptions settings) + { + _logger = logger; + _settings = settings.Value; + + _settings.Logger = new Logger(logger); + } + + public void Start() + { + _logger.LogInformation("WireMock.Net server starting"); + + _server = WireMockServer.Start(_settings); + + _logger.LogInformation($"WireMock.Net server settings {JsonConvert.SerializeObject(_settings)}"); + } + + public void Stop() + { + _logger.LogInformation("WireMock.Net server stopping"); + _server?.Stop(); + } + } +} diff --git a/examples/WireMock.Net.WebApplication.NET6/__admin/mappings/1e0686d3-5eb0-4c30-9482-db3735a1e4c4.json b/examples/WireMock.Net.WebApplication.NET6/__admin/mappings/1e0686d3-5eb0-4c30-9482-db3735a1e4c4.json new file mode 100644 index 00000000..abae1b82 --- /dev/null +++ b/examples/WireMock.Net.WebApplication.NET6/__admin/mappings/1e0686d3-5eb0-4c30-9482-db3735a1e4c4.json @@ -0,0 +1,184 @@ +{ + "Guid": "1e0686d3-5eb0-4c30-9482-db3735a1e4c4", + "Title": "", + "Request": { + "Path": { + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "/favicon.ico", + "IgnoreCase": false + } + ] + }, + "Methods": [ + "GET" + ], + "Headers": [ + { + "Name": "Accept", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", + "IgnoreCase": true + } + ] + }, + { + "Name": "Host", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "localhost:8081", + "IgnoreCase": true + } + ] + }, + { + "Name": "User-Agent", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36", + "IgnoreCase": true + } + ] + }, + { + "Name": ":method", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "GET", + "IgnoreCase": true + } + ] + }, + { + "Name": "Accept-Encoding", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "gzip, deflate, br", + "IgnoreCase": true + } + ] + }, + { + "Name": "Accept-Language", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "en-US,en;q=0.9,nl;q=0.8", + "IgnoreCase": true + } + ] + }, + { + "Name": "Referer", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "https://localhost:8081/__admin/mappings", + "IgnoreCase": true + } + ] + }, + { + "Name": "sec-ch-ua", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"99\", \"Google Chrome\";v=\"99\"", + "IgnoreCase": true + } + ] + }, + { + "Name": "sec-ch-ua-mobile", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "?0", + "IgnoreCase": true + } + ] + }, + { + "Name": "sec-ch-ua-platform", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "\"Windows\"", + "IgnoreCase": true + } + ] + }, + { + "Name": "sec-fetch-site", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "same-origin", + "IgnoreCase": true + } + ] + }, + { + "Name": "sec-fetch-mode", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "no-cors", + "IgnoreCase": true + } + ] + }, + { + "Name": "sec-fetch-dest", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "image", + "IgnoreCase": true + } + ] + } + ], + "Cookies": [ + { + "Name": "ai_user", + "Matchers": [ + { + "Name": "WildcardMatcher", + "Pattern": "4z4B71qxV7rOSA6Gf3IFZ1|2021-07-20T17:07:54.344Z", + "IgnoreCase": true + } + ] + } + ] + }, + "Response": { + "StatusCode": 200, + "Body": "Product Support Portal | SmartBear Software
", + "Headers": { + "Content-Type": "text/html", + "Last-Modified": "Thu, 10 Mar 2022 08:39:07 GMT", + "Transfer-Encoding": "chunked", + "Connection": "keep-alive", + "Date": "Fri, 11 Mar 2022 09:21:22 GMT", + "ETag": "W/\"cd426e4e5a34d81:0\"", + "X-XSS-Protection": "1; mode=block", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload", + "X-Frame-Options": "SAMEORIGIN", + "X-Content-Type-Options": "nosniff", + "Content-Security-Policy": "frame-ancestors 'self'", + "Vary": "Accept-Encoding", + "X-Cache": "Miss from cloudfront", + "Via": "1.1 e328b143eb69c36369a2def78300d502.cloudfront.net (CloudFront)", + "X-Amz-Cf-Pop": "AMS1-C1", + "X-Amz-Cf-Id": "fUBp1b6g0N3JnLuj_VcueuCf0Rw-eXfBNKHq7luNlAOtqAxU5MUdcA==" + } + } +} \ No newline at end of file diff --git a/examples/WireMock.Net.WebApplication.NET6/appsettings.json b/examples/WireMock.Net.WebApplication.NET6/appsettings.json new file mode 100644 index 00000000..2ab0a2c6 --- /dev/null +++ b/examples/WireMock.Net.WebApplication.NET6/appsettings.json @@ -0,0 +1,29 @@ +{ + "Logging": { + "IncludeScopes": false, + "Debug": { + "LogLevel": { + "Default": "Debug" + } + }, + "Console": { + "LogLevel": { + "Default": "Debug" + } + } + }, + "WireMockServerSettings": { + "StartAdminInterface": true, + "Urls": [ + "https://localhost:8081/" + ], + "AllowPartialMapping": false, + "HandleRequestsSynchronously": true, + "ThrowExceptionWhenMatcherFails": true, + "ProxyAndRecordSettings": { + "Url": "https://support.smartbear.com/", + "SaveMapping": true, + "SaveMappingToFile": true + } + } +} diff --git a/examples/WireMock.Net.WebApplication.NET6/readme.md b/examples/WireMock.Net.WebApplication.NET6/readme.md new file mode 100644 index 00000000..61d5b1a3 --- /dev/null +++ b/examples/WireMock.Net.WebApplication.NET6/readme.md @@ -0,0 +1,21 @@ +# Running in IIS + +Follow these links / steps: +* https://weblog.west-wind.com/posts/2016/Jun/06/Publishing-and-Running-ASPNET-Core-Applications-with-IIS +* https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/development-time-iis-support?view=aspnetcore-2.1 +* Create a `web.config` file + +## IIS Sites +![IIS Multiple](resources/iis-wiremock1and2.png) + +## App Pool settings +![IIS Multiple](resources/iis-apppool.png) + +## Publish Profiles +Two example publish profiles are created: +* [IIS Localhost 1](./Properties/PublishProfiles/IIS%20Localhost%201.pubxml) +* [IIS Localhost 2](./Properties/PublishProfiles/IIS%20Localhost%202.pubxml) + +## Debugging +Select the debug "IIS" if you want to debug in IIS. +![IIS Debug](resources/iis-debug.png) diff --git a/examples/WireMock.Net.WebApplication.NET6/web.config b/examples/WireMock.Net.WebApplication.NET6/web.config new file mode 100644 index 00000000..1805fd75 --- /dev/null +++ b/examples/WireMock.Net.WebApplication.NET6/web.config @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/WireMock.Net/ResponseBuilders/Response.WithProxy.cs b/src/WireMock.Net/ResponseBuilders/Response.WithProxy.cs index 28b2c24b..69951adf 100644 --- a/src/WireMock.Net/ResponseBuilders/Response.WithProxy.cs +++ b/src/WireMock.Net/ResponseBuilders/Response.WithProxy.cs @@ -28,7 +28,7 @@ namespace WireMock.ResponseBuilders return WithProxy(settings); } - /// + /// public IResponseBuilder WithProxy(ProxyAndRecordSettings settings) { Guard.NotNull(settings, nameof(settings));