mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-22 08:18:26 +02:00
ProxySettings : Add logic to not save some requests depending on HttpMethods (#900)
* Add ExcludedHttpMethods to ProxySettings * tst * fix * SaveMappingSettings * .
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace WireMock.Matchers;
|
namespace WireMock.Matchers;
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
using WireMock.Http;
|
using WireMock.Http;
|
||||||
|
using WireMock.Matchers;
|
||||||
using WireMock.Serialization;
|
using WireMock.Serialization;
|
||||||
using WireMock.Settings;
|
using WireMock.Settings;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
@@ -47,12 +49,33 @@ internal class ProxyHelper
|
|||||||
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate).ConfigureAwait(false);
|
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate).ConfigureAwait(false);
|
||||||
|
|
||||||
IMapping? newMapping = null;
|
IMapping? newMapping = null;
|
||||||
if (HttpStatusRangeParser.IsMatch(proxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
|
||||||
(proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile))
|
var saveMappingSettings = proxyAndRecordSettings.SaveMappingSettings;
|
||||||
|
|
||||||
|
bool save = true;
|
||||||
|
if (saveMappingSettings != null)
|
||||||
|
{
|
||||||
|
save &= Check(saveMappingSettings.StatusCodePattern,
|
||||||
|
() => HttpStatusRangeParser.IsMatch(saveMappingSettings.StatusCodePattern, responseMessage.StatusCode)
|
||||||
|
);
|
||||||
|
|
||||||
|
save &= Check(saveMappingSettings.HttpMethods,
|
||||||
|
() => saveMappingSettings.HttpMethods.Value.Contains(requestMessage.Method, StringComparer.OrdinalIgnoreCase)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (save && (proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile))
|
||||||
{
|
{
|
||||||
newMapping = _proxyMappingConverter.ToMapping(mapping, proxyAndRecordSettings, requestMessage, responseMessage);
|
newMapping = _proxyMappingConverter.ToMapping(mapping, proxyAndRecordSettings, requestMessage, responseMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (responseMessage, newMapping);
|
return (responseMessage, newMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool Check<T>(ProxySaveMappingSetting<T>? saveMappingSetting, Func<bool> action)
|
||||||
|
{
|
||||||
|
var isMatch = saveMappingSetting is null || action();
|
||||||
|
var matchBehaviour = saveMappingSetting?.MatchBehaviour ?? MatchBehaviour.AcceptOnMatch;
|
||||||
|
return isMatch == (matchBehaviour == MatchBehaviour.AcceptOnMatch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -26,8 +26,12 @@ internal class ProxyMappingConverter
|
|||||||
_dateTimeUtils = Guard.NotNull(dateTimeUtils);
|
_dateTimeUtils = Guard.NotNull(dateTimeUtils);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMapping ToMapping(IMapping? mapping, ProxyAndRecordSettings proxyAndRecordSettings, IRequestMessage requestMessage, ResponseMessage responseMessage)
|
public IMapping? ToMapping(IMapping? mapping, ProxyAndRecordSettings proxyAndRecordSettings, IRequestMessage requestMessage, ResponseMessage responseMessage)
|
||||||
{
|
{
|
||||||
|
var useDefinedRequestMatchers = proxyAndRecordSettings.UseDefinedRequestMatchers;
|
||||||
|
var excludedHeaders = new List<string>(proxyAndRecordSettings.ExcludedHeaders ?? new string[] { }) { "Cookie" };
|
||||||
|
var excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[0];
|
||||||
|
|
||||||
var request = (Request?)mapping?.RequestMatcher;
|
var request = (Request?)mapping?.RequestMatcher;
|
||||||
var clientIPMatcher = request?.GetRequestMessageMatcher<RequestMessageClientIPMatcher>();
|
var clientIPMatcher = request?.GetRequestMessageMatcher<RequestMessageClientIPMatcher>();
|
||||||
var pathMatcher = request?.GetRequestMessageMatcher<RequestMessagePathMatcher>();
|
var pathMatcher = request?.GetRequestMessageMatcher<RequestMessagePathMatcher>();
|
||||||
@@ -37,11 +41,6 @@ internal class ProxyMappingConverter
|
|||||||
var methodMatcher = request?.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
|
var methodMatcher = request?.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
|
||||||
var bodyMatcher = request?.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
var bodyMatcher = request?.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
||||||
|
|
||||||
var useDefinedRequestMatchers = proxyAndRecordSettings.UseDefinedRequestMatchers;
|
|
||||||
|
|
||||||
var excludedHeaders = new List<string>(proxyAndRecordSettings.ExcludedHeaders ?? new string[] { }) { "Cookie" };
|
|
||||||
var excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[] { };
|
|
||||||
|
|
||||||
var newRequest = Request.Create();
|
var newRequest = Request.Create();
|
||||||
|
|
||||||
// ClientIP
|
// ClientIP
|
||||||
|
|||||||
@@ -28,9 +28,28 @@ public class ProxyAndRecordSettings : HttpClientSettings
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Only save request/response to the internal Mappings if the status code is included in this pattern. (Note that SaveMapping must also be set to true.)
|
/// Only save request/response to the internal Mappings if the status code is included in this pattern. (Note that SaveMapping must also be set to true.)
|
||||||
/// The pattern can contain a single value like "200", but also ranges like "2xx", "100,300,600" or "100-299,6xx" are supported.
|
/// The pattern can contain a single value like "200", but also ranges like "2xx", "100,300,600" or "100-299,6xx" are supported.
|
||||||
|
///
|
||||||
|
/// Deprecated : use SaveMappingSettings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public string SaveMappingForStatusCodePattern { get; set; } = "*";
|
public string SaveMappingForStatusCodePattern
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SaveMappingSettings is null)
|
||||||
|
{
|
||||||
|
SaveMappingSettings = new ProxySaveMappingSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveMappingSettings.StatusCodePattern = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Additional SaveMappingSettings.
|
||||||
|
/// </summary>
|
||||||
|
[PublicAPI]
|
||||||
|
public ProxySaveMappingSettings? SaveMappingSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines a list from headers which will be excluded from the saved mappings.
|
/// Defines a list from headers which will be excluded from the saved mappings.
|
||||||
|
|||||||
20
src/WireMock.Net/Settings/ProxySaveMappingSetting.cs
Normal file
20
src/WireMock.Net/Settings/ProxySaveMappingSetting.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using WireMock.Matchers;
|
||||||
|
|
||||||
|
namespace WireMock.Settings;
|
||||||
|
|
||||||
|
public class ProxySaveMappingSetting<T>
|
||||||
|
{
|
||||||
|
public MatchBehaviour MatchBehaviour { get; } = MatchBehaviour.AcceptOnMatch;
|
||||||
|
|
||||||
|
public T Value { get; private set; }
|
||||||
|
|
||||||
|
public ProxySaveMappingSetting(T value, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
MatchBehaviour = matchBehaviour;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator ProxySaveMappingSetting<T>(T value) => new ProxySaveMappingSetting<T>(value);
|
||||||
|
|
||||||
|
public static implicit operator T(ProxySaveMappingSetting<T> @this) => @this.Value;
|
||||||
|
}
|
||||||
22
src/WireMock.Net/Settings/ProxySaveMappingSettings.cs
Normal file
22
src/WireMock.Net/Settings/ProxySaveMappingSettings.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace WireMock.Settings;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ProxySaveMappingSettings
|
||||||
|
/// </summary>
|
||||||
|
public class ProxySaveMappingSettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Only save request/response to the internal Mappings if the status code is included in this pattern. (Note that SaveMapping must also be set to true.)
|
||||||
|
/// The pattern can contain a single value like "200", but also ranges like "2xx", "100,300,600" or "100-299,6xx" are supported.
|
||||||
|
/// </summary>
|
||||||
|
[PublicAPI]
|
||||||
|
public ProxySaveMappingSetting<string>? StatusCodePattern { get; set; } = "*";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only save these Http Methods. (Note that SaveMapping must also be set to true.)
|
||||||
|
/// </summary>
|
||||||
|
[PublicAPI]
|
||||||
|
public ProxySaveMappingSetting<string[]>? HttpMethods { get; set; }
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
|
using WireMock.Matchers;
|
||||||
using WireMock.Types;
|
using WireMock.Types;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
|
|
||||||
@@ -111,7 +112,12 @@ public static class WireMockServerSettingsParser
|
|||||||
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
|
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
|
||||||
UseDefinedRequestMatchers = parser.GetBoolValue(nameof(ProxyAndRecordSettings.UseDefinedRequestMatchers)),
|
UseDefinedRequestMatchers = parser.GetBoolValue(nameof(ProxyAndRecordSettings.UseDefinedRequestMatchers)),
|
||||||
AppendGuidToSavedMappingFile = parser.GetBoolValue(nameof(ProxyAndRecordSettings.AppendGuidToSavedMappingFile)),
|
AppendGuidToSavedMappingFile = parser.GetBoolValue(nameof(ProxyAndRecordSettings.AppendGuidToSavedMappingFile)),
|
||||||
Url = proxyUrl!
|
Url = proxyUrl!,
|
||||||
|
SaveMappingSettings = new ProxySaveMappingSettings
|
||||||
|
{
|
||||||
|
StatusCodePattern = parser.GetStringValue("SaveMappingForStatusCodePattern", "*"),
|
||||||
|
// HttpMethods = new ProxySaveMappingSetting<string[]>(parser.GetValues("DoNotSaveMappingForHttpMethods", new string[0]), MatchBehaviour.RejectOnMatch)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
string? proxyAddress = parser.GetStringValue("WebProxyAddress");
|
string? proxyAddress = parser.GetStringValue("WebProxyAddress");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#if !(NET452 || NET461 || NETCOREAPP3_1)
|
#if !(NET452 || NET461 || NETCOREAPP3_1)
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using VerifyTests;
|
using VerifyTests;
|
||||||
using VerifyXunit;
|
using VerifyXunit;
|
||||||
@@ -70,7 +71,7 @@ public class ProxyMappingConverterTests
|
|||||||
var responseMessage = new ResponseMessage();
|
var responseMessage = new ResponseMessage();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var proxyMapping = _sut.ToMapping(mappingMock.Object, proxyAndRecordSettings, requestMessageMock.Object, responseMessage);
|
var proxyMapping = _sut.ToMapping(mappingMock.Object, proxyAndRecordSettings, requestMessageMock.Object, responseMessage)!;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var model = _mappingConverter.ToMappingModel(proxyMapping);
|
var model = _mappingConverter.ToMappingModel(proxyMapping);
|
||||||
|
|||||||
@@ -248,6 +248,45 @@ public class WireMockServerProxyTests
|
|||||||
fileSystemHandlerMock.Verify(f => f.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
fileSystemHandlerMock.Verify(f => f.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task WireMockServer_Proxy_With_DoNotSaveMappingForHttpMethod_Should_Not_SaveMapping()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
|
||||||
|
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
|
||||||
|
|
||||||
|
var settings = new WireMockServerSettings
|
||||||
|
{
|
||||||
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
|
{
|
||||||
|
Url = "http://www.google.com",
|
||||||
|
SaveMapping = true,
|
||||||
|
SaveMappingToFile = true,
|
||||||
|
SaveMappingSettings = new ProxySaveMappingSettings
|
||||||
|
{
|
||||||
|
HttpMethods = new ProxySaveMappingSetting<string[]>(new string[] { "GET" }, MatchBehaviour.RejectOnMatch) // To make sure that we don't want this mapping
|
||||||
|
}
|
||||||
|
},
|
||||||
|
FileSystemHandler = fileSystemHandlerMock.Object
|
||||||
|
};
|
||||||
|
var server = WireMockServer.Start(settings);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var requestMessage = new HttpRequestMessage
|
||||||
|
{
|
||||||
|
Method = HttpMethod.Get,
|
||||||
|
RequestUri = new Uri(server.Urls[0])
|
||||||
|
};
|
||||||
|
var httpClientHandler = new HttpClientHandler { AllowAutoRedirect = false };
|
||||||
|
await new HttpClient(httpClientHandler).SendAsync(requestMessage).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
server.Mappings.Should().HaveCount(1);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
fileSystemHandlerMock.Verify(f => f.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task WireMockServer_Proxy_Should_log_proxied_requests()
|
public async Task WireMockServer_Proxy_Should_log_proxied_requests()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user