diff --git a/src/WireMock.Net/Http/PortUtil.cs b/src/WireMock.Net/Http/PortUtil.cs index 519a9902..d98a2e30 100644 --- a/src/WireMock.Net/Http/PortUtil.cs +++ b/src/WireMock.Net/Http/PortUtil.cs @@ -9,6 +9,7 @@ namespace WireMock.Http /// public static class PortUtil { + private static readonly IPEndPoint DefaultLoopbackEndpoint = new IPEndPoint(IPAddress.Loopback, port: 0); private static readonly Regex UrlDetailsRegex = new Regex(@"^(?\w+)://[^/]+?(?\d+)?/", RegexOptions.Compiled); /// @@ -17,17 +18,10 @@ namespace WireMock.Http /// see http://stackoverflow.com/questions/138043/find-the-next-tcp-port-in-net. public static int FindFreeTcpPort() { - TcpListener tcpListener = null; - try + using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { - tcpListener = new TcpListener(IPAddress.Loopback, 0); - tcpListener.Start(); - - return ((IPEndPoint)tcpListener.LocalEndpoint).Port; - } - finally - { - tcpListener?.Stop(); + socket.Bind(DefaultLoopbackEndpoint); + return ((IPEndPoint)socket.LocalEndPoint).Port; } } diff --git a/src/WireMock.Net/Owin/WireMockMiddleware.cs b/src/WireMock.Net/Owin/WireMockMiddleware.cs index b065090e..dbfc24c6 100644 --- a/src/WireMock.Net/Owin/WireMockMiddleware.cs +++ b/src/WireMock.Net/Owin/WireMockMiddleware.cs @@ -58,7 +58,7 @@ namespace WireMock.Owin // Set start if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState) { - _options.Scenarios.Add(mapping.Scenario, null); + _options.Scenarios.TryAdd(mapping.Scenario, null); } } diff --git a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs index 54b84d1b..694ec065 100644 --- a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs +++ b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Collections.ObjectModel; using WireMock.Logging; using WireMock.Matchers; @@ -23,7 +22,9 @@ namespace WireMock.Owin public bool AllowPartialMapping { get; set; } - public IDictionary Mappings { get; } = new ConcurrentDictionary(); + public ConcurrentDictionary Mappings { get; } = new ConcurrentDictionary(); // Checked + + public ConcurrentDictionary Scenarios { get; } = new ConcurrentDictionary(); // Checked public ObservableCollection LogEntries { get; } = new ConcurentObservableCollection(); @@ -31,8 +32,6 @@ namespace WireMock.Owin public int? MaxRequestLogCount { get; set; } - public IDictionary Scenarios { get; } = new ConcurrentDictionary(); - #if !NETSTANDARD public Action PreWireMockMiddlewareInit { get; set; } diff --git a/src/WireMock.Net/ResponseMessage.cs b/src/WireMock.Net/ResponseMessage.cs index ccdce00d..79551b67 100644 --- a/src/WireMock.Net/ResponseMessage.cs +++ b/src/WireMock.Net/ResponseMessage.cs @@ -1,5 +1,4 @@ -using System.Collections.Concurrent; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Text; using WireMock.Util; @@ -8,14 +7,14 @@ using WireMock.Validation; namespace WireMock { /// - /// The response. + /// The ResponseMessage. /// public class ResponseMessage { /// /// Gets the headers. /// - public IDictionary> Headers { get; set; } = new ConcurrentDictionary>(); + public IDictionary> Headers { get; set; } = new Dictionary>(); /// /// Gets or sets the status code. diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs index 124215ed..40cd60b7 100644 --- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs +++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs @@ -210,7 +210,7 @@ namespace WireMock.Server if (settings.SaveMapping) { var mapping = ToMapping(requestMessage, responseMessage, settings.BlackListedHeaders ?? new string[] { }); - _options.Mappings.Add(mapping.Guid, mapping); + _options.Mappings.TryAdd(mapping.Guid, mapping); if (settings.SaveMappingToFile) { @@ -577,7 +577,7 @@ namespace WireMock.Server #region Scenarios private ResponseMessage ScenariosGet(RequestMessage requestMessage) { - var scenarios = Scenarios.Select(s => new + var scenarios = Scenarios.ToArray().Select(s => new { Name = s.Key, Started = s.Value != null, diff --git a/src/WireMock.Net/Server/FluentMockServer.cs b/src/WireMock.Net/Server/FluentMockServer.cs index 7804a434..e941dcd9 100644 --- a/src/WireMock.Net/Server/FluentMockServer.cs +++ b/src/WireMock.Net/Server/FluentMockServer.cs @@ -56,7 +56,7 @@ namespace WireMock.Server /// Gets the scenarios. /// [PublicAPI] - public IDictionary Scenarios => new ConcurrentDictionary(_options.Scenarios); + public ConcurrentDictionary Scenarios => new ConcurrentDictionary(_options.Scenarios); // Checked #region Start/Stop /// @@ -292,9 +292,9 @@ namespace WireMock.Server [PublicAPI] public void ResetMappings() { - foreach (var nonAdmin in _options.Mappings.Where(m => !m.Value.IsAdminInterface)) + foreach (var nonAdmin in _options.Mappings.ToArray().Where(m => !m.Value.IsAdminInterface)) { - _options.Mappings.Remove(nonAdmin); + _options.Mappings.TryRemove(nonAdmin.Key, out _); } } @@ -308,7 +308,7 @@ namespace WireMock.Server // Check a mapping exists with the same GUID, if so, remove it. if (_options.Mappings.ContainsKey(guid)) { - return _options.Mappings.Remove(guid); + return _options.Mappings.TryRemove(guid, out _); } return false; @@ -317,7 +317,7 @@ namespace WireMock.Server private bool DeleteMapping(string path) { // Check a mapping exists with the same path, if so, remove it. - var mapping = _options.Mappings.FirstOrDefault(entry => string.Equals(entry.Value.Path, path, StringComparison.OrdinalIgnoreCase)); + var mapping = _options.Mappings.ToArray().FirstOrDefault(entry => string.Equals(entry.Value.Path, path, StringComparison.OrdinalIgnoreCase)); return DeleteMapping(mapping.Key); } @@ -415,7 +415,7 @@ namespace WireMock.Server } else { - _options.Mappings.Add(mapping.Guid, mapping); + _options.Mappings.TryAdd(mapping.Guid, mapping); } } }