mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-14 06:13:35 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aeb95b02d2 | ||
|
|
2dbb984a1e | ||
|
|
88dd1b9aa4 | ||
|
|
87c4344d65 | ||
|
|
2851c820e0 | ||
|
|
13ab37dd3e | ||
|
|
f49046374a | ||
|
|
69488ced5f | ||
|
|
e6bcd625f7 | ||
|
|
d1b42bf436 | ||
|
|
f4861d9bab | ||
|
|
4c01ef4838 | ||
|
|
83866f5719 |
26
CHANGELOG.md
26
CHANGELOG.md
@@ -1,7 +1,25 @@
|
||||
# 1.1.10.0 (05 March 2020)
|
||||
- [#427](https://github.com/WireMock-Net/WireMock.Net/pull/427) - Add UsingOptions, UsingConnect and UsingTrace [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#434](https://github.com/WireMock-Net/WireMock.Net/pull/434) - Option to disable JSON deserialization [feature] contributed by [sebastianmattar](https://github.com/sebastianmattar)
|
||||
- [#435](https://github.com/WireMock-Net/WireMock.Net/pull/435) - Also call HandlebarsRegistrationCallback when using WithCallback(..) [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#408](https://github.com/WireMock-Net/WireMock.Net/issues/408) - Intermittent threading errors with FindLogEntries [bug]
|
||||
- [#433](https://github.com/WireMock-Net/WireMock.Net/issues/433) - HandlebarsRegistrationCallback not fired [feature]
|
||||
|
||||
# 1.1.9.0 (25 February 2020)
|
||||
- [#431](https://github.com/WireMock-Net/WireMock.Net/pull/431) - Fix LinqMatcher for JSON int64 [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#425](https://github.com/WireMock-Net/WireMock.Net/issues/425) - Allow 64 bit numbers in JSON [bug]
|
||||
|
||||
# 1.1.8.0 (22 February 2020)
|
||||
- [#419](https://github.com/WireMock-Net/WireMock.Net/pull/419) - Support multi line wild card matching [bug] contributed by [NoahLerner](https://github.com/NoahLerner)
|
||||
- [#421](https://github.com/WireMock-Net/WireMock.Net/pull/421) - Fix: do not return empty matchers array when Func has been used [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#423](https://github.com/WireMock-Net/WireMock.Net/pull/423) - Fixes for Cookie and Header Reject on Match [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#424](https://github.com/WireMock-Net/WireMock.Net/pull/424) - Don't return empty dictionary object for response headers in JSON mapping [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#418](https://github.com/WireMock-Net/WireMock.Net/issues/418) - Body matching fails if body has newline [bug]
|
||||
|
||||
# 1.1.7.0 (06 February 2020)
|
||||
- [#409](https://github.com/WireMock-Net/WireMock.Net/pull/409) - Admin Delete with mappings in body [feature] contributed by [thewholuver94](https://github.com/thewholuver94)
|
||||
- [#411](https://github.com/WireMock-Net/WireMock.Net/pull/411) - Improved relative path checking based on file existence [feature] contributed by [thewholuver94](https://github.com/thewholuver94)
|
||||
- [#413](https://github.com/WireMock-Net/WireMock.Net/pull/413) - Fix new Delete with body missing from IWireMockAdminApi interface contributed by [thewholuver94](https://github.com/thewholuver94)
|
||||
- [#409](https://github.com/WireMock-Net/WireMock.Net/pull/409) - Admin Delete with mappings in body [feature] contributed by [NoahLerner](https://github.com/NoahLerner)
|
||||
- [#411](https://github.com/WireMock-Net/WireMock.Net/pull/411) - Improved relative path checking based on file existence [feature] contributed by [NoahLerner](https://github.com/NoahLerner)
|
||||
- [#413](https://github.com/WireMock-Net/WireMock.Net/pull/413) - Fix new Delete with body missing from IWireMockAdminApi interface contributed by [NoahLerner](https://github.com/NoahLerner)
|
||||
- [#414](https://github.com/WireMock-Net/WireMock.Net/pull/414) - Fix logger in StandAlone [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#412](https://github.com/WireMock-Net/WireMock.Net/issues/412) - WireMock Standalone - null reference exception since settings.Logger [bug]
|
||||
|
||||
@@ -52,7 +70,7 @@
|
||||
- [#386](https://github.com/WireMock-Net/WireMock.Net/issues/386) - Is transforming contents of XML file supported.? [bug]
|
||||
|
||||
# 1.0.38.0 (30 November 2019)
|
||||
- [#376](https://github.com/WireMock-Net/WireMock.Net/pull/376) - Support int values for states and scenario naming [feature] contributed by [thewholuver94](https://github.com/thewholuver94)
|
||||
- [#376](https://github.com/WireMock-Net/WireMock.Net/pull/376) - Support int values for states and scenario naming [feature] contributed by [NoahLerner](https://github.com/NoahLerner)
|
||||
- [#378](https://github.com/WireMock-Net/WireMock.Net/pull/378) - Set handlebars dependency for .net 4.5.1 to fixed value [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#381](https://github.com/WireMock-Net/WireMock.Net/pull/381) - Use dotnet default development certificate for .NET Core 2.x [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#377](https://github.com/WireMock-Net/WireMock.Net/issues/377) - Unable to build against .NET 4.5.1 because of Handlebars [bug]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.1.7</VersionPrefix>
|
||||
<VersionPrefix>1.1.10</VersionPrefix>
|
||||
</PropertyGroup>
|
||||
|
||||
<Choose>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.1.7.0
|
||||
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.1.10.0
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
|
||||
<StartupObject>WireMock.Net.WebApplication.Program</StartupObject>
|
||||
<AssemblyName>WireMock.Net.WebApplication</AssemblyName>
|
||||
|
||||
@@ -16,5 +16,15 @@ namespace WireMock.Admin.Mappings
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
public IList<MatcherModel> Matchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ignore case.
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reject on match.
|
||||
/// </summary>
|
||||
public bool? RejectOnMatch { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -16,5 +16,15 @@ namespace WireMock.Admin.Mappings
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
public IList<MatcherModel> Matchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ignore case.
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reject on match.
|
||||
/// </summary>
|
||||
public bool? RejectOnMatch { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ namespace WireMock.Http
|
||||
return client;
|
||||
}
|
||||
|
||||
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url)
|
||||
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url, bool deserializeJson)
|
||||
{
|
||||
Check.NotNull(client, nameof(client));
|
||||
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||
@@ -83,7 +83,7 @@ namespace WireMock.Http
|
||||
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
|
||||
|
||||
// Create ResponseMessage
|
||||
return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri);
|
||||
return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/WireMock.Net/Http/HttpRequestMethods.cs
Normal file
18
src/WireMock.Net/Http/HttpRequestMethods.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace WireMock.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
|
||||
/// </summary>
|
||||
internal static class HttpRequestMethods
|
||||
{
|
||||
public const string CONNECT = "CONNECT";
|
||||
public const string DELETE = "DELETE";
|
||||
public const string GET = "GET";
|
||||
public const string HEAD = "HEAD";
|
||||
public const string OPTIONS = "OPTIONS";
|
||||
public const string PATCH = "PATCH";
|
||||
public const string POST = "POST";
|
||||
public const string PUT = "PUT";
|
||||
public const string TRACE = "TRACE";
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace WireMock.Http
|
||||
{
|
||||
internal static class HttpResponseMessageHelper
|
||||
{
|
||||
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri)
|
||||
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson)
|
||||
{
|
||||
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace WireMock.Http
|
||||
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
|
||||
responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault(), deserializeJson);
|
||||
}
|
||||
|
||||
foreach (var header in headers)
|
||||
|
||||
@@ -61,7 +61,8 @@ namespace WireMock.Matchers
|
||||
IgnoreCase = ignoreCase;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
|
||||
RegexOptions options = RegexOptions.Compiled;
|
||||
RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline;
|
||||
|
||||
if (ignoreCase)
|
||||
{
|
||||
options |= RegexOptions.IgnoreCase;
|
||||
|
||||
@@ -9,14 +9,15 @@ namespace WireMock.Matchers.Request
|
||||
/// <summary>
|
||||
/// The request cookie matcher.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="IRequestMatcher"/>
|
||||
public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
{
|
||||
private readonly MatchBehaviour _matchBehaviour;
|
||||
private readonly bool _ignoreCase;
|
||||
|
||||
/// <value>
|
||||
/// The funcs.
|
||||
/// </value>
|
||||
/// <summary>
|
||||
/// The functions
|
||||
/// </summary>
|
||||
public Func<IDictionary<string, string>, bool>[] Funcs { get; }
|
||||
|
||||
/// <summary>
|
||||
@@ -32,11 +33,11 @@ namespace WireMock.Matchers.Request
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">The ignoreCase.</param>
|
||||
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(pattern, nameof(pattern));
|
||||
@@ -50,15 +51,32 @@ namespace WireMock.Matchers.Request
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params string[] patterns) :
|
||||
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
Check.NotNull(patterns, nameof(patterns));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageCookieMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(matchers, nameof(matchers));
|
||||
|
||||
_matchBehaviour = matchBehaviour;
|
||||
Name = name;
|
||||
Matchers = matchers;
|
||||
_ignoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -52,33 +52,32 @@ namespace WireMock.Matchers.Request
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string[] patterns, bool ignoreCase)
|
||||
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params string[] patterns) :
|
||||
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(patterns, nameof(patterns));
|
||||
|
||||
_matchBehaviour = matchBehaviour;
|
||||
_ignoreCase = ignoreCase;
|
||||
Name = name;
|
||||
Matchers = patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(matchers, nameof(matchers));
|
||||
|
||||
_matchBehaviour = matchBehaviour;
|
||||
Name = name;
|
||||
Matchers = matchers;
|
||||
_ignoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,7 +124,7 @@ namespace WireMock.Matchers.Request
|
||||
}
|
||||
|
||||
WireMockList<string> list = headers[Name];
|
||||
return Matchers.Max(m => list.Max(value => m.IsMatch(value))); // TODO : is this correct ?
|
||||
return Matchers.Max(m => list.Max(m.IsMatch)); // TODO : is this correct ?
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,5 +41,7 @@ namespace WireMock.Owin
|
||||
bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
|
||||
bool? AllowAnyHttpStatusCodeInResponse { get; set; }
|
||||
|
||||
bool? DisableJsonBodyParsing { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ namespace WireMock.Owin.Mappers
|
||||
BodyData body = null;
|
||||
if (request.Body != null && BodyParser.ShouldParseBody(method, options.AllowBodyForAllHttpMethods == true))
|
||||
{
|
||||
body = await BodyParser.Parse(request.Body, request.ContentType);
|
||||
body = await BodyParser.Parse(request.Body, request.ContentType, !options.DisableJsonBodyParsing.GetValueOrDefault(false));
|
||||
}
|
||||
|
||||
return new RequestMessage(urldetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow };
|
||||
|
||||
@@ -45,5 +45,8 @@ namespace WireMock.Owin
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowAnyHttpStatusCodeInResponse"/>
|
||||
public bool? AllowAnyHttpStatusCodeInResponse { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableResponseBodyParsing"/>
|
||||
public bool? DisableJsonBodyParsing { get; set; }
|
||||
}
|
||||
}
|
||||
85
src/WireMock.Net/RequestBuilders/ICookiesRequestBuilder.cs
Normal file
85
src/WireMock.Net/RequestBuilders/ICookiesRequestBuilder.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
/// <summary>
|
||||
/// The CookieRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface ICookiesRequestBuilder : IParamsRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on name, pattern and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] string name, string pattern, MatchBehaviour matchBehaviour);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on name, pattern, ignoreCase and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on name, patterns and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] string name, string[] patterns, MatchBehaviour matchBehaviour);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on name, patterns, ignoreCase and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on name and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on name, ignoreCase and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the cookie-keys.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on name, ignoreCase, matchBehaviour and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the cookie-keys.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] string name, bool ignoreCase, MatchBehaviour matchBehaviour, [NotNull] params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The cookies funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] params Func<IDictionary<string, string>, bool>[] funcs);
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,9 @@ using WireMock.Matchers;
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
/// <summary>
|
||||
/// The HeadersAndCookieRequestBuilder interface.
|
||||
/// The HeadersRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IHeadersAndCookiesRequestBuilder : IParamsRequestBuilder
|
||||
public interface IHeadersRequestBuilder : ICookiesRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, pattern and matchBehaviour.
|
||||
@@ -56,36 +56,30 @@ namespace WireMock.RequestBuilders
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, ignoreCase and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the header-keys.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, ignoreCase, matchBehaviour and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the header-keys.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, bool ignoreCase, MatchBehaviour matchBehaviour, [NotNull] params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The headers funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string[]>, bool>[] funcs);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: cookie matching based on name, pattern, ignoreCase and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on name and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithCookie: matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithCookie([NotNull] params Func<IDictionary<string, string>, bool>[] funcs);
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,15 @@ namespace WireMock.RequestBuilders
|
||||
/// <summary>
|
||||
/// The MethodRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IMethodRequestBuilder : IHeadersAndCookiesRequestBuilder
|
||||
public interface IMethodRequestBuilder : IHeadersRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// UsingConnect: add HTTP Method matching on `CONNECT` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingDelete: add HTTP Method matching on `DELETE` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
@@ -24,7 +31,7 @@ namespace WireMock.RequestBuilders
|
||||
IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
|
||||
/// UsingHead: Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
@@ -44,6 +51,13 @@ namespace WireMock.RequestBuilders
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingPut: add HTTP Method matching on `OPTIONS` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingPut: add HTTP Method matching on `PUT` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
@@ -51,6 +65,13 @@ namespace WireMock.RequestBuilders
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingTrace: add HTTP Method matching on `TRACE` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingAnyMethod: add HTTP Method matching on any method.
|
||||
/// </summary>
|
||||
|
||||
113
src/WireMock.Net/RequestBuilders/Request.UsingMethods.cs
Normal file
113
src/WireMock.Net/RequestBuilders/Request.UsingMethods.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using System.Linq;
|
||||
using WireMock.Http;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingConnect(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.CONNECT));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.DELETE));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.GET));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.HEAD));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingOptions(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.OPTIONS));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.POST));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PATCH));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PUT));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingTrace(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.TRACE));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
|
||||
public IRequestBuilder UsingAnyMethod()
|
||||
{
|
||||
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
|
||||
foreach (var matcher in matchers)
|
||||
{
|
||||
_requestMatchers.Remove(matcher);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
|
||||
public IRequestBuilder UsingAnyVerb()
|
||||
{
|
||||
return UsingAnyMethod();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
|
||||
public IRequestBuilder UsingMethod(params string[] methods)
|
||||
{
|
||||
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
|
||||
public IRequestBuilder UsingVerb(params string[] verbs)
|
||||
{
|
||||
return UsingMethod(verbs);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
|
||||
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
|
||||
{
|
||||
Check.NotNullOrEmpty(methods, nameof(methods));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/WireMock.Net/RequestBuilders/Request.WithCookies.cs
Normal file
82
src/WireMock.Net/RequestBuilders/Request.WithCookies.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, string, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithCookie(string name, string pattern, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
return WithCookie(name, pattern, true, matchBehaviour);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, string, bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(pattern, nameof(pattern));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, pattern, ignoreCase));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, string[], MatchBehaviour)"/>
|
||||
public IRequestBuilder WithCookie(string name, string[] patterns, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
return WithCookie(name, patterns, true, matchBehaviour);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, string[], bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithCookie(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(patterns, nameof(patterns));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, ignoreCase, patterns));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithCookie(string name, params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, name, false, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, bool, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithCookie(string name, bool ignoreCase, params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, name, ignoreCase, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithCookie(string name, bool ignoreCase, MatchBehaviour matchBehaviour, params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, ignoreCase, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(Func{IDictionary{string, string}, bool}[])"/>
|
||||
public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
|
||||
{
|
||||
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/WireMock.Net/RequestBuilders/Request.WithHeaders.cs
Normal file
82
src/WireMock.Net/RequestBuilders/Request.WithHeaders.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
return WithHeader(name, pattern, true, matchBehaviour);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string, bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(pattern, nameof(pattern));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, pattern, ignoreCase));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string[], MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
return WithHeader(name, patterns, true, matchBehaviour);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string[], bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(patterns, nameof(patterns));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, ignoreCase, patterns));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, name, false, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, bool, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithHeader(string name, bool ignoreCase, params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, name, ignoreCase, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithHeader(string name, bool ignoreCase, MatchBehaviour matchBehaviour, params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, ignoreCase, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(Func{IDictionary{string, string[]}, bool}[])"/>
|
||||
public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)
|
||||
{
|
||||
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,162 +151,5 @@ namespace WireMock.RequestBuilders
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "DELETE"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "GET"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "HEAD"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "POST"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "PATCH"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "PUT"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
|
||||
public IRequestBuilder UsingAnyMethod()
|
||||
{
|
||||
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
|
||||
foreach (var matcher in matchers)
|
||||
{
|
||||
_requestMatchers.Remove(matcher);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
|
||||
public IRequestBuilder UsingAnyVerb()
|
||||
{
|
||||
return UsingAnyMethod();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
|
||||
public IRequestBuilder UsingMethod(params string[] methods)
|
||||
{
|
||||
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
|
||||
public IRequestBuilder UsingVerb(params string[] verbs)
|
||||
{
|
||||
return UsingMethod(verbs);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
|
||||
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
|
||||
{
|
||||
Check.NotNullOrEmpty(methods, nameof(methods));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
return WithHeader(name, pattern, true, matchBehaviour);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string, bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(pattern, nameof(pattern));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, pattern, ignoreCase));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string[], MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
return WithHeader(name, patterns, true, matchBehaviour);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string[], bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(patterns, nameof(patterns));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, patterns, ignoreCase));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(Func{IDictionary{string, string[]}, bool}[])"/>
|
||||
public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)
|
||||
{
|
||||
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(string, string, bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, pattern, ignoreCase));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(string, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithCookie(string name, params IStringMatcher[] matchers)
|
||||
{
|
||||
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(name, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(Func{IDictionary{string, string}, bool}[])"/>
|
||||
public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
|
||||
{
|
||||
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Http;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
@@ -341,47 +339,50 @@ namespace WireMock.ResponseBuilders
|
||||
await Task.Delay(Delay.Value);
|
||||
}
|
||||
|
||||
if (Callback != null)
|
||||
{
|
||||
var callbackResponseMessage = Callback(requestMessage);
|
||||
|
||||
if (!WithCallbackUsed)
|
||||
{
|
||||
// Copy StatusCode from ResponseMessage
|
||||
callbackResponseMessage.StatusCode = ResponseMessage.StatusCode;
|
||||
|
||||
// Copy Headers from ResponseMessage (if defined)
|
||||
if (ResponseMessage.Headers != null)
|
||||
{
|
||||
callbackResponseMessage.Headers = ResponseMessage.Headers;
|
||||
}
|
||||
}
|
||||
|
||||
return callbackResponseMessage;
|
||||
}
|
||||
|
||||
if (ProxyUrl != null && _httpClientForProxy != null)
|
||||
{
|
||||
var requestUri = new Uri(requestMessage.Url);
|
||||
var proxyUri = new Uri(ProxyUrl);
|
||||
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
|
||||
|
||||
return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
|
||||
return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri, !settings.DisableJsonBodyParsing.GetValueOrDefault(false));
|
||||
}
|
||||
|
||||
ResponseMessage responseMessage;
|
||||
if (Callback == null)
|
||||
{
|
||||
responseMessage = ResponseMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseMessage = Callback(requestMessage);
|
||||
|
||||
if (!WithCallbackUsed)
|
||||
{
|
||||
// Copy StatusCode from ResponseMessage
|
||||
responseMessage.StatusCode = ResponseMessage.StatusCode;
|
||||
|
||||
// Copy Headers from ResponseMessage (if defined)
|
||||
if (ResponseMessage.Headers != null)
|
||||
{
|
||||
responseMessage.Headers = ResponseMessage.Headers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (UseTransformer)
|
||||
{
|
||||
var factory = new HandlebarsContextFactory(settings.FileSystemHandler, settings.HandlebarsRegistrationCallback);
|
||||
var responseMessageTransformer = new ResponseMessageTransformer(factory);
|
||||
return responseMessageTransformer.Transform(requestMessage, ResponseMessage, UseTransformerForBodyAsFile);
|
||||
return responseMessageTransformer.Transform(requestMessage, responseMessage, UseTransformerForBodyAsFile);
|
||||
}
|
||||
|
||||
if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true)
|
||||
{
|
||||
ResponseMessage.BodyData.BodyAsBytes = settings.FileSystemHandler.ReadResponseBodyAsFile(ResponseMessage.BodyData.BodyAsFile);
|
||||
ResponseMessage.BodyData.BodyAsBytes = settings.FileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile);
|
||||
}
|
||||
|
||||
return ResponseMessage;
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,9 @@ namespace WireMock.Serialization
|
||||
var request = (Request)mapping.RequestMatcher;
|
||||
var response = (Response)mapping.Provider;
|
||||
|
||||
var clientIPMatchers = request.GetRequestMessageMatchers<RequestMessageClientIPMatcher>();
|
||||
var pathMatchers = request.GetRequestMessageMatchers<RequestMessagePathMatcher>();
|
||||
var urlMatchers = request.GetRequestMessageMatchers<RequestMessageUrlMatcher>();
|
||||
var clientIPMatchers = request.GetRequestMessageMatchers<RequestMessageClientIPMatcher>().Where(m => m.Matchers != null).SelectMany(m => m.Matchers).ToList();
|
||||
var pathMatchers = request.GetRequestMessageMatchers<RequestMessagePathMatcher>().Where(m => m.Matchers != null).SelectMany(m => m.Matchers).ToList();
|
||||
var urlMatchers = request.GetRequestMessageMatchers<RequestMessageUrlMatcher>().Where(m => m.Matchers != null).SelectMany(m => m.Matchers).ToList();
|
||||
var headerMatchers = request.GetRequestMessageMatchers<RequestMessageHeaderMatcher>();
|
||||
var cookieMatchers = request.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
|
||||
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
|
||||
@@ -45,36 +45,36 @@ namespace WireMock.Serialization
|
||||
SetStateTo = mapping.NextState,
|
||||
Request = new RequestModel
|
||||
{
|
||||
ClientIP = clientIPMatchers != null && clientIPMatchers.Any() ? new ClientIPModel
|
||||
ClientIP = clientIPMatchers.Any() ? new ClientIPModel
|
||||
{
|
||||
Matchers = _mapper.Map(clientIPMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers))
|
||||
Matchers = _mapper.Map(clientIPMatchers)
|
||||
} : null,
|
||||
|
||||
Path = pathMatchers != null && pathMatchers.Any() ? new PathModel
|
||||
Path = pathMatchers.Any() ? new PathModel
|
||||
{
|
||||
Matchers = _mapper.Map(pathMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers))
|
||||
Matchers = _mapper.Map(pathMatchers)
|
||||
} : null,
|
||||
|
||||
Url = urlMatchers != null && urlMatchers.Any() ? new UrlModel
|
||||
Url = urlMatchers.Any() ? new UrlModel
|
||||
{
|
||||
Matchers = _mapper.Map(urlMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers))
|
||||
Matchers = _mapper.Map(urlMatchers)
|
||||
} : null,
|
||||
|
||||
Methods = methodMatcher?.Methods,
|
||||
|
||||
Headers = headerMatchers != null && headerMatchers.Any() ? headerMatchers.Select(hm => new HeaderModel
|
||||
Headers = headerMatchers.Any() ? headerMatchers.Select(hm => new HeaderModel
|
||||
{
|
||||
Name = hm.Name,
|
||||
Matchers = _mapper.Map(hm.Matchers)
|
||||
}).ToList() : null,
|
||||
|
||||
Cookies = cookieMatchers != null && cookieMatchers.Any() ? cookieMatchers.Select(cm => new CookieModel
|
||||
Cookies = cookieMatchers.Any() ? cookieMatchers.Select(cm => new CookieModel
|
||||
{
|
||||
Name = cm.Name,
|
||||
Matchers = _mapper.Map(cm.Matchers)
|
||||
}).ToList() : null,
|
||||
|
||||
Params = paramsMatchers != null && paramsMatchers.Any() ? paramsMatchers.Select(pm => new ParamModel
|
||||
Params = paramsMatchers.Any() ? paramsMatchers.Select(pm => new ParamModel
|
||||
{
|
||||
Name = pm.Key,
|
||||
IgnoreCase = pm.IgnoreCase == true ? true : (bool?)null,
|
||||
@@ -124,11 +124,17 @@ namespace WireMock.Serialization
|
||||
mappingModel.Response.WebProxy = null;
|
||||
mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
|
||||
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
|
||||
mappingModel.Response.Headers = MapHeaders(response.ResponseMessage.Headers);
|
||||
|
||||
if (response.ResponseMessage.Headers != null && response.ResponseMessage.Headers.Count > 0)
|
||||
{
|
||||
mappingModel.Response.Headers = MapHeaders(response.ResponseMessage.Headers);
|
||||
}
|
||||
|
||||
if (response.UseTransformer)
|
||||
{
|
||||
mappingModel.Response.UseTransformer = response.UseTransformer;
|
||||
}
|
||||
|
||||
if (response.UseTransformerForBodyAsFile)
|
||||
{
|
||||
mappingModel.Response.UseTransformerForBodyAsFile = response.UseTransformerForBodyAsFile;
|
||||
@@ -197,12 +203,6 @@ namespace WireMock.Serialization
|
||||
private static IDictionary<string, object> MapHeaders(IDictionary<string, WireMockList<string>> dictionary)
|
||||
{
|
||||
var newDictionary = new Dictionary<string, object>();
|
||||
|
||||
if (dictionary == null || dictionary.Count == 0)
|
||||
{
|
||||
return newDictionary;
|
||||
}
|
||||
|
||||
foreach (var entry in dictionary)
|
||||
{
|
||||
object value = entry.Value.Count == 1 ? (object)entry.Value.ToString() : entry.Value;
|
||||
|
||||
@@ -275,7 +275,7 @@ namespace WireMock.Server
|
||||
var proxyUri = new Uri(settings.ProxyAndRecordSettings.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, !settings.DisableJsonBodyParsing.GetValueOrDefault(false));
|
||||
|
||||
if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
||||
(settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile))
|
||||
@@ -797,7 +797,12 @@ namespace WireMock.Server
|
||||
{
|
||||
foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))
|
||||
{
|
||||
requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
requestBuilder = requestBuilder.WithHeader(
|
||||
headerModel.Name,
|
||||
headerModel.IgnoreCase == true,
|
||||
headerModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
|
||||
headerModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,7 +810,11 @@ namespace WireMock.Server
|
||||
{
|
||||
foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
|
||||
{
|
||||
requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
requestBuilder = requestBuilder.WithCookie(
|
||||
cookieModel.Name,
|
||||
cookieModel.IgnoreCase == true,
|
||||
cookieModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
|
||||
cookieModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,9 +213,10 @@ namespace WireMock.Server
|
||||
}
|
||||
|
||||
_options.FileSystemHandler = _settings.FileSystemHandler;
|
||||
_options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
|
||||
_options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
|
||||
_options.PreWireMockMiddlewareInit = _settings.PreWireMockMiddlewareInit;
|
||||
_options.PostWireMockMiddlewareInit = _settings.PostWireMockMiddlewareInit;
|
||||
_options.Logger = _settings.Logger;
|
||||
_options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing;
|
||||
|
||||
_matcherMapper = new MatcherMapper(_settings);
|
||||
_mappingConverter = new MappingConverter(_matcherMapper);
|
||||
|
||||
@@ -143,5 +143,11 @@ namespace WireMock.Settings
|
||||
/// </summary>
|
||||
/// [PublicAPI]
|
||||
bool? AllowAnyHttpStatusCodeInResponse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set to true to disable Json deserialization when processing requests. (default set to false).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? DisableJsonBodyParsing { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -104,5 +104,9 @@ namespace WireMock.Settings
|
||||
|
||||
/// <inheritdoc cref="IWireMockServerSettings.AllowAnyHttpStatusCodeInResponse"/>
|
||||
public bool? AllowAnyHttpStatusCodeInResponse { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockServerSettings.DisableJsonBodyParsing"/>
|
||||
[PublicAPI]
|
||||
public bool? DisableJsonBodyParsing { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,8 @@ namespace WireMock.Settings
|
||||
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
|
||||
AllowCSharpCodeMatcher = parser.GetBoolValue("AllowCSharpCodeMatcher"),
|
||||
AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods"),
|
||||
AllowAnyHttpStatusCodeInResponse = parser.GetBoolValue("AllowAnyHttpStatusCodeInResponse")
|
||||
AllowAnyHttpStatusCodeInResponse = parser.GetBoolValue("AllowAnyHttpStatusCodeInResponse"),
|
||||
DisableJsonBodyParsing = parser.GetBoolValue("DisableJsonBodyParsing")
|
||||
};
|
||||
|
||||
if (logger != null)
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Http;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Types;
|
||||
using WireMock.Validation;
|
||||
@@ -30,15 +31,15 @@ namespace WireMock.Util
|
||||
*/
|
||||
private static readonly IDictionary<string, bool> BodyAllowedForMethods = new Dictionary<string, bool>
|
||||
{
|
||||
{ "HEAD", false },
|
||||
{ "GET", false },
|
||||
{ "PUT", true },
|
||||
{ "POST", true },
|
||||
{ "DELETE", true },
|
||||
{ "TRACE", false },
|
||||
{ "OPTIONS", true },
|
||||
{ "CONNECT", false },
|
||||
{ "PATCH", true }
|
||||
{ HttpRequestMethods.HEAD, false },
|
||||
{ HttpRequestMethods.GET, false },
|
||||
{ HttpRequestMethods.PUT, true },
|
||||
{ HttpRequestMethods.POST, true },
|
||||
{ HttpRequestMethods.DELETE, true },
|
||||
{ HttpRequestMethods.TRACE, false },
|
||||
{ HttpRequestMethods.OPTIONS, true },
|
||||
{ HttpRequestMethods.CONNECT, false },
|
||||
{ HttpRequestMethods.PATCH, true }
|
||||
};
|
||||
|
||||
private static readonly IStringMatcher[] MultipartContentTypesMatchers = {
|
||||
@@ -107,7 +108,7 @@ namespace WireMock.Util
|
||||
return BodyType.Bytes;
|
||||
}
|
||||
|
||||
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType)
|
||||
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType = null, bool deserializeJson = true)
|
||||
{
|
||||
Check.NotNull(stream, nameof(stream));
|
||||
|
||||
@@ -127,8 +128,6 @@ namespace WireMock.Util
|
||||
data.BodyAsString = encoding.GetString(data.BodyAsBytes);
|
||||
data.Encoding = encoding;
|
||||
data.DetectedBodyType = BodyType.String;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return data;
|
||||
@@ -142,7 +141,7 @@ namespace WireMock.Util
|
||||
data.DetectedBodyType = BodyType.String;
|
||||
|
||||
// If string is not null or empty, try to deserialize the string to a JObject
|
||||
if (!string.IsNullOrEmpty(data.BodyAsString))
|
||||
if (deserializeJson && !string.IsNullOrEmpty(data.BodyAsString))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace WireMock.Util
|
||||
break;
|
||||
|
||||
case JTokenType.Integer:
|
||||
castText = $"int({path})";
|
||||
castText = $"long({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Null:
|
||||
|
||||
@@ -70,12 +70,13 @@ namespace WireMock.Net.Tests.Matchers
|
||||
// Assign
|
||||
var input = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "IntegerId", new JValue(9) },
|
||||
{ "LongId", new JValue(long.MaxValue) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = new LinqMatcher("Id > 1 AND Name == \"Test\"");
|
||||
var matcher = new LinqMatcher("IntegerId > 1 AND LongId > 1 && Name == \"Test\"");
|
||||
double match = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
|
||||
@@ -8,18 +8,54 @@ namespace WireMock.Net.Tests.RequestBuilders
|
||||
{
|
||||
public class RequestBuilderUsingMethodTests
|
||||
{
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingConnect()
|
||||
{
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().UsingConnect();
|
||||
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
Check.That(matchers.Count).IsEqualTo(1);
|
||||
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("CONNECT");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingOptions()
|
||||
{
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().UsingOptions();
|
||||
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
Check.That(matchers.Count).IsEqualTo(1);
|
||||
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("OPTIONS");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingPatch()
|
||||
{
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().UsingPatch();
|
||||
|
||||
// Assert 1
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
Check.That(matchers.Count).IsEqualTo(1);
|
||||
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("PATCH");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingTrace()
|
||||
{
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().UsingTrace();
|
||||
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
Check.That(matchers.Count).IsEqualTo(1);
|
||||
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("TRACE");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingAnyMethod_ClearsAllOtherMatches()
|
||||
{
|
||||
|
||||
@@ -243,9 +243,9 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
// assign
|
||||
BodyData bodyData;
|
||||
if (body is byte[] b)
|
||||
bodyData = await BodyParser.Parse(new MemoryStream(b), null);
|
||||
bodyData = await BodyParser.Parse(new MemoryStream(b), null, true);
|
||||
else if (body is string s)
|
||||
bodyData = await BodyParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(s)), null);
|
||||
bodyData = await BodyParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(s)), null, true);
|
||||
else
|
||||
throw new Exception();
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "c", "x");
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "c", false, "x");
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -29,38 +29,7 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "c", "x");
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
// Assert
|
||||
Check.That(score).IsEqualTo(1.0d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestMessageCookieMatcher_GetMatchingScore_AcceptOnMatch_CookieDoesNotMatchPattern()
|
||||
{
|
||||
// Assign
|
||||
var cookies = new Dictionary<string, string> { { "c", "x" } };
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "no-match", "123");
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
// Assert
|
||||
Check.That(score).IsEqualTo(0.0d);
|
||||
}
|
||||
[Fact]
|
||||
public void RequestMessageCookieMatcher_GetMatchingScore_RejectOnMatch_CookieDoesNotMatchPattern()
|
||||
{
|
||||
// Assign
|
||||
var cookies = new Dictionary<string, string> { { "h", "x" } };
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "no-match", "123");
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "c", false, "x");
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -76,7 +45,7 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
// Assign
|
||||
var cookies = new Dictionary<string, string> { { "h", "x" } };
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "h", "x");
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "h", false, "x");
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -92,7 +61,7 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
// Assign
|
||||
var cookies = new Dictionary<string, string> { { "h", "x" } };
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "h", "x");
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "h", false, "x");
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -108,7 +77,23 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
// Assign
|
||||
var cookies = new Dictionary<string, string> { { "cook", "x" } };
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
|
||||
var matcher = new RequestMessageCookieMatcher("cook", new ExactMatcher("x"));
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "cook", false, new ExactMatcher("x"));
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
// Assert
|
||||
Check.That(score).IsEqualTo(1.0d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestMessageCookieMatcher_WithMissingCookie_When_RejectOnMatch_Is_True_Should_Match()
|
||||
{
|
||||
// Assign
|
||||
var cookies = new Dictionary<string, string> { { "cook", "x" } };
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
|
||||
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "uhuh", false, new ExactMatcher("x"));
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
// Assign
|
||||
var headers = new Dictionary<string, string[]> { { "h", new[] { "x" } } };
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, headers);
|
||||
var matcher = new RequestMessageHeaderMatcher("h", new ExactMatcher("x"));
|
||||
var matcher = new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, "h", false, new ExactMatcher("x"));
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using NFluent;
|
||||
using FluentAssertions;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
@@ -17,15 +17,49 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
public async Task Response_WithCallback()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var response = Response.Create().WithCallback(req => new ResponseMessage { BodyData = new BodyData { DetectedBodyType = BodyType.String, BodyAsString = req.Path + "Bar" }, StatusCode = 302 });
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var response = Response.Create()
|
||||
.WithCallback(request => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = request.Path + "Bar"
|
||||
},
|
||||
StatusCode = 302
|
||||
});
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var responseMessage = await response.ProvideResponseAsync(requestMessage, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo("/fooBar");
|
||||
Check.That(responseMessage.StatusCode).IsEqualTo(302);
|
||||
responseMessage.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
responseMessage.StatusCode.Should().Be(302);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_WithCallback_And_UseTransformer_Is_True()
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var response = Response.Create()
|
||||
.WithCallback(request => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = "{{request.Path}}Bar"
|
||||
},
|
||||
StatusCode = 302
|
||||
})
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(requestMessage, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
responseMessage.StatusCode.Should().Be(302);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Serialization;
|
||||
@@ -36,6 +35,7 @@ namespace WireMock.Net.Tests.Serialization
|
||||
model.Priority.Should().BeNull();
|
||||
model.Response.BodyAsJsonIndented.Should().BeNull();
|
||||
model.Response.UseTransformer.Should().BeNull();
|
||||
model.Response.Headers.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace WireMock.Net.Tests.Util
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson));
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
var body = await BodyParser.Parse(memoryStream, contentType, true);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
@@ -41,7 +41,7 @@ namespace WireMock.Net.Tests.Util
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
var body = await BodyParser.Parse(memoryStream, contentType, true);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
@@ -61,7 +61,23 @@ namespace WireMock.Net.Tests.Util
|
||||
var memoryStream = new MemoryStream(content);
|
||||
|
||||
// act
|
||||
var body = await BodyParser.Parse(memoryStream, null);
|
||||
var body = await BodyParser.Parse(memoryStream, null, true);
|
||||
|
||||
// assert
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] { 34, 97, 34 }, BodyType.String)]
|
||||
[InlineData(new byte[] { 97 }, BodyType.String)]
|
||||
[InlineData(new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 }, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_DetectedBodyTypeNoJsonParsing(byte[] content, BodyType detectedBodyType)
|
||||
{
|
||||
// arrange
|
||||
var memoryStream = new MemoryStream(content);
|
||||
|
||||
// act
|
||||
var body = await BodyParser.Parse(memoryStream, null, false);
|
||||
|
||||
// assert
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
@@ -95,7 +111,7 @@ Content-Type: text/html
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(memoryStream, contentType);
|
||||
var result = await BodyParser.Parse(memoryStream, contentType, true);
|
||||
|
||||
// Assert
|
||||
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.String);
|
||||
@@ -115,7 +131,7 @@ Content-Type: text/html
|
||||
var memoryStream = new MemoryStream(Encoding.UTF32.GetBytes(body));
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(memoryStream, contentType);
|
||||
var result = await BodyParser.Parse(memoryStream, contentType, true);
|
||||
|
||||
// Assert
|
||||
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.Bytes);
|
||||
@@ -133,7 +149,7 @@ Content-Type: text/html
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
var body = await BodyParser.Parse(memoryStream, contentType, true);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace WireMock.Net.Tests.Util
|
||||
{"Flt", new JValue(10.0f)},
|
||||
{"Dbl", new JValue(Math.PI)},
|
||||
{"Check", new JValue(true)},
|
||||
{"Items", new JArray(new[] {new JValue(4), new JValue(8)})},
|
||||
{"Items", new JArray(new[] { new JValue(4), new JValue(8) })},
|
||||
{
|
||||
"Child", new JObject
|
||||
{
|
||||
@@ -61,7 +61,8 @@ namespace WireMock.Net.Tests.Util
|
||||
{"TS", new JValue(TimeSpan.FromMilliseconds(999))}
|
||||
}
|
||||
},
|
||||
{"Id", new JValue(9)},
|
||||
{"I", new JValue(9)},
|
||||
{"L", new JValue(long.MaxValue)},
|
||||
{"Name", new JValue("Test")}
|
||||
};
|
||||
|
||||
@@ -70,10 +71,10 @@ namespace WireMock.Net.Tests.Util
|
||||
|
||||
// Assert
|
||||
var queryable = new[] { j }.AsQueryable().Select(line);
|
||||
bool result = queryable.Any("Id > 4");
|
||||
bool result = queryable.Any("I > 1 && L > 1");
|
||||
Check.That(result).IsTrue();
|
||||
|
||||
Check.That(line).IsEqualTo("new (Uri(U) as U, null as N, Guid(G) as G, double(Flt) as Flt, double(Dbl) as Dbl, bool(Check) as Check, (new [] { int(Items[0]), int(Items[1])}) as Items, new (int(Child.ChildId) as ChildId, DateTime(Child.ChildDateTime) as ChildDateTime, TimeSpan(Child.TS) as TS) as Child, int(Id) as Id, string(Name) as Name)");
|
||||
Check.That(line).IsEqualTo("new (Uri(U) as U, null as N, Guid(G) as G, double(Flt) as Flt, double(Dbl) as Dbl, bool(Check) as Check, (new [] { long(Items[0]), long(Items[1])}) as Items, new (long(Child.ChildId) as ChildId, DateTime(Child.ChildDateTime) as ChildDateTime, TimeSpan(Child.TS) as TS) as Child, long(I) as I, long(L) as L, string(Name) as Name)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -82,7 +83,7 @@ namespace WireMock.Net.Tests.Util
|
||||
// Assign
|
||||
var j = new JObject
|
||||
{
|
||||
{"B", new JValue(new byte[] {48, 49})}
|
||||
{ "B", new JValue(new byte[] {48, 49}) }
|
||||
};
|
||||
|
||||
// Act and Assert
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="responsebody.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="__admin\mappings\00000002-ee28-4f29-ae63-1ac9b0802d86.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
|
||||
Reference in New Issue
Block a user