Compare commits

...

23 Commits

Author SHA1 Message Date
Stef Heyenrath
c94113308d 1.2.12 2020-05-23 17:33:32 +02:00
Stef Heyenrath
1b1ddeab83 Fixed Proxy when using MultipartForm with byte[] (#473)
* wip

* ByteArrayContentHelper

* ByteArrayContentHelperTests
2020-05-23 16:48:25 +02:00
Stef Heyenrath
d9e3f38fee Create new .sln (#472)
* new sln

* .
2020-05-22 13:35:40 +02:00
Stef Heyenrath
c42c2d5d7a 1.2.11.0 2020-05-18 18:30:47 +02:00
Stef Heyenrath
d67a160144 Fix unhandled exception when target is unavailable (#469)
* wip

* fix

* 31

* known
2020-05-18 15:07:30 +02:00
Stef Heyenrath
7033d85e3a 1.2.10 2020-05-17 20:01:30 +02:00
Stef Heyenrath
7d873611ee Limits (#457) 2020-05-17 19:55:36 +02:00
Stef Heyenrath
f26bf62a13 Include Handlebars.Net.Helpers project (#456)
* wip

* h 100

* rename

* csproj
2020-05-17 19:55:06 +02:00
Stef Heyenrath
6938b6f73c 1.2.9.0 2020-05-14 06:25:36 +00:00
Stef Heyenrath
5b2cd061a6 Fix method ResetMappingsAsync in the RestEase-AdminApi (#465) 2020-05-14 08:00:44 +02:00
Stef Heyenrath
80993c7740 1.2.8.0 2020-05-04 17:36:28 +02:00
Sean Fausett
d4d0f8becd Fix SourceLink support (#463) 2020-05-04 17:33:41 +02:00
Stef Heyenrath
cd613d1c76 1.2.7.0 2020-04-30 17:52:48 +02:00
Stef Heyenrath
5f4c688e49 fix (#461) 2020-04-29 18:01:54 +02:00
Stef Heyenrath
e7949a47d9 1.2.6.0 2020-04-29 07:05:21 +00:00
Stef Heyenrath
a6cf7a48dc When using ResponseMessageTransformer : keep BodyEncoding (#460) 2020-04-29 08:40:49 +02:00
Stef Heyenrath
bf5afef7a1 1.2.5.0 2020-04-17 10:22:40 +00:00
Stef Heyenrath
a8934ec7f9 fix net452 (#454) 2020-04-17 12:18:45 +02:00
Stef Heyenrath
d2ac56e49a 1.2.4.0 2020-04-10 22:54:19 +02:00
Stef Heyenrath
e8a4d52797 Add ValidatedNotNullAttribute (for SonarQube) (#452)
* ValidatedNotNull

* usings
2020-04-10 22:51:34 +02:00
Stef Heyenrath
dac73b6fe0 codecov\1.10.0 (#451) 2020-04-10 20:28:07 +02:00
Stef Heyenrath
e91be0a4d1 Add support for GZip and Deflate (#439)
* gzip - wip

* wip

* tests

* fix gzip and deflate

* CheckIfShouldKillVBCSCompiler

* DisableRequestBodyDecompressing
2020-04-10 19:05:09 +02:00
Stef Heyenrath
a9974a4874 Add readme.md + license from mock4net (#444)
* add readme.md + license from mock4net

* common

* add license info
2020-04-05 18:42:22 +02:00
76 changed files with 2528 additions and 2183 deletions

31
.vscode/launch.json vendored
View File

@@ -1,22 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (WireMock.Net.StandAlone.NETCoreApp)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build_WireMock.Net.StandAlone.NETCoreApp",
"program": "${workspaceRoot}/examples/WireMock.Net.StandAlone.NETCoreApp/bin/Debug/netcoreapp2.0/WireMock.Net.StandAlone.NETCoreApp.dll",
"args": [],
"cwd": "${workspaceRoot}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

View File

@@ -1,3 +1,43 @@
# 1.2.12.0 (23 May 2020)
- [#472](https://github.com/WireMock-Net/WireMock.Net/pull/472) - Create new .sln contributed by [StefH](https://github.com/StefH)
- [#473](https://github.com/WireMock-Net/WireMock.Net/pull/473) - Fixed Proxy when using MultipartForm with byte[] [bug] contributed by [StefH](https://github.com/StefH)
- [#468](https://github.com/WireMock-Net/WireMock.Net/issues/468) - Proxy mode: Incorrect handling of multipart requests [bug]
# 1.2.11.0 (18 May 2020)
- [#469](https://github.com/WireMock-Net/WireMock.Net/pull/469) - Fix unhandled exception when target is unavailable [bug] contributed by [StefH](https://github.com/StefH)
- [#467](https://github.com/WireMock-Net/WireMock.Net/issues/467) - Proxy mode: Unhandled exception when target is not working [bug]
# 1.2.10 (17 May 2020)
- [#456](https://github.com/WireMock-Net/WireMock.Net/pull/456) - Include Handlebars.Net.Helpers project [feature] contributed by [StefH](https://github.com/StefH)
- [#457](https://github.com/WireMock-Net/WireMock.Net/pull/457) - Kestrel Options Limits [bug] contributed by [StefH](https://github.com/StefH)
- [#455](https://github.com/WireMock-Net/WireMock.Net/issues/455) - There is no option to increase body size while proxying [bug]
# 1.2.9.0 (14 May 2020)
- [#465](https://github.com/WireMock-Net/WireMock.Net/pull/465) - Fix method ResetMappingsAsync in the RestEase-AdminApi [bug] contributed by [StefH](https://github.com/StefH)
- [#464](https://github.com/WireMock-Net/WireMock.Net/issues/464) - RestClient Admin API Metadata Base Path Duplication [bug]
# 1.2.8.0 (04 May 2020)
- [#463](https://github.com/WireMock-Net/WireMock.Net/pull/463) - GH161: Fix SourceLink support [bug] contributed by [gitfool](https://github.com/gitfool)
# 1.2.7.0 (30 April 2020)
- [#461](https://github.com/WireMock-Net/WireMock.Net/pull/461) - Support Path in ProxyUrl contributed by [StefH](https://github.com/StefH)
- [#459](https://github.com/WireMock-Net/WireMock.Net/issues/459) - When respond with proxy requestMessage.Url is used, not AbsoluteUrl [bug]
# 1.2.6.0 (29 April 2020)
- [#460](https://github.com/WireMock-Net/WireMock.Net/pull/460) - When using ResponseMessageTransformer : keep BodyEncoding [bug] contributed by [StefH](https://github.com/StefH)
- [#458](https://github.com/WireMock-Net/WireMock.Net/issues/458) - Response BodyAsString loses BodyData.Encoding when UseTransformer = true [bug]
# 1.2.5.0 (17 April 2020)
- [#454](https://github.com/WireMock-Net/WireMock.Net/pull/454) - Fix port = 0 for net452 [bug] contributed by [StefH](https://github.com/StefH)
- [#453](https://github.com/WireMock-Net/WireMock.Net/issues/453) - MockServer not starting [bug]
# 1.2.4.0 (10 April 2020)
- [#439](https://github.com/WireMock-Net/WireMock.Net/pull/439) - Add support for GZip and Deflate [feature] contributed by [StefH](https://github.com/StefH)
- [#444](https://github.com/WireMock-Net/WireMock.Net/pull/444) - Add readme.md + license from mock4net [feature] contributed by [StefH](https://github.com/StefH)
- [#451](https://github.com/WireMock-Net/WireMock.Net/pull/451) - Update NuGet dependencies (e.g. coverage related) to fix CI-build [feature] contributed by [StefH](https://github.com/StefH)
- [#452](https://github.com/WireMock-Net/WireMock.Net/pull/452) - Add ValidatedNotNullAttribute (for SonarQube) [refactor] contributed by [StefH](https://github.com/StefH)
- [#426](https://github.com/WireMock-Net/WireMock.Net/issues/426) - Add support for compressed requests, such as GZIP or DEFLATE [feature]
# 1.2.3.0 (01 April 2020)
- [#449](https://github.com/WireMock-Net/WireMock.Net/pull/449) - Netstandard21 [feature] contributed by [StefH](https://github.com/StefH)
- [#447](https://github.com/WireMock-Net/WireMock.Net/issues/447) - Add support for .NET Standard 2.1 / .NET Core 3.1 [feature]

View File

@@ -4,7 +4,14 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.2.3</VersionPrefix>
<VersionPrefix>1.2.12</VersionPrefix>
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
</PropertyGroup>
<Choose>

View File

@@ -1,3 +1,3 @@
https://github.com/StefH/GitHubReleaseNotes
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.2.3.0
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.2.12.0

View File

@@ -21,13 +21,9 @@ A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) w
| | |
| ***Quality*** | &nbsp; |
| &nbsp;&nbsp;**Build Azure** | [![Build Status Azure](https://stef.visualstudio.com/WireMock.Net/_apis/build/status/WireMock.Net)](https://stef.visualstudio.com/WireMock.Net/_build/latest?definitionId=7) |
| &nbsp;&nbsp;**CodeFactor** | [![CodeFactor](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net/badge)](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net)
| &nbsp;&nbsp;**Sonar Quality Gate** | [![Sonar Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=alert_status)](https://sonarcloud.io/project/issues?id=wiremock) |
| &nbsp;&nbsp;**Sonar Bugs** | [![Sonar Bugs](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=bugs)](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=BUG) |
| &nbsp;&nbsp;**Sonar Code Smells** | [![Sonar Code Smells](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=code_smells)](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=CODE_SMELL) |
| &nbsp;&nbsp;**Sonar Coverage** | [![Sonar Coverage](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=coverage)](https://sonarcloud.io/component_measures?id=wiremock&metric=coverage) |
| &nbsp;&nbsp;**Codecov** | [![codecov](https://codecov.io/gh/WireMock-Net/WireMock.Net/branch/master/graph/badge.svg)](https://codecov.io/gh/WireMock-Net/WireMock.Net) |
| &nbsp;&nbsp;**Coveralls** | [![Coverage Status](https://coveralls.io/repos/github/WireMock-Net/WireMock.Net/badge.svg?branch=master)](https://coveralls.io/github/WireMock-Net/WireMock.Net?branch=master) |
| &nbsp;&nbsp;**Quality** | [![Sonar Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=alert_status)](https://sonarcloud.io/project/issues?id=wiremock) [![CodeFactor](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net/badge)](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net) |
| &nbsp;&nbsp;**Sonar Bugs** | [![Sonar Bugs](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=bugs)](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=BUG) [![Sonar Code Smells](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=code_smells)](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=CODE_SMELL) |
| &nbsp;&nbsp;**Coverage** | [![Sonar Coverage](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=coverage)](https://sonarcloud.io/component_measures?id=wiremock&metric=coverage) [![codecov](https://codecov.io/gh/WireMock-Net/WireMock.Net/branch/master/graph/badge.svg)](https://codecov.io/gh/WireMock-Net/WireMock.Net) [![Coverage Status](https://coveralls.io/repos/github/WireMock-Net/WireMock.Net/badge.svg?branch=master)](https://coveralls.io/github/WireMock-Net/WireMock.Net?branch=master) |
### NuGet packages

View File

@@ -1,13 +1,27 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EF242EDF-7133-4277-9A0C-18744DE08707}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8F890C6F-9ACC-438D-928A-AD61CDA862F2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{197A0EE3-94E5-4807-BBCF-2F1BCA28A6AE}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0BB8B634-407A-4610-A91F-11586990767A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net", "src\WireMock.Net\WireMock.Net.csproj", "{D3804228-91F4-4502-9595-39584E5A01AD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Abstractions", "src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj", "{B6269AAC-170A-4346-8B9A-579DED3D9A94}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.RestClient", "src\WireMock.Net.RestClient\WireMock.Net.RestClient.csproj", "{B6269AAC-170A-43D6-8B9A-579DED3D9A96}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.StandAlone", "src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj", "{B6269AAC-170A-43D5-8B9A-579DED3D9A95}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Tests", "test\WireMock.Net.Tests\WireMock.Net.Tests.csproj", "{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{985E0ADB-D4B4-473A-AA40-567E279B7946}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7EFB2C5B-1BB2-4AAF-BC9F-216ED80C594D}"
ProjectSection(SolutionItems) = preProject
.runsettings = .runsettings
.gitignore = .gitignore
azure-pipelines-ci-linux.yml = azure-pipelines-ci-linux.yml
azure-pipelines-ci.yml = azure-pipelines-ci.yml
azure-pipelines-linux.yml = azure-pipelines-linux.yml
@@ -17,348 +31,67 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Directory.Build.props = Directory.Build.props
GitHubReleaseNotes.txt = GitHubReleaseNotes.txt
README.md = README.md
ReSharper_WireMock.DotSettings = ReSharper_WireMock.DotSettings
report\run-codecov-local.cmd = report\run-codecov-local.cmd
report\run-coverlet-local.cmd = report\run-coverlet-local.cmd
WireMock.Net Solution.sln.DotSettings = WireMock.Net Solution.sln.DotSettings
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{F0C22C47-DF71-463C-9B04-B4E0F3B8708A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NETCoreApp3", "examples\WireMock.Net.Console.NETCoreApp3\WireMock.Net.Console.NETCoreApp3.csproj", "{8C424EAF-8269-46A2-9FF1-F6D4EADB5CD5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{890A1DED-C229-4FA1-969E-AAC3BBFC05E5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.Proxy.NETCoreApp2", "examples\WireMock.Net.Console.Proxy.NETCoreApp2\WireMock.Net.Console.Proxy.NETCoreApp2.csproj", "{41C19451-E980-4ED4-A011-DA7A1C23FC05}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net", "src\WireMock.Net\WireMock.Net.csproj", "{D3804228-91F4-4502-9595-39584E5A01AD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Tests", "test\WireMock.Net.Tests\WireMock.Net.Tests.csproj", "{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NETCoreApp", "examples\WireMock.Net.Console.NETCoreApp\WireMock.Net.Console.NETCoreApp.csproj", "{FE281639-B014-4C8A-96FA-141164A74713}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.Proxy.NETCoreApp", "examples\WireMock.Net.Console.Record.NETCoreApp\WireMock.Net.Console.Proxy.NETCoreApp.csproj", "{1995E414-F197-4AB4-90C2-68D806B5AF59}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Client", "examples\WireMock.Net.Client\WireMock.Net.Client.csproj", "{058D4B6C-C03E-49D0-91DB-A535B058FA0D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.StandAlone.NETCoreApp", "examples\WireMock.Net.StandAlone.NETCoreApp\WireMock.Net.StandAlone.NETCoreApp.csproj", "{10E16614-61CA-48D8-8BDD-664C13913DED}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.StandAlone.Net452", "examples\WireMock.Net.StandAlone.Net452\WireMock.Net.StandAlone.Net452.csproj", "{668F689E-57B4-422E-8846-C0FF643CA999}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.WebApplication.NETCore2", "examples\WireMock.Net.WebApplication\WireMock.Net.WebApplication.NETCore2.csproj", "{049539C1-7A66-4559-AD7A-B1C73B97CBB0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Proxy.Net452", "examples\WireMock.Net.Console.Proxy.Net452\WireMock.Net.Console.Proxy.Net452.csproj", "{26433A8F-BF01-4962-97EB-81BFFBB61096}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.Proxy.NETCoreApp2", "examples\WireMock.Net.Console.Proxy.NETCoreApp2\WireMock.Net.Console.Proxy.NETCoreApp2.csproj", "{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.StandAlone.Net461", "examples\WireMock.Net.StandAlone.Net461\WireMock.Net.StandAlone.Net461.csproj", "{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Service", "examples\Wiremock.Net.Service\WireMock.Net.Service.csproj", "{7F0B2446-0363-4720-AF46-F47F83B557DC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Net461.Classic", "examples\WireMock.Net.Console.Net461.Classic\WireMock.Net.Console.Net461.Classic.csproj", "{1261BB9B-A7D4-456C-8985-3CE560361B8E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Net452.Classic", "examples\WireMock.Net.Console.Net452.Classic\WireMock.Net.Console.Net452.Classic.csproj", "{668F689E-57B4-422E-8846-C0FF643CA268}"
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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.RestClient", "src\WireMock.Net.RestClient\WireMock.Net.RestClient.csproj", "{B6269AAC-170A-43D6-8B9A-579DED3D9A96}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Abstractions", "src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj", "{B6269AAC-170A-4346-8B9A-579DED3D9A94}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.StandAlone", "src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj", "{B6269AAC-170A-43D5-8B9A-579DED3D9A95}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.RequestLogTest", "examples\WireMock.Net.Console.RequestLogTest\WireMock.Net.Console.RequestLogTest.csproj", "{A9D039B9-7509-4CF1-9EFD-87EB82998575}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Client.Net472", "examples\WireMock.Net.Client.Net472\WireMock.Net.Client.Net472.csproj", "{02082E34-DEF2-47D0-AF0B-3326FAA908CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NETCoreApp3", "examples\WireMock.Net.Console.NETCoreApp3\WireMock.Net.Console.NETCoreApp3.csproj", "{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Client", "examples\WireMock.Net.Client\WireMock.Net.Client.csproj", "{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug - Sonar|Any CPU = Debug - Sonar|Any CPU
Debug - Sonar|x64 = Debug - Sonar|x64
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D3804228-91F4-4502-9595-39584E5A01AD}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Debug|x64.ActiveCfg = Debug|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Debug|x64.Build.0 = Debug|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Release|Any CPU.Build.0 = Release|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Release|x64.ActiveCfg = Release|Any CPU
{D3804228-91F4-4502-9595-39584E5A01AD}.Release|x64.Build.0 = Release|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug|x64.ActiveCfg = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug|x64.Build.0 = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Release|Any CPU.Build.0 = Release|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Release|x64.ActiveCfg = Release|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Release|x64.Build.0 = Release|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Debug|x64.ActiveCfg = Debug|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Debug|x64.Build.0 = Debug|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Release|Any CPU.Build.0 = Release|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Release|x64.ActiveCfg = Release|Any CPU
{FE281639-B014-4C8A-96FA-141164A74713}.Release|x64.Build.0 = Release|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Debug|x64.ActiveCfg = Debug|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Debug|x64.Build.0 = Debug|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Release|Any CPU.Build.0 = Release|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Release|x64.ActiveCfg = Release|Any CPU
{1995E414-F197-4AB4-90C2-68D806B5AF59}.Release|x64.Build.0 = Release|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Debug|x64.ActiveCfg = Debug|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Debug|x64.Build.0 = Debug|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Release|Any CPU.Build.0 = Release|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Release|x64.ActiveCfg = Release|Any CPU
{058D4B6C-C03E-49D0-91DB-A535B058FA0D}.Release|x64.Build.0 = Release|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Debug|x64.ActiveCfg = Debug|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Debug|x64.Build.0 = Debug|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Release|Any CPU.Build.0 = Release|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Release|x64.ActiveCfg = Release|Any CPU
{10E16614-61CA-48D8-8BDD-664C13913DED}.Release|x64.Build.0 = Release|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug|Any CPU.Build.0 = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug|x64.ActiveCfg = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug|x64.Build.0 = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Release|Any CPU.ActiveCfg = Release|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Release|Any CPU.Build.0 = Release|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Release|x64.ActiveCfg = Release|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA999}.Release|x64.Build.0 = Release|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Debug|x64.ActiveCfg = Debug|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Debug|x64.Build.0 = Debug|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Release|Any CPU.Build.0 = Release|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Release|x64.ActiveCfg = Release|Any CPU
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Release|x64.Build.0 = Release|Any CPU
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug - Sonar|x64.ActiveCfg = Debug|x64
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug - Sonar|x64.Build.0 = Debug|x64
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug|x64.ActiveCfg = Debug|x64
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug|x64.Build.0 = Debug|x64
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Release|Any CPU.Build.0 = Release|Any CPU
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Release|x64.ActiveCfg = Release|x64
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Release|x64.Build.0 = Release|x64
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Debug|x64.ActiveCfg = Debug|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Debug|x64.Build.0 = Debug|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Release|Any CPU.Build.0 = Release|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Release|x64.ActiveCfg = Release|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Release|x64.Build.0 = Release|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug|x64.ActiveCfg = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug|x64.Build.0 = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Release|Any CPU.Build.0 = Release|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Release|x64.ActiveCfg = Release|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Release|x64.Build.0 = Release|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug|x64.ActiveCfg = Debug|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug|x64.Build.0 = Debug|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|Any CPU.Build.0 = Release|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|x64.ActiveCfg = Release|Any CPU
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|x64.Build.0 = Release|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug|x64.ActiveCfg = Debug|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug|x64.Build.0 = Debug|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Release|Any CPU.Build.0 = Release|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Release|x64.ActiveCfg = Release|Any CPU
{1261BB9B-A7D4-456C-8985-3CE560361B8E}.Release|x64.Build.0 = Release|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug|Any CPU.Build.0 = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug|x64.ActiveCfg = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug|x64.Build.0 = Debug|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Release|Any CPU.ActiveCfg = Release|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Release|Any CPU.Build.0 = Release|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Release|x64.ActiveCfg = Release|Any CPU
{668F689E-57B4-422E-8846-C0FF643CA268}.Release|x64.Build.0 = Release|Any CPU
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug|x64.ActiveCfg = Debug|Any CPU
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug|x64.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
{83645809-9E01-4E81-8733-BA9497554ABF}.Release|x64.ActiveCfg = Release|Any CPU
{83645809-9E01-4E81-8733-BA9497554ABF}.Release|x64.Build.0 = Release|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug|x64.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug|x64.Build.0 = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Release|Any CPU.Build.0 = Release|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Release|x64.ActiveCfg = Release|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Release|x64.Build.0 = Release|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Debug|x64.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Debug|x64.Build.0 = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Release|Any CPU.Build.0 = Release|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Release|x64.ActiveCfg = Release|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A94}.Release|x64.Build.0 = Release|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6269AAC-170A-43D6-8B9A-579DED3D9A96}.Release|Any CPU.Build.0 = Release|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Debug|x64.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Debug|x64.Build.0 = Debug|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Release|Any CPU.Build.0 = Release|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Release|x64.ActiveCfg = Release|Any CPU
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}.Release|x64.Build.0 = Release|Any CPU
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Debug - Sonar|x64.Build.0 = Debug|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}.Debug|x64.ActiveCfg = Debug|Any CPU
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Debug|x64.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
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Release|x64.ActiveCfg = Release|Any CPU
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Release|x64.Build.0 = Release|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug|x64.ActiveCfg = Debug|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug|x64.Build.0 = Debug|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Release|Any CPU.Build.0 = Release|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Release|x64.ActiveCfg = Release|Any CPU
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Release|x64.Build.0 = Release|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug|x64.ActiveCfg = Debug|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug|x64.Build.0 = Debug|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Release|Any CPU.Build.0 = Release|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Release|x64.ActiveCfg = Release|Any CPU
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Release|x64.Build.0 = Release|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}.Release|Any CPU.Build.0 = Release|Any CPU
{8C424EAF-8269-46A2-9FF1-F6D4EADB5CD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C424EAF-8269-46A2-9FF1-F6D4EADB5CD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C424EAF-8269-46A2-9FF1-F6D4EADB5CD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C424EAF-8269-46A2-9FF1-F6D4EADB5CD5}.Release|Any CPU.Build.0 = Release|Any CPU
{41C19451-E980-4ED4-A011-DA7A1C23FC05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{41C19451-E980-4ED4-A011-DA7A1C23FC05}.Debug|Any CPU.Build.0 = Debug|Any CPU
{41C19451-E980-4ED4-A011-DA7A1C23FC05}.Release|Any CPU.ActiveCfg = Release|Any CPU
{41C19451-E980-4ED4-A011-DA7A1C23FC05}.Release|Any CPU.Build.0 = Release|Any CPU
{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D3804228-91F4-4502-9595-39584E5A01AD} = {EF242EDF-7133-4277-9A0C-18744DE08707}
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E} = {890A1DED-C229-4FA1-969E-AAC3BBFC05E5}
{FE281639-B014-4C8A-96FA-141164A74713} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{1995E414-F197-4AB4-90C2-68D806B5AF59} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{058D4B6C-C03E-49D0-91DB-A535B058FA0D} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{10E16614-61CA-48D8-8BDD-664C13913DED} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{668F689E-57B4-422E-8846-C0FF643CA999} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{049539C1-7A66-4559-AD7A-B1C73B97CBB0} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{26433A8F-BF01-4962-97EB-81BFFBB61096} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{7F0B2446-0363-4720-AF46-F47F83B557DC} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{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}
{B6269AAC-170A-43D6-8B9A-579DED3D9A96} = {EF242EDF-7133-4277-9A0C-18744DE08707}
{B6269AAC-170A-4346-8B9A-579DED3D9A94} = {EF242EDF-7133-4277-9A0C-18744DE08707}
{B6269AAC-170A-43D5-8B9A-579DED3D9A95} = {EF242EDF-7133-4277-9A0C-18744DE08707}
{A9D039B9-7509-4CF1-9EFD-87EB82998575} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{02082E34-DEF2-47D0-AF0B-3326FAA908CE} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{D3804228-91F4-4502-9595-39584E5A01AD} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{B6269AAC-170A-4346-8B9A-579DED3D9A94} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{B6269AAC-170A-43D6-8B9A-579DED3D9A96} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{B6269AAC-170A-43D5-8B9A-579DED3D9A95} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E} = {0BB8B634-407A-4610-A91F-11586990767A}
{8C424EAF-8269-46A2-9FF1-F6D4EADB5CD5} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{41C19451-E980-4ED4-A011-DA7A1C23FC05} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BF428BCC-C837-433B-87D2-15C7014B73E9}
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
EndGlobalSection
EndGlobal

View File

@@ -9,6 +9,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WWW/@EntryIndexedValue">WWW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XMS/@EntryIndexedValue">XMS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XUA/@EntryIndexedValue">XUA</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Flurl/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=funcs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Heyenrath/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jmes/@EntryIndexedValue">True</s:Boolean>

View File

@@ -6,7 +6,7 @@ variables:
steps:
- script: |
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework netcoreapp2.1 --logger trx
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework netcoreapp3.1 --logger trx
- task: PublishTestResults@2
inputs:
testRunner: VSTest

View File

@@ -28,11 +28,11 @@ steps:
displayName: Begin SonarScanner
condition: and(succeeded(), eq(variables['RUN_SONAR'], 'yes'))
# Build source, tests and run tests for net452 and netcoreapp2.1 (with coverage)
# Build source, tests and run tests for net452 and netcoreapp3.1 (with coverage)
- script: |
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework net452
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework netcoreapp2.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
displayName: 'Build source, tests and run tests for net452 and netcoreapp2.1 (with coverage)'
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework netcoreapp3.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
displayName: 'Build source, tests and run tests for net452 and netcoreapp3.1 (with coverage)'
# End SonarScanner
- script: |
@@ -46,7 +46,7 @@ steps:
# Upload coverage to codecov.io
- script: |
%USERPROFILE%\.nuget\packages\codecov\1.1.0\tools\codecov.exe -f "./test/WireMock.Net.Tests/coverage.opencover.xml" -t $(CODECOV_TOKEN)
%USERPROFILE%\.nuget\packages\codecov\1.10.0\tools\codecov.exe -f "./test/WireMock.Net.Tests/coverage.opencover.xml" -t $(CODECOV_TOKEN)
displayName: Upload coverage to codecov.io
# https://github.com/microsoft/azure-pipelines-tasks/issues/12212

View File

@@ -28,7 +28,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
<PackageReference Include="Handlebars.Net.Helpers" Version="1.0.0" />
<PackageReference Include="log4net" Version="2.0.8" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<!--<PackageReference Include="Microsoft.CodeAnalysis.Scripting.Common" Version="3.4.0" />-->

File diff suppressed because it is too large Load Diff

177
mock4net/LICENSE.txt Normal file
View File

@@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

3
mock4net/readme.md Normal file
View File

@@ -0,0 +1,3 @@
WireMock.Net is based on the source-code from https://github.com/alexvictoor/mock4net
The license in this folder is copied from https://github.com/alexvictoor/mock4net/blob/master/LICENSE.txt

View File

@@ -40,6 +40,11 @@ namespace WireMock.Admin.Requests
/// </summary>
public string AbsoluteUrl { get; set; }
/// <summary>
/// The ProxyUrl (if a proxy is used).
/// </summary>
public string ProxyUrl { get; set; }
/// <summary>
/// The query.
/// </summary>

View File

@@ -9,20 +9,11 @@
<AssemblyName>WireMock.Net.Abstractions</AssemblyName>
<PackageId>WireMock.Net.Abstractions</PackageId>
<PackageTags>wiremock;interfaces;models;classes;enumerations;types</PackageTags>
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
<RootNamespace>WireMock</RootNamespace>
<!--<DebugType>full</DebugType>
<IncludeSource>True</IncludeSource>
<IncludeSymbols>True</IncludeSymbols>-->
<ProjectGuid>{B6269AAC-170A-4346-8B9A-579DED3D9A94}</ProjectGuid>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
@@ -33,14 +24,13 @@
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
<!--<GeneratePackageOnBuild>true</GeneratePackageOnBuild>-->
<!--<PathMap>$(MSBuildProjectDirectory)=/</PathMap>-->
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>
</Project>

View File

@@ -86,7 +86,7 @@ namespace WireMock.Client
/// Delete (reset) all mappings.
/// </summary>
/// <param name="reloadStaticMappings">A value indicating whether to reload the static mappings after the reset.</param>
[Post("__admin/mappings/reset")]
[Post("mappings/reset")]
Task<StatusModel> ResetMappingsAsync(bool? reloadStaticMappings = false);
/// <summary>

View File

@@ -9,20 +9,11 @@
<AssemblyName>WireMock.Net.RestClient</AssemblyName>
<PackageId>WireMock.Net.RestClient</PackageId>
<PackageTags>wiremock;rest;client;restclient;restease;rest;json</PackageTags>
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
<RootNamespace>WireMock.Client</RootNamespace>
<!--<DebugType>full</DebugType>
<IncludeSource>True</IncludeSource>
<IncludeSymbols>True</IncludeSymbols>-->
<ProjectGuid>{B6269AAC-170A-43D6-8B9A-579DED3D9A96}</ProjectGuid>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
@@ -33,11 +24,12 @@
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
<!--<PathMap>$(MSBuildProjectDirectory)=/</PathMap>-->
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="RestEase" Version="1.4.10" />
</ItemGroup>

View File

@@ -8,20 +8,11 @@
<AssemblyName>WireMock.Net.StandAlone</AssemblyName>
<PackageId>WireMock.Net.StandAlone</PackageId>
<PackageTags>tdd;mock;http;wiremock;test;server;unittest</PackageTags>
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
<RootNamespace>WireMock.Net.StandAlone</RootNamespace>
<!--<DebugType>full</DebugType>
<IncludeSource>True</IncludeSource>
<IncludeSymbols>True</IncludeSymbols>-->
<ProjectGuid>{B6269AAC-170A-43D5-8B9A-579DED3D9A95}</ProjectGuid>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<CodeAnalysisRuleSet>WireMock.Net.StandAlone.ruleset</CodeAnalysisRuleSet>
@@ -30,9 +21,9 @@
<!--<DelaySign>true</DelaySign>-->
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
<!--<PathMap>$(MSBuildProjectDirectory)=/</PathMap>-->
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
@@ -45,9 +36,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2018.2.1">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="JetBrains.Annotations" Version="2018.2.1" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="7.8.0.7320">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

View File

@@ -0,0 +1,30 @@
using System.Net.Http;
using System.Net.Http.Headers;
using JetBrains.Annotations;
using WireMock.Validation;
namespace WireMock.Http
{
internal static class ByteArrayContentHelper
{
/// <summary>
/// Creates a ByteArrayContent object.
/// </summary>
/// <param name="content">The byte[] content (cannot be null)</param>
/// <param name="contentType">The ContentType (can be null)</param>
/// <returns>ByteArrayContent</returns>
internal static ByteArrayContent Create([NotNull] byte[] content, [CanBeNull] MediaTypeHeaderValue contentType)
{
Check.NotNull(content, nameof(content));
var byteContent = new ByteArrayContent(content);
if (contentType != null)
{
byteContent.Headers.Remove(HttpKnownHeaderNames.ContentType);
byteContent.Headers.ContentType = contentType;
}
return byteContent;
}
}
}

View File

@@ -68,7 +68,7 @@ namespace WireMock.Http
return client;
}
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url, bool deserializeJson)
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url, bool deserializeJson, bool decompressGzipAndDeflate)
{
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, deserializeJson);
return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate);
}
}
}

View File

@@ -1,10 +1,10 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using JetBrains.Annotations;
using Newtonsoft.Json;
using WireMock.Types;
using WireMock.Validation;
@@ -29,7 +29,7 @@ namespace WireMock.Http
switch (requestMessage.BodyData?.DetectedBodyType)
{
case BodyType.Bytes:
httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyData.BodyAsBytes);
httpRequestMessage.Content = ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes, contentType);
break;
case BodyType.Json:

View File

@@ -9,7 +9,7 @@ namespace WireMock.Http
{
internal static class HttpResponseMessageHelper
{
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson)
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson, bool decompressGzipAndDeflate)
{
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
@@ -24,7 +24,21 @@ namespace WireMock.Http
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
}
responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault(), deserializeJson);
IEnumerable<string> contentEncodingHeader = null;
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)))
{
contentEncodingHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)).Value;
}
var bodyParserSettings = new BodyParserSettings
{
Stream = stream,
ContentType = contentTypeHeader?.FirstOrDefault(),
DeserializeJson = deserializeJson,
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
DecompressGZipAndDeflate = decompressGzipAndDeflate
};
responseMessage.BodyData = await BodyParser.Parse(bodyParserSettings);
}
foreach (var header in headers)

View File

@@ -0,0 +1,2 @@
Some source files in this folder are based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.

View File

@@ -0,0 +1,40 @@
#if USE_ASPNETCORE && !NETSTANDARD1_3
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
namespace WireMock.Owin
{
internal partial class AspNetCoreSelfHost
{
private static void SetKestrelOptionsLimits(KestrelServerOptions options)
{
options.Limits.KeepAliveTimeout = TimeSpan.MaxValue;
options.Limits.MaxRequestBodySize = null; // https://stackoverflow.com/questions/46738364/increase-upload-request-length-limit-in-kestrel
options.Limits.MaxRequestBufferSize = null;
options.Limits.MaxRequestHeaderCount = 100;
options.Limits.MaxResponseBufferSize = null;
options.Limits.RequestHeadersTimeout = TimeSpan.MaxValue;
}
private static void SetHttpsAndUrls(KestrelServerOptions options, ICollection<(string Url, int Port)> urlDetails)
{
foreach (var detail in urlDetails)
{
if (detail.Url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
{
options.Listen(System.Net.IPAddress.Any, detail.Port, listenOptions =>
{
listenOptions.UseHttps();
});
}
else
{
options.Listen(System.Net.IPAddress.Any, detail.Port);
}
}
}
}
}
#endif

View File

@@ -0,0 +1,32 @@
#if USE_ASPNETCORE && NETSTANDARD1_3
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel;
using WireMock.HttpsCertificate;
namespace WireMock.Owin
{
internal partial class AspNetCoreSelfHost
{
private static void SetKestrelOptionsLimits(KestrelServerOptions options)
{
options.Limits.KeepAliveTimeout = TimeSpan.MaxValue;
options.Limits.MaxRequestBufferSize = null;
options.Limits.MaxRequestHeaderCount = 100;
options.Limits.MaxResponseBufferSize = null;
options.Limits.RequestHeadersTimeout = TimeSpan.MaxValue;
}
private static void SetHttpsAndUrls(KestrelServerOptions options, ICollection<(string Url, int Port)> urlDetails)
{
var urls = urlDetails.Select(u => u.Url);
if (urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
{
options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
}
}
}
}
#endif

View File

@@ -8,7 +8,6 @@ using JetBrains.Annotations;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using WireMock.HttpsCertificate;
using WireMock.Logging;
using WireMock.Owin.Mappers;
using WireMock.Util;
@@ -16,7 +15,7 @@ using WireMock.Validation;
namespace WireMock.Owin
{
internal class AspNetCoreSelfHost : IOwinSelfHost
internal partial class AspNetCoreSelfHost : IOwinSelfHost
{
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly IWireMockMiddlewareOptions _options;
@@ -78,31 +77,9 @@ namespace WireMock.Owin
})
.UseKestrel(options =>
{
var urlDetails = _urlOptions.GetDetails();
SetKestrelOptionsLimits(options);
#if NETSTANDARD1_3
var urls = urlDetails.Select(u => u.Url);
if (urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
{
options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
}
#else
foreach (var detail in urlDetails)
{
if (detail.Url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
{
options.Listen(System.Net.IPAddress.Any, detail.Port, listenOptions =>
{
listenOptions.UseHttps(); // PublicCertificateHelper.GetX509Certificate2()
});
}
else
{
options.Listen(System.Net.IPAddress.Any, detail.Port);
}
}
#endif
SetHttpsAndUrls(options, _urlOptions.GetDetails());
})
#if NETSTANDARD1_3
@@ -144,6 +121,7 @@ namespace WireMock.Owin
#elif NET46
_logger.Info("WireMock.Net server using .net 4.6.1 or higher");
#endif
#if NETSTANDARD1_3
return Task.Run(() =>
{

View File

@@ -1,43 +1,43 @@
using System.Collections.Generic;
using WireMock.Util;
namespace WireMock.Owin
{
internal class HostUrlOptions
{
public ICollection<string> Urls { get; set; }
public int? Port { get; set; }
public bool UseSSL { get; set; }
public ICollection<(string Url, int Port)> GetDetails()
{
var list = new List<(string Url, int Port)>();
if (Urls == null)
{
int port = Port ?? FindFreeTcpPort();
list.Add(($"{(UseSSL ? "https" : "http")}://localhost:{port}", port));
}
else
{
foreach (string url in Urls)
{
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
list.Add((url, port));
}
}
return list;
}
private int FindFreeTcpPort()
{
#if USE_ASPNETCORE || NETSTANDARD2_0 || NETSTANDARD2_1
return 0;
#else
return PortUtils.FindFreeTcpPort();
#endif
}
}
using System.Collections.Generic;
using WireMock.Util;
namespace WireMock.Owin
{
internal class HostUrlOptions
{
public ICollection<string> Urls { get; set; }
public int? Port { get; set; }
public bool UseSSL { get; set; }
public ICollection<(string Url, int Port)> GetDetails()
{
var list = new List<(string Url, int Port)>();
if (Urls == null)
{
int port = Port > 0 ? Port.Value : FindFreeTcpPort();
list.Add(($"{(UseSSL ? "https" : "http")}://localhost:{port}", port));
}
else
{
foreach (string url in Urls)
{
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
list.Add((url, port));
}
}
return list;
}
private int FindFreeTcpPort()
{
#if USE_ASPNETCORE || NETSTANDARD2_0 || NETSTANDARD2_1
return 0;
#else
return PortUtils.FindFreeTcpPort();
#endif
}
}
}

View File

@@ -43,5 +43,7 @@ namespace WireMock.Owin
bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
bool? DisableJsonBodyParsing { get; set; }
bool? DisableRequestBodyDecompressing { get; set; }
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WireMock.Http;
using WireMock.Models;
using WireMock.Util;
#if !USE_ASPNETCORE
@@ -27,12 +28,18 @@ namespace WireMock.Owin.Mappers
string method = request.Method;
Dictionary<string, string[]> headers = null;
IEnumerable<string> contentEncodingHeader = null;
if (request.Headers.Any())
{
headers = new Dictionary<string, string[]>();
foreach (var header in request.Headers)
{
headers.Add(header.Key, header.Value);
if (string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase))
{
contentEncodingHeader = header.Value;
}
}
}
@@ -49,7 +56,16 @@ 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, !options.DisableJsonBodyParsing.GetValueOrDefault(false));
var bodyParserSettings = new BodyParserSettings
{
Stream = request.Body,
ContentType = request.ContentType,
DeserializeJson = !options.DisableJsonBodyParsing.GetValueOrDefault(false),
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
DecompressGZipAndDeflate = !options.DisableRequestBodyDecompressing.GetValueOrDefault(false)
};
body = await BodyParser.Parse(bodyParserSettings);
}
return new RequestMessage(urldetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow };

View File

@@ -129,7 +129,7 @@ namespace WireMock.Owin
catch (Exception ex)
{
_options.Logger.Error($"Providing a Response for Mapping '{result?.Mapping?.Guid}' failed. HttpStatusCode set to 500. Exception: {ex}");
response = ResponseMessageBuilder.Create(JsonConvert.SerializeObject(ex), 500);
response = ResponseMessageBuilder.Create(ex.Message, 500);
}
finally
{

View File

@@ -46,7 +46,10 @@ namespace WireMock.Owin
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowOnlyDefinedHttpStatusCodeInResponse"/>
public bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableResponseBodyParsing"/>
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableJsonBodyParsing"/>
public bool? DisableJsonBodyParsing { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableRequestBodyDecompressing"/>
public bool? DisableRequestBodyDecompressing { get; set; }
}
}

View File

@@ -1,4 +1,6 @@
using System.Linq;
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using System.Linq;
using WireMock.Http;
using WireMock.Matchers;
using WireMock.Matchers.Request;

View File

@@ -1,73 +1,75 @@
using System;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Validation;
namespace WireMock.RequestBuilders
{
public partial class Request
{
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string, MatchBehaviour)"/>
public IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[], MatchBehaviour)"/>
public IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object, MatchBehaviour)"/>
public IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
public IRequestBuilder WithBody(IMatcher matcher)
{
return WithBody(new[] { matcher });
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
public IRequestBuilder WithBody(IMatcher[] matchers)
{
Check.NotNull(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageBodyMatcher(matchers));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{string, bool})"/>
public IRequestBuilder WithBody(Func<string, bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{byte[], bool})"/>
public IRequestBuilder WithBody(Func<byte[], bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{object, bool})"/>
public IRequestBuilder WithBody(Func<object, bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
}
}
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using System;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Validation;
namespace WireMock.RequestBuilders
{
public partial class Request
{
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string, MatchBehaviour)"/>
public IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[], MatchBehaviour)"/>
public IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object, MatchBehaviour)"/>
public IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
public IRequestBuilder WithBody(IMatcher matcher)
{
return WithBody(new[] { matcher });
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
public IRequestBuilder WithBody(IMatcher[] matchers)
{
Check.NotNull(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageBodyMatcher(matchers));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{string, bool})"/>
public IRequestBuilder WithBody(Func<string, bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{byte[], bool})"/>
public IRequestBuilder WithBody(Func<byte[], bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{object, bool})"/>
public IRequestBuilder WithBody(Func<object, bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
}
}

View File

@@ -1,4 +1,6 @@
using System;
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using System;
using System.Collections.Generic;
using WireMock.Matchers;
using WireMock.Matchers.Request;

View File

@@ -1,4 +1,6 @@
using System;
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using System;
using System.Collections.Generic;
using WireMock.Matchers;
using WireMock.Matchers.Request;

View File

@@ -1,4 +1,6 @@
using System;
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

View File

@@ -1,4 +1,6 @@
using JetBrains.Annotations;
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -30,6 +32,11 @@ namespace WireMock
/// </summary>
public string AbsoluteUrl { get; }
/// <summary>
/// The ProxyUrl (if a proxy is used).
/// </summary>
public string ProxyUrl { get; set; }
/// <summary>
/// Gets the DateTime.
/// </summary>
@@ -110,6 +117,11 @@ namespace WireMock
/// </summary>
public string DetectedBodyTypeFromContentType { get; }
/// <summary>
/// The detected compression from the Content-Encoding header. Convenience getter for Handlebars.
/// </summary>
public string DetectedCompression { get; }
/// <summary>
/// Gets the Host
/// </summary>
@@ -168,6 +180,7 @@ namespace WireMock
BodyAsBytes = BodyData?.BodyAsBytes;
DetectedBodyType = BodyData?.DetectedBodyType.ToString();
DetectedBodyTypeFromContentType = BodyData?.DetectedBodyTypeFromContentType.ToString();
DetectedCompression = BodyData?.DetectedCompression;
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
Cookies = cookies;

View File

@@ -1,3 +1,5 @@
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using System;
using System.Collections.Generic;
using System.Linq;
@@ -341,11 +343,25 @@ namespace WireMock.ResponseBuilders
if (ProxyUrl != null && _httpClientForProxy != null)
{
var requestUri = new Uri(requestMessage.Url);
var proxyUri = new Uri(ProxyUrl);
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
string RemoveFirstOccurrence(string source, string find)
{
int place = source.IndexOf(find, StringComparison.OrdinalIgnoreCase);
return place >= 0 ? source.Remove(place, find.Length) : source;
}
return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri, !settings.DisableJsonBodyParsing.GetValueOrDefault(false));
var requestUri = new Uri(requestMessage.Url);
// Build the proxy url and skip duplicates
string extra = RemoveFirstOccurrence(requestUri.LocalPath.TrimEnd('/'), new Uri(ProxyUrl).LocalPath.TrimEnd('/'));
requestMessage.ProxyUrl = ProxyUrl + extra + requestUri.Query;
return await HttpClientHelper.SendAsync(
_httpClientForProxy,
requestMessage,
requestMessage.ProxyUrl,
!settings.DisableJsonBodyParsing.GetValueOrDefault(false),
!settings.DisableRequestBodyDecompressing.GetValueOrDefault(false)
);
}
ResponseMessage responseMessage;

View File

@@ -1,4 +1,6 @@
using System.Collections.Generic;
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using System.Collections.Generic;
using System.Linq;
using WireMock.ResponseBuilders;
using WireMock.Types;

View File

@@ -1,4 +1,6 @@
using JetBrains.Annotations;
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using JetBrains.Annotations;
using System.Threading.Tasks;
using WireMock.Settings;

View File

@@ -2,9 +2,8 @@
using WireMock.Admin.Mappings;
using WireMock.Admin.Requests;
using WireMock.Logging;
using WireMock.Types;
using WireMock.ResponseBuilders;
using WireMock.Util;
using WireMock.Types;
namespace WireMock.Serialization
{
@@ -20,6 +19,7 @@ namespace WireMock.Serialization
AbsolutePath = logEntry.RequestMessage.AbsolutePath,
Url = logEntry.RequestMessage.Url,
AbsoluteUrl = logEntry.RequestMessage.AbsoluteUrl,
ProxyUrl = logEntry.RequestMessage.ProxyUrl,
Query = logEntry.RequestMessage.Query,
Method = logEntry.RequestMessage.Method,
Headers = logEntry.RequestMessage.Headers,

View File

@@ -1,4 +1,6 @@
using System;
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using System;
using WireMock.Matchers.Request;
using WireMock.ResponseProviders;
using WireMock.Settings;

View File

@@ -275,7 +275,13 @@ 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, !settings.DisableJsonBodyParsing.GetValueOrDefault(false));
var responseMessage = await HttpClientHelper.SendAsync(
_httpClientForProxy,
requestMessage,
proxyUriWithRequestPathAndQuery.AbsoluteUri,
!settings.DisableJsonBodyParsing.GetValueOrDefault(false),
!settings.DisableRequestBodyDecompressing.GetValueOrDefault(false)
);
if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
(settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile))

View File

@@ -1,11 +1,13 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using JetBrains.Annotations;
using Newtonsoft.Json;
using WireMock.Admin.Mappings;
using WireMock.Exceptions;
using WireMock.Handlers;
@@ -17,7 +19,6 @@ using WireMock.RequestBuilders;
using WireMock.ResponseProviders;
using WireMock.Serialization;
using WireMock.Settings;
using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Server

View File

@@ -1,155 +1,161 @@
using System;
using HandlebarsDotNet;
using JetBrains.Annotations;
using WireMock.Handlers;
using WireMock.Logging;
namespace WireMock.Settings
{
/// <summary>
/// IWireMockServerSettings
/// </summary>
public interface IWireMockServerSettings
{
/// <summary>
/// Gets or sets the port.
/// </summary>
[PublicAPI]
int? Port { get; set; }
/// <summary>
/// Gets or sets the use SSL.
/// </summary>
// ReSharper disable once InconsistentNaming
[PublicAPI]
bool? UseSSL { get; set; }
/// <summary>
/// Gets or sets whether to start admin interface.
/// </summary>
[PublicAPI]
bool? StartAdminInterface { get; set; }
/// <summary>
/// Gets or sets if the static mappings should be read at startup.
/// </summary>
[PublicAPI]
bool? ReadStaticMappings { get; set; }
/// <summary>
/// Watch the static mapping files + folder for changes when running.
/// </summary>
[PublicAPI]
bool? WatchStaticMappings { get; set; }
/// <summary>
/// A value indicating whether subdirectories within the static mappings path should be monitored.
/// </summary>
[PublicAPI]
bool? WatchStaticMappingsInSubdirectories { get; set; }
/// <summary>
/// Gets or sets if the proxy and record settings.
/// </summary>
[PublicAPI]
IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
/// <summary>
/// Gets or sets the urls.
/// </summary>
[PublicAPI]
string[] Urls { get; set; }
/// <summary>
/// StartTimeout
/// </summary>
[PublicAPI]
int StartTimeout { get; set; }
/// <summary>
/// Allow Partial Mapping (default set to false).
/// </summary>
[PublicAPI]
bool? AllowPartialMapping { get; set; }
/// <summary>
/// The username needed for __admin access.
/// </summary>
[PublicAPI]
string AdminUsername { get; set; }
/// <summary>
/// The password needed for __admin access.
/// </summary>
[PublicAPI]
string AdminPassword { get; set; }
/// <summary>
/// The RequestLog expiration in hours (optional).
/// </summary>
[PublicAPI]
int? RequestLogExpirationDuration { get; set; }
/// <summary>
/// The MaxRequestLog count (optional).
/// </summary>
[PublicAPI]
int? MaxRequestLogCount { get; set; }
/// <summary>
/// Action which is called (with the IAppBuilder or IApplicationBuilder) before the internal WireMockMiddleware is initialized. [Optional]
/// </summary>
[PublicAPI]
Action<object> PreWireMockMiddlewareInit { get; set; }
/// <summary>
/// Action which is called (with the IAppBuilder or IApplicationBuilder) after the internal WireMockMiddleware is initialized. [Optional]
/// </summary>
[PublicAPI]
Action<object> PostWireMockMiddlewareInit { get; set; }
/// <summary>
/// The IWireMockLogger which logs Debug, Info, Warning or Error
/// </summary>
[PublicAPI]
IWireMockLogger Logger { get; set; }
/// <summary>
/// Handler to interact with the file system to read and write static mapping files.
/// </summary>
[PublicAPI]
IFileSystemHandler FileSystemHandler { get; set; }
/// <summary>
/// Action which can be used to add additional Handlebars registrations. [Optional]
/// </summary>
[PublicAPI]
Action<IHandlebars, IFileSystemHandler> HandlebarsRegistrationCallback { get; set; }
/// <summary>
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
/// </summary>
[PublicAPI]
bool? AllowCSharpCodeMatcher { get; set; }
/// <summary>
/// Allow a Body for all HTTP Methods. (default set to false).
/// </summary>
[PublicAPI]
bool? AllowBodyForAllHttpMethods { get; set; }
/// <summary>
/// Allow only a HttpStatus Code in the response which is defined. (default set to false).
/// - false : also null, 0, empty or invalid HttpStatus codes are allowed.
/// - true : only codes defined in <see cref="System.Net.HttpStatusCode"/> are allowed.
/// </summary>
/// [PublicAPI]
bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
/// <summary>
/// Set to true to disable Json deserialization when processing requests. (default set to false).
/// </summary>
[PublicAPI]
bool? DisableJsonBodyParsing { get; set; }
}
using System;
using HandlebarsDotNet;
using JetBrains.Annotations;
using WireMock.Handlers;
using WireMock.Logging;
namespace WireMock.Settings
{
/// <summary>
/// IWireMockServerSettings
/// </summary>
public interface IWireMockServerSettings
{
/// <summary>
/// Gets or sets the port.
/// </summary>
[PublicAPI]
int? Port { get; set; }
/// <summary>
/// Gets or sets the use SSL.
/// </summary>
// ReSharper disable once InconsistentNaming
[PublicAPI]
bool? UseSSL { get; set; }
/// <summary>
/// Gets or sets whether to start admin interface.
/// </summary>
[PublicAPI]
bool? StartAdminInterface { get; set; }
/// <summary>
/// Gets or sets if the static mappings should be read at startup.
/// </summary>
[PublicAPI]
bool? ReadStaticMappings { get; set; }
/// <summary>
/// Watch the static mapping files + folder for changes when running.
/// </summary>
[PublicAPI]
bool? WatchStaticMappings { get; set; }
/// <summary>
/// A value indicating whether subdirectories within the static mappings path should be monitored.
/// </summary>
[PublicAPI]
bool? WatchStaticMappingsInSubdirectories { get; set; }
/// <summary>
/// Gets or sets if the proxy and record settings.
/// </summary>
[PublicAPI]
IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
/// <summary>
/// Gets or sets the urls.
/// </summary>
[PublicAPI]
string[] Urls { get; set; }
/// <summary>
/// StartTimeout
/// </summary>
[PublicAPI]
int StartTimeout { get; set; }
/// <summary>
/// Allow Partial Mapping (default set to false).
/// </summary>
[PublicAPI]
bool? AllowPartialMapping { get; set; }
/// <summary>
/// The username needed for __admin access.
/// </summary>
[PublicAPI]
string AdminUsername { get; set; }
/// <summary>
/// The password needed for __admin access.
/// </summary>
[PublicAPI]
string AdminPassword { get; set; }
/// <summary>
/// The RequestLog expiration in hours (optional).
/// </summary>
[PublicAPI]
int? RequestLogExpirationDuration { get; set; }
/// <summary>
/// The MaxRequestLog count (optional).
/// </summary>
[PublicAPI]
int? MaxRequestLogCount { get; set; }
/// <summary>
/// Action which is called (with the IAppBuilder or IApplicationBuilder) before the internal WireMockMiddleware is initialized. [Optional]
/// </summary>
[PublicAPI]
Action<object> PreWireMockMiddlewareInit { get; set; }
/// <summary>
/// Action which is called (with the IAppBuilder or IApplicationBuilder) after the internal WireMockMiddleware is initialized. [Optional]
/// </summary>
[PublicAPI]
Action<object> PostWireMockMiddlewareInit { get; set; }
/// <summary>
/// The IWireMockLogger which logs Debug, Info, Warning or Error
/// </summary>
[PublicAPI]
IWireMockLogger Logger { get; set; }
/// <summary>
/// Handler to interact with the file system to read and write static mapping files.
/// </summary>
[PublicAPI]
IFileSystemHandler FileSystemHandler { get; set; }
/// <summary>
/// Action which can be used to add additional Handlebars registrations. [Optional]
/// </summary>
[PublicAPI]
Action<IHandlebars, IFileSystemHandler> HandlebarsRegistrationCallback { get; set; }
/// <summary>
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
/// </summary>
[PublicAPI]
bool? AllowCSharpCodeMatcher { get; set; }
/// <summary>
/// Allow a Body for all HTTP Methods. (default set to false).
/// </summary>
[PublicAPI]
bool? AllowBodyForAllHttpMethods { get; set; }
/// <summary>
/// Allow only a HttpStatus Code in the response which is defined. (default set to false).
/// - false : also null, 0, empty or invalid HttpStatus codes are allowed.
/// - true : only codes defined in <see cref="System.Net.HttpStatusCode"/> are allowed.
/// </summary>
/// [PublicAPI]
bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
/// <summary>
/// Set to true to disable Json deserialization when processing requests. (default set to false).
/// </summary>
[PublicAPI]
bool? DisableJsonBodyParsing { get; set; }
/// <summary>
/// Disable support for GZip and Deflate request body decompression. (default set to false).
/// </summary>
[PublicAPI]
bool? DisableRequestBodyDecompressing { get; set; }
}
}

View File

@@ -103,10 +103,15 @@ namespace WireMock.Settings
public bool? AllowBodyForAllHttpMethods { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>
[PublicAPI]
public bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.DisableJsonBodyParsing"/>
[PublicAPI]
public bool? DisableJsonBodyParsing { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.DisableRequestBodyDecompressing"/>
[PublicAPI]
public bool? DisableRequestBodyDecompressing { get; set; }
}
}

View File

@@ -5,7 +5,7 @@ using WireMock.Validation;
namespace WireMock.Transformers
{
internal static class HandleBarsFile
internal static class HandlebarsFile
{
public static void Register(IHandlebars handlebarsContext, IFileSystemHandler fileSystemHandler)
{

View File

@@ -1,25 +0,0 @@
using HandlebarsDotNet;
using WireMock.Handlers;
namespace WireMock.Transformers
{
internal static class HandlebarsHelpers
{
public static void Register(IHandlebars handlebarsContext, IFileSystemHandler fileSystemHandler)
{
HandleBarsRegex.Register(handlebarsContext);
HandleBarsJsonPath.Register(handlebarsContext);
HandleBarsLinq.Register(handlebarsContext);
HandleBarsRandom.Register(handlebarsContext);
HandleBarsXeger.Register(handlebarsContext);
HandleBarsXPath.Register(handlebarsContext);
HandleBarsFile.Register(handlebarsContext, fileSystemHandler);
}
}
}

View File

@@ -9,7 +9,7 @@ using WireMock.Validation;
namespace WireMock.Transformers
{
internal static class HandleBarsJsonPath
internal static class HandlebarsJsonPath
{
public static void Register(IHandlebars handlebarsContext)
{

View File

@@ -9,7 +9,7 @@ using WireMock.Validation;
namespace WireMock.Transformers
{
internal static class HandleBarsLinq
internal static class HandlebarsLinq
{
public static void Register(IHandlebars handlebarsContext)
{

View File

@@ -11,7 +11,7 @@ using WireMock.Validation;
namespace WireMock.Transformers
{
internal static class HandleBarsRandom
internal static class HandlebarsRandom
{
public static void Register(IHandlebars handlebarsContext)
{

View File

@@ -7,7 +7,7 @@ using WireMock.Validation;
namespace WireMock.Transformers
{
internal static class HandleBarsRegex
internal static class HandlebarsRegex
{
public static void Register(IHandlebars handlebarsContext)
{

View File

@@ -10,7 +10,7 @@ using Wmhelp.XPath2;
namespace WireMock.Transformers
{
internal static class HandleBarsXPath
internal static class HandlebarsXPath
{
public static void Register(IHandlebars handlebarsContext)
{

View File

@@ -5,7 +5,7 @@ using WireMock.Validation;
namespace WireMock.Transformers
{
internal static class HandleBarsXeger
internal static class HandlebarsXeger
{
public static void Register(IHandlebars handlebarsContext)
{

View File

@@ -24,7 +24,7 @@ namespace WireMock.Transformers
{
var handlebars = Handlebars.Create(HandlebarsConfiguration);
HandlebarsHelpers.Register(handlebars, _fileSystemHandler);
WireMockHandlebarsHelpers.Register(handlebars, _fileSystemHandler);
_action?.Invoke(handlebars, _fileSystemHandler);

View File

@@ -1,233 +1,236 @@
using HandlebarsDotNet;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using WireMock.Types;
using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Transformers
{
internal class ResponseMessageTransformer
{
private readonly IHandlebarsContextFactory _factory;
public ResponseMessageTransformer([NotNull] IHandlebarsContextFactory factory)
{
Check.NotNull(factory, nameof(factory));
_factory = factory;
}
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
{
var handlebarsContext = _factory.Create();
var responseMessage = new ResponseMessage();
var template = new { request = requestMessage };
switch (original.BodyData?.DetectedBodyType)
{
case BodyType.Json:
TransformBodyAsJson(handlebarsContext.Handlebars, template, original, responseMessage);
break;
case BodyType.File:
TransformBodyAsFile(handlebarsContext, template, original, responseMessage, useTransformerForBodyAsFile);
break;
case BodyType.String:
responseMessage.BodyOriginal = original.BodyData.BodyAsString;
TransformBodyAsString(handlebarsContext.Handlebars, template, original, responseMessage);
break;
}
responseMessage.FaultType = original.FaultType;
responseMessage.FaultPercentage = original.FaultPercentage;
// Headers
var newHeaders = new Dictionary<string, WireMockList<string>>();
foreach (var header in original.Headers)
{
var templateHeaderKey = handlebarsContext.Handlebars.Compile(header.Key);
var templateHeaderValues = header.Value
.Select(handlebarsContext.Handlebars.Compile)
.Select(func => func(template))
.ToArray();
newHeaders.Add(templateHeaderKey(template), new WireMockList<string>(templateHeaderValues));
}
responseMessage.Headers = newHeaders;
switch (original.StatusCode)
{
case int statusCodeAsInteger:
responseMessage.StatusCode = statusCodeAsInteger;
break;
case string statusCodeAsString:
var templateForStatusCode = handlebarsContext.Handlebars.Compile(statusCodeAsString);
responseMessage.StatusCode = templateForStatusCode(template);
break;
}
return responseMessage;
}
private static void TransformBodyAsJson(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{
JToken jToken;
switch (original.BodyData.BodyAsJson)
{
case JObject bodyAsJObject:
jToken = bodyAsJObject.DeepClone();
WalkNode(handlebarsContext, jToken, template);
break;
case Array bodyAsArray:
jToken = JArray.FromObject(bodyAsArray);
WalkNode(handlebarsContext, jToken, template);
break;
case string bodyAsString:
jToken = ReplaceSingleNode(handlebarsContext, bodyAsString, template);
break;
default:
jToken = JObject.FromObject(original.BodyData.BodyAsJson);
WalkNode(handlebarsContext, jToken, template);
break;
}
responseMessage.BodyData = new BodyData
{
DetectedBodyType = original.BodyData.DetectedBodyType,
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
BodyAsJson = jToken
};
}
private static JToken ReplaceSingleNode(IHandlebars handlebarsContext, string stringValue, object context)
{
var templateForStringValue = handlebarsContext.Compile(stringValue);
string transformedString = templateForStringValue(context);
if (!string.Equals(stringValue, transformedString))
{
const string property = "_";
JObject dummy = JObject.Parse($"{{ \"{property}\": null }}");
JToken node = dummy[property];
ReplaceNodeValue(node, transformedString);
return dummy[property];
}
return stringValue;
}
private static void WalkNode(IHandlebars handlebarsContext, JToken node, object context)
{
if (node.Type == JTokenType.Object)
{
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
foreach (JProperty child in node.Children<JProperty>().ToArray())
{
WalkNode(handlebarsContext, child.Value, context);
}
}
else if (node.Type == JTokenType.Array)
{
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
foreach (JToken child in node.Children().ToArray())
{
WalkNode(handlebarsContext, child, context);
}
}
else if (node.Type == JTokenType.String)
{
// In case of string, try to transform the value.
string stringValue = node.Value<string>();
if (string.IsNullOrEmpty(stringValue))
{
return;
}
var templateForStringValue = handlebarsContext.Compile(stringValue);
string transformedString = templateForStringValue(context);
if (!string.Equals(stringValue, transformedString))
{
ReplaceNodeValue(node, transformedString);
}
}
}
private static void ReplaceNodeValue(JToken node, string stringValue)
{
if (bool.TryParse(stringValue, out bool valueAsBoolean))
{
node.Replace(valueAsBoolean);
return;
}
JToken value;
try
{
// Try to convert this string into a JsonObject
value = JToken.Parse(stringValue);
}
catch (JsonException)
{
// Ignore JsonException and just keep string value and convert to JToken
value = stringValue;
}
node.Replace(value);
}
private static void TransformBodyAsString(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{
var templateBodyAsString = handlebarsContext.Compile(original.BodyData.BodyAsString);
responseMessage.BodyData = new BodyData
{
DetectedBodyType = original.BodyData.DetectedBodyType,
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
BodyAsString = templateBodyAsString(template)
};
}
private void TransformBodyAsFile(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage, bool useTransformerForBodyAsFile)
{
var templateBodyAsFile = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsFile);
string transformedBodyAsFilename = templateBodyAsFile(template);
if (!useTransformerForBodyAsFile)
{
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
};
}
}
}
using HandlebarsDotNet;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WireMock.Types;
using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Transformers
{
internal class ResponseMessageTransformer
{
private readonly IHandlebarsContextFactory _factory;
public ResponseMessageTransformer([NotNull] IHandlebarsContextFactory factory)
{
Check.NotNull(factory, nameof(factory));
_factory = factory;
}
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
{
var handlebarsContext = _factory.Create();
var responseMessage = new ResponseMessage();
var template = new { request = requestMessage };
switch (original.BodyData?.DetectedBodyType)
{
case BodyType.Json:
TransformBodyAsJson(handlebarsContext.Handlebars, template, original, responseMessage);
break;
case BodyType.File:
TransformBodyAsFile(handlebarsContext, template, original, responseMessage, useTransformerForBodyAsFile);
break;
case BodyType.String:
responseMessage.BodyOriginal = original.BodyData.BodyAsString;
TransformBodyAsString(handlebarsContext.Handlebars, template, original, responseMessage);
break;
}
responseMessage.FaultType = original.FaultType;
responseMessage.FaultPercentage = original.FaultPercentage;
// Headers
var newHeaders = new Dictionary<string, WireMockList<string>>();
foreach (var header in original.Headers)
{
var templateHeaderKey = handlebarsContext.Handlebars.Compile(header.Key);
var templateHeaderValues = header.Value
.Select(handlebarsContext.Handlebars.Compile)
.Select(func => func(template))
.ToArray();
newHeaders.Add(templateHeaderKey(template), new WireMockList<string>(templateHeaderValues));
}
responseMessage.Headers = newHeaders;
switch (original.StatusCode)
{
case int statusCodeAsInteger:
responseMessage.StatusCode = statusCodeAsInteger;
break;
case string statusCodeAsString:
var templateForStatusCode = handlebarsContext.Handlebars.Compile(statusCodeAsString);
responseMessage.StatusCode = templateForStatusCode(template);
break;
}
return responseMessage;
}
private static void TransformBodyAsJson(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{
JToken jToken;
switch (original.BodyData.BodyAsJson)
{
case JObject bodyAsJObject:
jToken = bodyAsJObject.DeepClone();
WalkNode(handlebarsContext, jToken, template);
break;
case Array bodyAsArray:
jToken = JArray.FromObject(bodyAsArray);
WalkNode(handlebarsContext, jToken, template);
break;
case string bodyAsString:
jToken = ReplaceSingleNode(handlebarsContext, bodyAsString, template);
break;
default:
jToken = JObject.FromObject(original.BodyData.BodyAsJson);
WalkNode(handlebarsContext, jToken, template);
break;
}
responseMessage.BodyData = new BodyData
{
Encoding = original.BodyData.Encoding,
DetectedBodyType = original.BodyData.DetectedBodyType,
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
BodyAsJson = jToken
};
}
private static JToken ReplaceSingleNode(IHandlebars handlebarsContext, string stringValue, object context)
{
var templateForStringValue = handlebarsContext.Compile(stringValue);
string transformedString = templateForStringValue(context);
if (!string.Equals(stringValue, transformedString))
{
const string property = "_";
JObject dummy = JObject.Parse($"{{ \"{property}\": null }}");
JToken node = dummy[property];
ReplaceNodeValue(node, transformedString);
return dummy[property];
}
return stringValue;
}
private static void WalkNode(IHandlebars handlebarsContext, JToken node, object context)
{
if (node.Type == JTokenType.Object)
{
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
foreach (JProperty child in node.Children<JProperty>().ToArray())
{
WalkNode(handlebarsContext, child.Value, context);
}
}
else if (node.Type == JTokenType.Array)
{
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
foreach (JToken child in node.Children().ToArray())
{
WalkNode(handlebarsContext, child, context);
}
}
else if (node.Type == JTokenType.String)
{
// In case of string, try to transform the value.
string stringValue = node.Value<string>();
if (string.IsNullOrEmpty(stringValue))
{
return;
}
var templateForStringValue = handlebarsContext.Compile(stringValue);
string transformedString = templateForStringValue(context);
if (!string.Equals(stringValue, transformedString))
{
ReplaceNodeValue(node, transformedString);
}
}
}
private static void ReplaceNodeValue(JToken node, string stringValue)
{
if (bool.TryParse(stringValue, out bool valueAsBoolean))
{
node.Replace(valueAsBoolean);
return;
}
JToken value;
try
{
// Try to convert this string into a JsonObject
value = JToken.Parse(stringValue);
}
catch (JsonException)
{
// Ignore JsonException and just keep string value and convert to JToken
value = stringValue;
}
node.Replace(value);
}
private static void TransformBodyAsString(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{
var templateBodyAsString = handlebarsContext.Compile(original.BodyData.BodyAsString);
responseMessage.BodyData = new BodyData
{
Encoding = original.BodyData.Encoding,
DetectedBodyType = original.BodyData.DetectedBodyType,
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
BodyAsString = templateBodyAsString(template)
};
}
private void TransformBodyAsFile(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage, bool useTransformerForBodyAsFile)
{
var templateBodyAsFile = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsFile);
string transformedBodyAsFilename = templateBodyAsFile(template);
if (!useTransformerForBodyAsFile)
{
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
};
}
}
}
}

View File

@@ -0,0 +1,30 @@
using HandlebarsDotNet;
using HandlebarsDotNet.Helpers;
using WireMock.Handlers;
namespace WireMock.Transformers
{
internal static class WireMockHandlebarsHelpers
{
public static void Register(IHandlebars handlebarsContext, IFileSystemHandler fileSystemHandler)
{
// Register https://github.com/StefH/Handlebars.Net.Helpers
HandlebarsHelpers.Register(handlebarsContext);
// Register WireMock.Net specific helpers
HandlebarsRegex.Register(handlebarsContext);
HandlebarsJsonPath.Register(handlebarsContext);
HandlebarsLinq.Register(handlebarsContext);
HandlebarsRandom.Register(handlebarsContext);
HandlebarsXeger.Register(handlebarsContext);
HandlebarsXPath.Register(handlebarsContext);
HandlebarsFile.Register(handlebarsContext, fileSystemHandler);
}
}
}

View File

@@ -52,5 +52,10 @@ namespace WireMock.Util
/// The detected body type (detection based on Content-Type).
/// </summary>
public BodyType DetectedBodyTypeFromContentType { get; set; }
/// <summary>
/// The detected compression.
/// </summary>
public string DetectedCompression { get; set; }
}
}

View File

@@ -5,7 +5,6 @@ using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Newtonsoft.Json;
using WireMock.Http;
using WireMock.Matchers;
using WireMock.Types;
@@ -108,15 +107,17 @@ namespace WireMock.Util
return BodyType.Bytes;
}
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType = null, bool deserializeJson = true)
public static async Task<BodyData> Parse([NotNull] BodyParserSettings settings)
{
Check.NotNull(stream, nameof(stream));
Check.NotNull(settings, nameof(settings));
var bodyWithContentEncoding = await ReadBytesAsync(settings.Stream, settings.ContentEncoding, settings.DecompressGZipAndDeflate);
var data = new BodyData
{
BodyAsBytes = await ReadBytesAsync(stream),
BodyAsBytes = bodyWithContentEncoding.Value,
DetectedCompression = bodyWithContentEncoding.Key,
DetectedBodyType = BodyType.Bytes,
DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(contentType)
DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(settings.ContentType)
};
// In case of MultiPart: check if the BodyAsBytes is a valid UTF8 or ASCII string, in that case read as String else keep as-is
@@ -129,7 +130,7 @@ namespace WireMock.Util
data.Encoding = encoding;
data.DetectedBodyType = BodyType.String;
}
return data;
}
@@ -141,7 +142,7 @@ namespace WireMock.Util
data.DetectedBodyType = BodyType.String;
// If string is not null or empty, try to deserialize the string to a JObject
if (deserializeJson && !string.IsNullOrEmpty(data.BodyAsString))
if (settings.DeserializeJson && !string.IsNullOrEmpty(data.BodyAsString))
{
try
{
@@ -161,12 +162,21 @@ namespace WireMock.Util
return data;
}
private static async Task<byte[]> ReadBytesAsync(Stream stream)
private static async Task<KeyValuePair<string, byte[]>> ReadBytesAsync(Stream stream, string contentEncoding = null, bool decompressGZipAndDeflate = true)
{
using (var memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
return memoryStream.ToArray();
byte[] data = memoryStream.ToArray();
string type = contentEncoding?.ToLowerInvariant();
if (decompressGZipAndDeflate && (type == "gzip" || type == "deflate"))
{
return new KeyValuePair<string, byte[]>(type, CompressionUtils.Decompress(type, data));
}
return new KeyValuePair<string, byte[]>(null, data);
}
}
}

View File

@@ -0,0 +1,17 @@
using System.IO;
namespace WireMock.Util
{
internal class BodyParserSettings
{
public Stream Stream { get; set; }
public string ContentType { get; set; }
public string ContentEncoding { get; set; }
public bool DecompressGZipAndDeflate { get; set; } = true;
public bool DeserializeJson { get; set; } = true;
}
}

View File

@@ -1,29 +0,0 @@
using FastDeepCloner;
using System;
using System.Runtime.Serialization;
namespace WireMock.Util
{
internal static class CloneUtils
{
private static FastDeepClonerSettings settings = new FastDeepCloner.FastDeepClonerSettings()
{
FieldType = FastDeepCloner.FieldType.FieldInfo,
OnCreateInstance = new FastDeepCloner.Extensions.CreateInstance((Type type) =>
{
#if !NETSTANDARD1_3
return FormatterServices.GetUninitializedObject(type);
#else
#endif
})
};
public static T DeepClone<T>(T objectToBeCloned) where T : class
{
//return CloneExtensionsEx.CloneFactory.GetClone(objectToBeCloned);
// Expression.Lambda<Func<object>>(Expression.New(type)).Compile()
return FastDeepCloner.DeepCloner.Clone(objectToBeCloned, settings);
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.IO;
using System.IO.Compression;
namespace WireMock.Util
{
internal static class CompressionUtils
{
public static byte[] Compress(string contentEncoding, byte[] data)
{
using (var compressedStream = new MemoryStream())
using (var zipStream = Create(contentEncoding, compressedStream, CompressionMode.Compress))
{
zipStream.Write(data, 0, data.Length);
#if !NETSTANDARD1_3
zipStream.Close();
#endif
return compressedStream.ToArray();
}
}
public static byte[] Decompress(string contentEncoding, byte[] data)
{
using (var compressedStream = new MemoryStream(data))
using (var zipStream = Create(contentEncoding, compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{
zipStream.CopyTo(resultStream);
return resultStream.ToArray();
}
}
private static Stream Create(string contentEncoding, Stream stream, CompressionMode mode)
{
switch (contentEncoding)
{
case "gzip":
return new GZipStream(stream, mode);
case "deflate":
return new DeflateStream(stream, mode);
default:
throw new NotSupportedException($"ContentEncoding '{contentEncoding}' is not supported.");
}
}
}
}

View File

@@ -1,26 +0,0 @@
using System.Collections.Generic;
using System.Linq;
namespace WireMock.Util
{
public class IndexableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
/// <summary>
/// Gets the value associated with the specified index.
/// </summary>
/// <param name="index"> The index of the value to get.</param>
/// <returns>The value associated with the specified index.</returns>
public TValue this[int index]
{
get
{
// get the item for that index.
if (index < 0 || index > Count)
{
throw new KeyNotFoundException();
}
return Values.Cast<TValue>().ToArray()[index];
}
}
}
}

View File

@@ -1,80 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace WireMock.Util
{
/// <summary>
/// http://johnculviner.com/achieving-named-lock-locker-functionality-in-c-4-0/
/// </summary>
internal class NamedReaderWriterLocker
{
private readonly ConcurrentDictionary<string, ReaderWriterLockSlim> _lockDict = new ConcurrentDictionary<string, ReaderWriterLockSlim>();
public ReaderWriterLockSlim GetLock(string name)
{
return _lockDict.GetOrAdd(name, s => new ReaderWriterLockSlim());
}
public TResult RunWithReadLock<TResult>(string name, Func<TResult> body)
{
var rwLock = GetLock(name);
try
{
rwLock.EnterReadLock();
return body();
}
finally
{
rwLock.ExitReadLock();
}
}
public void RunWithReadLock(string name, Action body)
{
var rwLock = GetLock(name);
try
{
rwLock.EnterReadLock();
body();
}
finally
{
rwLock.ExitReadLock();
}
}
public TResult RunWithWriteLock<TResult>(string name, Func<TResult> body)
{
var rwLock = GetLock(name);
try
{
rwLock.EnterWriteLock();
return body();
}
finally
{
rwLock.ExitWriteLock();
}
}
public void RunWithWriteLock(string name, Action body)
{
var rwLock = GetLock(name);
try
{
rwLock.EnterWriteLock();
body();
}
finally
{
rwLock.ExitWriteLock();
}
}
public void RemoveLock(string name)
{
_lockDict.TryRemove(name, out _);
}
}
}

View File

@@ -16,7 +16,7 @@ namespace WireMock.Validation
internal static class Check
{
[ContractAnnotation("value:null => halt")]
public static T Condition<T>([NoEnumeration] T value, [NotNull] Predicate<T> condition, [InvokerParameterName] [NotNull] string parameterName)
public static T Condition<T>([NoEnumeration] T value, [ValidatedNotNull, NotNull] Predicate<T> condition, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
{
NotNull(condition, nameof(condition));
NotNull(value, nameof(value));
@@ -32,7 +32,7 @@ namespace WireMock.Validation
}
[ContractAnnotation("value:null => halt")]
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName)
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
{
if (ReferenceEquals(value, null))
{
@@ -45,7 +45,7 @@ namespace WireMock.Validation
}
[ContractAnnotation("value:null => halt")]
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName, [NotNull] string propertyName)
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName, [ValidatedNotNull, NotNull] string propertyName)
{
if (ReferenceEquals(value, null))
{
@@ -59,7 +59,7 @@ namespace WireMock.Validation
}
[ContractAnnotation("value:null => halt")]
public static IList<T> NotNullOrEmpty<T>(IList<T> value, [InvokerParameterName] [NotNull] string parameterName)
public static IList<T> NotNullOrEmpty<T>(IList<T> value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
{
NotNull(value, parameterName);
@@ -74,7 +74,7 @@ namespace WireMock.Validation
}
[ContractAnnotation("value:null => halt")]
public static string NotNullOrEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
public static string NotNullOrEmpty(string value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
{
Exception e = null;
if (ReferenceEquals(value, null))
@@ -96,20 +96,20 @@ namespace WireMock.Validation
return value;
}
public static string NullButNotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
{
if (!ReferenceEquals(value, null)
&& (value.Length == 0))
{
NotNullOrEmpty(parameterName, nameof(parameterName));
//public static string NullButNotEmpty(string value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
//{
// if (!ReferenceEquals(value, null)
// && (value.Length == 0))
// {
// NotNullOrEmpty(parameterName, nameof(parameterName));
throw new ArgumentException(CoreStrings.ArgumentIsEmpty(parameterName));
}
// throw new ArgumentException(CoreStrings.ArgumentIsEmpty(parameterName));
// }
return value;
}
// return value;
//}
public static IList<T> HasNoNulls<T>(IList<T> value, [InvokerParameterName] [NotNull] string parameterName)
public static IList<T> HasNoNulls<T>(IList<T> value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
where T : class
{
NotNull(value, parameterName);
@@ -124,16 +124,16 @@ namespace WireMock.Validation
return value;
}
public static Type ValidEntityType(Type value, [InvokerParameterName] [NotNull] string parameterName)
{
if (!value.GetTypeInfo().IsClass)
{
NotNullOrEmpty(parameterName, nameof(parameterName));
//public static Type ValidEntityType(Type value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
//{
// if (!value.GetTypeInfo().IsClass)
// {
// NotNullOrEmpty(parameterName, nameof(parameterName));
throw new ArgumentException(CoreStrings.InvalidEntityType(value, parameterName));
}
// throw new ArgumentException(CoreStrings.InvalidEntityType(value, parameterName));
// }
return value;
}
// return value;
//}
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace WireMock.Validation
{
/// <summary>
/// To fix 'xxx' is null on at least one execution path. See also https://rules.sonarsource.com/csharp/RSPEC-3900.
/// </summary>
internal class ValidatedNotNullAttribute : Attribute
{
}
}

View File

@@ -3,28 +3,17 @@
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
<AssemblyTitle>WireMock.Net</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<!--<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netcoreapp2.1</TargetFrameworks>-->
<!--<TargetFrameworks>net451;net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>-->
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;;netstandard2.1</TargetFrameworks>
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net</AssemblyName>
<PackageId>WireMock.Net</PackageId>
<PackageTags>tdd;mock;http;wiremock;test;server;unittest</PackageTags>
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
<RootNamespace>WireMock</RootNamespace>
<!--<DebugType>full</DebugType>
<IncludeSource>True</IncludeSource>
<IncludeSymbols>True</IncludeSymbols>-->
<ProjectGuid>{D3804228-91F4-4502-9595-39584E5A01AD}</ProjectGuid>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<!--<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<!--<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>-->
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>WireMock.Net.snk</AssemblyOriginatorKeyFile>
@@ -36,7 +25,8 @@
<None Include="WireMock.Net-Logo.png" Pack="true" PackagePath="../../"/>
</ItemGroup>-->
<!--https://github.com/aspnet/RoslynCodeDomProvider/issues/51-->
<!-- https://github.com/aspnet/RoslynCodeDomProvider/issues/51 -->
<!-- This is needed else we cannot build net452 in Azure DevOps Pipeline -->
<Target Name="CheckIfShouldKillVBCSCompiler" />
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
@@ -61,33 +51,21 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="Util\CloneUtils.cs" />
<Compile Remove="Util\IndexableDictionary.cs" />
<Compile Remove="Util\NamedReaderWriterLocker.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<!--<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />-->
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.10" />
<PackageReference Include="JmesPath.Net" Version="1.0.125" />
<PackageReference Include="Handlebars.Net.Helpers" Version="1.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug - Sonar'">
<PackageReference Include="SonarAnalyzer.CSharp" Version="7.8.0.7320">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.10" />
<PackageReference Include="JmesPath.Net" Version="1.0.125" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
<PackageReference Include="Handlebars.Net" Version="[1.9.0]" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'net451' ">
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard1.3' ">

View File

@@ -0,0 +1,44 @@
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using WireMock.Http;
using Xunit;
namespace WireMock.Net.Tests.Http
{
public class ByteArrayContentHelperTests
{
[Fact]
public async Task ByteArrayContentHelperTests_Create_WithNullContentType()
{
// Arrange
var content = Encoding.UTF8.GetBytes("test");
// Act
var result = ByteArrayContentHelper.Create(content, null);
// Assert
result.Headers.ContentType.Should().BeNull();
(await result.ReadAsByteArrayAsync()).Should().BeEquivalentTo(content);
}
[Theory]
[InlineData("application/octet-stream", "application/octet-stream")]
[InlineData("application/soap+xml", "application/soap+xml")]
[InlineData("multipart/form-data; boundary=------------------------x", "multipart/form-data; boundary=------------------------x")]
public async Task ByteArrayContentHelperTests_Create(string test, string expected)
{
// Arrange
var content = Encoding.UTF8.GetBytes("test");
var contentType = MediaTypeHeaderValue.Parse(test);
// Act
var result = ByteArrayContentHelper.Create(content, contentType);
// Assert
result.Headers.ContentType.ToString().Should().Be(expected);
(await result.ReadAsByteArrayAsync()).Should().BeEquivalentTo(content);
}
}
}

View File

@@ -243,18 +243,36 @@ namespace WireMock.Net.Tests.RequestMatchers
// assign
BodyData bodyData;
if (body is byte[] b)
bodyData = await BodyParser.Parse(new MemoryStream(b), null, true);
{
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(b),
ContentType = null,
DeserializeJson = true
};
bodyData = await BodyParser.Parse(bodyParserSettings);
}
else if (body is string s)
bodyData = await BodyParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(s)), null, true);
{
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(Encoding.UTF8.GetBytes(s)),
ContentType = null,
DeserializeJson = true
};
bodyData = await BodyParser.Parse(bodyParserSettings);
}
else
{
throw new Exception();
}
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", bodyData);
// act
var result = new RequestMatchResult();
var score = matcher.GetMatchingScore(requestMessage, result);
// assert
Check.That(score).IsEqualTo(shouldMatch ? 1d : 0d);
}
@@ -265,7 +283,7 @@ namespace WireMock.Net.Tests.RequestMatchers
{
var json = "{'a':'b'}";
var str = "HelloWorld";
var bytes = new byte[] {0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00};
var bytes = new byte[] { 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00 };
return new TheoryData<object, RequestMessageBodyMatcher, bool>
{

View File

@@ -0,0 +1,36 @@
using System.Threading.Tasks;
using NFluent;
using WireMock.Models;
using WireMock.ResponseBuilders;
using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests.ResponseBuilders
{
public class ResponseWithHandlebarsHelpersTests
{
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
private const string ClientIp = "::1";
[Fact]
public async Task Response_ProvideResponseAsync_HandlebarsHelpers_String_Uppercase()
{
// Assign
var body = new BodyData { BodyAsString = "abc", DetectedBodyType = BodyType.String };
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("{{String.Uppercase request.body}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("ABC");
}
}
}

View File

@@ -1,406 +1,432 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Moq;
using Newtonsoft.Json;
using NFluent;
using WireMock.Handlers;
using WireMock.Models;
using WireMock.ResponseBuilders;
using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;
using Xunit;
#if NET452
using Microsoft.Owin;
#else
using Microsoft.AspNetCore.Http;
#endif
namespace WireMock.Net.Tests.ResponseBuilders
{
public class ResponseWithHandlebarsTests
{
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
private const string ClientIp = "::1";
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithNullBody_ShouldNotThrowException()
{
// Assign
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
var request = new RequestMessage(urlDetails, "GET", ClientIp);
var response = Response.Create()
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
responseMessage.BodyData.Should().BeNull();
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_UrlPathVerb()
{
// Assign
var body = new BodyData
{
BodyAsString = "whatever",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POSt", ClientIp, body);
var response = Response.Create()
.WithBody("test {{request.url}} {{request.path}} {{request.method}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt");
}
[Theory]
[InlineData("Get")]
[InlineData("Post")]
public async Task Response_ProvideResponse_Handlebars_UrlPath(string httpMethod)
{
// Assign
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
var request = new RequestMessage(urlDetails, httpMethod, ClientIp);
var response = Response.Create()
.WithBody("{{request.url}} {{request.absoluteurl}} {{request.path}} {{request.absolutepath}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("http://localhost/a/b http://localhost/wiremock/a/b /a/b /wiremock/a/b");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_PathSegments()
{
// Assign
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
var request = new RequestMessage(urlDetails, "POST", ClientIp);
var response = Response.Create()
.WithBody("{{request.pathsegments.[0]}} {{request.absolutepathsegments.[0]}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("a wiremock");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_Query()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test keya=1 idx=1 idx=2 keyb=5");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_StatusCode()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
var response = Response.Create()
.WithStatusCode("{{request.query.a}}")
.WithBody("test")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.StatusCode).Equals("400");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_StatusCodeIsNull()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("test")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.StatusCode).Equals(null);
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_Header()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}").WithBody("test").WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.Headers).ContainsKey("x");
Check.That(responseMessage.Headers["x"]).ContainsExactly("text/plain");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_Headers()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}", "{{request.url}}").WithBody("test").WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.Headers).ContainsKey("x");
Check.That(responseMessage.Headers["x"]).Contains("text/plain");
Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_Origin_Port_Protocol_Host()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("test {{request.origin}} {{request.port}} {{request.protocol}} {{request.host}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost:1234 1234 http localhost");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsObject()
{
// Assign
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBodyAsJson(new { x = "test {{request.path}}" })
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"x\":\"test /foo_object\"}");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsArray()
{
// Assign
string jsonString = "{ \"a\": \"test 1\", \"b\": \"test 2\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_array"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBodyAsJson(new[] { "first", "{{request.path}}", "{{request.bodyAsJson.a}}", "{{request.bodyAsJson.b}}", "last" })
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("[\"first\",\"/foo_array\",\"test 1\",\"test 2\",\"last\"]");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile()
{
// Assign
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
var response = Response.Create()
.WithTransformer()
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
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>");
_settings.FileSystemHandler = 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, _settings);
// 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()
{
// Assign
string jsonString = "{ \"MyUniqueNumber\": \"1\" }";
var bodyData = new BodyData
{
BodyAsString = jsonString,
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
DetectedBodyTypeFromContentType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
string jsonPath = "\"$.MyUniqueNumber\"";
var response = Response.Create()
.WithTransformer()
.WithBodyFromFile(@"c:\\{{JsonPath.SelectToken request.body " + jsonPath + "}}\\test.json"); // why use a \\ here ?
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.json");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsNormalString()
{
// Assign
string jsonString = "{ \"name\": \"WireMock\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBodyAsJson("test")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("\"test\"");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsHandlebarsString()
{
// Assign
string jsonString = "{ \"name\": \"WireMock\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBodyAsJson("{{{request.bodyAsJson}}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}");
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Moq;
using Newtonsoft.Json;
using NFluent;
using WireMock.Handlers;
using WireMock.Models;
using WireMock.ResponseBuilders;
using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;
using Xunit;
#if NET452
using Microsoft.Owin;
#else
using Microsoft.AspNetCore.Http;
#endif
namespace WireMock.Net.Tests.ResponseBuilders
{
public class ResponseWithHandlebarsTests
{
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
private const string ClientIp = "::1";
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithNullBody_ShouldNotThrowException()
{
// Assign
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
var request = new RequestMessage(urlDetails, "GET", ClientIp);
var response = Response.Create()
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
responseMessage.BodyData.Should().BeNull();
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_UrlPathVerb()
{
// Assign
var body = new BodyData
{
BodyAsString = "whatever",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POSt", ClientIp, body);
var response = Response.Create()
.WithBody("test {{request.url}} {{request.path}} {{request.method}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt");
}
[Theory]
[InlineData("Get")]
[InlineData("Post")]
public async Task Response_ProvideResponse_Handlebars_UrlPath(string httpMethod)
{
// Assign
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
var request = new RequestMessage(urlDetails, httpMethod, ClientIp);
var response = Response.Create()
.WithBody("{{request.url}} {{request.absoluteurl}} {{request.path}} {{request.absolutepath}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("http://localhost/a/b http://localhost/wiremock/a/b /a/b /wiremock/a/b");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_PathSegments()
{
// Assign
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
var request = new RequestMessage(urlDetails, "POST", ClientIp);
var response = Response.Create()
.WithBody("{{request.pathsegments.[0]}} {{request.absolutepathsegments.[0]}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("a wiremock");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_Query()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test keya=1 idx=1 idx=2 keyb=5");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_StatusCode()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
var response = Response.Create()
.WithStatusCode("{{request.query.a}}")
.WithBody("test")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.StatusCode).Equals("400");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_StatusCodeIsNull()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("test")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.StatusCode).Equals(null);
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_Header()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}").WithBody("test").WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.Headers).ContainsKey("x");
Check.That(responseMessage.Headers["x"]).ContainsExactly("text/plain");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_Headers()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}", "{{request.url}}").WithBody("test").WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.Headers).ContainsKey("x");
Check.That(responseMessage.Headers["x"]).Contains("text/plain");
Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_Origin_Port_Protocol_Host()
{
// Assign
var body = new BodyData
{
BodyAsString = "abc",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("test {{request.origin}} {{request.port}} {{request.protocol}} {{request.host}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost:1234 1234 http localhost");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsObject()
{
// Assign
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBodyAsJson(new { x = "test {{request.path}}" })
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"x\":\"test /foo_object\"}");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsArray()
{
// Assign
string jsonString = "{ \"a\": \"test 1\", \"b\": \"test 2\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_array"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBodyAsJson(new[] { "first", "{{request.path}}", "{{request.bodyAsJson.a}}", "{{request.bodyAsJson.b}}", "last" })
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("[\"first\",\"/foo_array\",\"test 1\",\"test 2\",\"last\"]");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile()
{
// Assign
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
var response = Response.Create()
.WithTransformer()
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
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>");
_settings.FileSystemHandler = 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, _settings);
// 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()
{
// Assign
string jsonString = "{ \"MyUniqueNumber\": \"1\" }";
var bodyData = new BodyData
{
BodyAsString = jsonString,
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
DetectedBodyTypeFromContentType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
string jsonPath = "\"$.MyUniqueNumber\"";
var response = Response.Create()
.WithTransformer()
.WithBodyFromFile(@"c:\\{{JsonPath.SelectToken request.body " + jsonPath + "}}\\test.json"); // why use a \\ here ?
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.json");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsNormalString()
{
// Assign
string jsonString = "{ \"name\": \"WireMock\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBodyAsJson("test")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("\"test\"");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsHandlebarsString()
{
// Assign
string jsonString = "{ \"name\": \"WireMock\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBodyAsJson("{{{request.bodyAsJson}}}")
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsString_KeepsEncoding()
{
// Assign
const string text = "my-text";
Encoding enc = Encoding.Unicode;
var bodyData = new BodyData
{
BodyAsString = text,
DetectedBodyType = BodyType.String,
Encoding = enc
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBody("{{request.body}}", BodyDestinationFormat.SameAsSource, enc)
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
responseMessage.BodyData.BodyAsString.Should().Be(text);
responseMessage.BodyData.Encoding.Should().Be(enc);
}
}
}

View File

@@ -16,6 +16,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
{
public class ResponseWithProxyTests : IDisposable
{
private const string ClientIp = "::1";
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
private readonly WireMockServer _server;
private readonly Guid _guid;
@@ -27,21 +28,32 @@ namespace WireMock.Net.Tests.ResponseBuilders
_server = WireMockServer.Start();
_server.Given(Request.Create().UsingPost().WithPath($"/{_guid}"))
.RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 42 }).WithHeader("Content-Type", "application/json"));
_server.Given(Request.Create().UsingPost().WithPath($"/{_guid}/append"))
.RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 10 }).WithHeader("Content-Type", "application/json"));
_server.Given(Request.Create().UsingPost().WithPath($"/prepend/{_guid}"))
.RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 11 }).WithHeader("Content-Type", "application/json"));
_server.Given(Request.Create().UsingPost().WithPath($"/prepend/{_guid}/append"))
.RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 12 }).WithHeader("Content-Type", "application/json"));
}
[Fact]
public async Task Response_WithProxy()
[Theory]
[InlineData("", "", "{\"p\":42}")]
[InlineData("", "/append", "{\"p\":10}")]
[InlineData("/prepend", "", "{\"p\":11}")]
[InlineData("/prepend", "/append", "{\"p\":12}")]
public async Task Response_WithProxy(string prepend, string append, string expectedBody)
{
// Assign
var headers = new Dictionary<string, string[]> { { "Content-Type", new[] { "application/xml" } } };
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "POST", "::1", new BodyData { DetectedBodyType = BodyType.Json, BodyAsJson = new { a = 1 } }, headers);
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}{prepend}/{_guid}{append}"), "POST", ClientIp, new BodyData { DetectedBodyType = BodyType.Json, BodyAsJson = new { a = 1 } }, headers);
var response = Response.Create().WithProxy(_server.Urls[0]);
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo("{\"p\":42}");
Check.That(request.ProxyUrl).IsNotNull();
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo(expectedBody);
Check.That(responseMessage.StatusCode).IsEqualTo(201);
Check.That(responseMessage.Headers["Content-Type"].ToString()).IsEqualTo("application/json");
}
@@ -63,7 +75,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
var response = Response.Create().WithProxy(settings);
// Act
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "GET", "::1");
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "GET", ClientIp);
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws<HttpRequestException>();
}

View File

@@ -1,7 +1,10 @@
using NFluent;
using System;
using NFluent;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using WireMock.Types;
using WireMock.Util;
using Xunit;
@@ -19,10 +22,15 @@ namespace WireMock.Net.Tests.Util
public async Task BodyParser_Parse_ContentTypeJson(string contentType, string bodyAsJson, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
{
// Arrange
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson));
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson)),
ContentType = contentType,
DeserializeJson = true
};
// Act
var body = await BodyParser.Parse(memoryStream, contentType, true);
var body = await BodyParser.Parse(bodyParserSettings);
// Assert
Check.That(body.BodyAsBytes).IsNotNull();
@@ -38,10 +46,15 @@ namespace WireMock.Net.Tests.Util
public async Task BodyParser_Parse_ContentTypeString(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
{
// Arrange
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString)),
ContentType = contentType,
DeserializeJson = true
};
// Act
var body = await BodyParser.Parse(memoryStream, contentType, true);
var body = await BodyParser.Parse(bodyParserSettings);
// Assert
Check.That(body.BodyAsBytes).IsNotNull();
@@ -52,16 +65,21 @@ namespace WireMock.Net.Tests.Util
}
[Theory]
[InlineData(new byte[] {34, 97, 34}, BodyType.Json)]
[InlineData(new byte[] {97}, BodyType.String)]
[InlineData(new byte[] {0xFF, 0xD8, 0xFF, 0xE0}, BodyType.Bytes)]
[InlineData(new byte[] { 34, 97, 34 }, BodyType.Json)]
[InlineData(new byte[] { 97 }, BodyType.String)]
[InlineData(new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 }, BodyType.Bytes)]
public async Task BodyParser_Parse_DetectedBodyType(byte[] content, BodyType detectedBodyType)
{
// arrange
var memoryStream = new MemoryStream(content);
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(content),
ContentType = null,
DeserializeJson = true
};
// act
var body = await BodyParser.Parse(memoryStream, null, true);
var body = await BodyParser.Parse(bodyParserSettings);
// assert
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
@@ -74,10 +92,15 @@ namespace WireMock.Net.Tests.Util
public async Task BodyParser_Parse_DetectedBodyTypeNoJsonParsing(byte[] content, BodyType detectedBodyType)
{
// arrange
var memoryStream = new MemoryStream(content);
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(content),
ContentType = null,
DeserializeJson = false
};
// act
var body = await BodyParser.Parse(memoryStream, null, false);
var body = await BodyParser.Parse(bodyParserSettings);
// assert
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
@@ -108,10 +131,15 @@ Content-Type: text/html
-----------------------------9051914041544843365972754266--";
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(Encoding.UTF8.GetBytes(body)),
ContentType = contentType,
DeserializeJson = true
};
// Act
var result = await BodyParser.Parse(memoryStream, contentType, true);
var result = await BodyParser.Parse(bodyParserSettings);
// Assert
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.String);
@@ -127,11 +155,15 @@ Content-Type: text/html
// Arrange
string contentType = "multipart/form-data";
string body = char.ConvertFromUtf32(0x1D161); //U+1D161 = MUSICAL SYMBOL SIXTEENTH NOTE
var memoryStream = new MemoryStream(Encoding.UTF32.GetBytes(body));
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(Encoding.UTF8.GetBytes(body)),
ContentType = contentType,
DeserializeJson = true
};
// Act
var result = await BodyParser.Parse(memoryStream, contentType, true);
var result = await BodyParser.Parse(bodyParserSettings);
// Assert
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.Bytes);
@@ -142,14 +174,19 @@ Content-Type: text/html
}
[Theory]
[InlineData(null, "hello", BodyType.String, BodyType.Bytes)]
public async Task BodyParser_Parse_ContentTypeIsNull(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
[InlineData("hello", BodyType.String, BodyType.Bytes)]
public async Task BodyParser_Parse_ContentTypeIsNull(string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
{
// Arrange
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString)),
ContentType = null,
DeserializeJson = true
};
// Act
var body = await BodyParser.Parse(memoryStream, contentType, true);
var body = await BodyParser.Parse(bodyParserSettings);
// Assert
Check.That(body.BodyAsBytes).IsNotNull();
@@ -159,6 +196,60 @@ Content-Type: text/html
Check.That(body.DetectedBodyTypeFromContentType).IsEqualTo(detectedBodyTypeFromContentType);
}
[Theory]
[InlineData("gzip")]
[InlineData("deflate")]
public async Task BodyParser_Parse_ContentEncoding_GZip_And_DecompressGzipAndDeflate_Is_True_Should_Decompress(string compression)
{
// Arrange
var bytes = Encoding.ASCII.GetBytes("0");
var compressed = CompressionUtils.Compress(compression, bytes);
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(compressed),
ContentType = "text/plain",
DeserializeJson = false,
ContentEncoding = compression.ToUpperInvariant(),
DecompressGZipAndDeflate = true
};
// Act
var result = await BodyParser.Parse(bodyParserSettings);
// Assert
result.DetectedBodyType.Should().Be(BodyType.String);
result.DetectedBodyTypeFromContentType.Should().Be(BodyType.String);
result.BodyAsBytes.Should().BeEquivalentTo(new byte[] { 48 });
result.BodyAsJson.Should().BeNull();
result.BodyAsString.Should().Be("0");
result.DetectedCompression.Should().Be(compression);
}
[Theory]
[InlineData("gzip")]
[InlineData("deflate")]
public async Task BodyParser_Parse_ContentEncoding_GZip_And_DecompressGzipAndDeflate_Is_False_Should_Not_Decompress(string compression)
{
// Arrange
var bytes = Encoding.ASCII.GetBytes(Guid.NewGuid().ToString());
var compressed = CompressionUtils.Compress(compression, bytes);
var bodyParserSettings = new BodyParserSettings
{
Stream = new MemoryStream(compressed),
ContentType = "text/plain",
DeserializeJson = false,
ContentEncoding = compression.ToUpperInvariant(),
DecompressGZipAndDeflate = false
};
// Act
var result = await BodyParser.Parse(bodyParserSettings);
// Assert
result.BodyAsBytes.Should().BeEquivalentTo(compressed);
result.DetectedCompression.Should().BeNull();
}
[Theory]
[InlineData("HEAD", false)]
[InlineData("GET", false)]

View File

@@ -3,7 +3,7 @@
<PropertyGroup>
<Authors>Stef Heyenrath</Authors>
<!--<TargetFrameworks>net452;netcoreapp2.1</TargetFrameworks>-->
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<DebugType>full</DebugType>
<AssemblyName>WireMock.Net.Tests</AssemblyName>
<PackageId>WireMock.Net.Tests</PackageId>
@@ -35,21 +35,21 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Codecov" Version="1.1.0" />
<PackageReference Include="coverlet.msbuild" Version="2.3.1">
<PackageReference Include="Codecov" Version="1.10.0" />
<PackageReference Include="coverlet.msbuild" Version="2.8.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="5.7.0" />
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="System.Threading" Version="4.3.0" />
<PackageReference Include="RestEase" Version="1.4.10" />
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.10" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Moq" Version="4.10.1" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NFluent" Version="2.5.0" />
<PackageReference Include="OpenCover" Version="4.6.519" />
<PackageReference Include="ReportGenerator" Version="3.1.2" />
<PackageReference Include="NFluent" Version="2.7.0" />
<PackageReference Include="OpenCover" Version="4.7.922" />
<PackageReference Include="ReportGenerator" Version="4.5.4" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
<PackageReference Include="xunit" Version="2.4.1" />

View File

@@ -5,7 +5,10 @@ using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using NFluent;
using WireMock.Admin.Mappings;
using WireMock.Logging;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
@@ -50,7 +53,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_proxy_responses()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath(path))
@@ -76,7 +79,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_preserve_content_header_in_proxied_request()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var serverForProxyForwarding = WireMockServer.Start();
serverForProxyForwarding
.Given(Request.Create().WithPath(path))
@@ -123,7 +126,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_exclude_blacklisted_content_header_in_mapping()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var serverForProxyForwarding = WireMockServer.Start();
serverForProxyForwarding
.Given(Request.Create().WithPath(path))
@@ -165,7 +168,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_exclude_blacklisted_cookies_in_mapping()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var serverForProxyForwarding = WireMockServer.Start();
serverForProxyForwarding
.Given(Request.Create().WithPath(path))
@@ -214,7 +217,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_preserve_content_header_in_proxied_request_with_empty_content()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var serverForProxyForwarding = WireMockServer.Start();
serverForProxyForwarding
.Given(Request.Create().WithPath(path))
@@ -246,7 +249,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_preserve_content_header_in_proxied_response()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var serverForProxyForwarding = WireMockServer.Start();
serverForProxyForwarding
.Given(Request.Create().WithPath(path))
@@ -277,7 +280,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_change_absolute_location_header_in_proxied_response()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var settings = new WireMockServerSettings { AllowPartialMapping = false };
var serverForProxyForwarding = WireMockServer.Start(settings);
@@ -310,7 +313,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_preserve_cookie_header_in_proxied_request()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var serverForProxyForwarding = WireMockServer.Start();
serverForProxyForwarding
.Given(Request.Create().WithPath(path))
@@ -379,7 +382,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_set_BodyAsJson_in_proxied_response()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var serverForProxyForwarding = WireMockServer.Start();
serverForProxyForwarding
.Given(Request.Create().WithPath(path))
@@ -410,7 +413,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_set_Body_in_multipart_proxied_response()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var serverForProxyForwarding = WireMockServer.Start();
serverForProxyForwarding
.Given(Request.Create().WithPath(path))
@@ -440,7 +443,7 @@ namespace WireMock.Net.Tests
public async Task WireMockServer_Proxy_Should_Not_overrule_AdminMappings()
{
// Assign
string path = $"/prx_{Guid.NewGuid().ToString()}";
string path = $"/prx_{Guid.NewGuid()}";
var serverForProxyForwarding = WireMockServer.Start();
serverForProxyForwarding
.Given(Request.Create().WithPath(path))
@@ -482,5 +485,37 @@ namespace WireMock.Net.Tests
string content2 = await response2.Content.ReadAsStringAsync();
Check.That(content2).IsEqualTo("[]");
}
[Fact]
public async Task WireMockServer_Proxy_WhenTargetIsNotAvailable_Should_Return_CorrectResponse()
{
// Assign
var settings = new WireMockServerSettings
{
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
Url = $"http://error{Guid.NewGuid()}:12345"
}
};
var server = WireMockServer.Start(settings);
// Act
var requestMessage = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(server.Urls[0])
};
var httpClientHandler = new HttpClientHandler { AllowAutoRedirect = false };
var result = await new HttpClient(httpClientHandler).SendAsync(requestMessage);
// Assert
result.StatusCode.Should().Be(500);
var content = await result.Content.ReadAsStringAsync();
content.Should().Contain("known"); // On Linux it's "Name or service not known". On Windows it's "No such host is known.".
server.LogEntries.Should().HaveCount(1);
((StatusModel) server.LogEntries.First().ResponseMessage.BodyData.BodyAsJson).Status.Should().Contain("known");
}
}
}

View File

@@ -1,13 +1,17 @@
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using NFluent;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests
@@ -252,5 +256,35 @@ namespace WireMock.Net.Tests
Check.That(response.StatusCode).Equals(HttpStatusCode.Created);
Check.That(await response.Content.ReadAsStringAsync()).Contains("Mapping added");
}
[Theory]
[InlineData("gzip")]
[InlineData("deflate")]
public async Task WireMockServer_Should_SupportRequestGZipAndDeflate(string contentEncoding)
{
// Arrange
const string body = "hello wiremock";
byte[] compressed = CompressionUtils.Compress(contentEncoding, Encoding.UTF8.GetBytes(body));
var server = WireMockServer.Start();
server.Given(
Request.Create()
.WithPath("/foo")
.WithBody("hello wiremock")
)
.RespondWith(
Response.Create().WithBody("OK")
);
var content = new StreamContent(new MemoryStream(compressed));
content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
content.Headers.ContentEncoding.Add(contentEncoding);
// Act
var response = await new HttpClient().PostAsync($"{server.Urls[0]}/foo", content);
// Assert
Check.That(await response.Content.ReadAsStringAsync()).Contains("OK");
}
}
}