Compare commits

..

48 Commits

Author SHA1 Message Date
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
Stef Heyenrath
1ddd8ff58f Merge branch 'master' of https://github.com/WireMock-Net/WireMock.Net 2020-04-01 22:45:46 +02:00
Stef Heyenrath
5174f9823c 1.2.3.0 2020-04-01 22:45:36 +02:00
Stef Heyenrath
79da7d042b Netstandard21 (#449)
* Add NetStandard2.1

* 21

* CS-Script.Core

* csscript

* ex
2020-04-01 17:10:45 +02:00
Stef Heyenrath
e041e78bc7 1.2.2.0 2020-03-25 17:05:01 +00:00
Stef Heyenrath
5809fae602 fix port (#446) 2020-03-25 17:00:15 +01:00
Stef Heyenrath
8a295e806c post_with_query ; 4 params 2020-03-23 07:56:32 +00:00
Stef Heyenrath
d5d9d4bd1b WireMock.Net.Console.NETCoreApp3 2020-03-22 14:02:51 +01:00
Stef Heyenrath
5f274f1179 example: post_with_query 2020-03-22 12:04:26 +01:00
Stef Heyenrath
8c1cd41df9 1.2.1.0 2020-03-17 22:15:39 +01:00
Stef Heyenrath
fe4ad50119 Fix Null body in handlebar transformation (#442) 2020-03-17 13:52:43 +01:00
Stef Heyenrath
bde981b522 .net 472 example (#440)
ok
2020-03-15 11:17:36 +01:00
Stef Heyenrath
a1d2deb6a9 1.2.0.0 2020-03-14 11:11:32 +01:00
Stef Heyenrath
10dbff2c02 AllowOnlyDefinedHttpStatusCodeInResponse (#422) 2020-03-14 09:13:14 +01:00
Stef Heyenrath
68ffcda53b Let the .NET core/standard WebHostBuilder use a random port (#417)
* wip

* code reformat
2020-03-14 08:51:26 +01:00
Stef Heyenrath
aeb95b02d2 1.1.10 2020-03-05 18:23:16 +01:00
Stef Heyenrath
2dbb984a1e wip (#435) 2020-03-05 18:20:49 +01:00
Stef Heyenrath
88dd1b9aa4 Option to disable JSON deserialization (#434)
* Option to disable JSON deserialization

* Fix build errors, add test case

* make new parameter optional

* set default for contentType as well
2020-03-05 17:59:24 +01:00
Stef Heyenrath
87c4344d65 UsingOptions, UsingConnect and UsingTrace (#427) 2020-03-05 17:56:24 +01:00
Stef Heyenrath
2851c820e0 1.1.9 2020-02-25 22:22:01 +01:00
Stef Heyenrath
13ab37dd3e LinqMatcher (#431) 2020-02-25 22:17:15 +01:00
Stef Heyenrath
f49046374a 1.1.8.0 2020-02-22 11:14:11 +01:00
Stef Heyenrath
69488ced5f fixes for Cookie and Header Reject on Match (#423) 2020-02-22 11:07:45 +01:00
Stef Heyenrath
e6bcd625f7 Don't return empty dictionary object for response headers in JSON mapping (#424) 2020-02-22 11:07:04 +01:00
Stef Heyenrath
d1b42bf436 wip (#421) 2020-02-15 08:30:08 +01:00
Stef Heyenrath
f4861d9bab /needs-a-key 2020-02-14 16:34:52 +01:00
Noah Lerner
4c01ef4838 Support multi line wild card matching (#419) 2020-02-13 20:05:56 +01:00
Stef Heyenrath
83866f5719 Example: RejectOnMatch 2020-02-11 08:55:06 +01:00
Stef Heyenrath
f72c3c33ef 1.1.7 2020-02-06 18:44:52 +01:00
Noah Lerner
32248b6585 Fix new Delete with body missing from IWireMockAdminApi interface (#413)
* Fix new Delete with body missing from IWireMockAdminApi interface

* Admin Delete with mappings in body (#409)

* Add unit test for delete with body

* change order of checks for readability. looks nicer.

* Allow body in DELETE requests

* Fix unit tests according to DELETE supporting body

* Re-run CI

* Fix DELETE with body unit test

* Fix ElementAt index in mappings list

* Fix DELETE with body unit test

* Fix theory tag must be accompanied by some InlineData or Member

* Fix didn't use correct checking syntax

* Fix wrap entire unit test in if region
2020-02-05 19:11:44 +01:00
Stef Heyenrath
1df4502631 fix (#414) 2020-02-05 19:09:57 +01:00
Noah Lerner
5e76a82a21 Improved relative path checking based on file existence (#411)
* Improved relative path checking based on file existence

If the file exists at the relative path, then use it. If not, then use the path as is.

* Apply File.Exists logic to ReadResponseBodyAsString as well

* Make path handling more robust since path is user defined

* Unit tests for relative path feature

* Replace all back and forward slashes with system dependent DirectorySeparatorChar

* Attempt fix broken directory separator chars for Unix platforms

* Revert wrapping GetMappingFolder with CleanPath

* Move CleanPath logic to its own class

* Remove whitespace

* Remove more whitespace

* Improve CleanPath method

* Move PathUtils tests to separate class

Add another test to ResponseWithBodyFromFileTests

* Fix Response_ProvideResponse_WithBodyFromFile_InAdminMappingFolder

* Debug Linux CI build

* Debug Linux CI

* print all files from admin mappings folder

* Debug CleanPath

* Fix removed leading directory separator char in Linux breaks file path

Remove debugging statements

* Move combine to PathUtils

* PathUtils + PathUtilsTests

* Remove replicated (3x) tests throughout ResponseWithBodyFromFileTests

Co-authored-by: Stef Heyenrath <Stef.Heyenrath@gmail.com>
2020-02-02 13:49:34 +01:00
Stef Heyenrath
06ae9d72c3 1.1.6.0 2020-01-27 18:51:31 +01:00
Stef Heyenrath
307a89d324 AllowAnyHttpStatusCodeInResponse (#407)
* .

* ,

* PUBLISH_TESTRESULTS

* fix logging

* fix compile error

* codefactor fix

* Debug - Sonar + other things in csproj
2020-01-27 18:47:58 +01:00
Stef Heyenrath
6ae7fc1d75 <VersionPrefix>1.1.5</VersionPrefix> 2020-01-25 18:06:51 +01:00
Stef Heyenrath
29e86abe12 1.1.5.0 2020-01-25 17:58:44 +01:00
Stef Heyenrath
710fc8dcf6 Fixed StatusCode = null or < 0 (#406)
* .

* fix tests

* responseModel.StatusCode is int statusCodeAsInt && statusCodeAsInt > 0

* < 0
2020-01-25 17:51:38 +01:00
Stef Heyenrath
dfbfa5fd35 1.1.4.0 2020-01-25 15:28:43 +01:00
Stef Heyenrath
69bbd76ca4 Log Exception (#405) 2020-01-25 15:25:47 +01:00
Stef Heyenrath
bd0c5a83c9 WireMock.Net.Service 2020-01-25 13:54:09 +01:00
Stef Heyenrath
a08efe2f78 steps: 2020-01-25 12:39:36 +01:00
Stef Heyenrath
6e151098e5 azure-pipelines 2020-01-25 12:29:13 +01:00
Stef Heyenrath
43d481435c 1.1.3 2020-01-22 16:40:10 +01:00
Kashif Jamal Soofi
ea1be6641a Fix for invalid cast exception (#403) 2020-01-22 14:27:44 +01:00
113 changed files with 3006 additions and 1132 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,64 @@
# 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]
- [#448](https://github.com/WireMock-Net/WireMock.Net/issues/448) - WireMock.Net is not compatible with Microsoft.VisualStudio.Web.CodeGeneration.Design 3.1.1 [bug]
# 1.2.2.0 (25 March 2020)
- [#446](https://github.com/WireMock-Net/WireMock.Net/pull/446) - When port is provided: WireMockServer still takes a random port [bug] contributed by [StefH](https://github.com/StefH)
- [#445](https://github.com/WireMock-Net/WireMock.Net/issues/445) - Port where WireMockServer listens to - v1.2x [bug]
# 1.2.1.0 (17 March 2020)
- [#442](https://github.com/WireMock-Net/WireMock.Net/pull/442) - Fix Null body in handlebars transformation [bug] contributed by [StefH](https://github.com/StefH)
# 1.2.0.0 (14 March 2020)
- [#417](https://github.com/WireMock-Net/WireMock.Net/pull/417) - Let the .NET core/standard WebHostBuilder use a random port [bug] contributed by [StefH](https://github.com/StefH)
- [#422](https://github.com/WireMock-Net/WireMock.Net/pull/422) - AllowOnlyDefinedHttpStatusCodeInResponse [bug] contributed by [StefH](https://github.com/StefH)
- [#379](https://github.com/WireMock-Net/WireMock.Net/issues/379) - Trusting the self signed certificate to enable SSL on dotnet core [bug]
- [#420](https://github.com/WireMock-Net/WireMock.Net/issues/420) - Updating to 1.1.6+ breaks tests because new AllowAnyHttpStatusCodeInResponse option defaults to false [bug]
# 1.1.10 (05 March 2020)
- [#427](https://github.com/WireMock-Net/WireMock.Net/pull/427) - Add UsingOptions, UsingConnect and UsingTrace [feature] contributed by [StefH](https://github.com/StefH)
- [#434](https://github.com/WireMock-Net/WireMock.Net/pull/434) - Option to disable JSON deserialization [feature] contributed by [sebastianmattar](https://github.com/sebastianmattar)
- [#435](https://github.com/WireMock-Net/WireMock.Net/pull/435) - Also call HandlebarsRegistrationCallback when using WithCallback(..) [feature] contributed by [StefH](https://github.com/StefH)
- [#408](https://github.com/WireMock-Net/WireMock.Net/issues/408) - Intermittent threading errors with FindLogEntries [bug]
- [#433](https://github.com/WireMock-Net/WireMock.Net/issues/433) - HandlebarsRegistrationCallback not fired [feature]
# 1.1.9.0 (25 February 2020)
- [#431](https://github.com/WireMock-Net/WireMock.Net/pull/431) - Fix LinqMatcher for JSON int64 [bug] contributed by [StefH](https://github.com/StefH)
- [#425](https://github.com/WireMock-Net/WireMock.Net/issues/425) - Allow 64 bit numbers in JSON [bug]
# 1.1.8.0 (22 February 2020)
- [#419](https://github.com/WireMock-Net/WireMock.Net/pull/419) - Support multi line wild card matching [bug] contributed by [NoahLerner](https://github.com/NoahLerner)
- [#421](https://github.com/WireMock-Net/WireMock.Net/pull/421) - Fix: do not return empty matchers array when Func has been used [bug] contributed by [StefH](https://github.com/StefH)
- [#423](https://github.com/WireMock-Net/WireMock.Net/pull/423) - Fixes for Cookie and Header Reject on Match [bug] contributed by [StefH](https://github.com/StefH)
- [#424](https://github.com/WireMock-Net/WireMock.Net/pull/424) - Don't return empty dictionary object for response headers in JSON mapping [feature] contributed by [StefH](https://github.com/StefH)
- [#418](https://github.com/WireMock-Net/WireMock.Net/issues/418) - Body matching fails if body has newline [bug]
# 1.1.7.0 (06 February 2020)
- [#409](https://github.com/WireMock-Net/WireMock.Net/pull/409) - Admin Delete with mappings in body [feature] contributed by [NoahLerner](https://github.com/NoahLerner)
- [#411](https://github.com/WireMock-Net/WireMock.Net/pull/411) - Improved relative path checking based on file existence [feature] contributed by [NoahLerner](https://github.com/NoahLerner)
- [#413](https://github.com/WireMock-Net/WireMock.Net/pull/413) - Fix new Delete with body missing from IWireMockAdminApi interface contributed by [NoahLerner](https://github.com/NoahLerner)
- [#414](https://github.com/WireMock-Net/WireMock.Net/pull/414) - Fix logger in StandAlone [bug] contributed by [StefH](https://github.com/StefH)
- [#412](https://github.com/WireMock-Net/WireMock.Net/issues/412) - WireMock Standalone - null reference exception since settings.Logger [bug]
# 1.1.6.0 (27 January 2020)
- [#407](https://github.com/WireMock-Net/WireMock.Net/pull/407) - AllowAnyHttpStatusCodeInResponse [feature] contributed by [StefH](https://github.com/StefH)
# 1.1.5.0 (25 January 2020)
- [#405](https://github.com/WireMock-Net/WireMock.Net/pull/405) - Fix logging an Exception Message (linux docker on azure) [bug] contributed by [StefH](https://github.com/StefH)
- [#406](https://github.com/WireMock-Net/WireMock.Net/pull/406) - Fixed StatusCode = null or &lt; 0 [bug] contributed by [StefH](https://github.com/StefH)
# 1.1.3.0 (22 January 2020)
- [#403](https://github.com/WireMock-Net/WireMock.Net/pull/403) - Fix for invalid cast exception contributed by [kashifsoofi](https://github.com/kashifsoofi)
- [#402](https://github.com/WireMock-Net/WireMock.Net/issues/402) - Invalid Cast Exception [bug]
# 1.1.2.0 (09 January 2020)
- [#399](https://github.com/WireMock-Net/WireMock.Net/pull/399) - ResponseModel.StatusCode is deserialized as either string or long. [bug] contributed by [vitaliydavydiak](https://github.com/vitaliydavydiak)
- [#400](https://github.com/WireMock-Net/WireMock.Net/issues/400) - StatusCode not built correctly when loaded from mapping file. [bug]
@@ -34,7 +95,7 @@
- [#386](https://github.com/WireMock-Net/WireMock.Net/issues/386) - Is transforming contents of XML file supported.? [bug]
# 1.0.38.0 (30 November 2019)
- [#376](https://github.com/WireMock-Net/WireMock.Net/pull/376) - Support int values for states and scenario naming [feature] contributed by [thewholuver94](https://github.com/thewholuver94)
- [#376](https://github.com/WireMock-Net/WireMock.Net/pull/376) - Support int values for states and scenario naming [feature] contributed by [NoahLerner](https://github.com/NoahLerner)
- [#378](https://github.com/WireMock-Net/WireMock.Net/pull/378) - Set handlebars dependency for .net 4.5.1 to fixed value [bug] contributed by [StefH](https://github.com/StefH)
- [#381](https://github.com/WireMock-Net/WireMock.Net/pull/381) - Use dotnet default development certificate for .NET Core 2.x [feature] contributed by [StefH](https://github.com/StefH)
- [#377](https://github.com/WireMock-Net/WireMock.Net/issues/377) - Unable to build against .NET 4.5.1 because of Handlebars [bug]

View File

@@ -4,7 +4,14 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.1.2</VersionPrefix>
<VersionPrefix>1.2.4</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.1.2.0
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.2.4.0

View File

@@ -1,16 +1,17 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.902
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EF242EDF-7133-4277-9A0C-18744DE08707}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{197A0EE3-94E5-4807-BBCF-2F1BCA28A6AE}"
ProjectSection(SolutionItems) = preProject
.runsettings = .runsettings
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
azure-pipelines-nuget.yml = azure-pipelines-nuget.yml
azure-pipelines.yml = azure-pipelines.yml
build-info.md = build-info.md
CHANGELOG.md = CHANGELOG.md
Directory.Build.props = Directory.Build.props
@@ -64,14 +65,24 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.StandAlone", "
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}"
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
@@ -80,6 +91,10 @@ Global
{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
@@ -88,6 +103,10 @@ Global
{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
@@ -96,6 +115,10 @@ Global
{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
@@ -104,6 +127,10 @@ Global
{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
@@ -112,6 +139,10 @@ Global
{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
@@ -120,6 +151,10 @@ Global
{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
@@ -128,6 +163,10 @@ Global
{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
@@ -136,6 +175,10 @@ Global
{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
@@ -144,6 +187,10 @@ Global
{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
@@ -152,6 +199,10 @@ Global
{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
@@ -160,6 +211,10 @@ Global
{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
@@ -168,6 +223,10 @@ Global
{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
@@ -176,6 +235,10 @@ Global
{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
@@ -184,6 +247,10 @@ Global
{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
@@ -192,6 +259,10 @@ Global
{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
@@ -200,6 +271,10 @@ Global
{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
@@ -208,6 +283,10 @@ Global
{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-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
@@ -216,6 +295,10 @@ Global
{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
@@ -224,6 +307,30 @@ Global
{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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -248,6 +355,8 @@ Global
{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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BF428BCC-C837-433B-87D2-15C7014B73E9}

View File

@@ -0,0 +1,13 @@
pool:
vmImage: 'Ubuntu 16.04'
variables:
buildConfiguration: 'Release'
steps:
- script: |
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework netcoreapp2.1 --logger trx
- task: PublishTestResults@2
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'

View File

@@ -46,10 +46,12 @@ 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
- task: PublishTestResults@2
condition: and(succeeded(), eq(variables['PUBLISH_TESTRESULTS'], 'yes'))
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'

View File

@@ -1,13 +1,23 @@
trigger:
- none
pool:
vmImage: 'Ubuntu 16.04'
variables:
buildProjects: '**/src/**/*.csproj'
buildConfiguration: 'Release'
steps:
- script: |
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework netcoreapp2.1 --logger trx
- task: PublishTestResults@2
- task: DotNetCoreCLI@2
displayName: Build Release
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'
command: 'build'
arguments: /p:Configuration=$(buildConfiguration)
projects: $(buildProjects)
- task: PublishBuildArtifacts@1
displayName: Publish Artifacts
condition: succeeded()
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

View File

@@ -0,0 +1,35 @@
using Newtonsoft.Json;
using RestEase;
using System;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using WireMock.Client;
namespace WireMock.Net.Client.Net472
{
class Program
{
static async Task Main(string[] args)
{
// Create an implementation of the IWireMockAdminApi and pass in the base URL for the API.
var api = RestClient.For<IWireMockAdminApi>("http://localhost:9091");
// Set BASIC Auth
var value = Convert.ToBase64String(Encoding.ASCII.GetBytes("a:b"));
api.Authorization = new AuthenticationHeaderValue("Basic", value);
var settings1 = await api.GetSettingsAsync();
Console.WriteLine($"settings1 = {JsonConvert.SerializeObject(settings1)}");
}
}
//public interface IWireMockAdminApi
//{
// /// <summary>
// /// Authentication header
// /// </summary>
// [Header("Authorization")]
// AuthenticationHeaderValue Authorization { get; set; }
//}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WireMock.Net.Client.Net472")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("mStack.nl")]
[assembly: AssemblyProduct("WireMock.Net.Client.Net472")]
[assembly: AssemblyCopyright("Copyright © mStack.nl 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("02082e34-def2-47d0-af0b-3326faa908ce")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{02082E34-DEF2-47D0-AF0B-3326FAA908CE}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>WireMock.Net.Client.Net472</RootNamespace>
<AssemblyName>WireMock.Net.Client.Net472</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.6.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="RestEase, Version=1.4.10.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\RestEase.1.4.10\lib\net45\RestEase.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WireMock.Net.Abstractions, Version=1.2.0.0, Culture=neutral, PublicKeyToken=c8d65537854e1f03, processorArchitecture=MSIL">
<HintPath>..\..\packages\WireMock.Net.Abstractions.1.2.0\lib\net45\WireMock.Net.Abstractions.dll</HintPath>
</Reference>
<Reference Include="WireMock.Net.RestClient">
<HintPath>..\..\packages\WireMock.Net.RestClient.1.2.0\lib\net45\WireMock.Net.RestClient.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\packages\Brutal.Dev.StrongNameSigner.2.7.1\build\Brutal.Dev.StrongNameSigner.targets" Condition="Exists('..\..\packages\Brutal.Dev.StrongNameSigner.2.7.1\build\Brutal.Dev.StrongNameSigner.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Brutal.Dev.StrongNameSigner.2.7.1\build\Brutal.Dev.StrongNameSigner.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Brutal.Dev.StrongNameSigner.2.7.1\build\Brutal.Dev.StrongNameSigner.targets'))" />
</Target>
</Project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Brutal.Dev.StrongNameSigner" version="2.7.1" targetFramework="net472" />
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net472" />
<package id="RestEase" version="1.4.10" targetFramework="net472" />
<package id="WireMock.Net.Abstractions" version="1.2.0" targetFramework="net472" />
<package id="WireMock.Net.RestClient" version="1.2.0" targetFramework="net472" />
</packages>

View File

@@ -14,7 +14,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net.RestClient\WireMock.Net.RestClient.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<!--<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />-->
</ItemGroup>
</Project>

View File

@@ -0,0 +1,55 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\WireMock.Net.Console.Net452.Classic\MainApp.cs" Link="MainApp.cs" />
<Compile Include="..\WireMock.Net.Console.Net452.Classic\CustomFileSystemFileHandler.cs" Link="CustomFileSystemFileHandler.cs" />
<Compile Include="..\WireMock.Net.Console.NETCoreApp\Program.cs" Link="Program.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="__admin\mappings\*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Compile Remove="__admin\mappings\1.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="__admin\mappings\array.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
<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" />-->
</ItemGroup>
<ItemGroup>
<None Update="log4net.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="__admin\mappings\791a3f31-6946-4ce7-8e6f-0237c7443275.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="__admin\mappings\791a3f31-6946-4ce7-8e6f-0237c7443275.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="__admin\mappings\MyXmlResponse.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1 @@
// C# Hello

View File

@@ -0,0 +1,22 @@
{
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/static/mapping"
}
]
},
"Methods": [
"get"
]
},
"Response": {
"BodyAsJson": { "body": "static mapping" },
"Headers": {
"Content-Type": "application/json",
"Test-X": [ "test 1", "test 2" ]
}
}
}

View File

@@ -0,0 +1,29 @@
{
"Guid": "791a3f31-6946-4ce7-8e6f-0237c7443275",
"Title": "",
"Priority": 0,
"Request": {
"Path": "/proxy-google-test-post",
"Methods": [
"post"
],
"Body": {}
},
"Response": {
"StatusCode": 404,
"Body": "<!DOCTYPE html>\n<html lang=en>\n <meta charset=utf-8>\n <meta name=viewport content=\"initial-scale=1, minimum-scale=1, width=device-width\">\n <title>Error 404 (Not Found)!!1</title>\n <style>\n *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}\n </style>\n <a href=//www.google.com/><span id=logo aria-label=Google></span></a>\n <p><b>404.</b> <ins>Thats an error.</ins>\n <p>The requested URL <code>/proxy-google-test-post</code> was not found on this server. <ins>Thats all we know.</ins>\n",
"BodyAsBytes": "PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ZW4+CiAgPG1ldGEgY2hhcnNldD11dGYtOD4KICA8bWV0YSBuYW1lPXZpZXdwb3J0IGNvbnRlbnQ9ImluaXRpYWwtc2NhbGU9MSwgbWluaW11bS1zY2FsZT0xLCB3aWR0aD1kZXZpY2Utd2lkdGgiPgogIDx0aXRsZT5FcnJvciA0MDQgKE5vdCBGb3VuZCkhITE8L3RpdGxlPgogIDxzdHlsZT4KICAgICp7bWFyZ2luOjA7cGFkZGluZzowfWh0bWwsY29kZXtmb250OjE1cHgvMjJweCBhcmlhbCxzYW5zLXNlcmlmfWh0bWx7YmFja2dyb3VuZDojZmZmO2NvbG9yOiMyMjI7cGFkZGluZzoxNXB4fWJvZHl7bWFyZ2luOjclIGF1dG8gMDttYXgtd2lkdGg6MzkwcHg7bWluLWhlaWdodDoxODBweDtwYWRkaW5nOjMwcHggMCAxNXB4fSogPiBib2R5e2JhY2tncm91bmQ6dXJsKC8vd3d3Lmdvb2dsZS5jb20vaW1hZ2VzL2Vycm9ycy9yb2JvdC5wbmcpIDEwMCUgNXB4IG5vLXJlcGVhdDtwYWRkaW5nLXJpZ2h0OjIwNXB4fXB7bWFyZ2luOjExcHggMCAyMnB4O292ZXJmbG93OmhpZGRlbn1pbnN7Y29sb3I6Izc3Nzt0ZXh0LWRlY29yYXRpb246bm9uZX1hIGltZ3tib3JkZXI6MH1AbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOjc3MnB4KXtib2R5e2JhY2tncm91bmQ6bm9uZTttYXJnaW4tdG9wOjA7bWF4LXdpZHRoOm5vbmU7cGFkZGluZy1yaWdodDowfX0jbG9nb3tiYWNrZ3JvdW5kOnVybCgvL3d3dy5nb29nbGUuY29tL2ltYWdlcy9icmFuZGluZy9nb29nbGVsb2dvLzF4L2dvb2dsZWxvZ29fY29sb3JfMTUweDU0ZHAucG5nKSBuby1yZXBlYXQ7bWFyZ2luLWxlZnQ6LTVweH1AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4tcmVzb2x1dGlvbjoxOTJkcGkpeyNsb2dve2JhY2tncm91bmQ6dXJsKC8vd3d3Lmdvb2dsZS5jb20vaW1hZ2VzL2JyYW5kaW5nL2dvb2dsZWxvZ28vMngvZ29vZ2xlbG9nb19jb2xvcl8xNTB4NTRkcC5wbmcpIG5vLXJlcGVhdCAwJSAwJS8xMDAlIDEwMCU7LW1vei1ib3JkZXItaW1hZ2U6dXJsKC8vd3d3Lmdvb2dsZS5jb20vaW1hZ2VzL2JyYW5kaW5nL2dvb2dsZWxvZ28vMngvZ29vZ2xlbG9nb19jb2xvcl8xNTB4NTRkcC5wbmcpIDB9fUBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKC13ZWJraXQtbWluLWRldmljZS1waXhlbC1yYXRpbzoyKXsjbG9nb3tiYWNrZ3JvdW5kOnVybCgvL3d3dy5nb29nbGUuY29tL2ltYWdlcy9icmFuZGluZy9nb29nbGVsb2dvLzJ4L2dvb2dsZWxvZ29fY29sb3JfMTUweDU0ZHAucG5nKSBuby1yZXBlYXQ7LXdlYmtpdC1iYWNrZ3JvdW5kLXNpemU6MTAwJSAxMDAlfX0jbG9nb3tkaXNwbGF5OmlubGluZS1ibG9jaztoZWlnaHQ6NTRweDt3aWR0aDoxNTBweH0KICA8L3N0eWxlPgogIDxhIGhyZWY9Ly93d3cuZ29vZ2xlLmNvbS8+PHNwYW4gaWQ9bG9nbyBhcmlhLWxhYmVsPUdvb2dsZT48L3NwYW4+PC9hPgogIDxwPjxiPjQwNC48L2I+IDxpbnM+VGhhdOKAmXMgYW4gZXJyb3IuPC9pbnM+CiAgPHA+VGhlIHJlcXVlc3RlZCBVUkwgPGNvZGU+L3Byb3h5LWdvb2dsZS10ZXN0LXBvc3Q8L2NvZGU+IHdhcyBub3QgZm91bmQgb24gdGhpcyBzZXJ2ZXIuICA8aW5zPlRoYXTigJlzIGFsbCB3ZSBrbm93LjwvaW5zPgo=",
"BodyEncoding": {
"CodePage": 65001,
"EncodingName": "Unicode (UTF-8)",
"WebName": "utf-8"
},
"UseTransformer": false,
"Headers": {
"Date": "Wed, 27 Oct 2017 18:57:40 GMT",
"Alt-Svc": "quic=\":443\"; ma=2592000; v=\"39,38,37,35\"",
"Referrer-Policy": "no-referrer",
"Connection": "close"
}
}
}

View File

@@ -0,0 +1,19 @@
{
"Guid": "873d495f-940e-4b86-a1f4-4f0fc7be8b8b",
"Priority": 4,
"Request": {
"Path": {},
"Methods": [
"get"
]
},
"Response": {
"StatusCode": 200,
"BodyDestination": "SameAsSource",
"Body": "NO PATH OR URL",
"UseTransformer": false,
"Headers": {
"Content-Type": "application/json"
}
}
}

View File

@@ -0,0 +1,22 @@
{
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/bodyasfilexmltest",
"IgnoreCase": false
}
]
},
"Methods": [
"get"
]
},
"Response": {
"StatusCode": 200,
"Headers": {"Content-Type": "application/xml"},
"BodyAsFile": "MyXmlResponse.xml",
"UseTransformer": false
}
}

View File

@@ -0,0 +1,3 @@
<xml>
<hello>world</hello>
</xml>

View File

@@ -0,0 +1,46 @@
[
{
"Title": "1",
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/mappings_static_1"
}
]
},
"Methods": [
"get"
]
},
"Response": {
"BodyAsJson": { "result": "mappings static_1" },
"Headers": {
"Content-Type": "application/json"
}
}
},
{
"Title": "2",
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/mappings_static_2"
}
]
},
"Methods": [
"get"
]
},
"Response": {
"BodyAsJson": { "result": "mappings static_2" },
"Headers": {
"Content-Type": "application/json"
}
}
}
]

View File

@@ -11,6 +11,7 @@ using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Settings;
using WireMock.Util;
namespace WireMock.Net.ConsoleApplication
{
@@ -59,7 +60,7 @@ namespace WireMock.Net.ConsoleApplication
{
var transformer = new CustomNameTransformer();
handlebarsContext.RegisterHelper(transformer.Name, transformer.Render);
}
},
// Uncomment below if you want to use the CustomFileSystemFileHandler
// FileSystemHandler = new CustomFileSystemFileHandler()
@@ -493,6 +494,20 @@ namespace WireMock.Net.ConsoleApplication
.WithBody("<xml>ok</xml>")
);
server
.Given(Request.Create()
.UsingPost()
.WithPath("/post_with_query")
.WithHeader("PRIVATE-TOKEN", "t")
.WithParam("name", "stef")
.WithParam("path", "p")
.WithParam("visibility", "Private")
.WithParam("parent_id", "1")
)
.RespondWith(Response.Create()
.WithBody("OK : post_with_query")
);
server.Given(Request.Create()
.WithPath("/services/query/")
.WithParam("q", "SELECT Id from User where username='user@gmail.com'")
@@ -501,6 +516,12 @@ namespace WireMock.Net.ConsoleApplication
.WithStatusCode(200)
.WithHeader("Content-Type", "application/json")
.WithBodyAsJson(new { Id = "5bdf076c-5654-4b3e-842c-7caf1fabf8c9" }));
server
.Given(Request.Create().WithPath("/random200or505").UsingGet())
.RespondWith(Response.Create().WithCallback(request => new ResponseMessage
{
StatusCode = new Random().Next(1, 100) == 1 ? 504 : 200
}));
System.Console.WriteLine(JsonConvert.SerializeObject(server.MappingModels, Formatting.Indented));

View File

@@ -8,6 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>

View File

@@ -47,18 +47,12 @@
<Reference Include="Microsoft.Owin.Hosting, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
</Reference>
<Reference Include="MimeKitLite, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bede1c8a46c66814, processorArchitecture=MSIL">
<HintPath>..\..\packages\MimeKitLite.2.0.1\lib\net45\MimeKitLite.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="RestEase, Version=1.4.10.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\RestEase.1.4.10\lib\net45\RestEase.dll</HintPath>
</Reference>
<Reference Include="SimMetrics.Net, Version=1.0.5.0, Culture=neutral, PublicKeyToken=c58dc06d59f3391b, processorArchitecture=MSIL">
<HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath>
</Reference>
@@ -86,8 +80,8 @@
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="XPath2, Version=1.0.7.0, Culture=neutral, PublicKeyToken=463c6d7fb740c7e5, processorArchitecture=MSIL">
<HintPath>..\..\packages\XPath2.1.0.6.1\lib\net40\XPath2.dll</HintPath>
<Reference Include="XPath2, Version=1.0.9.0, Culture=neutral, PublicKeyToken=463c6d7fb740c7e5, processorArchitecture=MSIL">
<HintPath>..\..\packages\XPath2.1.0.10\lib\net40\XPath2.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>

View File

@@ -1,8 +1,9 @@
using log4net;
using System;
using log4net;
using Newtonsoft.Json;
using Wiremock.Net.Service;
using WireMock.Admin.Requests;
using WireMock.Logging;
using WireMock.Models.Requests;
namespace WireMock.Net.Service
{
@@ -30,6 +31,11 @@ namespace WireMock.Net.Service
Log.ErrorFormat(formatString, args);
}
public void Error(string message, Exception exception)
{
Log.Error(message, exception);
}
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);

View File

@@ -9,11 +9,9 @@
<package id="Microsoft.Owin" version="2.0.2" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net452" />
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net452" />
<package id="MimeKitLite" version="2.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net452" />
<package id="Owin" version="1.0" targetFramework="net452" />
<package id="RestEase" version="1.4.10" targetFramework="net452" />
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net452" />
<package id="System.Net.Http" version="4.3.3" targetFramework="net452" />
<package id="XPath2" version="1.0.6.1" targetFramework="net452" />
<package id="XPath2" version="1.0.10" targetFramework="net452" />
</packages>

View File

@@ -1,8 +1,8 @@
{
"profiles": {
"WireMock.Net.StandAlone.NETCoreApp": {
"commandName": "Project",
"commandLineArgs": "--Urls http://*:9091 --WireMockLogger WireMockConsoleLogger"
}
}
{
"profiles": {
"WireMock.Net.StandAlone.NETCoreApp": {
"commandName": "Project",
"commandLineArgs": "--Port 9091 --WireMockLogger WireMockConsoleLogger"
}
}
}

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.1;netcoreapp2.0;netcoreapp1.1</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
<StartupObject>WireMock.Net.StandAlone.NETCoreApp.Program</StartupObject>
</PropertyGroup>

View File

@@ -1,7 +1,8 @@
using log4net;
using System;
using log4net;
using Newtonsoft.Json;
using WireMock.Admin.Requests;
using WireMock.Logging;
using WireMock.Models.Requests;
namespace WireMock.Net.StandAlone.NETCoreApp
{
@@ -29,6 +30,11 @@ namespace WireMock.Net.StandAlone.NETCoreApp
Log.ErrorFormat(formatString, args);
}
public void Error(string message, Exception exception)
{
Log.Error(message, exception);
}
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
<StartupObject>WireMock.Net.WebApplication.Program</StartupObject>
<AssemblyName>WireMock.Net.WebApplication</AssemblyName>

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

@@ -16,5 +16,15 @@ namespace WireMock.Admin.Mappings
/// Gets or sets the matchers.
/// </summary>
public IList<MatcherModel> Matchers { get; set; }
/// <summary>
/// Gets or sets the ignore case.
/// </summary>
public bool? IgnoreCase { get; set; }
/// <summary>
/// Reject on match.
/// </summary>
public bool? RejectOnMatch { get; set; }
}
}

View File

@@ -16,5 +16,15 @@ namespace WireMock.Admin.Mappings
/// Gets or sets the matchers.
/// </summary>
public IList<MatcherModel> Matchers { get; set; }
/// <summary>
/// Gets or sets the ignore case.
/// </summary>
public bool? IgnoreCase { get; set; }
/// <summary>
/// Reject on match.
/// </summary>
public bool? RejectOnMatch { get; set; }
}
}

View File

@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using System;
using JetBrains.Annotations;
using WireMock.Admin.Requests;
namespace WireMock.Logging
@@ -45,6 +46,15 @@ namespace WireMock.Logging
[StringFormatMethod("formatString")]
void Error([NotNull] string formatString, [NotNull] params object[] args);
/// <summary>
/// Writes the message at the Error level using the specified exception.
/// </summary>
/// <param name="formatString">The format string.</param>
/// <param name="exception">The exception.</param>
[PublicAPI]
[StringFormatMethod("formatString")]
void Error([NotNull] string formatString, [NotNull] Exception exception);
/// <summary>
/// Writes the LogEntryModel (LogRequestModel, LogResponseModel and more).
/// </summary>

View File

@@ -4,18 +4,11 @@
<Description>Commonly used interfaces, models, enumerations and types.</Description>
<AssemblyTitle>WireMock.Net.Abstractions</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>netstandard1.0;netstandard2.0;net45</TargetFrameworks>
<TargetFrameworks>netstandard1.0;netstandard2.0;netstandard2.1;net45</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<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>
@@ -34,7 +27,7 @@
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
<!--<GeneratePackageOnBuild>true</GeneratePackageOnBuild>-->
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>

View File

@@ -74,6 +74,14 @@ namespace WireMock.Client
[Delete("mappings")]
Task<StatusModel> DeleteMappingsAsync();
/// <summary>
/// Delete mappings according to GUIDs
/// </summary>
/// <param name="mappings">MappingModels</param>
[Delete("mappings")]
[Header("Content-Type", "application/json")]
Task<StatusModel> DeleteMappingsAsync([Body] IList<MappingModel> mappings);
/// <summary>
/// Delete (reset) all mappings.
/// </summary>

View File

@@ -4,18 +4,11 @@
<Description>A RestClient using RestEase to access the admin interface.</Description>
<AssemblyTitle>WireMock.Net.RestClient</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>netstandard1.1;netstandard2.0;net45</TargetFrameworks>
<TargetFrameworks>netstandard1.1;netstandard2.0;netstandard2.1;net45</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<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>

View File

@@ -17,13 +17,13 @@ namespace WireMock.Net.StandAlone
/// </summary>
/// <param name="settings">The FluentMockServerSettings</param>
[PublicAPI]
public static WireMockServer Start([NotNull] FluentMockServerSettings settings)
public static WireMockServer Start([NotNull] IWireMockServerSettings settings)
{
Check.NotNull(settings, nameof(settings));
var server = WireMockServer.Start(settings);
settings.Logger.Info("WireMock.Net server listening at {0}", string.Join(",", server.Urls));
settings.Logger?.Info("WireMock.Net server listening at {0}", string.Join(",", server.Urls));
return server;
}
@@ -38,9 +38,9 @@ namespace WireMock.Net.StandAlone
{
Check.NotNull(args, nameof(args));
var settings = (FluentMockServerSettings) WireMockServerSettingsParser.ParseArguments(args);
var settings = WireMockServerSettingsParser.ParseArguments(args, logger);
settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
settings.Logger?.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
return Start(settings);
}

View File

@@ -3,18 +3,11 @@
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<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>
@@ -36,7 +29,7 @@
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' ">
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' ">
<DefineConstants>NETSTANDARD;USE_ASPNETCORE</DefineConstants>
</PropertyGroup>

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Handlers
@@ -80,20 +81,20 @@ namespace WireMock.Handlers
public byte[] ReadResponseBodyAsFile(string path)
{
Check.NotNullOrEmpty(path, nameof(path));
// In case the path is a filename, the path will be adjusted to the MappingFolder.
path = PathUtils.CleanPath(path);
// If the file exists at the given path relative to the MappingsFolder, then return that.
// Else the path will just be as-is.
return File.ReadAllBytes(Path.GetFileName(path) == path ? Path.Combine(GetMappingFolder(), path) : path);
return File.ReadAllBytes(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path);
}
/// <inheritdoc cref="IFileSystemHandler.ReadResponseBodyAsString"/>
public string ReadResponseBodyAsString(string path)
{
Check.NotNullOrEmpty(path, nameof(path));
path = PathUtils.CleanPath(path);
// In case the path is a filename, the path will be adjusted to the MappingFolder.
// Else the path will just be as-is.
return File.ReadAllText(Path.GetFileName(path) == path ? Path.Combine(GetMappingFolder(), path) : path);
return File.ReadAllText(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path);
}
/// <inheritdoc cref="IFileSystemHandler.FileExists"/>

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)
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);
return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate);
}
}
}

View File

@@ -0,0 +1,18 @@
namespace WireMock.Http
{
/// <summary>
/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
/// </summary>
internal static class HttpRequestMethods
{
public const string CONNECT = "CONNECT";
public const string DELETE = "DELETE";
public const string GET = "GET";
public const string HEAD = "HEAD";
public const string OPTIONS = "OPTIONS";
public const string PATCH = "PATCH";
public const string POST = "POST";
public const string PUT = "PUT";
public const string TRACE = "TRACE";
}
}

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

@@ -36,12 +36,27 @@ namespace WireMock.Logging
Console.WriteLine(Format("Warn", formatString, args));
}
/// <see cref="IWireMockLogger.Error"/>
/// <see cref="IWireMockLogger.Error(string, object[])"/>
public void Error(string formatString, params object[] args)
{
Console.WriteLine(Format("Error", formatString, args));
}
/// <see cref="IWireMockLogger.Error(string, Exception)"/>
public void Error(string formatString, Exception exception)
{
Console.WriteLine(Format("Error", formatString, exception.Message));
if (exception is AggregateException ae)
{
ae.Handle(ex =>
{
Console.WriteLine(Format("Error", "Exception {0}", exception.Message));
return true;
});
}
}
/// <see cref="IWireMockLogger.DebugRequestResponse"/>
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{

View File

@@ -1,4 +1,5 @@
using WireMock.Admin.Requests;
using System;
using WireMock.Admin.Requests;
namespace WireMock.Logging
{
@@ -26,12 +27,18 @@ namespace WireMock.Logging
// Log nothing
}
/// <see cref="IWireMockLogger.Error"/>
/// <see cref="IWireMockLogger.Error(string, object[])"/>
public void Error(string formatString, params object[] args)
{
// Log nothing
}
/// <see cref="IWireMockLogger.Error(string, Exception)"/>
public void Error(string formatString, Exception exception)
{
// Log nothing
}
/// <see cref="IWireMockLogger.DebugRequestResponse"/>
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{

View File

@@ -82,7 +82,7 @@ namespace WireMock.Matchers
object result = null;
#if NET451 || NET452
#if (NET451 || NET452)
var compilerParams = new System.CodeDom.Compiler.CompilerParameters
{
GenerateInMemory = true,
@@ -122,36 +122,42 @@ namespace WireMock.Matchers
{
result = methodInfo.Invoke(helper, new[] { inputValue });
}
catch
catch (Exception ex)
{
throw new WireMockException("CSharpCodeMatcher: Unable to call method 'IsMatch' in WireMock.CodeHelper");
throw new WireMockException("CSharpCodeMatcher: Unable to call method 'IsMatch' in WireMock.CodeHelper", ex);
}
}
#elif NET46 || NET461
#elif (NET46 || NET461)
dynamic script;
try
{
script = CSScriptLibrary.CSScript.Evaluator.CompileCode(source).CreateObject("*");
}
catch
catch (Exception ex)
{
throw new WireMockException("CSharpCodeMatcher: Unable to create compiler for WireMock.CodeHelper");
throw new WireMockException("CSharpCodeMatcher: Unable to create compiler for WireMock.CodeHelper", ex);
}
try
{
result = script.IsMatch(inputValue);
}
catch
catch (Exception ex)
{
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper");
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper", ex);
}
#elif NETSTANDARD2_0
#elif (NETSTANDARD2_0 || NETSTANDARD2_1)
dynamic script;
try
{
var assembly = CSScriptLib.CSScript.Evaluator.CompileCode(source);
#if NETSTANDARD2_0
script = csscript.GenericExtensions.CreateObject(assembly, "*");
#else
script = CSScriptLib.ReflectionExtensions.CreateObject(assembly,"*");
#endif
}
catch (Exception ex)
{
@@ -164,10 +170,10 @@ namespace WireMock.Matchers
}
catch (Exception ex)
{
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper");
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper", ex);
}
#else
throw new NotSupportedException("The 'CSharpCodeMatcher' cannot be used in netstandard 1.3");
throw new NotSupportedException("The 'CSharpCodeMatcher' cannot be used in netstandard 1.3");
#endif
try
{

View File

@@ -61,7 +61,8 @@ namespace WireMock.Matchers
IgnoreCase = ignoreCase;
MatchBehaviour = matchBehaviour;
RegexOptions options = RegexOptions.Compiled;
RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline;
if (ignoreCase)
{
options |= RegexOptions.IgnoreCase;

View File

@@ -9,14 +9,15 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The request cookie matcher.
/// </summary>
/// <inheritdoc cref="IRequestMatcher"/>
public class RequestMessageCookieMatcher : IRequestMatcher
{
private readonly MatchBehaviour _matchBehaviour;
private readonly bool _ignoreCase;
/// <value>
/// The funcs.
/// </value>
/// <summary>
/// The functions
/// </summary>
public Func<IDictionary<string, string>, bool>[] Funcs { get; }
/// <summary>
@@ -32,11 +33,11 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">The ignoreCase.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase)
{
Check.NotNull(name, nameof(name));
Check.NotNull(pattern, nameof(pattern));
@@ -50,15 +51,32 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params string[] patterns) :
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
{
Check.NotNull(patterns, nameof(patterns));
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
public RequestMessageCookieMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNull(matchers, nameof(matchers));
_matchBehaviour = matchBehaviour;
Name = name;
Matchers = matchers;
_ignoreCase = ignoreCase;
}
/// <summary>

View File

@@ -52,33 +52,32 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string[] patterns, bool ignoreCase)
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params string[] patterns) :
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
{
Check.NotNull(name, nameof(name));
Check.NotNull(patterns, nameof(patterns));
_matchBehaviour = matchBehaviour;
_ignoreCase = ignoreCase;
Name = name;
Matchers = patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray();
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNull(matchers, nameof(matchers));
_matchBehaviour = matchBehaviour;
Name = name;
Matchers = matchers;
_ignoreCase = ignoreCase;
}
/// <summary>
@@ -125,7 +124,7 @@ namespace WireMock.Matchers.Request
}
WireMockList<string> list = headers[Name];
return Matchers.Max(m => list.Max(value => m.IsMatch(value))); // TODO : is this correct ?
return Matchers.Max(m => list.Max(m.IsMatch)); // TODO : is this correct ?
}
}
}

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

@@ -1,172 +1,180 @@
#if USE_ASPNETCORE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using WireMock.Handlers;
using WireMock.HttpsCertificate;
using WireMock.Logging;
using WireMock.Owin.Mappers;
using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Owin
{
internal class AspNetCoreSelfHost : IOwinSelfHost
{
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly IWireMockMiddlewareOptions _options;
private readonly string[] _urls;
private readonly IWireMockLogger _logger;
private Exception _runningException;
private IWebHost _host;
public bool IsStarted { get; private set; }
public List<string> Urls { get; } = new List<string>();
public List<int> Ports { get; } = new List<int>();
public Exception RunningException => _runningException;
public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
{
Check.NotNull(options, nameof(options));
Check.NotNullOrEmpty(uriPrefixes, nameof(uriPrefixes));
_logger = options.Logger ?? new WireMockConsoleLogger();
foreach (string uriPrefix in uriPrefixes)
{
Urls.Add(uriPrefix);
PortUtils.TryExtract(uriPrefix, out string protocol, out string host, out int port);
Ports.Add(port);
}
_options = options;
_urls = uriPrefixes;
}
public Task StartAsync()
{
var builder = new WebHostBuilder();
// Workaround for https://github.com/WireMock-Net/WireMock.Net/issues/292
// On some platforms, AppContext.BaseDirectory is null, which causes WebHostBuilder to fail if ContentRoot is not
// specified (even though we don't actually use that base path mechanism, since we have our own way of configuring
// a filesystem handler).
if (string.IsNullOrEmpty(AppContext.BaseDirectory))
{
builder.UseContentRoot(System.IO.Directory.GetCurrentDirectory());
}
_host = builder
.ConfigureServices(services =>
{
services.AddSingleton(_options.FileSystemHandler);
services.AddSingleton(_options);
services.AddSingleton<IMappingMatcher, MappingMatcher>();
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
})
.Configure(appBuilder =>
{
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
appBuilder.UseMiddleware<WireMockMiddleware>();
_options.PostWireMockMiddlewareInit?.Invoke(appBuilder);
})
.UseKestrel(options =>
{
#if NETSTANDARD1_3
if (_urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
{
options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
}
#else
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore2x
foreach (string url in _urls.Where(u => u.StartsWith("http://", StringComparison.OrdinalIgnoreCase)))
{
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
options.Listen(System.Net.IPAddress.Any, port);
}
foreach (string url in _urls.Where(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
{
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
options.Listen(System.Net.IPAddress.Any, port, listenOptions =>
{
listenOptions.UseHttps(); // PublicCertificateHelper.GetX509Certificate2()
});
}
#endif
})
#if NETSTANDARD1_3
.UseUrls(_urls)
#endif
.Build();
return RunHost(_cts.Token);
}
private Task RunHost(CancellationToken token)
{
try
{
var appLifetime = (IApplicationLifetime)_host.Services.GetService(typeof(IApplicationLifetime));
appLifetime.ApplicationStarted.Register(() =>
{
IsStarted = true;
});
#if NETSTANDARD1_3
_logger.Info("WireMock.Net server using netstandard1.3");
#elif NETSTANDARD2_0
_logger.Info("WireMock.Net server using netstandard2.0");
#elif NET46
_logger.Info("WireMock.Net server using .net 4.6.1 or higher");
#endif
#if NETSTANDARD1_3
return Task.Run(() =>
{
_host.Run(token);
});
#else
return _host.RunAsync(token);
#endif
}
catch (Exception e)
{
_runningException = e;
_logger.Error(e.ToString());
IsStarted = false;
return Task.CompletedTask;
}
}
public Task StopAsync()
{
_cts.Cancel();
IsStarted = false;
#if NETSTANDARD1_3
return Task.FromResult(true);
#else
return _host.StopAsync();
#endif
}
}
}
#if USE_ASPNETCORE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
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;
using WireMock.Validation;
namespace WireMock.Owin
{
internal class AspNetCoreSelfHost : IOwinSelfHost
{
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly IWireMockMiddlewareOptions _options;
private readonly IWireMockLogger _logger;
private readonly HostUrlOptions _urlOptions;
private Exception _runningException;
private IWebHost _host;
public bool IsStarted { get; private set; }
public List<string> Urls { get; } = new List<string>();
public List<int> Ports { get; } = new List<int>();
public Exception RunningException => _runningException;
public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions)
{
Check.NotNull(options, nameof(options));
Check.NotNull(urlOptions, nameof(urlOptions));
_logger = options.Logger ?? new WireMockConsoleLogger();
_options = options;
_urlOptions = urlOptions;
}
public Task StartAsync()
{
var builder = new WebHostBuilder();
// Workaround for https://github.com/WireMock-Net/WireMock.Net/issues/292
// On some platforms, AppContext.BaseDirectory is null, which causes WebHostBuilder to fail if ContentRoot is not
// specified (even though we don't actually use that base path mechanism, since we have our own way of configuring
// a filesystem handler).
if (string.IsNullOrEmpty(AppContext.BaseDirectory))
{
builder.UseContentRoot(System.IO.Directory.GetCurrentDirectory());
}
_host = builder
.ConfigureServices(services =>
{
services.AddSingleton(_options);
services.AddSingleton<IMappingMatcher, MappingMatcher>();
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
})
.Configure(appBuilder =>
{
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
appBuilder.UseMiddleware<WireMockMiddleware>();
_options.PostWireMockMiddlewareInit?.Invoke(appBuilder);
})
.UseKestrel(options =>
{
var urlDetails = _urlOptions.GetDetails();
#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
})
#if NETSTANDARD1_3
.UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray())
#endif
.Build();
return RunHost(_cts.Token);
}
private Task RunHost(CancellationToken token)
{
try
{
var appLifetime = (IApplicationLifetime)_host.Services.GetService(typeof(IApplicationLifetime));
appLifetime.ApplicationStarted.Register(() =>
{
var addresses = _host.ServerFeatures
.Get<Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>()
.Addresses;
foreach (string address in addresses)
{
Urls.Add(address.Replace("0.0.0.0", "localhost"));
PortUtils.TryExtract(address, out string protocol, out string host, out int port);
Ports.Add(port);
}
IsStarted = true;
});
#if NETSTANDARD1_3
_logger.Info("WireMock.Net server using netstandard1.3");
#elif NETSTANDARD2_0
_logger.Info("WireMock.Net server using netstandard2.0");
#elif NETSTANDARD2_1
_logger.Info("WireMock.Net server using netstandard2.1");
#elif NET46
_logger.Info("WireMock.Net server using .net 4.6.1 or higher");
#endif
#if NETSTANDARD1_3
return Task.Run(() =>
{
_host.Run(token);
});
#else
return _host.RunAsync(token);
#endif
}
catch (Exception e)
{
_runningException = e;
_logger.Error(e.ToString());
IsStarted = false;
return Task.CompletedTask;
}
}
public Task StopAsync()
{
_cts.Cancel();
IsStarted = false;
#if NETSTANDARD1_3
return Task.FromResult(true);
#else
return _host.StopAsync();
#endif
}
}
}
#endif

View File

@@ -0,0 +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
}
}
}

View File

@@ -39,5 +39,11 @@ namespace WireMock.Owin
IFileSystemHandler FileSystemHandler { get; set; }
bool? AllowBodyForAllHttpMethods { get; set; }
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,15 @@ 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);
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

@@ -1,16 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using RandomDataGenerator.FieldOptions;
using RandomDataGenerator.Randomizers;
using WireMock.Exceptions;
using WireMock.Handlers;
using WireMock.Http;
using WireMock.ResponseBuilders;
using WireMock.Types;
using WireMock.Util;
using WireMock.Validation;
#if !USE_ASPNETCORE
using IResponse = Microsoft.Owin.IOwinResponse;
@@ -24,11 +25,11 @@ namespace WireMock.Owin.Mappers
/// <summary>
/// OwinResponseMapper
/// </summary>
public class OwinResponseMapper : IOwinResponseMapper
internal class OwinResponseMapper : IOwinResponseMapper
{
private readonly IRandomizerNumber<double> _randomizerDouble = RandomizerFactory.GetRandomizer(new FieldOptionsDouble { Min = 0, Max = 1 });
private readonly IRandomizerBytes _randomizerBytes = RandomizerFactory.GetRandomizer(new FieldOptionsBytes { Min = 100, Max = 200 });
private readonly IFileSystemHandler _fileSystemHandler;
private readonly IWireMockMiddlewareOptions _options;
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
// https://msdn.microsoft.com/en-us/library/78h415ay(v=vs.110).aspx
@@ -43,12 +44,12 @@ namespace WireMock.Owin.Mappers
/// <summary>
/// Constructor
/// </summary>
/// <param name="fileSystemHandler">The IFileSystemHandler.</param>
public OwinResponseMapper(IFileSystemHandler fileSystemHandler)
/// <param name="options">The IWireMockMiddlewareOptions.</param>
public OwinResponseMapper(IWireMockMiddlewareOptions options)
{
Check.NotNull(fileSystemHandler, nameof(fileSystemHandler));
Check.NotNull(options, nameof(options));
_fileSystemHandler = fileSystemHandler;
_options = options;
}
/// <inheritdoc cref="IOwinResponseMapper.MapAsync"/>
@@ -83,11 +84,13 @@ namespace WireMock.Owin.Mappers
switch (responseMessage.StatusCode)
{
case int statusCodeAsInteger:
response.StatusCode = statusCodeAsInteger;
response.StatusCode = MapStatusCode(statusCodeAsInteger);
break;
case string statusCodeAsString:
response.StatusCode = int.Parse(statusCodeAsString);
// Note: this case will also match on null
int.TryParse(statusCodeAsString, out int result);
response.StatusCode = MapStatusCode(result);
break;
}
@@ -99,6 +102,16 @@ namespace WireMock.Owin.Mappers
}
}
private int MapStatusCode(int code)
{
if (_options.AllowOnlyDefinedHttpStatusCodeInResponse == true && !Enum.IsDefined(typeof(HttpStatusCode), code))
{
return (int)HttpStatusCode.OK;
}
return code;
}
private bool IsFault(ResponseMessage responseMessage)
{
return responseMessage.FaultPercentage == null || _randomizerDouble.Generate() <= responseMessage.FaultPercentage;
@@ -126,7 +139,7 @@ namespace WireMock.Owin.Mappers
break;
case BodyType.File:
bytes = _fileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile);
bytes = _options.FileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile);
break;
}

View File

@@ -6,10 +6,8 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using WireMock.Handlers;
using WireMock.Logging;
using WireMock.Owin.Mappers;
using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Owin
@@ -19,24 +17,22 @@ namespace WireMock.Owin
private readonly IWireMockMiddlewareOptions _options;
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly IWireMockLogger _logger;
private Exception _runningException;
public OwinSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
public OwinSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions)
{
Check.NotNull(options, nameof(options));
Check.NotNullOrEmpty(uriPrefixes, nameof(uriPrefixes));
_logger = options.Logger ?? new WireMockConsoleLogger();
foreach (string uriPrefix in uriPrefixes)
{
Urls.Add(uriPrefix);
PortUtils.TryExtract(uriPrefix, out string protocol, out string host, out int port);
Ports.Add(port);
}
Check.NotNull(urlOptions, nameof(urlOptions));
_options = options;
_logger = options.Logger ?? new WireMockConsoleLogger();
foreach (var detail in urlOptions.GetDetails())
{
Urls.Add(detail.Url);
Ports.Add(detail.Port);
}
}
public bool IsStarted { get; private set; }
@@ -76,7 +72,7 @@ namespace WireMock.Owin
try
{
var requestMapper = new OwinRequestMapper();
var responseMapper = new OwinResponseMapper(_options.FileSystemHandler);
var responseMapper = new OwinResponseMapper(_options);
var matcher = new MappingMatcher(_options);
Action<IAppBuilder> startup = app =>

View File

@@ -42,5 +42,14 @@ namespace WireMock.Owin
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowBodyForAllHttpMethods"/>
public bool? AllowBodyForAllHttpMethods { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowOnlyDefinedHttpStatusCodeInResponse"/>
public bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableJsonBodyParsing"/>
public bool? DisableJsonBodyParsing { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableRequestBodyDecompressing"/>
public bool? DisableRequestBodyDecompressing { get; set; }
}
}

View File

@@ -0,0 +1,85 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using WireMock.Matchers;
namespace WireMock.RequestBuilders
{
/// <summary>
/// The CookieRequestBuilder interface.
/// </summary>
public interface ICookiesRequestBuilder : IParamsRequestBuilder
{
/// <summary>
/// WithCookie: matching based on name, pattern and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, string pattern, MatchBehaviour matchBehaviour);
/// <summary>
/// WithCookie: matching based on name, pattern, ignoreCase and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithCookie: matching based on name, patterns and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, string[] patterns, MatchBehaviour matchBehaviour);
/// <summary>
/// WithCookie: matching based on name, patterns, ignoreCase and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithCookie: matching based on name and IStringMatcher[].
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// WithCookie: matching based on name, ignoreCase and IStringMatcher[].
/// </summary>
/// <param name="name">The name.</param>
/// <param name="ignoreCase">Ignore the case from the cookie-keys.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// WithCookie: matching based on name, ignoreCase, matchBehaviour and IStringMatcher[].
/// </summary>
/// <param name="name">The name.</param>
/// <param name="ignoreCase">Ignore the case from the cookie-keys.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, bool ignoreCase, MatchBehaviour matchBehaviour, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// WithCookie: matching based on functions.
/// </summary>
/// <param name="funcs">The cookies funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] params Func<IDictionary<string, string>, bool>[] funcs);
}
}

View File

@@ -6,9 +6,9 @@ using WireMock.Matchers;
namespace WireMock.RequestBuilders
{
/// <summary>
/// The HeadersAndCookieRequestBuilder interface.
/// The HeadersRequestBuilder interface.
/// </summary>
public interface IHeadersAndCookiesRequestBuilder : IParamsRequestBuilder
public interface IHeadersRequestBuilder : ICookiesRequestBuilder
{
/// <summary>
/// WithHeader: matching based on name, pattern and matchBehaviour.
@@ -56,36 +56,30 @@ namespace WireMock.RequestBuilders
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// WithHeader: matching based on name, ignoreCase and IStringMatcher[].
/// </summary>
/// <param name="name">The name.</param>
/// <param name="ignoreCase">Ignore the case from the header-keys.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// WithHeader: matching based on name, ignoreCase, matchBehaviour and IStringMatcher[].
/// </summary>
/// <param name="name">The name.</param>
/// <param name="ignoreCase">Ignore the case from the header-keys.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, bool ignoreCase, MatchBehaviour matchBehaviour, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// WithHeader: matching based on functions.
/// </summary>
/// <param name="funcs">The headers funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string[]>, bool>[] funcs);
/// <summary>
/// WithCookie: cookie matching based on name, pattern, ignoreCase and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithCookie: matching based on name and IStringMatcher[].
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// WithCookie: matching based on functions.
/// </summary>
/// <param name="funcs">The funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] params Func<IDictionary<string, string>, bool>[] funcs);
}
}

View File

@@ -7,8 +7,15 @@ namespace WireMock.RequestBuilders
/// <summary>
/// The MethodRequestBuilder interface.
/// </summary>
public interface IMethodRequestBuilder : IHeadersAndCookiesRequestBuilder
public interface IMethodRequestBuilder : IHeadersRequestBuilder
{
/// <summary>
/// UsingConnect: add HTTP Method matching on `CONNECT` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingDelete: add HTTP Method matching on `DELETE` and matchBehaviour (optional).
/// </summary>
@@ -24,7 +31,7 @@ namespace WireMock.RequestBuilders
IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
/// UsingHead: Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
@@ -44,6 +51,13 @@ namespace WireMock.RequestBuilders
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingPut: add HTTP Method matching on `OPTIONS` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingPut: add HTTP Method matching on `PUT` and matchBehaviour (optional).
/// </summary>
@@ -51,6 +65,13 @@ namespace WireMock.RequestBuilders
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingTrace: add HTTP Method matching on `TRACE` and matchBehaviour (optional).
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// UsingAnyMethod: add HTTP Method matching on any method.
/// </summary>

View File

@@ -0,0 +1,115 @@
// 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;
using WireMock.Validation;
namespace WireMock.RequestBuilders
{
public partial class Request
{
/// <inheritdoc cref="IMethodRequestBuilder.UsingConnect(MatchBehaviour)"/>
public IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.CONNECT));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.DELETE));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.GET));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.HEAD));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingOptions(MatchBehaviour)"/>
public IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.OPTIONS));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.POST));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PATCH));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PUT));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingTrace(MatchBehaviour)"/>
public IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.TRACE));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
public IRequestBuilder UsingAnyMethod()
{
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
foreach (var matcher in matchers)
{
_requestMatchers.Remove(matcher);
}
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
public IRequestBuilder UsingAnyVerb()
{
return UsingAnyMethod();
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
public IRequestBuilder UsingMethod(params string[] methods)
{
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
public IRequestBuilder UsingVerb(params string[] verbs)
{
return UsingMethod(verbs);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
{
Check.NotNullOrEmpty(methods, nameof(methods));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
return this;
}
}
}

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

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Validation;
namespace WireMock.RequestBuilders
{
public partial class Request
{
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, string, MatchBehaviour)"/>
public IRequestBuilder WithCookie(string name, string pattern, MatchBehaviour matchBehaviour)
{
return WithCookie(name, pattern, true, matchBehaviour);
}
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, string, bool, MatchBehaviour)"/>
public IRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
Check.NotNull(name, nameof(name));
Check.NotNull(pattern, nameof(pattern));
_requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, pattern, ignoreCase));
return this;
}
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, string[], MatchBehaviour)"/>
public IRequestBuilder WithCookie(string name, string[] patterns, MatchBehaviour matchBehaviour)
{
return WithCookie(name, patterns, true, matchBehaviour);
}
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, string[], bool, MatchBehaviour)"/>
public IRequestBuilder WithCookie(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
Check.NotNull(name, nameof(name));
Check.NotNull(patterns, nameof(patterns));
_requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, ignoreCase, patterns));
return this;
}
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, IStringMatcher[])"/>
public IRequestBuilder WithCookie(string name, params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNullOrEmpty(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, name, false, matchers));
return this;
}
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, bool, IStringMatcher[])"/>
public IRequestBuilder WithCookie(string name, bool ignoreCase, params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNullOrEmpty(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, name, ignoreCase, matchers));
return this;
}
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(string, IStringMatcher[])"/>
public IRequestBuilder WithCookie(string name, bool ignoreCase, MatchBehaviour matchBehaviour, params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNullOrEmpty(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, ignoreCase, matchers));
return this;
}
/// <inheritdoc cref="ICookiesRequestBuilder.WithCookie(Func{IDictionary{string, string}, bool}[])"/>
public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));
_requestMatchers.Add(new RequestMessageCookieMatcher(funcs));
return this;
}
}
}

View File

@@ -0,0 +1,84 @@
// 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;
using WireMock.Validation;
namespace WireMock.RequestBuilders
{
public partial class Request
{
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string, MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour)
{
return WithHeader(name, pattern, true, matchBehaviour);
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string, bool, MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
Check.NotNull(name, nameof(name));
Check.NotNull(pattern, nameof(pattern));
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, pattern, ignoreCase));
return this;
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string[], MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour)
{
return WithHeader(name, patterns, true, matchBehaviour);
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string[], bool, MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
Check.NotNull(name, nameof(name));
Check.NotNull(patterns, nameof(patterns));
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, ignoreCase, patterns));
return this;
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, IStringMatcher[])"/>
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNullOrEmpty(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, name, false, matchers));
return this;
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, bool, IStringMatcher[])"/>
public IRequestBuilder WithHeader(string name, bool ignoreCase, params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNullOrEmpty(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, name, ignoreCase, matchers));
return this;
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, IStringMatcher[])"/>
public IRequestBuilder WithHeader(string name, bool ignoreCase, MatchBehaviour matchBehaviour, params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNullOrEmpty(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, ignoreCase, matchers));
return this;
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(Func{IDictionary{string, string[]}, bool}[])"/>
public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
return this;
}
}
}

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;
@@ -151,162 +153,5 @@ namespace WireMock.RequestBuilders
_requestMatchers.Add(new RequestMessageUrlMatcher(funcs));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "DELETE"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "GET"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "HEAD"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "POST"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "PATCH"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "PUT"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
public IRequestBuilder UsingAnyMethod()
{
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
foreach (var matcher in matchers)
{
_requestMatchers.Remove(matcher);
}
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
public IRequestBuilder UsingAnyVerb()
{
return UsingAnyMethod();
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
public IRequestBuilder UsingMethod(params string[] methods)
{
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
public IRequestBuilder UsingVerb(params string[] verbs)
{
return UsingMethod(verbs);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
{
Check.NotNullOrEmpty(methods, nameof(methods));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string, MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour)
{
return WithHeader(name, pattern, true, matchBehaviour);
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string, bool, MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
Check.NotNull(name, nameof(name));
Check.NotNull(pattern, nameof(pattern));
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, pattern, ignoreCase));
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string[], MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour)
{
return WithHeader(name, patterns, true, matchBehaviour);
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string[], bool, MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
Check.NotNull(name, nameof(name));
Check.NotNull(patterns, nameof(patterns));
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, patterns, ignoreCase));
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, IStringMatcher[])"/>
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNullOrEmpty(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, matchers));
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(Func{IDictionary{string, string[]}, bool}[])"/>
public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(string, string, bool, MatchBehaviour)"/>
public IRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, pattern, ignoreCase));
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(string, IStringMatcher[])"/>
public IRequestBuilder WithCookie(string name, params IStringMatcher[] matchers)
{
Check.NotNullOrEmpty(matchers, nameof(matchers));
_requestMatchers.Add(new RequestMessageCookieMatcher(name, matchers));
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(Func{IDictionary{string, string}, bool}[])"/>
public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));
_requestMatchers.Add(new RequestMessageCookieMatcher(funcs));
return this;
}
}
}

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;
@@ -110,6 +112,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 +175,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,4 +1,5 @@
using System.Net;
using WireMock.Settings;
namespace WireMock.ResponseBuilders
{
@@ -9,6 +10,7 @@ namespace WireMock.ResponseBuilders
{
/// <summary>
/// The with status code.
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
@@ -16,6 +18,7 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// The with status code.
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
@@ -23,6 +26,7 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// The with status code.
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>

View File

@@ -1,12 +1,12 @@
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.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Http;
using WireMock.ResponseProviders;
using WireMock.Settings;
@@ -60,7 +60,7 @@ namespace WireMock.ResponseBuilders
[PublicAPI]
public static IResponseBuilder Create([CanBeNull] ResponseMessage responseMessage = null)
{
var message = responseMessage ?? new ResponseMessage { StatusCode = (int)HttpStatusCode.OK };
var message = responseMessage ?? new ResponseMessage(); // { StatusCode = (int)HttpStatusCode.OK };
return new Response(message);
}
@@ -341,47 +341,56 @@ namespace WireMock.ResponseBuilders
await Task.Delay(Delay.Value);
}
if (Callback != null)
{
var callbackResponseMessage = Callback(requestMessage);
if (!WithCallbackUsed)
{
// Copy StatusCode from ResponseMessage
callbackResponseMessage.StatusCode = ResponseMessage.StatusCode;
// Copy Headers from ResponseMessage (if defined)
if (ResponseMessage.Headers != null)
{
callbackResponseMessage.Headers = ResponseMessage.Headers;
}
}
return callbackResponseMessage;
}
if (ProxyUrl != null && _httpClientForProxy != null)
{
var requestUri = new Uri(requestMessage.Url);
var proxyUri = new Uri(ProxyUrl);
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
return await HttpClientHelper.SendAsync(
_httpClientForProxy,
requestMessage,
proxyUriWithRequestPathAndQuery.AbsoluteUri,
!settings.DisableJsonBodyParsing.GetValueOrDefault(false),
!settings.DisableRequestBodyDecompressing.GetValueOrDefault(false)
);
}
ResponseMessage responseMessage;
if (Callback == null)
{
responseMessage = ResponseMessage;
}
else
{
responseMessage = Callback(requestMessage);
if (!WithCallbackUsed)
{
// Copy StatusCode from ResponseMessage
responseMessage.StatusCode = ResponseMessage.StatusCode;
// Copy Headers from ResponseMessage (if defined)
if (ResponseMessage.Headers != null)
{
responseMessage.Headers = ResponseMessage.Headers;
}
}
}
if (UseTransformer)
{
var factory = new HandlebarsContextFactory(settings.FileSystemHandler, settings.HandlebarsRegistrationCallback);
var responseMessageTransformer = new ResponseMessageTransformer(factory);
return responseMessageTransformer.Transform(requestMessage, ResponseMessage, UseTransformerForBodyAsFile);
return responseMessageTransformer.Transform(requestMessage, responseMessage, UseTransformerForBodyAsFile);
}
if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true)
{
ResponseMessage.BodyData.BodyAsBytes = settings.FileSystemHandler.ReadResponseBodyAsFile(ResponseMessage.BodyData.BodyAsFile);
ResponseMessage.BodyData.BodyAsBytes = settings.FileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile);
}
return ResponseMessage;
return responseMessage;
}
}
}

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;
@@ -20,7 +22,7 @@ namespace WireMock
/// <summary>
/// Gets or sets the status code.
/// </summary>
public object StatusCode { get; set; } = 200;
public object StatusCode { get; set; }
/// <summary>
/// Gets or sets the body.

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

