Skip to content

Commit

Permalink
ProxySettings : Add logic to not save some requests depending on Http…
Browse files Browse the repository at this point in the history
…Methods (#900)

* Add ExcludedHttpMethods to ProxySettings

* tst

* fix

* SaveMappingSettings

* .
  • Loading branch information
StefH committed Mar 9, 2023
1 parent 61cdc13 commit 674fa89
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 12 deletions.
1 change: 0 additions & 1 deletion src/WireMock.Net/Matchers/MatchScores.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

namespace WireMock.Matchers;
Expand Down
27 changes: 25 additions & 2 deletions src/WireMock.Net/Proxy/ProxyHelper.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Stef.Validation;
using WireMock.Http;
using WireMock.Matchers;
using WireMock.Serialization;
using WireMock.Settings;
using WireMock.Util;
Expand Down Expand Up @@ -47,12 +49,33 @@ public ProxyHelper(WireMockServerSettings settings)
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate).ConfigureAwait(false);

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);
}

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);
}
}
11 changes: 5 additions & 6 deletions src/WireMock.Net/Serialization/ProxyMappingConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ public ProxyMappingConverter(WireMockServerSettings settings, IGuidUtils guidUti
_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 clientIPMatcher = request?.GetRequestMessageMatcher<RequestMessageClientIPMatcher>();
var pathMatcher = request?.GetRequestMessageMatcher<RequestMessagePathMatcher>();
Expand All @@ -37,11 +41,6 @@ public IMapping ToMapping(IMapping? mapping, ProxyAndRecordSettings proxyAndReco
var methodMatcher = request?.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
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();

// ClientIP
Expand Down
21 changes: 20 additions & 1 deletion src/WireMock.Net/Settings/ProxyAndRecordSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,28 @@ public class ProxyAndRecordSettings : HttpClientSettings
/// <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.
///
/// Deprecated : use SaveMappingSettings.
/// </summary>
[PublicAPI]
public string SaveMappingForStatusCodePattern
{
set
{
if (SaveMappingSettings is null)
{
SaveMappingSettings = new ProxySaveMappingSettings();
}

SaveMappingSettings.StatusCodePattern = value;
}
}

/// <summary>
/// Additional SaveMappingSettings.
/// </summary>
[PublicAPI]
public string SaveMappingForStatusCodePattern { get; set; } = "*";
public ProxySaveMappingSettings? SaveMappingSettings { get; set; }

/// <summary>
/// Defines a list from headers which will be excluded from the saved mappings.
Expand Down
20 changes: 20 additions & 0 deletions src/WireMock.Net/Settings/ProxySaveMappingSetting.cs
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions src/WireMock.Net/Settings/ProxySaveMappingSettings.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
8 changes: 7 additions & 1 deletion src/WireMock.Net/Settings/WireMockServerSettingsParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using JetBrains.Annotations;
using Stef.Validation;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.Types;
using WireMock.Util;

Expand Down Expand Up @@ -111,7 +112,12 @@ public static bool TryParseArguments(string[] args, [NotNullWhen(true)] out Wire
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
UseDefinedRequestMatchers = parser.GetBoolValue(nameof(ProxyAndRecordSettings.UseDefinedRequestMatchers)),
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");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#if !(NET452 || NET461 || NETCOREAPP3_1)
using System;
using System.Threading.Tasks;
using FluentAssertions;
using Moq;
using VerifyTests;
using VerifyXunit;
Expand Down Expand Up @@ -70,7 +71,7 @@ public Task ToMapping_UseDefinedRequestMatchers_True()
var responseMessage = new ResponseMessage();

// Act
var proxyMapping = _sut.ToMapping(mappingMock.Object, proxyAndRecordSettings, requestMessageMock.Object, responseMessage);
var proxyMapping = _sut.ToMapping(mappingMock.Object, proxyAndRecordSettings, requestMessageMock.Object, responseMessage)!;

// Assert
var model = _mappingConverter.ToMappingModel(proxyMapping);
Expand Down
39 changes: 39 additions & 0 deletions test/WireMock.Net.Tests/WireMockServer.Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,45 @@ public async Task WireMockServer_Proxy_With_SaveMappingForStatusCodePattern_Is_F
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]
public async Task WireMockServer_Proxy_Should_log_proxied_requests()
{
Expand Down

0 comments on commit 674fa89

Please sign in to comment.