mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-14 06:13:35 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3c2af0c22 | ||
|
|
2dd30b4f14 | ||
|
|
45d8c0cc27 | ||
|
|
178f2cf02f | ||
|
|
1b326a54d6 | ||
|
|
8bafd6a1ba | ||
|
|
a47750c058 | ||
|
|
5bb10c3350 | ||
|
|
3a221f51b1 | ||
|
|
0ff23a3d15 | ||
|
|
9b323ab388 | ||
|
|
9b3c750754 |
32
CHANGELOG.md
32
CHANGELOG.md
@@ -1,7 +1,23 @@
|
||||
# 1.0.40.0 (09 December 2019)
|
||||
- [#389](https://github.com/WireMock-Net/WireMock.Net/pull/389) - Fix QueryStringParser [bug] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
# 1.0.39.0 (07 December 2019)
|
||||
- [#370](https://github.com/WireMock-Net/WireMock.Net/pull/370) - Add WebProxySettings (use when proxying requests) [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#388](https://github.com/WireMock-Net/WireMock.Net/pull/388) - Transform body as file [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#369](https://github.com/WireMock-Net/WireMock.Net/issues/369) - Question: Is there a way to provide a corporate proxy configuration? [feature]
|
||||
- [#375](https://github.com/WireMock-Net/WireMock.Net/issues/375) - Proxying does not follow redirects : make this configurable [feature]
|
||||
- [#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)
|
||||
- [#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]
|
||||
|
||||
# 1.0.37.0 (08 November 2019)
|
||||
- [#373](https://github.com/WireMock-Net/WireMock.Net/pull/373) - Make Sonar and WhiteSource optional in the Azure pipelines build [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#374](https://github.com/WireMock-Net/WireMock.Net/pull/374) - WatchStaticMappingsInSubdirectories [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#372](https://github.com/WireMock-Net/WireMock.Net/issues/372) - Reset in WireMock admin API not working fine. [feature, question]
|
||||
- [#372](https://github.com/WireMock-Net/WireMock.Net/issues/372) - Reset in WireMock admin API not working fine. [feature]
|
||||
|
||||
# 1.0.36.0 (26 October 2019)
|
||||
- [#360](https://github.com/WireMock-Net/WireMock.Net/pull/360) - Add support for Faults [feature] contributed by [StefH](https://github.com/StefH)
|
||||
@@ -15,7 +31,7 @@
|
||||
- [#354](https://github.com/WireMock-Net/WireMock.Net/pull/354) - AllowBodyForAllHttpMethods [bug, feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#365](https://github.com/WireMock-Net/WireMock.Net/pull/365) - Bump Microsoft.AspNetCore.All from 2.0.8 to 2.0.9 in /examples/WireMock.Net.WebApplication [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#366](https://github.com/WireMock-Net/WireMock.Net/pull/366) - Update ObsoleteAnnotations [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#352](https://github.com/WireMock-Net/WireMock.Net/issues/352) - DELETE request drops the body [feature, question]
|
||||
- [#352](https://github.com/WireMock-Net/WireMock.Net/issues/352) - DELETE request drops the body [feature]
|
||||
|
||||
# 1.0.33.0 (12 October 2019)
|
||||
- [#311](https://github.com/WireMock-Net/WireMock.Net/pull/311) - fix jsonpath matcher [bug] contributed by [StefH](https://github.com/StefH)
|
||||
@@ -28,7 +44,7 @@
|
||||
- [#307](https://github.com/WireMock-Net/WireMock.Net/issues/307) - JsonPathMatcher always convert to JArray before matching [bug]
|
||||
- [#329](https://github.com/WireMock-Net/WireMock.Net/issues/329) - Feature: Add support for CSharpCodeMatcher [feature]
|
||||
- [#350](https://github.com/WireMock-Net/WireMock.Net/issues/350) - Admin requests fail when content type includes a charset [bug]
|
||||
- [#356](https://github.com/WireMock-Net/WireMock.Net/issues/356) - JsonMatcher not working when JSON contains a DateTimeOffset
|
||||
- [#356](https://github.com/WireMock-Net/WireMock.Net/issues/356) - JsonMatcher not working when JSON contains a DateTimeOffset [bug]
|
||||
|
||||
# 1.0.32.0 (20 September 2019)
|
||||
- [#348](https://github.com/WireMock-Net/WireMock.Net/pull/348) - When posting new mapping, use DateParseHandling.None [bug] contributed by [StefH](https://github.com/StefH)
|
||||
@@ -40,7 +56,6 @@
|
||||
- [#339](https://github.com/WireMock-Net/WireMock.Net/pull/339) - Fix ConcurrentObservableCollection [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#345](https://github.com/WireMock-Net/WireMock.Net/pull/345) - Fix CompareTo in RequestMatchResult [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#346](https://github.com/WireMock-Net/WireMock.Net/pull/346) - Fix recorded requests skipped by request logger contributed by [vitaliydavydiak](https://github.com/vitaliydavydiak)
|
||||
- [#327](https://github.com/WireMock-Net/WireMock.Net/issues/327) - Index must be within the bounds of the List - Bug [bug]
|
||||
- [#337](https://github.com/WireMock-Net/WireMock.Net/issues/337) - Proxy Missing header Content-Type - tried with Recording [bug]
|
||||
- [#344](https://github.com/WireMock-Net/WireMock.Net/issues/344) - Mapping adding order matters for multiple mappings? [bug]
|
||||
|
||||
@@ -60,7 +75,6 @@
|
||||
- [#323](https://github.com/WireMock-Net/WireMock.Net/pull/323) - Refactor MappingConverter & MatcherMapper [refactor] contributed by [StefH](https://github.com/StefH)
|
||||
- [#326](https://github.com/WireMock-Net/WireMock.Net/pull/326) - Fix Parsing Guid in PUT Mapping [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#252](https://github.com/WireMock-Net/WireMock.Net/issues/252) - Proxy with Transform
|
||||
- [#287](https://github.com/WireMock-Net/WireMock.Net/issues/287) - Error with parameter that contains a "=" character [bug, question]
|
||||
- [#308](https://github.com/WireMock-Net/WireMock.Net/issues/308) - __admin/requests - "Collection was modified" exception [bug]
|
||||
- [#313](https://github.com/WireMock-Net/WireMock.Net/issues/313) - RequestLogExpirationDuration - bug [bug]
|
||||
- [#325](https://github.com/WireMock-Net/WireMock.Net/issues/325) - Admin API: PUT Mapping, FormatException because of wrong parsing of the Query [bug]
|
||||
@@ -70,7 +84,6 @@
|
||||
|
||||
# 1.0.24.0 (22 July 2019)
|
||||
- [#302](https://github.com/WireMock-Net/WireMock.Net/pull/302) - Fixed bug 301 by not setting BodyAsFile to null after first use [bug] contributed by [rwwilden](https://github.com/rwwilden)
|
||||
- [#299](https://github.com/WireMock-Net/WireMock.Net/issues/299) - Get Mappings models instead of just IMapping interface [feature, question]
|
||||
- [#301](https://github.com/WireMock-Net/WireMock.Net/issues/301) - Error thrown when calling mocked endpoint second time when using file-based response body [bug]
|
||||
|
||||
# 1.0.23.0 (16 July 2019)
|
||||
@@ -78,15 +91,12 @@
|
||||
|
||||
# 1.0.22.0 (15 July 2019)
|
||||
- [#297](https://github.com/WireMock-Net/WireMock.Net/pull/297) - FixNullRef (#295) contributed by [StefH](https://github.com/StefH)
|
||||
- [#178](https://github.com/WireMock-Net/WireMock.Net/issues/178) - Bug: Path matching fails when the URL contains encoded parts [bug, question]
|
||||
- [#295](https://github.com/WireMock-Net/WireMock.Net/issues/295) - NullRef in 1.0.21 [bug]
|
||||
|
||||
# 1.0.21.0 (03 July 2019)
|
||||
- [#286](https://github.com/WireMock-Net/WireMock.Net/pull/286) - Handlebars Extension [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#293](https://github.com/WireMock-Net/WireMock.Net/pull/293) - workaround for AppContext.BaseDirectory being null on some platforms contributed by [eli-darkly](https://github.com/eli-darkly)
|
||||
- [#294](https://github.com/WireMock-Net/WireMock.Net/pull/294) - don't strip request body if we don't recognize the request method contributed by [eli-darkly](https://github.com/eli-darkly)
|
||||
- [#285](https://github.com/WireMock-Net/WireMock.Net/issues/285) - Need ability to add custom ResponseMessageTransformers [feature, question]
|
||||
- [#288](https://github.com/WireMock-Net/WireMock.Net/issues/288) - Allow setting root folder in LocalFileSystemHandler [feature, question]
|
||||
- [#289](https://github.com/WireMock-Net/WireMock.Net/issues/289) - Bug: When WatchStaticMappings=true throws exceptions on updating the mapping files [bug]
|
||||
- [#290](https://github.com/WireMock-Net/WireMock.Net/issues/290) - Request body is dropped if verb is REPORT [bug]
|
||||
- [#292](https://github.com/WireMock-Net/WireMock.Net/issues/292) - Can't start server in Xamarin Android [bug]
|
||||
@@ -112,7 +122,6 @@
|
||||
- [#271](https://github.com/WireMock-Net/WireMock.Net/pull/271) - Support Dynamic response files using Handlebars templating [bug, feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#272](https://github.com/WireMock-Net/WireMock.Net/pull/272) - Add unit test for JsonPath and BodyAsFile mapping contributed by [denstorti](https://github.com/denstorti)
|
||||
- [#273](https://github.com/WireMock-Net/WireMock.Net/pull/273) - Dynamic response handlebars templating (2) [bug, feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#270](https://github.com/WireMock-Net/WireMock.Net/issues/270) - Dynamic response files using Handlebars templating [bug, question]
|
||||
|
||||
# 1.0.14.0 (20 April 2019)
|
||||
- [#269](https://github.com/WireMock-Net/WireMock.Net/pull/269) - Add JmesPath matcher [feature] contributed by [StefH](https://github.com/StefH)
|
||||
@@ -143,6 +152,7 @@
|
||||
# 1.0.7.0 (19 January 2019)
|
||||
- [#244](https://github.com/WireMock-Net/WireMock.Net/pull/244) - Fix BodyAsFile to also allow relative paths [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#240](https://github.com/WireMock-Net/WireMock.Net/issues/240) - How to submit mappings for multiple request, responses [feature]
|
||||
- [#243](https://github.com/WireMock-Net/WireMock.Net/issues/243) - Not able to read response from file [bug]
|
||||
|
||||
# 1.0.6.1 (10 January 2019)
|
||||
- [#247](https://github.com/WireMock-Net/WireMock.Net/pull/247) - Issue 225 improve logging in example for wire mock as windows service contributed by [paulssn](https://github.com/paulssn)
|
||||
@@ -301,9 +311,7 @@
|
||||
- [#134](https://github.com/WireMock-Net/WireMock.Net/pull/134) - Stef negate matcher contributed by [alastairtree](https://github.com/alastairtree)
|
||||
- [#135](https://github.com/WireMock-Net/WireMock.Net/pull/135) - Merge into the stef_negate_matcher branch (solves issue #133) contributed by [StefH](https://github.com/StefH)
|
||||
- [#138](https://github.com/WireMock-Net/WireMock.Net/pull/138) - Added Negate matcher logic contributed by [StefH](https://github.com/StefH)
|
||||
- [#128](https://github.com/WireMock-Net/WireMock.Net/issues/128) - Feature: Negate a matcher [feature, question]
|
||||
- [#130](https://github.com/WireMock-Net/WireMock.Net/issues/130) - ...
|
||||
- [#133](https://github.com/WireMock-Net/WireMock.Net/issues/133) - Issue: Wildcard matching a json body does not work? [bug, question]
|
||||
|
||||
# 1.0.3.16 (17 April 2018)
|
||||
- [#121](https://github.com/WireMock-Net/WireMock.Net/pull/121) - Fix for issue #118 [bug] contributed by [raghavendrabankapur](https://github.com/raghavendrabankapur)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.0.37</VersionPrefix>
|
||||
<VersionPrefix>1.0.40</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.0.37.0
|
||||
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.0.40.0
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2036
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29512.175
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EF242EDF-7133-4277-9A0C-18744DE08707}"
|
||||
EndProject
|
||||
@@ -61,6 +61,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Net452
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NETCoreApp2", "examples\WireMock.Net.Console.NETCoreApp2\WireMock.Net.Console.NETCoreApp2.csproj", "{83645809-9E01-4E81-8733-BA9497554ABF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.RequestLogTest", "examples\WireMock.Net.Console.RequestLogTest\WireMock.Net.Console.RequestLogTest.csproj", "{A9D039B9-7509-4CF1-9EFD-87EB82998575}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -131,6 +133,10 @@ Global
|
||||
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83645809-9E01-4E81-8733-BA9497554ABF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{83645809-9E01-4E81-8733-BA9497554ABF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -152,6 +158,7 @@ Global
|
||||
{1261BB9B-A7D4-456C-8985-3CE560361B8E} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
{668F689E-57B4-422E-8846-C0FF643CA268} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
{83645809-9E01-4E81-8733-BA9497554ABF} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {BF428BCC-C837-433B-87D2-15C7014B73E9}
|
||||
|
||||
@@ -43,4 +43,4 @@ steps:
|
||||
inputs:
|
||||
command: custom
|
||||
custom: nuget
|
||||
arguments: push $(Build.ArtifactStagingDirectory)\packages\*.nupkg --source https://api.nuget.org/v3/index.json --no-service-endpoint --api-key $(NuGetKey)
|
||||
arguments: push $(Build.ArtifactStagingDirectory)\packages\*.nupkg -n true -s https://api.nuget.org/v3/index.json -k $(NuGetKey)
|
||||
@@ -79,6 +79,7 @@ steps:
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
|
||||
# https://github.com/NuGet/Home/issues/8148
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Push to MyGet
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
|
||||
@@ -1 +1 @@
|
||||
C# Hello
|
||||
// C# Hello
|
||||
@@ -105,6 +105,24 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.WithProxy(new ProxyAndRecordSettings { Url = "http://postman-echo.com/get" })
|
||||
);
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingGet()
|
||||
.WithHeader("postmanecho", "get2")
|
||||
)
|
||||
.RespondWith(Response.Create()
|
||||
.WithProxy(new ProxyAndRecordSettings
|
||||
{
|
||||
Url = "http://postman-echo.com/get",
|
||||
WebProxySettings = new WebProxySettings
|
||||
{
|
||||
Address = "http://company",
|
||||
UserName = "test",
|
||||
Password = "pwd"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingGet()
|
||||
|
||||
63
examples/WireMock.Net.Console.RequestLogTest/Program.cs
Normal file
63
examples/WireMock.Net.Console.RequestLogTest/Program.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Net.StandAlone;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Net.Console.RequestLogTest
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
var server = StandAloneApp.Start(new FluentMockServerSettings
|
||||
{
|
||||
Port = 19019,
|
||||
StartAdminInterface = true,
|
||||
StartTimeout = 1000,
|
||||
MaxRequestLogCount = 100,
|
||||
RequestLogExpirationDuration = 6,
|
||||
Logger = new WireMockConsoleLogger()
|
||||
});
|
||||
|
||||
server
|
||||
.Given(Request
|
||||
.Create()
|
||||
.UsingGet())
|
||||
.RespondWith(Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { result = "x" }));
|
||||
|
||||
await Task.Delay(2000);
|
||||
|
||||
var client = new HttpClient();
|
||||
client.BaseAddress = new Uri(server.Urls[0]);
|
||||
|
||||
var options = new ParallelOptions()
|
||||
{
|
||||
MaxDegreeOfParallelism = 2
|
||||
};
|
||||
|
||||
var list = Enumerable.Range(1, 1000);
|
||||
Parallel.ForEach(list, options, async i =>
|
||||
{
|
||||
string result = await client.GetStringAsync("/x");
|
||||
System.Console.WriteLine(result);
|
||||
});
|
||||
|
||||
//for (int i = 0; i < 1000; i++)
|
||||
//{
|
||||
// string result = await client.GetStringAsync("/x");
|
||||
// System.Console.WriteLine(result);
|
||||
//}
|
||||
|
||||
System.Console.WriteLine("Press any key to stop the server");
|
||||
System.Console.ReadKey();
|
||||
server.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj" />
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
@@ -87,8 +86,20 @@ namespace WireMock.Net.StandAlone
|
||||
SaveMappingForStatusCodePattern = parser.GetStringValue("SaveMappingForStatusCodePattern"),
|
||||
ClientX509Certificate2ThumbprintOrSubjectName = parser.GetStringValue("ClientX509Certificate2ThumbprintOrSubjectName"),
|
||||
BlackListedHeaders = parser.GetValues("BlackListedHeaders"),
|
||||
BlackListedCookies = parser.GetValues("BlackListedCookies")
|
||||
BlackListedCookies = parser.GetValues("BlackListedCookies"),
|
||||
AllowAutoRedirect = parser.GetBoolValue("AllowAutoRedirect")
|
||||
};
|
||||
|
||||
string proxyAddress = parser.GetStringValue("WebProxyAddress");
|
||||
if (!string.IsNullOrEmpty(proxyAddress))
|
||||
{
|
||||
settings.ProxyAndRecordSettings.WebProxySettings = new WebProxySettings
|
||||
{
|
||||
Address = proxyAddress,
|
||||
UserName = parser.GetStringValue("WebProxyUserName"),
|
||||
Password = parser.GetStringValue("WebProxyPassword")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
|
||||
|
||||
@@ -62,6 +62,11 @@ namespace WireMock.Admin.Mappings
|
||||
/// </summary>
|
||||
public bool? UseTransformer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use the Handlerbars transformer for the content from the referenced BodyAsFile.
|
||||
/// </summary>
|
||||
public bool? UseTransformerForBodyAsFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the headers.
|
||||
/// </summary>
|
||||
@@ -91,5 +96,10 @@ namespace WireMock.Admin.Mappings
|
||||
/// Gets or sets the fault.
|
||||
/// </summary>
|
||||
public FaultModel Fault { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the WebProxy settings.
|
||||
/// </summary>
|
||||
public WebProxyModel WebProxy { get; set; }
|
||||
}
|
||||
}
|
||||
23
src/WireMock.Net/Admin/Mappings/WebProxyModel.cs
Normal file
23
src/WireMock.Net/Admin/Mappings/WebProxyModel.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace WireMock.Admin.Mappings
|
||||
{
|
||||
/// <summary>
|
||||
/// WebProxy settings
|
||||
/// </summary>
|
||||
public class WebProxyModel
|
||||
{
|
||||
/// <summary>
|
||||
/// A string instance that contains the address of the proxy server.
|
||||
/// </summary>
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user name associated with the credentials.
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The password for the user name associated with the credentials.
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Admin.Requests
|
||||
|
||||
28
src/WireMock.Net/Compatibility/WebProxy.cs
Normal file
28
src/WireMock.Net/Compatibility/WebProxy.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
#if NETSTANDARD1_3
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
internal class WebProxy : IWebProxy
|
||||
{
|
||||
private readonly string _proxy;
|
||||
public ICredentials Credentials { get; set; }
|
||||
|
||||
public WebProxy(string proxy)
|
||||
{
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
public Uri GetProxy(Uri destination)
|
||||
{
|
||||
return new Uri(_proxy);
|
||||
}
|
||||
|
||||
public bool IsBypassed(Uri host)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.HttpsCertificate;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Http
|
||||
{
|
||||
internal static class HttpClientHelper
|
||||
{
|
||||
public static HttpClient CreateHttpClient(string clientX509Certificate2ThumbprintOrSubjectName = null)
|
||||
public static HttpClient CreateHttpClient(IProxyAndRecordSettings settings)
|
||||
{
|
||||
#if NETSTANDARD
|
||||
var handler = new HttpClientHandler
|
||||
@@ -36,20 +37,30 @@ namespace WireMock.Http
|
||||
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
|
||||
#endif
|
||||
|
||||
if (!string.IsNullOrEmpty(clientX509Certificate2ThumbprintOrSubjectName))
|
||||
if (!string.IsNullOrEmpty(settings.ClientX509Certificate2ThumbprintOrSubjectName))
|
||||
{
|
||||
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
|
||||
|
||||
var x509Certificate2 = ClientCertificateHelper.GetCertificate(clientX509Certificate2ThumbprintOrSubjectName);
|
||||
var x509Certificate2 = ClientCertificateHelper.GetCertificate(settings.ClientX509Certificate2ThumbprintOrSubjectName);
|
||||
handler.ClientCertificates.Add(x509Certificate2);
|
||||
}
|
||||
|
||||
// For proxy we shouldn't follow auto redirects
|
||||
handler.AllowAutoRedirect = false;
|
||||
handler.AllowAutoRedirect = settings.AllowAutoRedirect == true;
|
||||
|
||||
// If UseCookies enabled, httpClient ignores Cookie header
|
||||
handler.UseCookies = false;
|
||||
|
||||
if (settings.WebProxySettings != null)
|
||||
{
|
||||
handler.UseProxy = true;
|
||||
|
||||
handler.Proxy = new WebProxy(settings.WebProxySettings.Address);
|
||||
if (settings.WebProxySettings.UserName != null && settings.WebProxySettings.Password != null)
|
||||
{
|
||||
handler.Proxy.Credentials = new NetworkCredential(settings.WebProxySettings.UserName, settings.WebProxySettings.Password);
|
||||
}
|
||||
}
|
||||
|
||||
var client = new HttpClient(handler);
|
||||
#if NET452 || NET46
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
|
||||
|
||||
@@ -3,6 +3,9 @@ using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace WireMock.HttpsCertificate
|
||||
{
|
||||
/// <summary>
|
||||
/// Only used for NetStandard 1.3
|
||||
/// </summary>
|
||||
internal static class PublicCertificateHelper
|
||||
{
|
||||
// 1] Generate using https://www.pluralsight.com/blog/software-development/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace WireMock.Owin
|
||||
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
|
||||
options.Listen(System.Net.IPAddress.Any, port, listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(PublicCertificateHelper.GetX509Certificate2());
|
||||
listenOptions.UseHttps(); // PublicCertificateHelper.GetX509Certificate2()
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace WireMock
|
||||
|
||||
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||
Cookies = cookies;
|
||||
RawQuery = WebUtility.UrlDecode(urlDetails.Url.Query);
|
||||
RawQuery = urlDetails.Url.Query;
|
||||
Query = QueryStringParser.Parse(RawQuery);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace WireMock.ResponseBuilders
|
||||
/// WithBody : Create a fault response.
|
||||
/// </summary>
|
||||
/// <param name="faultType">The FaultType.</param>
|
||||
/// <param name="percentage">The percentage when this fault should occur. When null, it's always.</param>
|
||||
/// <param name="percentage">The percentage when this fault should occur. When null, it's always a fault.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithFault(FaultType faultType, [CanBeNull] double? percentage = null);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
/// <returns>
|
||||
/// The <see cref="IResponseBuilder"/>.
|
||||
/// </returns>
|
||||
IResponseBuilder WithTransformer();
|
||||
IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile = false);
|
||||
}
|
||||
}
|
||||
48
src/WireMock.Net/ResponseBuilders/Response.WithProxy.cs
Normal file
48
src/WireMock.Net/ResponseBuilders/Response.WithProxy.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Net.Http;
|
||||
using WireMock.Http;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.ResponseBuilders
|
||||
{
|
||||
public partial class Response
|
||||
{
|
||||
private HttpClient _httpClientForProxy;
|
||||
|
||||
/// <summary>
|
||||
/// The Proxy URL to use.
|
||||
/// </summary>
|
||||
public string ProxyUrl { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The WebProxy settings.
|
||||
/// </summary>
|
||||
public IWebProxySettings WebProxySettings { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IProxyResponseBuilder.WithProxy(string, string)"/>
|
||||
public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2ThumbprintOrSubjectName = null)
|
||||
{
|
||||
Check.NotNullOrEmpty(proxyUrl, nameof(proxyUrl));
|
||||
|
||||
var settings = new ProxyAndRecordSettings
|
||||
{
|
||||
Url = proxyUrl,
|
||||
ClientX509Certificate2ThumbprintOrSubjectName = clientX509Certificate2ThumbprintOrSubjectName
|
||||
};
|
||||
|
||||
return WithProxy(settings);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IProxyResponseBuilder.WithProxy(IProxyAndRecordSettings)"/>
|
||||
public IResponseBuilder WithProxy(IProxyAndRecordSettings settings)
|
||||
{
|
||||
Check.NotNull(settings, nameof(settings));
|
||||
|
||||
ProxyUrl = settings.Url;
|
||||
WebProxySettings = settings.WebProxySettings;
|
||||
|
||||
_httpClientForProxy = HttpClientHelper.CreateHttpClient(settings);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,6 @@ namespace WireMock.ResponseBuilders
|
||||
/// </summary>
|
||||
public partial class Response : IResponseBuilder
|
||||
{
|
||||
private HttpClient _httpClientForProxy;
|
||||
|
||||
/// <summary>
|
||||
/// The delay
|
||||
/// </summary>
|
||||
@@ -34,14 +32,9 @@ namespace WireMock.ResponseBuilders
|
||||
public bool UseTransformer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Proxy URL to use.
|
||||
/// Gets a value indicating whether to use the Handlerbars transformer for the content from the referenced BodyAsFile.
|
||||
/// </summary>
|
||||
public string ProxyUrl { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The client X509Certificate2 Thumbprint or SubjectName to use.
|
||||
/// </summary>
|
||||
public string ClientX509Certificate2ThumbprintOrSubjectName { get; private set; }
|
||||
public bool UseTransformerForBodyAsFile { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the response message.
|
||||
@@ -311,10 +304,11 @@ namespace WireMock.ResponseBuilders
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer"/>
|
||||
public IResponseBuilder WithTransformer()
|
||||
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(bool)"/>
|
||||
public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile = false)
|
||||
{
|
||||
UseTransformer = true;
|
||||
UseTransformerForBodyAsFile = transformContentFromBodyAsFile;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -333,25 +327,6 @@ namespace WireMock.ResponseBuilders
|
||||
return WithDelay(TimeSpan.FromMilliseconds(milliseconds));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IProxyResponseBuilder.WithProxy(string, string)"/>
|
||||
public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2ThumbprintOrSubjectName = null)
|
||||
{
|
||||
Check.NotNullOrEmpty(proxyUrl, nameof(proxyUrl));
|
||||
|
||||
ProxyUrl = proxyUrl;
|
||||
ClientX509Certificate2ThumbprintOrSubjectName = clientX509Certificate2ThumbprintOrSubjectName;
|
||||
_httpClientForProxy = HttpClientHelper.CreateHttpClient(clientX509Certificate2ThumbprintOrSubjectName);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IProxyResponseBuilder.WithProxy(IProxyAndRecordSettings)"/>
|
||||
public IResponseBuilder WithProxy(IProxyAndRecordSettings settings)
|
||||
{
|
||||
Check.NotNull(settings, nameof(settings));
|
||||
|
||||
return WithProxy(settings.Url, settings.ClientX509Certificate2ThumbprintOrSubjectName);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback"/>
|
||||
public IResponseBuilder WithCallback(Func<RequestMessage, ResponseMessage> callbackHandler)
|
||||
{
|
||||
@@ -414,7 +389,7 @@ namespace WireMock.ResponseBuilders
|
||||
{
|
||||
var factory = new HandlebarsContextFactory(settings.FileSystemHandler, settings.HandlebarsRegistrationCallback);
|
||||
var responseMessageTransformer = new ResponseMessageTransformer(factory);
|
||||
return responseMessageTransformer.Transform(requestMessage, ResponseMessage);
|
||||
return responseMessageTransformer.Transform(requestMessage, ResponseMessage, UseTransformerForBodyAsFile);
|
||||
}
|
||||
|
||||
if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true)
|
||||
|
||||
@@ -4,6 +4,7 @@ using WireMock.Admin.Mappings;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
@@ -112,19 +113,26 @@ namespace WireMock.Serialization
|
||||
mappingModel.Response.BodyAsFile = null;
|
||||
mappingModel.Response.BodyAsFileIsCached = null;
|
||||
mappingModel.Response.UseTransformer = null;
|
||||
mappingModel.Response.UseTransformerForBodyAsFile = null;
|
||||
mappingModel.Response.BodyEncoding = null;
|
||||
mappingModel.Response.ProxyUrl = response.ProxyUrl;
|
||||
mappingModel.Response.Fault = null;
|
||||
mappingModel.Response.WebProxy = MapWebProxy(response.WebProxySettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
mappingModel.Response.WebProxy = null;
|
||||
mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
|
||||
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
|
||||
mappingModel.Response.Headers = Map(response.ResponseMessage.Headers);
|
||||
mappingModel.Response.Headers = MapHeaders(response.ResponseMessage.Headers);
|
||||
if (response.UseTransformer)
|
||||
{
|
||||
mappingModel.Response.UseTransformer = response.UseTransformer;
|
||||
}
|
||||
if (response.UseTransformerForBodyAsFile)
|
||||
{
|
||||
mappingModel.Response.UseTransformerForBodyAsFile = response.UseTransformerForBodyAsFile;
|
||||
}
|
||||
|
||||
if (response.ResponseMessage.BodyData != null)
|
||||
{
|
||||
@@ -176,14 +184,25 @@ namespace WireMock.Serialization
|
||||
return mappingModel;
|
||||
}
|
||||
|
||||
private static IDictionary<string, object> Map(IDictionary<string, WireMockList<string>> dictionary)
|
||||
private static WebProxyModel MapWebProxy(IWebProxySettings settings)
|
||||
{
|
||||
return settings != null ? new WebProxyModel
|
||||
{
|
||||
Address = settings.Address,
|
||||
UserName = settings.UserName,
|
||||
Password = settings.Password
|
||||
} : null;
|
||||
}
|
||||
|
||||
private static IDictionary<string, object> MapHeaders(IDictionary<string, WireMockList<string>> dictionary)
|
||||
{
|
||||
var newDictionary = new Dictionary<string, object>();
|
||||
|
||||
if (dictionary == null || dictionary.Count == 0)
|
||||
{
|
||||
return null;
|
||||
return newDictionary;
|
||||
}
|
||||
|
||||
var newDictionary = new Dictionary<string, object>();
|
||||
foreach (var entry in dictionary)
|
||||
{
|
||||
object value = entry.Value.Count == 1 ? (object)entry.Value.ToString() : entry.Value;
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace WireMock.Server
|
||||
|
||||
private void InitProxyAndRecord(IFluentMockServerSettings settings)
|
||||
{
|
||||
_httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ProxyAndRecordSettings.ClientX509Certificate2ThumbprintOrSubjectName);
|
||||
_httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ProxyAndRecordSettings);
|
||||
|
||||
var respondProvider = Given(Request.Create().WithPath("/*").UsingAnyMethod());
|
||||
if (settings.StartAdminInterface == true)
|
||||
@@ -785,17 +785,24 @@ namespace WireMock.Server
|
||||
|
||||
if (responseModel.UseTransformer == true)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithTransformer();
|
||||
responseBuilder = responseBuilder.WithTransformer(responseModel.UseTransformerForBodyAsFile == true);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(responseModel.ProxyUrl))
|
||||
{
|
||||
if (string.IsNullOrEmpty(responseModel.X509Certificate2ThumbprintOrSubjectName))
|
||||
var proxyAndRecordSettings = new ProxyAndRecordSettings
|
||||
{
|
||||
return responseBuilder.WithProxy(responseModel.ProxyUrl);
|
||||
}
|
||||
Url = responseModel.ProxyUrl,
|
||||
ClientX509Certificate2ThumbprintOrSubjectName = responseModel.X509Certificate2ThumbprintOrSubjectName,
|
||||
WebProxySettings = responseModel.WebProxy != null ? new WebProxySettings
|
||||
{
|
||||
Address = responseModel.WebProxy.Address,
|
||||
UserName = responseModel.WebProxy.UserName,
|
||||
Password = responseModel.WebProxy.Password
|
||||
} : null
|
||||
};
|
||||
|
||||
return responseBuilder.WithProxy(responseModel.ProxyUrl, responseModel.X509Certificate2ThumbprintOrSubjectName);
|
||||
return responseBuilder.WithProxy(proxyAndRecordSettings);
|
||||
}
|
||||
|
||||
if (responseModel.StatusCode.HasValue)
|
||||
|
||||
@@ -61,6 +61,13 @@ namespace WireMock.Server
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider InScenario(string scenario);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the the scenario with an integer value.
|
||||
/// </summary>
|
||||
/// <param name="scenario">The scenario.</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider InScenario(int scenario);
|
||||
|
||||
/// <summary>
|
||||
/// Execute this respond only in case the current state is equal to specified one.
|
||||
/// </summary>
|
||||
@@ -68,11 +75,25 @@ namespace WireMock.Server
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WhenStateIs(string state);
|
||||
|
||||
/// <summary>
|
||||
/// Execute this respond only in case the current state is equal to specified one.
|
||||
/// </summary>
|
||||
/// <param name="state">Any object which identifies the current state</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WhenStateIs(int state);
|
||||
|
||||
/// <summary>
|
||||
/// Once this mapping is executed the state will be changed to specified one.
|
||||
/// </summary>
|
||||
/// <param name="state">Any object which identifies the new state</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WillSetStateTo(string state);
|
||||
|
||||
/// <summary>
|
||||
/// Once this mapping is executed the state will be changed to specified one.
|
||||
/// </summary>
|
||||
/// <param name="state">Any object which identifies the new state</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WillSetStateTo(int state);
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,13 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WhenStateIs"/>
|
||||
/// <see cref="IRespondWithAProvider.InScenario(int)"/>
|
||||
public IRespondWithAProvider InScenario(int scenario)
|
||||
{
|
||||
return InScenario(scenario.ToString());
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WhenStateIs(string)"/>
|
||||
public IRespondWithAProvider WhenStateIs(string state)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_scenario))
|
||||
@@ -106,7 +112,13 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WillSetStateTo"/>
|
||||
/// <see cref="IRespondWithAProvider.WhenStateIs(int)"/>
|
||||
public IRespondWithAProvider WhenStateIs(int state)
|
||||
{
|
||||
return WhenStateIs(state.ToString());
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WillSetStateTo(string)"/>
|
||||
public IRespondWithAProvider WillSetStateTo(string state)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_scenario))
|
||||
@@ -118,5 +130,11 @@ namespace WireMock.Server
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WillSetStateTo(int)"/>
|
||||
public IRespondWithAProvider WillSetStateTo(int state)
|
||||
{
|
||||
return WillSetStateTo(state.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,5 +44,15 @@ namespace WireMock.Settings
|
||||
/// Defines a list of cookies which will excluded from the saved mappings.
|
||||
/// </summary>
|
||||
string[] BlackListedCookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the WebProxySettings.
|
||||
/// </summary>
|
||||
IWebProxySettings WebProxySettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Proxy requests should follow redirection (30x).
|
||||
/// </summary>
|
||||
bool? AllowAutoRedirect { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/WireMock.Net/Settings/IWebProxySettings.cs
Normal file
20
src/WireMock.Net/Settings/IWebProxySettings.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
public interface IWebProxySettings
|
||||
{
|
||||
/// <summary>
|
||||
/// A string instance that contains the address of the proxy server.
|
||||
/// </summary>
|
||||
string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user name associated with the credentials.
|
||||
/// </summary>
|
||||
string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The password for the user name associated with the credentials.
|
||||
/// </summary>
|
||||
string Password { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -34,5 +34,13 @@ namespace WireMock.Settings
|
||||
/// <inheritdoc cref="IProxyAndRecordSettings.BlackListedCookies"/>
|
||||
[PublicAPI]
|
||||
public string[] BlackListedCookies { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IProxyAndRecordSettings.WebProxySettings"/>
|
||||
[PublicAPI]
|
||||
public IWebProxySettings WebProxySettings { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IProxyAndRecordSettings.AllowAutoRedirect"/>
|
||||
[PublicAPI]
|
||||
public bool? AllowAutoRedirect { get; set; }
|
||||
}
|
||||
}
|
||||
19
src/WireMock.Net/Settings/WebProxySettings.cs
Normal file
19
src/WireMock.Net/Settings/WebProxySettings.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
public class WebProxySettings : IWebProxySettings
|
||||
{
|
||||
/// <inheritdoc cref="IWebProxySettings.Address"/>
|
||||
[PublicAPI]
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebProxySettings.UserName"/>
|
||||
[PublicAPI]
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebProxySettings.Password"/>
|
||||
[PublicAPI]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
11
src/WireMock.Net/Transformers/HandlebarsContext.cs
Normal file
11
src/WireMock.Net/Transformers/HandlebarsContext.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using HandlebarsDotNet;
|
||||
using WireMock.Handlers;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal class HandlebarsContext : IHandlebarsContext
|
||||
{
|
||||
public IHandlebars Handlebars { get; set; }
|
||||
public IFileSystemHandler FileSystemHandler { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -20,15 +20,19 @@ namespace WireMock.Transformers
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public IHandlebars Create()
|
||||
public IHandlebarsContext Create()
|
||||
{
|
||||
var handlebarsContext = Handlebars.Create(HandlebarsConfiguration);
|
||||
var handlebars = Handlebars.Create(HandlebarsConfiguration);
|
||||
|
||||
HandlebarsHelpers.Register(handlebarsContext, _fileSystemHandler);
|
||||
HandlebarsHelpers.Register(handlebars, _fileSystemHandler);
|
||||
|
||||
_action?.Invoke(handlebarsContext, _fileSystemHandler);
|
||||
_action?.Invoke(handlebars, _fileSystemHandler);
|
||||
|
||||
return handlebarsContext;
|
||||
return new HandlebarsContext
|
||||
{
|
||||
Handlebars = handlebars,
|
||||
FileSystemHandler = _fileSystemHandler
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
src/WireMock.Net/Transformers/IHandlebarsContext.cs
Normal file
12
src/WireMock.Net/Transformers/IHandlebarsContext.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using HandlebarsDotNet;
|
||||
using WireMock.Handlers;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
interface IHandlebarsContext
|
||||
{
|
||||
IHandlebars Handlebars { get; set; }
|
||||
|
||||
IFileSystemHandler FileSystemHandler { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,6 @@ namespace WireMock.Transformers
|
||||
{
|
||||
interface IHandlebarsContextFactory
|
||||
{
|
||||
IHandlebars Create();
|
||||
IHandlebarsContext Create();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using HandlebarsDotNet;
|
||||
using JetBrains.Annotations;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
@@ -21,7 +20,7 @@ namespace WireMock.Transformers
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original)
|
||||
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
var handlebarsContext = _factory.Create();
|
||||
|
||||
@@ -36,7 +35,7 @@ namespace WireMock.Transformers
|
||||
break;
|
||||
|
||||
case BodyType.File:
|
||||
TransformBodyAsFile(handlebarsContext, template, original, responseMessage);
|
||||
TransformBodyAsFile(handlebarsContext, template, original, responseMessage, useTransformerForBodyAsFile);
|
||||
break;
|
||||
|
||||
case BodyType.String:
|
||||
@@ -52,9 +51,9 @@ namespace WireMock.Transformers
|
||||
var newHeaders = new Dictionary<string, WireMockList<string>>();
|
||||
foreach (var header in original.Headers)
|
||||
{
|
||||
var templateHeaderKey = handlebarsContext.Compile(header.Key);
|
||||
var templateHeaderKey = handlebarsContext.Handlebars.Compile(header.Key);
|
||||
var templateHeaderValues = header.Value
|
||||
.Select(handlebarsContext.Compile)
|
||||
.Select(handlebarsContext.Handlebars.Compile)
|
||||
.Select(func => func(template))
|
||||
.ToArray();
|
||||
|
||||
@@ -66,7 +65,7 @@ namespace WireMock.Transformers
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
private static void TransformBodyAsJson(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
private static void TransformBodyAsJson(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
JToken jToken;
|
||||
switch (original.BodyData.BodyAsJson)
|
||||
@@ -94,7 +93,7 @@ namespace WireMock.Transformers
|
||||
};
|
||||
}
|
||||
|
||||
private static void WalkNode(IHandlebars handlebarsContext, JToken node, object context)
|
||||
private static void WalkNode(IHandlebarsContext handlebarsContext, JToken node, object context)
|
||||
{
|
||||
if (node.Type == JTokenType.Object)
|
||||
{
|
||||
@@ -121,7 +120,7 @@ namespace WireMock.Transformers
|
||||
return;
|
||||
}
|
||||
|
||||
var templateForStringValue = handlebarsContext.Compile(stringValue);
|
||||
var templateForStringValue = handlebarsContext.Handlebars.Compile(stringValue);
|
||||
string transformedString = templateForStringValue(context);
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
@@ -153,9 +152,9 @@ namespace WireMock.Transformers
|
||||
node.Replace(value);
|
||||
}
|
||||
|
||||
private static void TransformBodyAsString(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
private static void TransformBodyAsString(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
var templateBodyAsString = handlebarsContext.Compile(original.BodyData.BodyAsString);
|
||||
var templateBodyAsString = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsString);
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
@@ -165,16 +164,33 @@ namespace WireMock.Transformers
|
||||
};
|
||||
}
|
||||
|
||||
private static void TransformBodyAsFile(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
private void TransformBodyAsFile(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
var templateBodyAsFile = handlebarsContext.Compile(original.BodyData.BodyAsFile);
|
||||
var templateBodyAsFile = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsFile);
|
||||
string transformedBodyAsFilename = templateBodyAsFile(template);
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
if (!useTransformerForBodyAsFile)
|
||||
{
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsFile = templateBodyAsFile(template)
|
||||
};
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
string text = handlebarsContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
|
||||
var templateBodyAsString = handlebarsContext.Handlebars.Compile(text);
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = templateBodyAsString(template),
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
@@ -30,7 +31,7 @@ namespace WireMock.Util
|
||||
.Split(new[] { '&', ';' }, StringSplitOptions.RemoveEmptyEntries) // Support "?key=value;key=anotherValue" and "?key=value&key=anotherValue"
|
||||
.Select(parameter => parameter.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries))
|
||||
.GroupBy(parts => parts[0], JoinParts)
|
||||
.ToDictionary(grouping => grouping.Key, grouping => new WireMockList<string>(grouping.SelectMany(x => x)));
|
||||
.ToDictionary(grouping => grouping.Key, grouping => new WireMockList<string>(grouping.SelectMany(x => x).Select(WebUtility.UrlDecode)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.0" />
|
||||
<PackageReference Include="Handlebars.Net" Version="[1.9.0]" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' != 'net451' ">
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NFluent;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
@@ -226,7 +227,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var response = Response.Create()
|
||||
.WithTransformer()
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\test.xml"); // why use a \\ here ?
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settingsMock.Object);
|
||||
@@ -235,6 +236,30 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_And_TransformContentFromBodyAsFile()
|
||||
{
|
||||
// Assign
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>())).Returns("<xml MyUniqueNumber=\"{{request.query.MyUniqueNumber}}\"></xml>");
|
||||
|
||||
_settingsMock.SetupGet(s => s.FileSystemHandler).Returns(filesystemHandlerMock.Object);
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithTransformer(true)
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settingsMock.Object);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
Check.That(responseMessage.BodyData.DetectedBodyType).Equals(BodyType.String);
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("<xml MyUniqueNumber=\"1\"></xml>");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_JsonPath()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using NFluent;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Models;
|
||||
using WireMock.RequestBuilders;
|
||||
@@ -45,6 +46,28 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
Check.That(responseMessage.Headers["Content-Type"].ToString()).IsEqualTo("application/json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_WithProxy_WebProxySettings()
|
||||
{
|
||||
// Assign
|
||||
var settings = new ProxyAndRecordSettings
|
||||
{
|
||||
Url = "http://test.nl",
|
||||
WebProxySettings = new WebProxySettings
|
||||
{
|
||||
Address = "http://company",
|
||||
UserName = "x",
|
||||
Password = "y"
|
||||
}
|
||||
};
|
||||
var response = Response.Create().WithProxy(settings);
|
||||
|
||||
// Act
|
||||
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "GET", "::1");
|
||||
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settingsMock.Object)).Throws<HttpRequestException>();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_server?.Dispose();
|
||||
|
||||
@@ -61,6 +61,90 @@ namespace WireMock.Net.Tests
|
||||
Check.That(responseWithState).Equals("Test state msg");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_Respect_Int_Valued_Scenarios_and_States()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = FluentMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WillSetStateTo(2)
|
||||
.RespondWith(Response.Create().WithBody("Scenario 1, Setting State 2"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WhenStateIs(2)
|
||||
.RespondWith(Response.Create().WithBody("Scenario 1, State 2"));
|
||||
|
||||
// when
|
||||
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path);
|
||||
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path);
|
||||
|
||||
// then
|
||||
Check.That(responseIntScenario).Equals("Scenario 1, Setting State 2");
|
||||
Check.That(responseWithIntState).Equals("Scenario 1, State 2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_Respect_Mixed_String_Scenario_and_Int_State()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = FluentMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("state string")
|
||||
.WillSetStateTo(1)
|
||||
.RespondWith(Response.Create().WithBody("string state, Setting State 2"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("state string")
|
||||
.WhenStateIs(1)
|
||||
.RespondWith(Response.Create().WithBody("string state, State 2"));
|
||||
|
||||
// when
|
||||
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path);
|
||||
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path);
|
||||
|
||||
// then
|
||||
Check.That(responseIntScenario).Equals("string state, Setting State 2");
|
||||
Check.That(responseWithIntState).Equals("string state, State 2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_Respect_Mixed_Int_Scenario_and_String_Scenario_and_String_State()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = FluentMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WillSetStateTo("Next State")
|
||||
.RespondWith(Response.Create().WithBody("int state, Setting State 2"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("1")
|
||||
.WhenStateIs("Next State")
|
||||
.RespondWith(Response.Create().WithBody("string state, State 2"));
|
||||
|
||||
// when
|
||||
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path);
|
||||
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path);
|
||||
|
||||
// then
|
||||
Check.That(responseIntScenario).Equals("int state, Setting State 2");
|
||||
Check.That(responseWithIntState).Equals("string state, State 2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_TodoList_Example()
|
||||
{
|
||||
|
||||
@@ -188,6 +188,34 @@ namespace WireMock.Net.Tests.Util
|
||||
result["key"].Should().Equal(new WireMockList<string>(new[] { "1", "2", "3" }));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_With1ParamContainingEscapedAnd()
|
||||
{
|
||||
// Assign
|
||||
string query = "?winkel=C%26A";
|
||||
|
||||
// Act
|
||||
var result = QueryStringParser.Parse(query);
|
||||
|
||||
// Assert
|
||||
result.Count.Should().Be(1);
|
||||
result["winkel"].Should().Equal(new WireMockList<string>(new[] { "C&A" }));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_With1ParamContainingParentheses()
|
||||
{
|
||||
// Assign
|
||||
string query = "?Transaction=(123)";
|
||||
|
||||
// Act
|
||||
var result = QueryStringParser.Parse(query);
|
||||
|
||||
// Assert
|
||||
result.Count.Should().Be(1);
|
||||
result["Transaction"].Should().Equal(new WireMockList<string>(new[] { "(123)" }));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_WithMultipleParamWithSameKey()
|
||||
{
|
||||
@@ -227,12 +255,12 @@ namespace WireMock.Net.Tests.Util
|
||||
|
||||
// Assert
|
||||
result.Count.Should().Be(6);
|
||||
result["q"].Should().Equal(new WireMockList<string>("energy+edge"));
|
||||
result["q"].Should().Equal(new WireMockList<string>("energy edge"));
|
||||
result["rls"].Should().Equal(new WireMockList<string>("com.microsoft:en-au"));
|
||||
result["ie"].Should().Equal(new WireMockList<string>("UTF-8"));
|
||||
result["oe"].Should().Equal(new WireMockList<string>("UTF-8"));
|
||||
result["startIndex"].Should().Equal(new WireMockList<string>());
|
||||
result["startPage"].Should().Equal(new WireMockList<string>("1%22"));
|
||||
result["startPage"].Should().Equal(new WireMockList<string>("1\""));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user