@@ -5,9 +5,8 @@ using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Settings;
using WireMock.Util;
using WireMock.Validation;
using WireMock.Types;
using WireMock.Validation;
namespace WireMock.Serialization
{
@@ -27,9 +26,9 @@ namespace WireMock.Serialization
var request = (Request)mapping.RequestMatcher;
var response = (Response)mapping.Provider;
var clientIPMatchers = request.GetRequestMessageMatchers<RequestMessageClientIPMatcher>();
var pathMatchers = request.GetRequestMessageMatchers<RequestMessagePathMatcher>();
var urlMatchers = request.GetRequestMessageMatchers<RequestMessageUrlMatcher>();
var clientIPMatchers = request.GetRequestMessageMatchers<RequestMessageClientIPMatcher>().Where(m => m.Matchers != null).SelectMany(m => m.Matchers).ToList();
var pathMatchers = request.GetRequestMessageMatchers<RequestMessagePathMatcher>().Where(m => m.Matchers != null).SelectMany(m => m.Matchers).ToList();
var urlMatchers = request.GetRequestMessageMatchers<RequestMessageUrlMatcher>().Where(m => m.Matchers != null).SelectMany(m => m.Matchers).ToList();
var headerMatchers = request.GetRequestMessageMatchers<RequestMessageHeaderMatcher>();
var cookieMatchers = request.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
@@ -46,36 +45,36 @@ namespace WireMock.Serialization
SetStateTo = mapping.NextState,
Request = new RequestModel
{
ClientIP = clientIPMatchers != null && clientIPMatchers.Any() ? new ClientIPModel
ClientIP = clientIPMatchers.Any() ? new ClientIPModel
{
Matchers = _mapper.Map(clientIPMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers))
Matchers = _mapper.Map(clientIPMatchers)
} : null,
Path = pathMatchers != null && pathMatchers.Any() ? new PathModel
Path = pathMatchers.Any() ? new PathModel
{
Matchers = _mapper.Map(pathMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers))
Matchers = _mapper.Map(pathMatchers)
} : null,
Url = urlMatchers != null && urlMatchers.Any() ? new UrlModel
Url = urlMatchers.Any() ? new UrlModel
{
Matchers = _mapper.Map(urlMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers))
Matchers = _mapper.Map(urlMatchers)
} : null,
Methods = methodMatcher?.Methods,
Headers = headerMatchers != null && headerMatchers.Any() ? headerMatchers.Select(hm => new HeaderModel
Headers = headerMatchers.Any() ? headerMatchers.Select(hm => new HeaderModel
{
Name = hm.Name,
Matchers = _mapper.Map(hm.Matchers)
}).ToList() : null,
Cookies = cookieMatchers != null && cookieMatchers.Any() ? cookieMatchers.Select(cm => new CookieModel
Cookies = cookieMatchers.Any() ? cookieMatchers.Select(cm => new CookieModel
{
Name = cm.Name,
Matchers = _mapper.Map(cm.Matchers)
}).ToList() : null,
Params = paramsMatchers != null && paramsMatchers.Any() ? paramsMatchers.Select(pm => new ParamModel
Params = paramsMatchers.Any() ? paramsMatchers.Select(pm => new ParamModel
{
Name = pm.Key,
IgnoreCase = pm.IgnoreCase == true ? true : (bool?)null,
@@ -125,11 +124,17 @@ namespace WireMock.Serialization
mappingModel.Response.WebProxy = null;
mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
mappingModel.Response.Headers = MapHeaders(response.ResponseMessage.Headers);
if (response.ResponseMessage.Headers != null && response.ResponseMessage.Headers.Count > 0)
{
mappingModel.Response.Headers = MapHeaders(response.ResponseMessage.Headers);
}
if (response.UseTransformer)
{
mappingModel.Response.UseTransformer = response.UseTransformer;
}
if (response.UseTransformerForBodyAsFile)
{
mappingModel.Response.UseTransformerForBodyAsFile = response.UseTransformerForBodyAsFile;
@@ -198,12 +203,6 @@ namespace WireMock.Serialization
private static IDictionary<string, object> MapHeaders(IDictionary<string, WireMockList<string>> dictionary)
{
var newDictionary = new Dictionary<string, object>();
if (dictionary == null || dictionary.Count == 0)
{
return newDictionary;
}
foreach (var entry in dictionary)
{
object value = entry.Value.Count == 1 ? (object)entry.Value.ToString() : entry.Value;

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

@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
@@ -274,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);
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))
@@ -554,11 +561,63 @@ namespace WireMock.Server
private ResponseMessage MappingsDelete(RequestMessage requestMessage)
{
ResetMappings();
if (!string.IsNullOrEmpty(requestMessage.Body))
{
var deletedGuids = MappingsDeleteMappingFromBody(requestMessage);
if (deletedGuids != null)
{
return ResponseMessageBuilder.Create($"Mappings deleted. Affected GUIDs: [{string.Join(", ", deletedGuids.ToArray())}]");
}
else
{
// return bad request
return ResponseMessageBuilder.Create("Poorly formed mapping JSON.", 400);
}
}
else
{
ResetMappings();
ResetScenarios();
ResetScenarios();
return ResponseMessageBuilder.Create("Mappings deleted");
return ResponseMessageBuilder.Create("Mappings deleted");
}
}
private IEnumerable<Guid> MappingsDeleteMappingFromBody(RequestMessage requestMessage)
{
var deletedGuids = new List<Guid>();
try
{
var mappingModels = DeserializeRequestMessageToArray<MappingModel>(requestMessage);
foreach (var mappingModel in mappingModels)
{
if (mappingModel.Guid.HasValue)
{
if (DeleteMapping(mappingModel.Guid.Value))
{
deletedGuids.Add(mappingModel.Guid.Value);
}
else
{
_settings.Logger.Debug($"Did not find/delete mapping with GUID: {mappingModel.Guid.Value}.");
}
}
}
}
catch (ArgumentException a)
{
_settings.Logger.Error("ArgumentException: {0}", a);
return null;
}
catch (Exception e)
{
_settings.Logger.Error("Exception: {0}", e);
return null;
}
return deletedGuids;
}
private ResponseMessage MappingsReset(RequestMessage requestMessage)
@@ -744,7 +803,12 @@ namespace WireMock.Server
{
foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))
{
requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
requestBuilder = requestBuilder.WithHeader(
headerModel.Name,
headerModel.IgnoreCase == true,
headerModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
headerModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray()
);
}
}
@@ -752,7 +816,11 @@ namespace WireMock.Server
{
foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
{
requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
requestBuilder = requestBuilder.WithCookie(
cookieModel.Name,
cookieModel.IgnoreCase == true,
cookieModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
cookieModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
}
}
@@ -808,12 +876,13 @@ namespace WireMock.Server
return responseBuilder.WithProxy(proxyAndRecordSettings);
}
if (responseModel.StatusCode is string)
if (responseModel.StatusCode is string statusCodeAsString)
{
responseBuilder = responseBuilder.WithStatusCode((string) responseModel.StatusCode);
responseBuilder = responseBuilder.WithStatusCode(statusCodeAsString);
}
else
else if (responseModel.StatusCode != null)
{
// Convert to Int32 because Newtonsoft deserializes an 'object' with a number value to a long.
responseBuilder = responseBuilder.WithStatusCode(Convert.ToInt32(responseModel.StatusCode));
}
@@ -871,7 +940,7 @@ namespace WireMock.Server
DetectedBodyType = BodyType.String,
BodyAsString = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _jsonSerializerSettings)
},
StatusCode = 200,
StatusCode = (int)HttpStatusCode.OK,
Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMockList<string>(ContentTypeJson) } }
};
}

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
@@ -202,31 +203,37 @@ namespace WireMock.Server
_settings.Logger.Info("WireMock.Net by Stef Heyenrath (https://github.com/WireMock-Net/WireMock.Net)");
_settings.Logger.Debug("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
HostUrlOptions urlOptions;
if (settings.Urls != null)
{
Urls = settings.Urls.ToArray();
urlOptions = new HostUrlOptions
{
Urls = settings.Urls
};
}
else
{
int port = settings.Port > 0 ? settings.Port.Value : PortUtils.FindFreeTcpPort();
Urls = new[] { $"{(settings.UseSSL == true ? "https" : "http")}://localhost:{port}" };
urlOptions = new HostUrlOptions
{
UseSSL = settings.UseSSL == true,
Port = settings.Port
};
}
_options.FileSystemHandler = _settings.FileSystemHandler;
_options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
_options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
_options.PreWireMockMiddlewareInit = _settings.PreWireMockMiddlewareInit;
_options.PostWireMockMiddlewareInit = _settings.PostWireMockMiddlewareInit;
_options.Logger = _settings.Logger;
_options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing;
_matcherMapper = new MatcherMapper(_settings);
_mappingConverter = new MappingConverter(_matcherMapper);
#if USE_ASPNETCORE
_httpServer = new AspNetCoreSelfHost(_options, Urls);
_httpServer = new AspNetCoreSelfHost(_options, urlOptions);
#else
_httpServer = new OwinSelfHost(_options, Urls);
_httpServer = new OwinSelfHost(_options, urlOptions);
#endif
Ports = _httpServer.Ports;
var startTask = _httpServer.StartAsync();
using (var ctsStartTimeout = new CancellationTokenSource(settings.StartTimeout))
@@ -253,12 +260,21 @@ namespace WireMock.Server
ctsStartTimeout.Token.WaitHandle.WaitOne(ServerStartDelayInMs);
}
Urls = _httpServer.Urls.ToArray();
Ports = _httpServer.Ports;
}
if (settings.AllowBodyForAllHttpMethods == true)
{
_options.AllowBodyForAllHttpMethods = _settings.AllowBodyForAllHttpMethods;
_settings.Logger.Info("AllowBodyForAllHttpMethods is set to {0}", _settings.AllowBodyForAllHttpMethods == true);
_settings.Logger.Info("AllowBodyForAllHttpMethods is set to True");
}
if (settings.AllowOnlyDefinedHttpStatusCodeInResponse == true)
{
_options.AllowOnlyDefinedHttpStatusCodeInResponse = _settings.AllowOnlyDefinedHttpStatusCodeInResponse;
_settings.Logger.Info("AllowOnlyDefinedHttpStatusCodeInResponse is set to True");
}
if (settings.AllowPartialMapping == true)

