mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-21 07:51:23 +02:00
Add Proxy Setting for: SaveMappingForStatusCodePattern to only save the mapping when the status code matches the pattern (#357)
* proxy * HttpStatusRangeParserTests * test
This commit is contained in:
@@ -267,7 +267,8 @@ namespace WireMock.Server
|
|||||||
|
|
||||||
var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
|
var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
|
||||||
|
|
||||||
if (settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile)
|
if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
||||||
|
(settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile))
|
||||||
{
|
{
|
||||||
var mapping = ToMapping(requestMessage, responseMessage, settings.ProxyAndRecordSettings.BlackListedHeaders ?? new string[] { }, settings.ProxyAndRecordSettings.BlackListedCookies ?? new string[] { });
|
var mapping = ToMapping(requestMessage, responseMessage, settings.ProxyAndRecordSettings.BlackListedHeaders ?? new string[] { }, settings.ProxyAndRecordSettings.BlackListedCookies ?? new string[] { });
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace WireMock.Settings
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace WireMock.Settings
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IProxyAndRecordSettings
|
/// IProxyAndRecordSettings
|
||||||
@@ -16,7 +18,14 @@
|
|||||||
bool SaveMapping { get; set; }
|
bool SaveMapping { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Save the mapping for each request/response to also file. (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.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
string SaveMappingForStatusCodePattern { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Save the mapping for each request/response also to a file. (Note that SaveMapping must also be set to true.)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool SaveMappingToFile { get; set; }
|
bool SaveMappingToFile { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ namespace WireMock.Settings
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool SaveMapping { get; set; } = true;
|
public bool SaveMapping { get; set; } = true;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IProxyAndRecordSettings.SaveMappingForStatusCodePattern"/>
|
||||||
|
[PublicAPI]
|
||||||
|
public string SaveMappingForStatusCodePattern { get; set; } = "*";
|
||||||
|
|
||||||
/// <inheritdoc cref="IProxyAndRecordSettings.SaveMappingToFile"/>
|
/// <inheritdoc cref="IProxyAndRecordSettings.SaveMappingToFile"/>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool SaveMappingToFile { get; set; } = true;
|
public bool SaveMappingToFile { get; set; } = true;
|
||||||
|
|||||||
71
src/WireMock.Net/Util/HttpStatusRangeParser.cs
Normal file
71
src/WireMock.Net/Util/HttpStatusRangeParser.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace WireMock.Util
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Based on https://github.com/tmenier/Flurl/blob/129565361e135e639f1d44a35a78aea4302ac6ca/src/Flurl.Http/HttpStatusRangeParser.cs
|
||||||
|
/// </summary>
|
||||||
|
internal static class HttpStatusRangeParser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified pattern is match.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pattern">The pattern. (Can be null, in that case it's allowed.)</param>
|
||||||
|
/// <param name="httpStatusCode">The value.</param>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="pattern"/> is invalid.</exception>
|
||||||
|
public static bool IsMatch(string pattern, HttpStatusCode httpStatusCode)
|
||||||
|
{
|
||||||
|
return IsMatch(pattern, (int)httpStatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified pattern is match.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pattern">The pattern. (Can be null, in that case it's allowed.)</param>
|
||||||
|
/// <param name="httpStatusCode">The value.</param>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="pattern"/> is invalid.</exception>
|
||||||
|
public static bool IsMatch(string pattern, int httpStatusCode)
|
||||||
|
{
|
||||||
|
if (pattern == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var range in pattern.Split(',').Select(p => p.Trim()))
|
||||||
|
{
|
||||||
|
switch (range)
|
||||||
|
{
|
||||||
|
case "":
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case "*":
|
||||||
|
return true; // special case - allow everything
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] bounds = range.Split('-');
|
||||||
|
int lower = 0;
|
||||||
|
int upper = 0;
|
||||||
|
|
||||||
|
bool valid =
|
||||||
|
bounds.Length <= 2 &&
|
||||||
|
int.TryParse(Regex.Replace(bounds.First().Trim(), "[*xX]", "0"), out lower) &&
|
||||||
|
int.TryParse(Regex.Replace(bounds.Last().Trim(), "[*xX]", "9"), out upper);
|
||||||
|
|
||||||
|
if (!valid)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Invalid range pattern: \"{pattern}\". Examples of allowed patterns: \"400\", \"4xx\", \"300,400-403\", \"*\".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (httpStatusCode >= lower && httpStatusCode <= upper)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
test/WireMock.Net.Tests/Util/HttpStatusRangeParserTests.cs
Normal file
75
test/WireMock.Net.Tests/Util/HttpStatusRangeParserTests.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
using FluentAssertions;
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using WireMock.Util;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Tests.Util
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Based on https://raw.githubusercontent.com/tmenier/Flurl/129565361e135e639f1d44a35a78aea4302ac6ca/Test/Flurl.Test/Http/HttpStatusRangeParserTests.cs
|
||||||
|
/// </summary>
|
||||||
|
public class HttpStatusRangeParserTests
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData("4**", 399, false)]
|
||||||
|
[InlineData("4**", 400, true)]
|
||||||
|
[InlineData("4**", 499, true)]
|
||||||
|
[InlineData("4**", 500, false)]
|
||||||
|
|
||||||
|
[InlineData("4xx", 399, false)]
|
||||||
|
[InlineData("4xx", 400, true)]
|
||||||
|
[InlineData("4xx", 499, true)]
|
||||||
|
[InlineData("4xx", 500, false)]
|
||||||
|
|
||||||
|
[InlineData("4XX", 399, false)]
|
||||||
|
[InlineData("4XX", 400, true)]
|
||||||
|
[InlineData("4XX", 499, true)]
|
||||||
|
[InlineData("4XX", 500, false)]
|
||||||
|
|
||||||
|
[InlineData("400-499", 399, false)]
|
||||||
|
[InlineData("400-499", 400, true)]
|
||||||
|
[InlineData("400-499", 499, true)]
|
||||||
|
[InlineData("400-499", 500, false)]
|
||||||
|
|
||||||
|
[InlineData("100,3xx,600", 100, true)]
|
||||||
|
[InlineData("100,3xx,600", 101, false)]
|
||||||
|
[InlineData("100,3xx,600", 300, true)]
|
||||||
|
[InlineData("100,3xx,600", 399, true)]
|
||||||
|
[InlineData("100,3xx,600", 400, false)]
|
||||||
|
[InlineData("100,3xx,600", 600, true)]
|
||||||
|
|
||||||
|
[InlineData("400-409,490-499", 399, false)]
|
||||||
|
[InlineData("400-409,490-499", 405, true)]
|
||||||
|
[InlineData("400-409,490-499", 450, false)]
|
||||||
|
[InlineData("400-409,490-499", 495, true)]
|
||||||
|
[InlineData("400-409,490-499", 500, false)]
|
||||||
|
|
||||||
|
[InlineData("*", 0, true)]
|
||||||
|
[InlineData(",,,*", 9999, true)]
|
||||||
|
|
||||||
|
[InlineData("", 0, false)]
|
||||||
|
[InlineData(",,,", 9999, false)]
|
||||||
|
|
||||||
|
[InlineData(null, 399, true)]
|
||||||
|
public void HttpStatusRangeParser_ValidPattern_IsMatch(string pattern, int value, bool expectedResult)
|
||||||
|
{
|
||||||
|
HttpStatusRangeParser.IsMatch(pattern, value).Should().Be(expectedResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void HttpStatusRangeParser_ValidPattern_HttpStatusCode_IsMatch()
|
||||||
|
{
|
||||||
|
HttpStatusRangeParser.IsMatch("4xx", HttpStatusCode.BadRequest).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("-100")]
|
||||||
|
[InlineData("100-")]
|
||||||
|
[InlineData("1yy")]
|
||||||
|
public void HttpStatusRangeParser_InvalidPattern_ThrowsException(string pattern)
|
||||||
|
{
|
||||||
|
Assert.Throws<ArgumentException>(() => HttpStatusRangeParser.IsMatch(pattern, 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user