From e9ee4e91f9f88fc48908e1590a0d8e68de0daa22 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Tue, 21 Mar 2017 14:45:34 +0100 Subject: [PATCH] HttpListener : Stop fix --- src/WireMock.Net/Http/TinyHttpServer.cs | 23 ++++++++++++++----- src/WireMock.Net/Server/FluentMockServer.cs | 11 ++++++--- .../FluentMockServerTests.cs | 12 +++++++++- .../Http/TinyHttpServerTests.cs | 2 +- .../HttpListenerRequestMapperTests.cs | 5 ++-- .../HttpListenerResponseMapperTests.cs | 2 +- 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/WireMock.Net/Http/TinyHttpServer.cs b/src/WireMock.Net/Http/TinyHttpServer.cs index 61acb0e8..7601b3f9 100644 --- a/src/WireMock.Net/Http/TinyHttpServer.cs +++ b/src/WireMock.Net/Http/TinyHttpServer.cs @@ -13,11 +13,11 @@ namespace WireMock.Http /// public class TinyHttpServer { - private readonly Action _httpHandler; + private readonly Action _httpHandler; private readonly HttpListener _listener; - private CancellationTokenSource _cts; + private readonly CancellationTokenSource _cts; /// /// Gets a value indicating whether this server is started. @@ -33,6 +33,7 @@ namespace WireMock.Http /// /// The urls. /// + [PublicAPI] public List Urls { get; } = new List(); /// @@ -41,6 +42,7 @@ namespace WireMock.Http /// /// The ports. /// + [PublicAPI] public List Ports { get; } = new List(); /// @@ -48,11 +50,13 @@ namespace WireMock.Http /// /// The uriPrefixes. /// The http handler. - public TinyHttpServer([NotNull] Action httpHandler, [NotNull] params string[] uriPrefixes) + public TinyHttpServer([NotNull] Action httpHandler, [NotNull] params string[] uriPrefixes) { Check.NotNull(httpHandler, nameof(httpHandler)); Check.NotEmpty(uriPrefixes, nameof(uriPrefixes)); + _cts = new CancellationTokenSource(); + _httpHandler = httpHandler; // Create a listener. @@ -70,22 +74,26 @@ namespace WireMock.Http /// /// Start the server. /// + [PublicAPI] public void Start() { _listener.Start(); + IsStarted = true; - _cts = new CancellationTokenSource(); Task.Run( async () => { - using (_listener) + //using (_listener) { while (!_cts.Token.IsCancellationRequested) { HttpListenerContext context = await _listener.GetContextAsync(); - _httpHandler(context); + _httpHandler(context, _cts.Token); } + + _listener.Stop(); + IsStarted = false; } }, _cts.Token); @@ -94,8 +102,11 @@ namespace WireMock.Http /// /// Stop the server. /// + [PublicAPI] public void Stop() { + _listener?.Stop(); + _cts.Cancel(); } } diff --git a/src/WireMock.Net/Server/FluentMockServer.cs b/src/WireMock.Net/Server/FluentMockServer.cs index 9cdc0885..277b2877 100644 --- a/src/WireMock.Net/Server/FluentMockServer.cs +++ b/src/WireMock.Net/Server/FluentMockServer.cs @@ -13,6 +13,7 @@ using WireMock.Matchers; using WireMock.Matchers.Request; using WireMock.RequestBuilders; using WireMock.Validation; +using System.Threading; namespace WireMock.Server { @@ -255,7 +256,7 @@ namespace WireMock.Server [PublicAPI] public void Stop() { - _httpServer.Stop(); + _httpServer?.Stop(); } /// @@ -432,13 +433,17 @@ namespace WireMock.Server /// The handle request. /// /// The HttpListenerContext. - private async void HandleRequestAsync(HttpListenerContext ctx) + /// The CancellationToken. + private async void HandleRequestAsync(HttpListenerContext ctx, CancellationToken cancel) { + if (cancel.IsCancellationRequested) + return; + if (_requestProcessingDelay > TimeSpan.Zero) { lock (_syncRoot) { - Task.Delay(_requestProcessingDelay.Value).Wait(); + Task.Delay(_requestProcessingDelay.Value, cancel).Wait(cancel); } } diff --git a/test/WireMock.Net.Tests/FluentMockServerTests.cs b/test/WireMock.Net.Tests/FluentMockServerTests.cs index 190c5185..16360019 100644 --- a/test/WireMock.Net.Tests/FluentMockServerTests.cs +++ b/test/WireMock.Net.Tests/FluentMockServerTests.cs @@ -30,6 +30,16 @@ namespace WireMock.Net.Tests return current; } + [Test] + public void FluentMockServer_StartStop() + { + var server1 = FluentMockServer.Start("http://localhost:9090/"); + server1.Stop(); + + var server2 = FluentMockServer.Start("http://localhost:9090/"); + server2.Stop(); + } + [Test] public void FluentMockServer_ReadStaticMapping_WithNonGuidFilename() { @@ -346,7 +356,7 @@ namespace WireMock.Net.Tests [TearDown] public void ShutdownServer() { - _server.Stop(); + _server?.Stop(); } } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/Http/TinyHttpServerTests.cs b/test/WireMock.Net.Tests/Http/TinyHttpServerTests.cs index 099dac0d..4f06fefe 100644 --- a/test/WireMock.Net.Tests/Http/TinyHttpServerTests.cs +++ b/test/WireMock.Net.Tests/Http/TinyHttpServerTests.cs @@ -25,7 +25,7 @@ namespace WireMock.Net.Tests.Http var port = PortUtil.FindFreeTcpPort(); bool called = false; var urlPrefix = "http://localhost:" + port + "/"; - var server = new TinyHttpServer(ctx => called = true, urlPrefix); + var server = new TinyHttpServer((ctx, token) => called = true, urlPrefix); server.Start(); // when diff --git a/test/WireMock.Net.Tests/HttpListenerRequestMapperTests.cs b/test/WireMock.Net.Tests/HttpListenerRequestMapperTests.cs index 24d8a1b1..61e4d6d1 100644 --- a/test/WireMock.Net.Tests/HttpListenerRequestMapperTests.cs +++ b/test/WireMock.Net.Tests/HttpListenerRequestMapperTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Net; using System.Net.Http; +using System.Threading; using System.Threading.Tasks; using NFluent; using NUnit.Framework; @@ -103,7 +104,7 @@ namespace WireMock.Net.Tests { private static volatile RequestMessage _lastRequestMessage; - private MapperServer(Action httpHandler, string urlPrefix) : base(httpHandler, urlPrefix) + private MapperServer(Action httpHandler, string urlPrefix) : base(httpHandler, urlPrefix) { } @@ -127,7 +128,7 @@ namespace WireMock.Net.Tests int port = PortUtil.FindFreeTcpPort(); UrlPrefix = "http://localhost:" + port + "/"; var server = new MapperServer( - context => + (context, token) => { LastRequestMessage = new HttpListenerRequestMapper().Map(context.Request); context.Response.Close(); diff --git a/test/WireMock.Net.Tests/HttpListenerResponseMapperTests.cs b/test/WireMock.Net.Tests/HttpListenerResponseMapperTests.cs index 132e644e..fcd9371f 100644 --- a/test/WireMock.Net.Tests/HttpListenerResponseMapperTests.cs +++ b/test/WireMock.Net.Tests/HttpListenerResponseMapperTests.cs @@ -112,7 +112,7 @@ namespace WireMock.Net.Tests var responseReady = new AutoResetEvent(false); HttpListenerResponse response = null; _server = new TinyHttpServer( - context => + (context, token) => { response = context.Response; responseReady.Set();