View File

@@ -1,141 +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; }
}
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

@@ -101,5 +101,17 @@ namespace WireMock.Settings
/// <inheritdoc cref="IWireMockServerSettings.AllowBodyForAllHttpMethods"/>
[PublicAPI]
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

@@ -34,7 +34,9 @@ namespace WireMock.Settings
MaxRequestLogCount = parser.GetIntValue("MaxRequestLogCount"),
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
AllowCSharpCodeMatcher = parser.GetBoolValue("AllowCSharpCodeMatcher"),
AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods")
AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods"),
AllowOnlyDefinedHttpStatusCodeInResponse = parser.GetBoolValue("AllowOnlyDefinedHttpStatusCodeInResponse"),
DisableJsonBodyParsing = parser.GetBoolValue("DisableJsonBodyParsing")
};
if (logger != null)

View File

@@ -30,7 +30,7 @@ namespace WireMock.Transformers
var template = new { request = requestMessage };
switch (original.BodyData.DetectedBodyType)
switch (original.BodyData?.DetectedBodyType)
{
case BodyType.Json:
TransformBodyAsJson(handlebarsContext.Handlebars, template, original, responseMessage);

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,7 @@ 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;
using WireMock.Validation;
@@ -30,15 +30,15 @@ namespace WireMock.Util
*/
private static readonly IDictionary<string, bool> BodyAllowedForMethods = new Dictionary<string, bool>
{
{ "HEAD", false },
{ "GET", false },
{ "PUT", true },
{ "POST", true },
{ "DELETE", false },
{ "TRACE", false },
{ "OPTIONS", true },
{ "CONNECT", false },
{ "PATCH", true }
{ HttpRequestMethods.HEAD, false },
{ HttpRequestMethods.GET, false },
{ HttpRequestMethods.PUT, true },
{ HttpRequestMethods.POST, true },
{ HttpRequestMethods.DELETE, true },
{ HttpRequestMethods.TRACE, false },
{ HttpRequestMethods.OPTIONS, true },
{ HttpRequestMethods.CONNECT, false },
{ HttpRequestMethods.PATCH, true }
};
private static readonly IStringMatcher[] MultipartContentTypesMatchers = {
@@ -107,15 +107,17 @@ namespace WireMock.Util
return BodyType.Bytes;
}
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType)
public static async Task<BodyData> Parse([NotNull] 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
@@ -127,8 +129,6 @@ namespace WireMock.Util
data.BodyAsString = encoding.GetString(data.BodyAsBytes);
data.Encoding = encoding;
data.DetectedBodyType = BodyType.String;
return data;
}
return data;
@@ -142,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 (!string.IsNullOrEmpty(data.BodyAsString))
if (settings.DeserializeJson && !string.IsNullOrEmpty(data.BodyAsString))
{
try
{
@@ -162,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

@@ -151,7 +151,7 @@ namespace WireMock.Util
break;
case JTokenType.Integer:
castText = $"int({path})";
castText = $"long({path})";
break;
case JTokenType.Null:

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

@@ -0,0 +1,36 @@
using System.IO;
namespace WireMock.Util
{
internal static class PathUtils
{
/// <summary>
/// Robust handling of the user defined path.
/// Also supports Unix and Windows platforms
/// </summary>
/// <param name="path">The path to clean</param>
public static string CleanPath(string path)
{
return path?.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar);
}
/// <summary>
/// Removes leading directory separator chars from the filepath, which could break Path.Combine
/// </summary>
/// <param name="path">The path to remove the loading DirectorySeparatorChars</param>
public static string RemoveLeadingDirectorySeparators(string path)
{
return path?.TrimStart(new[] { Path.DirectorySeparatorChar });
}
/// <summary>
/// Combine two paths
/// </summary>
/// <param name="root">The root path</param>
/// <param name="path">The path</param>
public static string Combine(string root, string path)
{
return Path.Combine(root, RemoveLeadingDirectorySeparators(path));
}
}
}

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,30 +3,20 @@
<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</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>
<!--<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<CodeAnalysisRuleSet>WireMock.Net.ruleset</CodeAnalysisRuleSet>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>-->
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>WireMock.Net.snk</AssemblyOriginatorKeyFile>
<!--<DelaySign>true</DelaySign>-->
@@ -37,15 +27,20 @@
<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'">
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
<!--<PathMap>$(MSBuildProjectDirectory)=/</PathMap>-->
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0'">
<PropertyGroup Condition="'$(Configuration)' == 'Debug - Sonar'">
<CodeAnalysisRuleSet>WireMock.Net.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'">
<DefineConstants>NETSTANDARD;USE_ASPNETCORE</DefineConstants>
</PropertyGroup>
@@ -57,29 +52,22 @@
<DefineConstants>USE_ASPNETCORE;NET46</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Remove="RequestBuilders\Request.WithFault.cs" />
<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="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" />
</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" />
<!--<PackageReference Include="CloneExtensionsEx" Version="1.0.2" />-->
<!--<PackageReference Include="FastDeepCloner" Version="1.2.5" />-->
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
@@ -140,6 +128,13 @@
<PackageReference Include="CS-Script.Core" Version="1.1.1" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.1'">
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.4" />
<!-- https://github.com/WireMock-Net/WireMock.Net/issues/448 -->
<PackageReference Include="CS-Script.Core" Version="1.3.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
</ItemGroup>

View File

@@ -70,12 +70,13 @@ namespace WireMock.Net.Tests.Matchers
// Assign
var input = new JObject
{
{ "Id", new JValue(9) },
{ "IntegerId", new JValue(9) },
{ "LongId", new JValue(long.MaxValue) },
{ "Name", new JValue("Test") }
};
// Act
var matcher = new LinqMatcher("Id > 1 AND Name == \"Test\"");
var matcher = new LinqMatcher("IntegerId > 1 AND LongId > 1 && Name == \"Test\"");
double match = matcher.IsMatch(input);
// Assert

View File

@@ -96,7 +96,7 @@ namespace WireMock.Net.Tests
var listOfTasks = new List<Task<HttpResponseMessage>>();
for (var i = 0; i < expectedCount; i++)
{
Thread.Sleep(10);
Thread.Sleep(50);
listOfTasks.Add(http.GetAsync($"{server.Urls[0]}{path}"));
}
var responses = await Task.WhenAll(listOfTasks);

View File

@@ -9,6 +9,7 @@ using WireMock.Owin.Mappers;
using WireMock.ResponseBuilders;
using WireMock.Types;
using WireMock.Util;
using WireMock.Owin;
#if NET452
using Microsoft.Owin;
using IResponse = Microsoft.Owin.IOwinResponse;
@@ -30,6 +31,7 @@ namespace WireMock.Net.Tests.Owin.Mappers
private readonly Mock<Stream> _stream;
private readonly Mock<IHeaderDictionary> _headers;
private readonly Mock<IFileSystemHandler> _fileSystemHandlerMock;
private readonly Mock<IWireMockMiddlewareOptions> _optionsMock;
public OwinResponseMapperTests()
{
@@ -37,6 +39,13 @@ namespace WireMock.Net.Tests.Owin.Mappers
_stream.SetupAllProperties();
_stream.Setup(s => s.WriteAsync(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>())).Returns(CompletedTask);
_fileSystemHandlerMock = new Mock<IFileSystemHandler>();
_fileSystemHandlerMock.SetupAllProperties();
_optionsMock = new Mock<IWireMockMiddlewareOptions>();
_optionsMock.SetupAllProperties();
_optionsMock.SetupGet(o => o.FileSystemHandler).Returns(_fileSystemHandlerMock.Object);
_headers = new Mock<IHeaderDictionary>();
_headers.SetupAllProperties();
#if NET452
@@ -50,10 +59,7 @@ namespace WireMock.Net.Tests.Owin.Mappers
_responseMock.SetupGet(r => r.Body).Returns(_stream.Object);
_responseMock.SetupGet(r => r.Headers).Returns(_headers.Object);
_fileSystemHandlerMock = new Mock<IFileSystemHandler>();
_fileSystemHandlerMock.SetupAllProperties();
_sut = new OwinResponseMapper(_fileSystemHandlerMock.Object);
_sut = new OwinResponseMapper(_optionsMock.Object);
}
[Fact]
@@ -63,20 +69,96 @@ namespace WireMock.Net.Tests.Owin.Mappers
await _sut.MapAsync(null, _responseMock.Object);
}
[Fact]
public async Task OwinResponseMapper_MapAsync_StatusCode()
[Theory]
[InlineData(300, 300)]
[InlineData(500, 500)]
public async Task OwinResponseMapper_MapAsync_Valid_StatusCode(object code, int expected)
{
// Arrange
var responseMessage = new ResponseMessage
{
StatusCode = 302
StatusCode = code
};
// Act
await _sut.MapAsync(responseMessage, _responseMock.Object);
// Assert
_responseMock.VerifySet(r => r.StatusCode = 302, Times.Once);
_responseMock.VerifySet(r => r.StatusCode = expected, Times.Once);
}
[Theory]
[InlineData(0, 200)]
[InlineData(-1, 200)]
[InlineData(10000, 200)]
[InlineData(300, 300)]
public async Task OwinResponseMapper_MapAsync_Invalid_StatusCode_When_AllowOnlyDefinedHttpStatusCodeInResponseSet_Is_True(object code, int expected)
{
// Arrange
_optionsMock.SetupGet(o => o.AllowOnlyDefinedHttpStatusCodeInResponse).Returns(true);
var responseMessage = new ResponseMessage
{
StatusCode = code
};
// Act
await _sut.MapAsync(responseMessage, _responseMock.Object);
// Assert
_responseMock.VerifySet(r => r.StatusCode = expected, Times.Once);
}
[Fact]
public async Task OwinResponseMapper_MapAsync_Null_StatusCode_When_AllowOnlyDefinedHttpStatusCodeInResponseSet_Is_True()
{
// Arrange
_optionsMock.SetupGet(o => o.AllowOnlyDefinedHttpStatusCodeInResponse).Returns(true);
var responseMessage = new ResponseMessage
{
StatusCode = null
};
// Act
await _sut.MapAsync(responseMessage, _responseMock.Object);
// Assert
_responseMock.VerifyNoOtherCalls();
}
[Fact]
public async Task OwinResponseMapper_MapAsync_StatusCode_Is_Null()
{
// Arrange
var responseMessage = new ResponseMessage
{
StatusCode = null
};
// Act
await _sut.MapAsync(responseMessage, _responseMock.Object);
// Assert
_responseMock.VerifyNoOtherCalls();
}
[Theory]
[InlineData(0, 0)]
[InlineData(-1, -1)]
[InlineData(10000, 10000)]
[InlineData(300, 300)]
public async Task OwinResponseMapper_MapAsync_StatusCode_Is_NotInEnumRange(object code, int expected)
{
// Arrange
var responseMessage = new ResponseMessage
{
StatusCode = code
};
// Act
await _sut.MapAsync(responseMessage, _responseMock.Object);
// Assert
_responseMock.VerifySet(r => r.StatusCode = expected, Times.Once);
}
[Fact]

