diff --git a/examples/WireMock.Net.Console.Record.NETCoreApp/Program.cs b/examples/WireMock.Net.Console.Record.NETCoreApp/Program.cs index 700fa2c5..7d1e16b8 100644 --- a/examples/WireMock.Net.Console.Record.NETCoreApp/Program.cs +++ b/examples/WireMock.Net.Console.Record.NETCoreApp/Program.cs @@ -12,12 +12,13 @@ namespace WireMock.Net.Console.Record.NETCoreApp { Urls = new[] { "http://localhost:9091/", "https://localhost:9443/" }, StartAdminInterface = true, - ReadStaticMappings = true, + ReadStaticMappings = false, ProxyAndRecordSettings = new ProxyAndRecordSettings { Url = "https://www.google.com", //X509Certificate2ThumbprintOrSubjectName = "www.yourclientcertname.com OR yourcertificatethumbprint (only if the service you're proxying to requires it)", - SaveMapping = true + SaveMapping = true, + SaveMappingToFile = false } }); diff --git a/src/WireMock.Net.StandAlone/StandAloneApp.cs b/src/WireMock.Net.StandAlone/StandAloneApp.cs index 9bd1f26f..d7f0238c 100644 --- a/src/WireMock.Net.StandAlone/StandAloneApp.cs +++ b/src/WireMock.Net.StandAlone/StandAloneApp.cs @@ -66,6 +66,7 @@ namespace WireMock.Net.StandAlone { Url = proxyURL, SaveMapping = parser.GetBoolValue("SaveMapping"), + SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"), X509Certificate2ThumbprintOrSubjectName = parser.GetStringValue("X509Certificate2ThumbprintOrSubjectName") }; } diff --git a/src/WireMock.Net/Mapping.cs b/src/WireMock.Net/Mapping.cs index 1fd3c8f6..72d9a136 100644 --- a/src/WireMock.Net/Mapping.cs +++ b/src/WireMock.Net/Mapping.cs @@ -13,25 +13,16 @@ namespace WireMock /// /// Gets the unique identifier. /// - /// - /// The unique identifier. - /// public Guid Guid { get; } /// /// Gets the unique title. /// - /// - /// The unique title. - /// public string Title { get; } /// /// Gets the priority. /// - /// - /// The priority. - /// public int Priority { get; } /// diff --git a/src/WireMock.Net/Serialization/MappingConverter.cs b/src/WireMock.Net/Serialization/MappingConverter.cs index a1a76777..9eb635fe 100644 --- a/src/WireMock.Net/Serialization/MappingConverter.cs +++ b/src/WireMock.Net/Serialization/MappingConverter.cs @@ -79,7 +79,7 @@ namespace WireMock.Serialization Funcs = Map(pm.Funcs) }).ToList() : null, - Body = methodMatcher?.Methods != null && methodMatcher.Methods.Count(m => m == "get") == 1 ? null : new BodyModel + Body = methodMatcher?.Methods != null && methodMatcher.Methods.Any(m => m == "get") ? null : new BodyModel { Matcher = bodyMatcher != null ? Map(bodyMatcher.Matcher) : null, Func = bodyMatcher != null ? Map(bodyMatcher.Func) : null, @@ -115,14 +115,16 @@ namespace WireMock.Serialization mappingModel.Response.BodyAsFile = response.ResponseMessage.BodyAsFile; mappingModel.Response.BodyAsFileIsCached = response.ResponseMessage.BodyAsFileIsCached; mappingModel.Response.UseTransformer = response.UseTransformer; - mappingModel.Response.BodyEncoding = response.ResponseMessage.BodyEncoding != null - ? new EncodingModel + + if (response.ResponseMessage.BodyEncoding != null) + { + mappingModel.Response.BodyEncoding = new EncodingModel { EncodingName = response.ResponseMessage.BodyEncoding.EncodingName, CodePage = response.ResponseMessage.BodyEncoding.CodePage, WebName = response.ResponseMessage.BodyEncoding.WebName - } - : null; + }; + } } return mappingModel; diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs index a4bf2ad2..f89120b8 100644 --- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs +++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs @@ -130,11 +130,11 @@ namespace WireMock.Server } #region Proxy and Record - private HttpClient httpClientForProxy; + private HttpClient _httpClientForProxy; private void InitProxyAndRecord(ProxyAndRecordSettings settings) { - httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.X509Certificate2ThumbprintOrSubjectName); + _httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.X509Certificate2ThumbprintOrSubjectName); Given(Request.Create().WithPath("/*").UsingAnyVerb()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings)); } @@ -144,12 +144,17 @@ namespace WireMock.Server var proxyUri = new Uri(settings.Url); var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery); - var responseMessage = await HttpClientHelper.SendAsync(httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri); + var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri); if (settings.SaveMapping) { var mapping = ToMapping(requestMessage, responseMessage); - SaveMappingToFile(mapping); + _options.Mappings.Add(mapping); + + if (settings.SaveMappingToFile) + { + SaveMappingToFile(mapping); + } } return responseMessage; @@ -157,11 +162,20 @@ namespace WireMock.Server private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage) { - var request = (Request)Request.Create(); + var request = Request.Create(); request.WithPath(requestMessage.Path); request.UsingVerb(requestMessage.Method); - var response = (Response)Response.Create(responseMessage); + requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray())); + requestMessage.Headers.Loop((key, value) => request.WithHeader(key, new ExactMatcher(value.ToArray()))); + requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, new ExactMatcher(value))); + + if (requestMessage.Body != null) + { + request.WithBody(new ExactMatcher(requestMessage.Body)); + } + + var response = Response.Create(responseMessage); return new Mapping(Guid.NewGuid(), string.Empty, request, response, 0, null, null, null); } @@ -530,8 +544,9 @@ namespace WireMock.Server { var pathModel = JsonUtils.ParseJTokenToObject(requestModel.Path); if (pathModel?.Matchers != null) - requestBuilder = - requestBuilder.WithPath(pathModel.Matchers.Select(MappingConverter.Map).ToArray()); + { + requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MappingConverter.Map).ToArray()); + } } } @@ -546,8 +561,9 @@ namespace WireMock.Server { var urlModel = JsonUtils.ParseJTokenToObject(requestModel.Url); if (urlModel?.Matchers != null) - requestBuilder = - requestBuilder.WithUrl(urlModel.Matchers.Select(MappingConverter.Map).ToArray()); + { + requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MappingConverter.Map).ToArray()); + } } } diff --git a/src/WireMock.Net/Settings/ProxyAndRecordSettings.cs b/src/WireMock.Net/Settings/ProxyAndRecordSettings.cs index 2c58136a..5787070e 100644 --- a/src/WireMock.Net/Settings/ProxyAndRecordSettings.cs +++ b/src/WireMock.Net/Settings/ProxyAndRecordSettings.cs @@ -11,10 +11,15 @@ public string Url { get; set; } /// - /// Save the mapping for each request/response. + /// Save the mapping for each request/response to the internal Mappings. /// public bool SaveMapping { get; set; } = true; + /// + /// Save the mapping for each request/response to also file. (Note that SaveMapping must also be set to true.) + /// + public bool SaveMappingToFile { get; set; } = true; + /// /// The clientCertificate thumbprint or subject name fragment to use. Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com"" /// diff --git a/src/WireMock.Net/Util/DictionaryExtensions.cs b/src/WireMock.Net/Util/DictionaryExtensions.cs new file mode 100644 index 00000000..a84fed07 --- /dev/null +++ b/src/WireMock.Net/Util/DictionaryExtensions.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using JetBrains.Annotations; +using WireMock.Validation; + +namespace WireMock.Util +{ + /// + /// Some IDictionary Extensions + /// + public static class DictionaryExtensions + { + /// + /// Loops the dictionary and executes the specified action. + /// + /// The type of the key. + /// The type of the value. + /// The dictionary to loop (can be null). + /// The action. + public static void Loop(this IDictionary dictionary, [NotNull] Action action) + { + Check.NotNull(action, nameof(action)); + + if (dictionary != null) + { + foreach (var entry in dictionary) + { + action(entry.Key, entry.Value); + } + } + } + } +} \ No newline at end of file