From ddf2b492406edccd572bc6f51ce25a4532fac781 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Thu, 18 Mar 2021 14:29:13 +0100 Subject: [PATCH 1/4] wip (#594) --- .../Program.cs | 137 ++++++++++-------- .../Request/RequestMessageBodyMatcher.cs | 21 +++ .../RequestBuilders/IBodyRequestBuilder.cs | 12 +- .../RequestBuilders/Request.WithBody.cs | 10 ++ .../RequestWithBodyTests.cs | 19 +++ 5 files changed, 133 insertions(+), 66 deletions(-) diff --git a/examples/WireMock.Net.StandAlone.NETCoreApp/Program.cs b/examples/WireMock.Net.StandAlone.NETCoreApp/Program.cs index a39469763..ed512adaf 100644 --- a/examples/WireMock.Net.StandAlone.NETCoreApp/Program.cs +++ b/examples/WireMock.Net.StandAlone.NETCoreApp/Program.cs @@ -1,70 +1,79 @@ -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading; -using log4net; -using log4net.Config; -using log4net.Repository; -using WireMock.RequestBuilders; -using WireMock.ResponseBuilders; -using WireMock.Server; -using WireMock.Settings; - -namespace WireMock.Net.StandAlone.NETCoreApp -{ - static class Program - { - private static readonly ILoggerRepository LogRepository = LogManager.GetRepository(Assembly.GetEntryAssembly()); - // private static readonly ILog Log = LogManager.GetLogger(typeof(Program)); - - private static int sleepTime = 30000; - private static WireMockServer _server; - - static void Main(string[] args) - { - XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config")); - +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using log4net; +using log4net.Config; +using log4net.Repository; +using WireMock.RequestBuilders; +using WireMock.ResponseBuilders; +using WireMock.Server; +using WireMock.Settings; +using WireMock.Util; + +namespace WireMock.Net.StandAlone.NETCoreApp +{ + static class Program + { + private static readonly ILoggerRepository LogRepository = LogManager.GetRepository(Assembly.GetEntryAssembly()); + // private static readonly ILog Log = LogManager.GetLogger(typeof(Program)); + + private static int sleepTime = 30000; + private static WireMockServer _server; + + static void Main(string[] args) + { + XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config")); + if (!WireMockServerSettingsParser.TryParseArguments(args, out var settings, new WireMockLog4NetLogger())) { return; } - settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'"))); - - _server = WireMockServer.Start(settings); - - _server - .Given(Request.Create() - .UsingAnyMethod()) - .RespondWith(Response.Create() - .WithTransformer() - .WithBody("{{Random Type=\"Integer\" Min=100 Max=999999}} {{DateTime.Now}} {{DateTime.Now \"yyyy-MMM\"}} {{String.Format (DateTime.Now) \"MMM-dd\"}}")); - - Console.WriteLine($"{DateTime.UtcNow} Press Ctrl+C to shut down"); - - Console.CancelKeyPress += (s, e) => - { - Stop("CancelKeyPress"); - }; - - System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += ctx => - { - Stop("AssemblyLoadContext.Default.Unloading"); - }; - - while (true) - { - Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server running : {_server.IsStarted}"); - Thread.Sleep(sleepTime); - } - } - - private static void Stop(string why) - { - Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server stopping because '{why}'"); - _server.Stop(); - Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server stopped"); - } - } + settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'"))); + + _server = WireMockServer.Start(settings); + + _server.Given(Request.Create().WithPath("/api/sap") + .UsingPost() + .WithBody((IBodyData xmlData) => { + //xmlData is always null + return true; + })) + .RespondWith(Response.Create().WithStatusCode(System.Net.HttpStatusCode.OK)); + + _server + .Given(Request.Create() + .UsingAnyMethod()) + .RespondWith(Response.Create() + .WithTransformer() + .WithBody("{{Random Type=\"Integer\" Min=100 Max=999999}} {{DateTime.Now}} {{DateTime.Now \"yyyy-MMM\"}} {{String.Format (DateTime.Now) \"MMM-dd\"}}")); + + Console.WriteLine($"{DateTime.UtcNow} Press Ctrl+C to shut down"); + + Console.CancelKeyPress += (s, e) => + { + Stop("CancelKeyPress"); + }; + + System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += ctx => + { + Stop("AssemblyLoadContext.Default.Unloading"); + }; + + while (true) + { + Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server running : {_server.IsStarted}"); + Thread.Sleep(sleepTime); + } + } + + private static void Stop(string why) + { + Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server stopping because '{why}'"); + _server.Stop(); + Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server stopped"); + } + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs b/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs index 93fe0adbe..d2e8d307e 100644 --- a/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs +++ b/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using WireMock.Types; +using WireMock.Util; using WireMock.Validation; namespace WireMock.Matchers.Request @@ -26,6 +27,11 @@ public class RequestMessageBodyMatcher : IRequestMatcher /// public Func JsonFunc { get; } + /// + /// The body data function for BodyData + /// + public Func BodyDataFunc { get; } + /// /// The matchers. /// @@ -88,6 +94,16 @@ public RequestMessageBodyMatcher([NotNull] Func func) JsonFunc = func; } + /// + /// Initializes a new instance of the class. + /// + /// The function. + public RequestMessageBodyMatcher([NotNull] Func func) + { + Check.NotNull(func, nameof(func)); + BodyDataFunc = func; + } + /// /// Initializes a new instance of the class. /// @@ -158,6 +174,11 @@ private double CalculateMatchScore(IRequestMessage requestMessage) return MatchScores.ToScore(DataFunc(requestMessage?.BodyData?.BodyAsBytes)); } + if (BodyDataFunc != null) + { + return MatchScores.ToScore(BodyDataFunc(requestMessage?.BodyData)); + } + return MatchScores.Mismatch; } } diff --git a/src/WireMock.Net/RequestBuilders/IBodyRequestBuilder.cs b/src/WireMock.Net/RequestBuilders/IBodyRequestBuilder.cs index 464d62f7c..f4e768a15 100644 --- a/src/WireMock.Net/RequestBuilders/IBodyRequestBuilder.cs +++ b/src/WireMock.Net/RequestBuilders/IBodyRequestBuilder.cs @@ -2,7 +2,8 @@ using System; using WireMock.Matchers; using WireMock.Matchers.Request; - +using WireMock.Util; + namespace WireMock.RequestBuilders { /// @@ -63,10 +64,17 @@ public interface IBodyRequestBuilder : IRequestMatcher IRequestBuilder WithBody([NotNull] Func func); /// - /// WithBody: func (object) + /// WithBody: func (json object) /// /// The function. /// The . IRequestBuilder WithBody([NotNull] Func func); + + /// + /// WithBody: func (BodyData object) + /// + /// The function. + /// The . + IRequestBuilder WithBody([NotNull] Func func); } } \ No newline at end of file diff --git a/src/WireMock.Net/RequestBuilders/Request.WithBody.cs b/src/WireMock.Net/RequestBuilders/Request.WithBody.cs index 2828a26eb..a1f60b5ff 100644 --- a/src/WireMock.Net/RequestBuilders/Request.WithBody.cs +++ b/src/WireMock.Net/RequestBuilders/Request.WithBody.cs @@ -3,6 +3,7 @@ using System; using WireMock.Matchers; using WireMock.Matchers.Request; +using WireMock.Util; using WireMock.Validation; namespace WireMock.RequestBuilders @@ -71,5 +72,14 @@ public IRequestBuilder WithBody(Func func) _requestMatchers.Add(new RequestMessageBodyMatcher(func)); return this; } + + /// + public IRequestBuilder WithBody(Func func) + { + Check.NotNull(func, nameof(func)); + + _requestMatchers.Add(new RequestMessageBodyMatcher(func)); + return this; + } } } diff --git a/test/WireMock.Net.Tests/RequestWithBodyTests.cs b/test/WireMock.Net.Tests/RequestWithBodyTests.cs index 82d4420f3..1cb5e3f46 100644 --- a/test/WireMock.Net.Tests/RequestWithBodyTests.cs +++ b/test/WireMock.Net.Tests/RequestWithBodyTests.cs @@ -54,6 +54,25 @@ public void Request_WithBody_FuncJson() Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0); } + [Fact] + public void Request_WithBody_FuncBodyData() + { + // Assign + var requestBuilder = Request.Create().UsingAnyMethod().WithBody((IBodyData b) => b != null); + + // Act + var body = new BodyData + { + BodyAsJson = 123, + DetectedBodyType = BodyType.Json + }; + var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body); + + // Assert + var requestMatchResult = new RequestMatchResult(); + Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0); + } + [Fact] public void Request_WithBody_FuncByteArray() { From 2fb0f92a2df41aba913015cfd0f28d0a7f3094ff Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Fri, 19 Mar 2021 15:17:39 +0100 Subject: [PATCH 2/4] Use Handlebars.Net.Helpers Version="2.1.2" (#595) --- src/WireMock.Net/WireMock.Net.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/WireMock.Net/WireMock.Net.csproj b/src/WireMock.Net/WireMock.Net.csproj index ed4a574ea..5e125ddac 100644 --- a/src/WireMock.Net/WireMock.Net.csproj +++ b/src/WireMock.Net/WireMock.Net.csproj @@ -121,12 +121,12 @@ - - - - - - + + + + + + From 6f7d2c83f5b74dd8faa60a021c0c8173e3ab59e4 Mon Sep 17 00:00:00 2001 From: Ben Arnold Date: Sun, 21 Mar 2021 08:12:19 +0000 Subject: [PATCH 3/4] Remove an approximate two second delay in response to the first request from a new socket connection, only occuring on some Windows 10 machines. (#597) A side-effect of this fix is that is also allows connections to IPv6 addresses. --- .../Owin/AspNetCoreSelfHost.NETStandard.cs | 4 +- src/WireMock.Net/Owin/AspNetCoreSelfHost.cs | 2 +- .../WireMock.Net.Tests/WireMockServerTests.cs | 46 +++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/WireMock.Net/Owin/AspNetCoreSelfHost.NETStandard.cs b/src/WireMock.Net/Owin/AspNetCoreSelfHost.NETStandard.cs index aefc35e59..22653f8cd 100644 --- a/src/WireMock.Net/Owin/AspNetCoreSelfHost.NETStandard.cs +++ b/src/WireMock.Net/Owin/AspNetCoreSelfHost.NETStandard.cs @@ -24,7 +24,7 @@ private static void SetHttpsAndUrls(KestrelServerOptions kestrelOptions, IWireMo { if (urlDetail.IsHttps) { - kestrelOptions.Listen(System.Net.IPAddress.Any, urlDetail.Port, listenOptions => + kestrelOptions.ListenAnyIP(urlDetail.Port, listenOptions => { if (wireMockMiddlewareOptions.CustomCertificateDefined) { @@ -45,7 +45,7 @@ private static void SetHttpsAndUrls(KestrelServerOptions kestrelOptions, IWireMo } else { - kestrelOptions.Listen(System.Net.IPAddress.Any, urlDetail.Port); + kestrelOptions.ListenAnyIP(urlDetail.Port); } } } diff --git a/src/WireMock.Net/Owin/AspNetCoreSelfHost.cs b/src/WireMock.Net/Owin/AspNetCoreSelfHost.cs index 1fe2e9a7e..29bf4ba81 100644 --- a/src/WireMock.Net/Owin/AspNetCoreSelfHost.cs +++ b/src/WireMock.Net/Owin/AspNetCoreSelfHost.cs @@ -106,7 +106,7 @@ private Task RunHost(CancellationToken token) foreach (string address in addresses) { - Urls.Add(address.Replace("0.0.0.0", "localhost")); + Urls.Add(address.Replace("0.0.0.0", "localhost").Replace("[::]", "localhost")); PortUtils.TryExtract(address, out bool isHttps, out string protocol, out string host, out int port); Ports.Add(port); diff --git a/test/WireMock.Net.Tests/WireMockServerTests.cs b/test/WireMock.Net.Tests/WireMockServerTests.cs index bc35f3b3f..5cb939b87 100644 --- a/test/WireMock.Net.Tests/WireMockServerTests.cs +++ b/test/WireMock.Net.Tests/WireMockServerTests.cs @@ -305,5 +305,51 @@ public async Task WireMockServer_Should_SupportRequestGZipAndDeflate(string cont server.Stop(); } + +#if !NET452 + [Fact] + public async Task WireMockServer_Should_respond_to_ipv4_loopback() + { + // Assign + var server = WireMockServer.Start(); + + server + .Given(Request.Create() + .WithPath("/*")) + .RespondWith(Response.Create() + .WithStatusCode(200) + .WithBody("from ipv4 loopback")); + + // Act + var response = await new HttpClient().GetStringAsync($"http://127.0.0.1:{server.Ports[0]}/foo"); + + // Assert + Check.That(response).IsEqualTo("from ipv4 loopback"); + + server.Stop(); + } + + [Fact] + public async Task WireMockServer_Should_respond_to_ipv6_loopback() + { + // Assign + var server = WireMockServer.Start(); + + server + .Given(Request.Create() + .WithPath("/*")) + .RespondWith(Response.Create() + .WithStatusCode(200) + .WithBody("from ipv6 loopback")); + + // Act + var response = await new HttpClient().GetStringAsync($"http://[::1]:{server.Ports[0]}/foo"); + + // Assert + Check.That(response).IsEqualTo("from ipv6 loopback"); + + server.Stop(); + } +#endif } } \ No newline at end of file From cee73023c79c0c7f5a73ce5dac03664ffa52c625 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Sun, 21 Mar 2021 09:22:18 +0100 Subject: [PATCH 4/4] 1.4.7 --- CHANGELOG.md | 9 ++++++--- Directory.Build.props | 2 +- GitHubReleaseNotes.txt | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a1c4c866..ac3505b19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.4.7 (21 March 2021) +- [#594](https://github.com/WireMock-Net/WireMock.Net/pull/594) - Add possibility to the WithBody() to use IBodyData [feature] contributed by [StefH](https://github.com/StefH) +- [#595](https://github.com/WireMock-Net/WireMock.Net/pull/595) - Use Handlebars.Net.Helpers Version="2.1.2" [feature] contributed by [StefH](https://github.com/StefH) +- [#597](https://github.com/WireMock-Net/WireMock.Net/pull/597) - Remove 2 second delay from first response and add IPv6 address support [bug, feature] contributed by [benagain](https://github.com/benagain) + # 1.4.6 (26 February 2021) - [#587](https://github.com/WireMock-Net/WireMock.Net/pull/587) - Fix WithCallback logic when using other fluent builder statements [bug] contributed by [StefH](https://github.com/StefH) - [#569](https://github.com/WireMock-Net/WireMock.Net/issues/569) - WithCallback circumvent the rest of the builder [bug] @@ -43,6 +48,7 @@ - [#549](https://github.com/WireMock-Net/WireMock.Net/issues/549) - WithProxy(...) does not save the mappings to file [bug] # 1.3.8 (03 December 2020) +- [#539](https://github.com/WireMock-Net/WireMock.Net/pull/539) - Support for partial JSON matching contributed by [gleb-osokin](https://github.com/gleb-osokin) - [#542](https://github.com/WireMock-Net/WireMock.Net/pull/542) - Create dotnet-wiremock tool [feature] contributed by [StefH](https://github.com/StefH) - [#543](https://github.com/WireMock-Net/WireMock.Net/pull/543) - Add support for .NET 5 [feature] contributed by [StefH](https://github.com/StefH) - [#544](https://github.com/WireMock-Net/WireMock.Net/pull/544) - Use Java 11 in Azure Pipelines (needed for SonarCloud) [feature] contributed by [StefH](https://github.com/StefH) @@ -50,9 +56,6 @@ - [#547](https://github.com/WireMock-Net/WireMock.Net/pull/547) - Fix Proxying with SSL and NetCoreApp3.1 [bug] contributed by [StefH](https://github.com/StefH) - [#524](https://github.com/WireMock-Net/WireMock.Net/issues/524) - Proxying with SSL Not Working in .NET Core 3.1 [bug] -# 1.3.7 (17 November 2020) -- [#539](https://github.com/WireMock-Net/WireMock.Net/pull/539) - Support for partial JSON matching contributed by [gleb-osokin](https://github.com/gleb-osokin) - # 1.3.6 (10 November 2020) - [#529](https://github.com/WireMock-Net/WireMock.Net/pull/529) - Add assertions for ClientIP, Url and ProxyUrl [feature] contributed by [akamud](https://github.com/akamud) - [#535](https://github.com/WireMock-Net/WireMock.Net/pull/535) - WithCallback should use also use enum HttpStatusCode [bug] contributed by [StefH](https://github.com/StefH) diff --git a/Directory.Build.props b/Directory.Build.props index b42e7e767..d9a88a26d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ - 1.4.6 + 1.4.7 See CHANGELOG.md https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png https://github.com/WireMock-Net/WireMock.Net diff --git a/GitHubReleaseNotes.txt b/GitHubReleaseNotes.txt index b56e91c33..9d4181ab7 100644 --- a/GitHubReleaseNotes.txt +++ b/GitHubReleaseNotes.txt @@ -1,3 +1,3 @@ https://github.com/StefH/GitHubReleaseNotes -GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.4.6 \ No newline at end of file +GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.4.7 \ No newline at end of file