View File

@@ -8,18 +8,54 @@ namespace WireMock.Net.Tests.RequestBuilders
{
public class RequestBuilderUsingMethodTests
{
[Fact]
public void RequestBuilder_UsingConnect()
{
// Act
var requestBuilder = (Request)Request.Create().UsingConnect();
// Assert
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
Check.That(matchers.Count).IsEqualTo(1);
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("CONNECT");
}
[Fact]
public void RequestBuilder_UsingOptions()
{
// Act
var requestBuilder = (Request)Request.Create().UsingOptions();
// Assert
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
Check.That(matchers.Count).IsEqualTo(1);
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("OPTIONS");
}
[Fact]
public void RequestBuilder_UsingPatch()
{
// Act
var requestBuilder = (Request)Request.Create().UsingPatch();
// Assert 1
// Assert
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
Check.That(matchers.Count).IsEqualTo(1);
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("PATCH");
}
[Fact]
public void RequestBuilder_UsingTrace()
{
// Act
var requestBuilder = (Request)Request.Create().UsingTrace();
// Assert
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
Check.That(matchers.Count).IsEqualTo(1);
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("TRACE");
}
[Fact]
public void RequestBuilder_UsingAnyMethod_ClearsAllOtherMatches()
{

View File

@@ -4,9 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Moq;
using Newtonsoft.Json;
using NFluent;
using System.Linq;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Models;
@@ -245,18 +243,36 @@ namespace WireMock.Net.Tests.RequestMatchers
// assign
BodyData bodyData;
if (body is byte[] b)
bodyData = await BodyParser.Parse(new MemoryStream(b), null);
{
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);
{
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);
}
@@ -267,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

@@ -14,7 +14,7 @@ namespace WireMock.Net.Tests.RequestMatchers
{
// Assign
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1");
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "c", "x");
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "c", false, "x");
// Act
var result = new RequestMatchResult();
@@ -29,38 +29,7 @@ namespace WireMock.Net.Tests.RequestMatchers
{
// Assign
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1");
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "c", "x");
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageCookieMatcher_GetMatchingScore_AcceptOnMatch_CookieDoesNotMatchPattern()
{
// Assign
var cookies = new Dictionary<string, string> { { "c", "x" } };
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "no-match", "123");
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(0.0d);
}
[Fact]
public void RequestMessageCookieMatcher_GetMatchingScore_RejectOnMatch_CookieDoesNotMatchPattern()
{
// Assign
var cookies = new Dictionary<string, string> { { "h", "x" } };
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "no-match", "123");
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "c", false, "x");
// Act
var result = new RequestMatchResult();
@@ -76,7 +45,7 @@ namespace WireMock.Net.Tests.RequestMatchers
// Assign
var cookies = new Dictionary<string, string> { { "h", "x" } };
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "h", "x");
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "h", false, "x");
// Act
var result = new RequestMatchResult();
@@ -92,7 +61,7 @@ namespace WireMock.Net.Tests.RequestMatchers
// Assign
var cookies = new Dictionary<string, string> { { "h", "x" } };
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "h", "x");
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "h", false, "x");
// Act
var result = new RequestMatchResult();
@@ -108,7 +77,23 @@ namespace WireMock.Net.Tests.RequestMatchers
// Assign
var cookies = new Dictionary<string, string> { { "cook", "x" } };
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher("cook", new ExactMatcher("x"));
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "cook", false, new ExactMatcher("x"));
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageCookieMatcher_WithMissingCookie_When_RejectOnMatch_Is_True_Should_Match()
{
// Assign
var cookies = new Dictionary<string, string> { { "cook", "x" } };
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "uhuh", false, new ExactMatcher("x"));
// Act
var result = new RequestMatchResult();

View File

@@ -108,7 +108,7 @@ namespace WireMock.Net.Tests.RequestMatchers
// Assign
var headers = new Dictionary<string, string[]> { { "h", new[] { "x" } } };
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", null, headers);
var matcher = new RequestMessageHeaderMatcher("h", new ExactMatcher("x"));
var matcher = new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, "h", false, new ExactMatcher("x"));
// Act
var result = new RequestMatchResult();

Some files were not shown because too many files have changed in this diff Show More