diff --git a/src/WireMock.Net/Serialization/ProxyMappingConverter.cs b/src/WireMock.Net/Serialization/ProxyMappingConverter.cs index 49a6f6eae..483cf294c 100644 --- a/src/WireMock.Net/Serialization/ProxyMappingConverter.cs +++ b/src/WireMock.Net/Serialization/ProxyMappingConverter.cs @@ -31,6 +31,7 @@ public ProxyMappingConverter(WireMockServerSettings settings, IGuidUtils guidUti var useDefinedRequestMatchers = proxyAndRecordSettings.UseDefinedRequestMatchers; var excludedHeaders = new List(proxyAndRecordSettings.ExcludedHeaders ?? new string[] { }) { "Cookie" }; var excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[0]; + var excludedParams = proxyAndRecordSettings.ExcludedParams ?? new string[0]; var request = (Request?)mapping?.RequestMatcher; var clientIPMatcher = request?.GetRequestMessageMatcher(); @@ -74,12 +75,21 @@ public ProxyMappingConverter(WireMockServerSettings settings, IGuidUtils guidUti { foreach (var paramMatcher in paramMatchers) { - newRequest.WithParam(paramMatcher.Key, paramMatcher.MatchBehaviour, paramMatcher.Matchers!.ToArray()); + if (!excludedParams.Contains(paramMatcher.Key, StringComparer.OrdinalIgnoreCase)) + { + newRequest.WithParam(paramMatcher.Key, paramMatcher.MatchBehaviour, paramMatcher.Matchers!.ToArray()); + } } } else { - requestMessage.Query?.Loop((key, value) => newRequest.WithParam(key, false, value.ToArray())); + requestMessage.Query?.Loop((key, value) => + { + if (!excludedParams.Contains(key, StringComparer.OrdinalIgnoreCase)) + { + newRequest.WithParam(key, false, value.ToArray()); + } + }); } // Cookies diff --git a/src/WireMock.Net/Settings/ProxyAndRecordSettings.cs b/src/WireMock.Net/Settings/ProxyAndRecordSettings.cs index 6227d1625..719a04fc7 100644 --- a/src/WireMock.Net/Settings/ProxyAndRecordSettings.cs +++ b/src/WireMock.Net/Settings/ProxyAndRecordSettings.cs @@ -57,6 +57,12 @@ public string SaveMappingForStatusCodePattern [PublicAPI] public string[]? ExcludedHeaders { get; set; } + /// + /// Defines a list of params which will be excluded from the saved mappings. + /// + [PublicAPI] + public string[]? ExcludedParams { get; set; } + /// /// Defines a list of cookies which will be excluded from the saved mappings. /// diff --git a/test/WireMock.Net.Tests/WireMockServer.Proxy.cs b/test/WireMock.Net.Tests/WireMockServer.Proxy.cs index 1f670cf6b..7955222b3 100644 --- a/test/WireMock.Net.Tests/WireMockServer.Proxy.cs +++ b/test/WireMock.Net.Tests/WireMockServer.Proxy.cs @@ -528,6 +528,48 @@ public async Task WireMockServer_Proxy_Should_exclude_ExcludedCookies_in_mapping Check.That(matchers).Contains("GoodCookie"); } + [Fact] + public async Task WireMockServer_Proxy_Should_exclude_ExcludedParams_in_mapping() + { + // Assign + string path = $"/prx_{Guid.NewGuid()}"; + var serverForProxyForwarding = WireMockServer.Start(); + serverForProxyForwarding + .Given(Request.Create().WithPath(path)) + .RespondWith(Response.Create()); + + var settings = new WireMockServerSettings + { + ProxyAndRecordSettings = new ProxyAndRecordSettings + { + Url = serverForProxyForwarding.Urls[0], + SaveMapping = true, + SaveMappingToFile = false, + ExcludedParams = new[] { "timestamp" } + } + }; + var server = WireMockServer.Start(settings); + var defaultMapping = server.Mappings.First(); + var param01 = "?timestamp=2023-03-23"; + var param02 = "&name=person"; + + // Act + var requestMessage = new HttpRequestMessage + { + Method = HttpMethod.Post, + RequestUri = new Uri($"{server.Urls[0]}{path}{param01}{param02}"), + Content = new StringContent("stringContent"), + }; + await new HttpClient().SendAsync(requestMessage).ConfigureAwait(false); + + // Assert + var mapping = server.Mappings.FirstOrDefault(m => m.Guid != defaultMapping.Guid); + Check.That(mapping).IsNotNull(); + var matchers = ((Request)mapping.RequestMatcher).GetRequestMessageMatchers().Select(m => m.Key).ToList(); + Check.That(matchers).Not.Contains("timestamp"); + Check.That(matchers).Contains("name"); + } + [Fact] public async Task WireMockServer_Proxy_Should_preserve_content_header_in_proxied_request_with_empty_content() {