mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-02-24 17:55:01 +01:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad6c59e3b5 | ||
|
|
0c25b2e9f2 | ||
|
|
1ffd56701c | ||
|
|
4f87146622 | ||
|
|
693778659e | ||
|
|
51070dab63 | ||
|
|
e21582aacf | ||
|
|
9778c5adbe | ||
|
|
1caa769618 | ||
|
|
cf4e83b10b | ||
|
|
95a201573a | ||
|
|
b248c8c6e5 | ||
|
|
180526c8b4 | ||
|
|
361d40189b | ||
|
|
061eb93fd0 | ||
|
|
e5b2ad0543 | ||
|
|
66b2ff16de | ||
|
|
40ff8514ac | ||
|
|
cdcaaa970a | ||
|
|
d07a89c907 | ||
|
|
141ed5d96c | ||
|
|
6d60b3773a | ||
|
|
e6af765777 | ||
|
|
97d80ada11 | ||
|
|
51bd9ec186 | ||
|
|
da798a59aa | ||
|
|
71196b51c9 | ||
|
|
d0fc889f42 | ||
|
|
fd5bc203c3 | ||
|
|
601af2d6b2 | ||
|
|
ea16ee866b | ||
|
|
ee0cb6e670 | ||
|
|
798603118c | ||
|
|
208303729e | ||
|
|
d39e9ef7fa | ||
|
|
431e5656ca | ||
|
|
fa919343ac | ||
|
|
d0b48e2967 | ||
|
|
018d2a904d | ||
|
|
939a5a61ab | ||
|
|
a15e6747b0 | ||
|
|
6c38400827 | ||
|
|
cb1117fdaa | ||
|
|
e25c873765 | ||
|
|
d83f308591 | ||
|
|
c8c9ab99c5 | ||
|
|
d134684bcb | ||
|
|
a96b7bca1e | ||
|
|
cbe6a0a2b4 | ||
|
|
15370a89ca | ||
|
|
656f7f5432 | ||
|
|
bcdc3d646a | ||
|
|
10350fac04 | ||
|
|
37244d5c2f | ||
|
|
07f03997c0 | ||
|
|
7c289d44a7 |
168
CHANGELOG.md
Normal file
168
CHANGELOG.md
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
# 1.0.3.2 (14 February 2018)
|
||||||
|
|
||||||
|
- [#90](https://github.com/WireMock-Net/WireMock.Net/pull/90) - Concurrent issue (#88) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#89](https://github.com/WireMock-Net/WireMock.Net/pull/89) - Add log4net logging contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#88](https://github.com/WireMock-Net/WireMock.Net/issues/88) - Bug: Standalone server throws 500 error when receiving concurrent requests +fix
|
||||||
|
- [#87](https://github.com/WireMock-Net/WireMock.Net/issues/87) - Feature: Add logging
|
||||||
|
|
||||||
|
Commits: 51070dab63...693778659e
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.3.1 (14 February 2018)
|
||||||
|
|
||||||
|
- [#89](https://github.com/WireMock-Net/WireMock.Net/pull/89) - Add log4net logging contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#87](https://github.com/WireMock-Net/WireMock.Net/issues/87) - Feature: Add logging
|
||||||
|
|
||||||
|
Commits: ...
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.3 (04 February 2018)
|
||||||
|
|
||||||
|
- [#86](https://github.com/WireMock-Net/WireMock.Net/issues/86) - Feature : Add FileSystemWatcher logic for watching static mapping files +feature
|
||||||
|
- [#85](https://github.com/WireMock-Net/WireMock.Net/issues/85) - Bug: https for netstandard does not work ? +fix
|
||||||
|
- [#83](https://github.com/WireMock-Net/WireMock.Net/issues/83) - Feature : Add also a method in IProxyResponseBuilder to provide proxy-settings +feature
|
||||||
|
- [#82](https://github.com/WireMock-Net/WireMock.Net/issues/82) - Feature: make it possible to ignore some headers when proxying +feature
|
||||||
|
- [#81](https://github.com/WireMock-Net/WireMock.Net/issues/81) - Feature: When using proxy, only BodyAsBytes in case of binary data?
|
||||||
|
- [#80](https://github.com/WireMock-Net/WireMock.Net/issues/80) - Feature: When using proxy, in case Content-Type is JSON, use BodyAsJson in Response
|
||||||
|
|
||||||
|
Commits: 40ff8514ac...cf4e83b10b
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.13 (23 January 2018)
|
||||||
|
|
||||||
|
- [#79](https://github.com/WireMock-Net/WireMock.Net/pull/79) - Fix missed content headers contributed by ([vladimir-fed](https://github.com/vladimir-fed))
|
||||||
|
- [#78](https://github.com/WireMock-Net/WireMock.Net/issues/78) - WireMock not working when attempting to access from anything other than localhost.
|
||||||
|
- [#57](https://github.com/WireMock-Net/WireMock.Net/issues/57) - ProxyAndRecord does not save query-parameters, headers and body +fix
|
||||||
|
|
||||||
|
Commits: 6d60b3773a...cdcaaa970a
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.12 (16 January 2018)
|
||||||
|
|
||||||
|
- [#77](https://github.com/WireMock-Net/WireMock.Net/pull/77) - Fixed issue #76 contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#76](https://github.com/WireMock-Net/WireMock.Net/issues/76) - Bug: IFluentMockServerAdmin is missing content-type for some POST/PUT calls
|
||||||
|
- [#75](https://github.com/WireMock-Net/WireMock.Net/pull/75) - Add WireMock.Net.WebApplication example contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#74](https://github.com/WireMock-Net/WireMock.Net/pull/74) - Capturing the index of the existing mapping before removing and insert the updated mapping at the same index of the list contributed by ([raghavendrabankapur](https://github.com/raghavendrabankapur))
|
||||||
|
- [#73](https://github.com/WireMock-Net/WireMock.Net/issues/73) - Updated mapping is not being picked and responded with the response
|
||||||
|
|
||||||
|
Commits: da798a59aa...e6af765777
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.11 (20 December 2017)
|
||||||
|
|
||||||
|
- [#72](https://github.com/WireMock-Net/WireMock.Net/issues/72) - Matching WithParam on OData End Points
|
||||||
|
|
||||||
|
Commits: 71196b51c9...71196b51c9
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.9 (07 December 2017)
|
||||||
|
|
||||||
|
- [#71](https://github.com/WireMock-Net/WireMock.Net/pull/71) - Fixed restricted headers on response contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#69](https://github.com/WireMock-Net/WireMock.Net/issues/69) - Instructions are incorrect (?)
|
||||||
|
|
||||||
|
Commits: 601af2d6b2...fd5bc203c3
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.10 (12 December 2017)
|
||||||
|
|
||||||
|
- [#70](https://github.com/WireMock-Net/WireMock.Net/issues/70) - Proxy/Intercept pattern is throwing a keep alive header error with net461
|
||||||
|
|
||||||
|
Commits: d0fc889f42...d0fc889f42
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.8 (23 November 2017)
|
||||||
|
|
||||||
|
- [#68](https://github.com/WireMock-Net/WireMock.Net/issues/68) - Full path required in Stub
|
||||||
|
- [#67](https://github.com/WireMock-Net/WireMock.Net/pull/67) - bug: fix supporting the Patch method and logging the body contributed by Alastair Crabtree ([alastairtree](https://github.com/alastairtree))
|
||||||
|
- [#65](https://github.com/WireMock-Net/WireMock.Net/pull/65) - bug: Fix admin api client definition returning the wrong types contributed by Alastair Crabtree ([alastairtree](https://github.com/alastairtree))
|
||||||
|
- [#64](https://github.com/WireMock-Net/WireMock.Net/issues/64) - Pull Requests do not trigger test + codecoverage ?
|
||||||
|
|
||||||
|
Commits: d0b48e2967...ea16ee866b
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.7 (18 November 2017)
|
||||||
|
|
||||||
|
- [#63](https://github.com/WireMock-Net/WireMock.Net/pull/63) - Fix issue with concurrent logging contributed by ([vladimir-fed](https://github.com/vladimir-fed))
|
||||||
|
- [#62](https://github.com/WireMock-Net/WireMock.Net/pull/62) - Add the Host, Protocol, Port and Origin to the Request message so they can be used in templating contributed by Alastair Crabtree ([alastairtree](https://github.com/alastairtree))
|
||||||
|
- [#61](https://github.com/WireMock-Net/WireMock.Net/issues/61) - Partial mapping
|
||||||
|
- [#53](https://github.com/WireMock-Net/WireMock.Net/issues/53) - New feature request: Access to Owin pipeline
|
||||||
|
- [#42](https://github.com/WireMock-Net/WireMock.Net/issues/42) - Enhancement - Save/load request logs to/from disk +feature
|
||||||
|
- [#27](https://github.com/WireMock-Net/WireMock.Net/issues/27) - New feature: Record and Save
|
||||||
|
|
||||||
|
Commits: e25c873765...018d2a904d
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.6 (30 October 2017)
|
||||||
|
|
||||||
|
- [#60](https://github.com/WireMock-Net/WireMock.Net/pull/60) - Fix proxy headers handling contributed by Oleksandr Liakhevych ([Dreamescaper](https://github.com/Dreamescaper))
|
||||||
|
- [#59](https://github.com/WireMock-Net/WireMock.Net/pull/59) - Add ability to provide multiple values for headers in response contributed by Oleksandr Liakhevych ([Dreamescaper](https://github.com/Dreamescaper))
|
||||||
|
- [#58](https://github.com/WireMock-Net/WireMock.Net/issues/58) - Multiple headers with same name +feature
|
||||||
|
- [#56](https://github.com/WireMock-Net/WireMock.Net/issues/56) - WithBodyFromFile Support +feature
|
||||||
|
- [#54](https://github.com/WireMock-Net/WireMock.Net/issues/54) - Proxy for AWS: Error unmarshalling response back from AWS +fix
|
||||||
|
|
||||||
|
Commits: cbe6a0a2b4...d83f308591
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.5 (24 October 2017)
|
||||||
|
|
||||||
|
- [#55](https://github.com/WireMock-Net/WireMock.Net/pull/55) - Fix the problem with headers passthrough contributed by deeptowncitizen ([deeptowncitizen](https://github.com/deeptowncitizen)) +fix
|
||||||
|
- [#52](https://github.com/WireMock-Net/WireMock.Net/issues/52) - SimMetrics.NET error when trying to install NuGet Package
|
||||||
|
- [#48](https://github.com/WireMock-Net/WireMock.Net/issues/48) - Stateful support +feature
|
||||||
|
- [#44](https://github.com/WireMock-Net/WireMock.Net/issues/44) - Bug: Server not listening after Start() returns (on macOS) +fix
|
||||||
|
|
||||||
|
Commits: 7c289d44a7...15370a89ca
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.4 (10 October 2017)
|
||||||
|
|
||||||
|
- [#51](https://github.com/WireMock-Net/WireMock.Net/pull/51) - Observable logs contributed by deeptowncitizen ([deeptowncitizen](https://github.com/deeptowncitizen))
|
||||||
|
- [#50](https://github.com/WireMock-Net/WireMock.Net/issues/50) - New Feature: Callbacks
|
||||||
|
- [#49](https://github.com/WireMock-Net/WireMock.Net/pull/49) - stateful behavior contributed by deeptowncitizen ([deeptowncitizen](https://github.com/deeptowncitizen))
|
||||||
|
- [#47](https://github.com/WireMock-Net/WireMock.Net/issues/47) - Feature: add matcher details to Request to see which matchers match/not match +feature
|
||||||
|
- [#46](https://github.com/WireMock-Net/WireMock.Net/issues/46) - Log the ip-address from the client/caller also in the RequestLog +feature
|
||||||
|
- [#45](https://github.com/WireMock-Net/WireMock.Net/pull/45) - Add RequestLogExpirationDuration and MaxRequestLogCount (#43) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#43](https://github.com/WireMock-Net/WireMock.Net/issues/43) - Feature: Add RequestLogExpirationDuration and MaxRequestLogCount
|
||||||
|
- [#41](https://github.com/WireMock-Net/WireMock.Net/pull/41) - Dotnet 20 preview final contributed by Stef Heyenrath ([StefH](https://github.com/StefH)) +feature
|
||||||
|
- [#40](https://github.com/WireMock-Net/WireMock.Net/pull/40) - Expose more settings to stand-alone app contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#39](https://github.com/WireMock-Net/WireMock.Net/pull/39) - Listen on http://*:9090 contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#38](https://github.com/WireMock-Net/WireMock.Net/issues/38) - Bug: support also listening on *:{port}
|
||||||
|
- [#37](https://github.com/WireMock-Net/WireMock.Net/issues/37) - Wrong Request Match result is returning
|
||||||
|
- [#36](https://github.com/WireMock-Net/WireMock.Net/issues/36) - How to implement a request body-dependent response?
|
||||||
|
- [#35](https://github.com/WireMock-Net/WireMock.Net/pull/35) - Revert changes that were made by mistake in prior PR contributed by ([phillee007](https://github.com/phillee007))
|
||||||
|
- [#34](https://github.com/WireMock-Net/WireMock.Net/issues/34) - Where is SearchLogsFor method?
|
||||||
|
- [#33](https://github.com/WireMock-Net/WireMock.Net/issues/33) - Issue with launching sample code (StandAlone server) +fix
|
||||||
|
- [#32](https://github.com/WireMock-Net/WireMock.Net/pull/32) - [Feature] Add support for client certificate password and test with real services that require client certificate auth contributed by ([phillee007](https://github.com/phillee007)) +feature
|
||||||
|
- [#31](https://github.com/WireMock-Net/WireMock.Net/issues/31) - Feature request: Nuget package for standalone version +feature
|
||||||
|
- [#20](https://github.com/WireMock-Net/WireMock.Net/issues/20) - Add client certificate authentication
|
||||||
|
- [#19](https://github.com/WireMock-Net/WireMock.Net/issues/19) - Is this the same as Mock4Net?
|
||||||
|
- [#15](https://github.com/WireMock-Net/WireMock.Net/issues/15) - New feature: Proxying +feature
|
||||||
|
|
||||||
|
Commits: 538195551d...e87e09e10d
|
||||||
|
|
||||||
|
|
||||||
|
# 1.02.1 (14 June 2017)
|
||||||
|
|
||||||
|
- [#30](https://github.com/WireMock-Net/WireMock.Net/issues/30) - [Feature] Disable partial mappings by default in standalone version +fix
|
||||||
|
- [#29](https://github.com/WireMock-Net/WireMock.Net/issues/29) - Support of .Net 4.0
|
||||||
|
- [#28](https://github.com/WireMock-Net/WireMock.Net/issues/28) - Facing issue with WildcardMatcher and '?'
|
||||||
|
|
||||||
|
Commits: 84db9bbf0d...7111ab384b
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.2.0 (05 May 2017)
|
||||||
|
|
||||||
|
- [#26](https://github.com/WireMock-Net/WireMock.Net/pull/26) - merge netstandard into main contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||||
|
- [#25](https://github.com/WireMock-Net/WireMock.Net/issues/25) - Upgrade to vs2017 +feature
|
||||||
|
- [#23](https://github.com/WireMock-Net/WireMock.Net/issues/23) - Consider port to .Net Core
|
||||||
|
- [#21](https://github.com/WireMock-Net/WireMock.Net/issues/21) - Admin static json mappings +feature
|
||||||
|
|
||||||
|
Commits: b547993415...8d9cef6dd1
|
||||||
|
|
||||||
|
|
||||||
|
# 1.0.1.2 (27 February 2017)
|
||||||
|
|
||||||
|
- [#24](https://github.com/WireMock-Net/WireMock.Net/pull/24) - Body Encoding contributed by Sebastian Bebrys ([sbebrys](https://github.com/sbebrys))
|
||||||
|
- [#22](https://github.com/WireMock-Net/WireMock.Net/issues/22) - Add basic-authentication for accessing admin-interface +feature
|
||||||
|
- [#8](https://github.com/WireMock-Net/WireMock.Net/issues/8) - admin rest api
|
||||||
|
|
||||||
|
Commits: bb35f55bbb...02803562c6
|
||||||
BIN
GitReleaseNotes.exe
Normal file
BIN
GitReleaseNotes.exe
Normal file
Binary file not shown.
5
GitReleaseNotes.txt
Normal file
5
GitReleaseNotes.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
https://github.com/GitTools/GitReleaseNotes
|
||||||
|
|
||||||
|
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.3.2
|
||||||
|
|
||||||
|
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /allTags
|
||||||
22
README.md
22
README.md
@@ -3,9 +3,9 @@ A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) w
|
|||||||
|
|
||||||
[](https://ci.appveyor.com/project/StefH/wiremock-net)
|
[](https://ci.appveyor.com/project/StefH/wiremock-net)
|
||||||
[](https://codecov.io/gh/WireMock-Net/WireMock.Net)
|
[](https://codecov.io/gh/WireMock-Net/WireMock.Net)
|
||||||
[](https://coveralls.io/github/StefH/WireMock.Net?branch=master)
|
[](https://coveralls.io/github/WireMock-Net/WireMock.Net?branch=master)
|
||||||
[](https://github.com/StefH/WireMock.Net/issues)
|
[](https://github.com/WireMock-Net/WireMock.Net/issues)
|
||||||
[](https://github.com/StefH/WireMock.Net/stargazers)
|
[](https://github.com/WireMock-Net/WireMock.Net/stargazers)
|
||||||
|
|
||||||
| Name | NuGet |
|
| Name | NuGet |
|
||||||
| ---- | ----- |
|
| ---- | ----- |
|
||||||
@@ -28,7 +28,7 @@ To build you need:
|
|||||||
|
|
||||||
|
|
||||||
## Stubbing
|
## Stubbing
|
||||||
A core feature of WireMock.Net is the ability to return canned/predefined HTTP responses for requests matching criteria, see [Wiki : Stubbing](https://github.com/StefH/WireMock.Net/wiki/Stubbing).
|
A core feature of WireMock.Net is the ability to return canned/predefined HTTP responses for requests matching criteria, see [Wiki : Stubbing & Request Matching](https://github.com/WireMock-Net/WireMock.Net/wiki/Stubbing-and-Request-Matching).
|
||||||
|
|
||||||
## Using WireMock in UnitTest framework
|
## Using WireMock in UnitTest framework
|
||||||
You can use your favorite test framework and use WireMock within your tests, see
|
You can use your favorite test framework and use WireMock within your tests, see
|
||||||
@@ -43,6 +43,16 @@ This is quite straight forward to launch a mock server within a console applicat
|
|||||||
### SSL
|
### SSL
|
||||||
You can start a standalone mock server listening for HTTPS requests. To do so, there is just a flag to set when creating the server:
|
You can start a standalone mock server listening for HTTPS requests. To do so, there is just a flag to set when creating the server:
|
||||||
```csharp
|
```csharp
|
||||||
var server = FluentMockServer.Start(port: 8443, ssl: true);
|
var server1 = FluentMockServer.Start(port: 8443, ssl: true);
|
||||||
|
|
||||||
|
// or like this
|
||||||
|
|
||||||
|
var server2 = FluentMockServer.Start(new FluentMockServerSettings
|
||||||
|
{
|
||||||
|
Urls = new[] { "http://localhost:9091", "https://localhost:9443" }
|
||||||
|
});
|
||||||
```
|
```
|
||||||
Obviously you need a certificate registered on your box, properly associated with your application and the port number that will be used. This is not really specific to WireMock, not very straightforward and hence the following stackoverflow thread might come handy: [Httplistener with https support](http://stackoverflow.com/questions/11403333/httplistener-with-https-support)
|
|
||||||
|
- In case when using **net 4.5.2** or **net 4.6**, you need a certificate registered on your box, properly associated with your application and the port number that will be used. This is not really specific to WireMock.Net, not very straightforward and hence the following stackoverflow thread might come handy: [Httplistener with https support](http://stackoverflow.com/questions/11403333/httplistener-with-https-support).
|
||||||
|
|
||||||
|
- When using **netstandard**, WireMock.Net uses a self signed certificate (which can be overriden if you like) to host https urls.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26430.13
|
VisualStudioVersion = 15.0.27130.2027
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EF242EDF-7133-4277-9A0C-18744DE08707}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EF242EDF-7133-4277-9A0C-18744DE08707}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -9,7 +9,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.runsettings = .runsettings
|
.runsettings = .runsettings
|
||||||
appveyor.yml = appveyor.yml
|
appveyor.yml = appveyor.yml
|
||||||
|
CHANGELOG.md = CHANGELOG.md
|
||||||
codecov-local.cmd = codecov-local.cmd
|
codecov-local.cmd = codecov-local.cmd
|
||||||
|
GitReleaseNotes.txt = GitReleaseNotes.txt
|
||||||
README.md = README.md
|
README.md = README.md
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
@@ -21,11 +23,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net", "src\WireMoc
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Tests", "test\WireMock.Net.Tests\WireMock.Net.Tests.csproj", "{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Tests", "test\WireMock.Net.Tests\WireMock.Net.Tests.csproj", "{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.NETCoreApp", "examples\WireMock.Net.Console.NETCoreApp\WireMock.Net.Console.NETCoreApp.csproj", "{FE281639-B014-4C8A-96FA-141164A74713}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NETCoreApp", "examples\WireMock.Net.Console.NETCoreApp\WireMock.Net.Console.NETCoreApp.csproj", "{FE281639-B014-4C8A-96FA-141164A74713}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.Record.NETCoreApp", "examples\WireMock.Net.Console.Record.NETCoreApp\WireMock.Net.Console.Record.NETCoreApp.csproj", "{1995E414-F197-4AB4-90C2-68D806B5AF59}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.Proxy.NETCoreApp", "examples\WireMock.Net.Console.Record.NETCoreApp\WireMock.Net.Console.Proxy.NETCoreApp.csproj", "{1995E414-F197-4AB4-90C2-68D806B5AF59}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Client", "examples\WireMock.Net.Client\WireMock.Net.Client.csproj", "{058D4B6C-C03E-49D0-91DB-A535B058FA0D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Client", "examples\WireMock.Net.Client\WireMock.Net.Client.csproj", "{058D4B6C-C03E-49D0-91DB-A535B058FA0D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.StandAlone", "src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj", "{B6269AAC-170A-43D5-8B9A-579DED3D9A95}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.StandAlone", "src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj", "{B6269AAC-170A-43D5-8B9A-579DED3D9A95}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -36,6 +38,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.StandAlone.Net
|
|||||||
{B6269AAC-170A-43D5-8B9A-579DED3D9A95} = {B6269AAC-170A-43D5-8B9A-579DED3D9A95}
|
{B6269AAC-170A-43D5-8B9A-579DED3D9A95} = {B6269AAC-170A-43D5-8B9A-579DED3D9A95}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.NET452", "examples\WireMock.Net.ConsoleApplication\WireMock.Net.Console.NET452.csproj", "{668F689E-57B4-422E-8846-C0FF643CA268}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.WebApplication", "examples\WireMock.Net.WebApplication\WireMock.Net.WebApplication.csproj", "{049539C1-7A66-4559-AD7A-B1C73B97CBB0}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Proxy.Net452", "examples\WireMock.Net.Console.Proxy.Net452\WireMock.Net.Console.Proxy.Net452.csproj", "{26433A8F-BF01-4962-97EB-81BFFBB61096}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.Proxy.NETCoreApp2", "examples\WireMock.Net.Console.Proxy.NETCoreApp2\WireMock.Net.Console.Proxy.NETCoreApp2.csproj", "{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -74,6 +84,22 @@ Global
|
|||||||
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{668F689E-57B4-422E-8846-C0FF643CA999}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{668F689E-57B4-422E-8846-C0FF643CA999}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{668F689E-57B4-422E-8846-C0FF643CA999}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{668F689E-57B4-422E-8846-C0FF643CA999}.Release|Any CPU.Build.0 = Release|Any CPU
|
{668F689E-57B4-422E-8846-C0FF643CA999}.Release|Any CPU.Build.0 = Release|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}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{668F689E-57B4-422E-8846-C0FF643CA268}.Release|Any CPU.Build.0 = Release|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}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{049539C1-7A66-4559-AD7A-B1C73B97CBB0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{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}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Release|Any CPU.Build.0 = Release|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}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -87,5 +113,12 @@ Global
|
|||||||
{B6269AAC-170A-43D5-8B9A-579DED3D9A95} = {EF242EDF-7133-4277-9A0C-18744DE08707}
|
{B6269AAC-170A-43D5-8B9A-579DED3D9A95} = {EF242EDF-7133-4277-9A0C-18744DE08707}
|
||||||
{10E16614-61CA-48D8-8BDD-664C13913DED} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
{10E16614-61CA-48D8-8BDD-664C13913DED} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||||
{668F689E-57B4-422E-8846-C0FF643CA999} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
{668F689E-57B4-422E-8846-C0FF643CA999} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||||
|
{668F689E-57B4-422E-8846-C0FF643CA268} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||||
|
{049539C1-7A66-4559-AD7A-B1C73B97CBB0} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||||
|
{26433A8F-BF01-4962-97EB-81BFFBB61096} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||||
|
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {BF428BCC-C837-433B-87D2-15C7014B73E9}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ environment:
|
|||||||
before_build:
|
before_build:
|
||||||
- dotnet restore .\src\WireMock.Net\WireMock.Net.csproj
|
- dotnet restore .\src\WireMock.Net\WireMock.Net.csproj
|
||||||
- dotnet restore .\src\WireMock.Net.Standalone\WireMock.Net.Standalone.csproj
|
- dotnet restore .\src\WireMock.Net.Standalone\WireMock.Net.Standalone.csproj
|
||||||
- nuget restore .\examples\WireMock.Net.ConsoleApplication\WireMock.Net.ConsoleApplication.csproj -PackagesDirectory packages
|
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
# build WireMock.Net
|
# build WireMock.Net
|
||||||
@@ -39,6 +38,6 @@ test_script:
|
|||||||
- nuget.exe install coveralls.net -ExcludeVersion
|
- nuget.exe install coveralls.net -ExcludeVersion
|
||||||
- pip install codecov
|
- pip install codecov
|
||||||
|
|
||||||
- cmd: '"OpenCover\tools\OpenCover.Console.exe" -register:user -target:dotnet.exe -targetargs:"test test\WireMock.Net.Tests\WireMock.Net.Tests.csproj --no-build" -returntargetcode -filter:"+[WireMock.Net]* -[WireMock.Net.Tests*]*" -output:coverage.xml -oldstyle -searchdirs:".\test\WireMock.Net.Tests\bin\%CONFIGURATION%\net452"'
|
- cmd: '"OpenCover\tools\OpenCover.Console.exe" -target:dotnet.exe -targetargs:"test test\WireMock.Net.Tests\WireMock.Net.Tests.csproj --no-build" -output:coverage.xml -returntargetcode -register:user -filter:"+[WireMock.Net]* -[WireMock.Net.Tests*]*" -nodefaultfilters -returntargetcode -oldstyle -searchdirs:".\test\WireMock.Net.Tests\bin\%CONFIGURATION%\net452"'
|
||||||
- codecov -f "coverage.xml"
|
- codecov -f "coverage.xml"
|
||||||
- coveralls.net\tools\csmacnz.Coveralls.exe --opencover -i .\coverage.xml
|
- coveralls.net\tools\csmacnz.Coveralls.exe --opencover -i .\coverage.xml
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||||
<PackageReference Include="RestEase" Version="1.4.3" />
|
<PackageReference Include="RestEase" Version="1.4.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,11 +1,21 @@
|
|||||||
using WireMock.Net.ConsoleApplication;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using log4net.Config;
|
||||||
|
using log4net.Repository;
|
||||||
|
using WireMock.Net.ConsoleApplication;
|
||||||
|
|
||||||
namespace WireMock.Net.Console.NETCoreApp
|
namespace WireMock.Net.Console.NETCoreApp
|
||||||
{
|
{
|
||||||
static class Program
|
static class Program
|
||||||
{
|
{
|
||||||
|
private static readonly ILoggerRepository LogRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
|
||||||
|
|
||||||
static void Main(params string[] args)
|
static void Main(params string[] args)
|
||||||
{
|
{
|
||||||
|
XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config"));
|
||||||
|
|
||||||
MainApp.Run();
|
MainApp.Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,27 @@
|
|||||||
<Content Include="__admin\mappings\11111110-a633-40e8-a244-5cb80bc0ab66.json">
|
<Content Include="__admin\mappings\11111110-a633-40e8-a244-5cb80bc0ab66.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="__admin\mappings\826aff7c-6208-4a3c-923d-575248907db4.json">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
<PackageReference Include="log4net" Version="2.0.8" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||||
|
</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>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -14,8 +14,9 @@
|
|||||||
},
|
},
|
||||||
"Response": {
|
"Response": {
|
||||||
"BodyAsJson": { "body": "static mapping" },
|
"BodyAsJson": { "body": "static mapping" },
|
||||||
"Headers": {
|
"Headers": {
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json",
|
||||||
}
|
"Test-X": [ "test 1", "test 2" ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"Guid": "791a3f31-6946-4ce7-8e6f-0237c7443275",
|
||||||
|
"Title": "",
|
||||||
|
"Priority": 0,
|
||||||
|
"Request": {
|
||||||
|
"Path": {
|
||||||
|
"Matchers": [
|
||||||
|
{
|
||||||
|
"Name": "WildcardMatcher",
|
||||||
|
"Pattern": "/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>That’s an error.</ins>\n <p>The requested URL <code>/proxy-google-test-post</code> was not found on this server. <ins>That’s 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
20
examples/WireMock.Net.Console.NETCoreApp/log4net.config
Normal file
20
examples/WireMock.Net.Console.NETCoreApp/log4net.config
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<configSections>
|
||||||
|
<section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
|
||||||
|
</configSections>
|
||||||
|
<appSettings>
|
||||||
|
<add key="log4net.Internal.Debug" value="true"/>
|
||||||
|
</appSettings>
|
||||||
|
<log4net>
|
||||||
|
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
|
||||||
|
<layout type="log4net.Layout.PatternLayout">
|
||||||
|
<conversionPattern value="%date [%thread] %-5level %logger{1} - %message%newline" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
<root>
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="ConsoleAppender" />
|
||||||
|
</root>
|
||||||
|
</log4net>
|
||||||
|
</configuration>
|
||||||
18
examples/WireMock.Net.Console.NETCoreApp/nlog.config
Normal file
18
examples/WireMock.Net.Console.NETCoreApp/nlog.config
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
autoReload="true"
|
||||||
|
internalLogLevel="info"
|
||||||
|
internalLogFile="c:\temp\wiremock-internal-nlog.log">
|
||||||
|
|
||||||
|
<targets>
|
||||||
|
<!-- write logs to file -->
|
||||||
|
<target xsi:type="File" name="all" fileName="c:\temp\wiremock-${shortdate}.log"
|
||||||
|
layout="${longdate}|${event-properties:item=EventId.Id}|${uppercase:${level}}|${logger}|${message} ${exception}" />
|
||||||
|
</targets>
|
||||||
|
|
||||||
|
<!-- rules to map from logger name to target -->
|
||||||
|
<rules>
|
||||||
|
<logger name="*" minlevel="Debug" writeTo="all" />
|
||||||
|
</rules>
|
||||||
|
</nlog>
|
||||||
36
examples/WireMock.Net.Console.Proxy.NETCoreApp2/Program.cs
Normal file
36
examples/WireMock.Net.Console.Proxy.NETCoreApp2/Program.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using WireMock.Server;
|
||||||
|
using WireMock.Settings;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Console.Proxy.NETCoreApp2
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var server = FluentMockServer.Start(new FluentMockServerSettings
|
||||||
|
{
|
||||||
|
Urls = new[] { "http://localhost:9091", "https://localhost:9443" },
|
||||||
|
StartAdminInterface = true,
|
||||||
|
ReadStaticMappings = false,
|
||||||
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
|
{
|
||||||
|
Url = "https://www.google.com",
|
||||||
|
//ClientX509Certificate2ThumbprintOrSubjectName = "www.yourclientcertname.com OR yourcertificatethumbprint (only if the service you're proxying to requires it)",
|
||||||
|
SaveMapping = true,
|
||||||
|
SaveMappingToFile = false,
|
||||||
|
BlackListedHeaders = new[] { "dnt", "Content-Length" }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.LogEntriesChanged += (sender, eventRecordArgs) =>
|
||||||
|
{
|
||||||
|
System.Console.WriteLine(JsonConvert.SerializeObject(eventRecordArgs.NewItems, Formatting.Indented));
|
||||||
|
};
|
||||||
|
|
||||||
|
System.Console.WriteLine("Press any key to stop the server");
|
||||||
|
System.Console.ReadKey();
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:63377/",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WireMock.Net.Console.Proxy.NETCoreApp2": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"applicationUrl": "http://localhost:63378/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
6
examples/WireMock.Net.Console.Proxy.Net452/App.config
Normal file
6
examples/WireMock.Net.Console.Proxy.Net452/App.config
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
36
examples/WireMock.Net.Console.Proxy.Net452/Program.cs
Normal file
36
examples/WireMock.Net.Console.Proxy.Net452/Program.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using WireMock.Server;
|
||||||
|
using WireMock.Settings;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Console.Proxy.Net452
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var server = FluentMockServer.Start(new FluentMockServerSettings
|
||||||
|
{
|
||||||
|
Urls = new[] { "http://localhost:9091/", "https://localhost:9443/" },
|
||||||
|
StartAdminInterface = true,
|
||||||
|
ReadStaticMappings = false,
|
||||||
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
|
{
|
||||||
|
Url = "https://www.google.com",
|
||||||
|
//ClientX509Certificate2ThumbprintOrSubjectName = "www.yourclientcertname.com OR yourcertificatethumbprint (only if the service you're proxying to requires it)",
|
||||||
|
SaveMapping = true,
|
||||||
|
SaveMappingToFile = false,
|
||||||
|
BlackListedHeaders = new[] { "dnt", "Content-Length" }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.LogEntriesChanged += (sender, eventRecordArgs) =>
|
||||||
|
{
|
||||||
|
System.Console.WriteLine(JsonConvert.SerializeObject(eventRecordArgs.NewItems, Formatting.Indented));
|
||||||
|
};
|
||||||
|
|
||||||
|
System.Console.WriteLine("Press any key to stop the server");
|
||||||
|
System.Console.ReadKey();
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
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.Console.Proxy.Net452")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("WireMock.Net.Console.Proxy.Net452")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © Stef Heyenrath 2018")]
|
||||||
|
[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("26433a8f-bf01-4962-97eb-81bffbb61096")]
|
||||||
|
|
||||||
|
// 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")]
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
<?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>{26433A8F-BF01-4962-97EB-81BFFBB61096}</ProjectGuid>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<RootNamespace>WireMock.Net.Console.Proxy.Net452</RootNamespace>
|
||||||
|
<AssemblyName>WireMock.Net.Console.Proxy.Net452</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
|
</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>
|
||||||
|
<StartupObject>WireMock.Net.Console.Proxy.Net452.Program</StartupObject>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Condition="'$(Platform)' == 'x64'" Include="..\packages\Libuv.1.10.0\runtimes\win7-x64\native\libuv.dll">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<Link>libuv.dll</Link>
|
||||||
|
</None>
|
||||||
|
<None Condition="'$(Platform)' == 'x86'" Include="..\packages\Libuv.1.10.0\runtimes\win7-x86\native\libuv.dll">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<Link>libuv.dll</Link>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<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" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj">
|
||||||
|
<Project>{b6269aac-170a-43d5-8b9a-579ded3d9a95}</Project>
|
||||||
|
<Name>WireMock.Net.StandAlone</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj">
|
||||||
|
<Project>{d3804228-91f4-4502-9595-39584e5a01ad}</Project>
|
||||||
|
<Name>WireMock.Net</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
|
||||||
|
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net452" />
|
||||||
|
</packages>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
using WireMock.Settings;
|
using WireMock.Settings;
|
||||||
|
|
||||||
namespace WireMock.Net.Console.Record.NETCoreApp
|
namespace WireMock.Net.Console.Proxy.NETCoreApp
|
||||||
{
|
{
|
||||||
static class Program
|
static class Program
|
||||||
{
|
{
|
||||||
@@ -10,13 +10,16 @@ namespace WireMock.Net.Console.Record.NETCoreApp
|
|||||||
{
|
{
|
||||||
var server = FluentMockServer.Start(new FluentMockServerSettings
|
var server = FluentMockServer.Start(new FluentMockServerSettings
|
||||||
{
|
{
|
||||||
Urls = new[] { "http://localhost:9095/", "https://localhost:9096/" },
|
Urls = new[] { "http://localhost:9091/", "https://localhost:9443/" },
|
||||||
StartAdminInterface = true,
|
StartAdminInterface = true,
|
||||||
|
ReadStaticMappings = false,
|
||||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
{
|
{
|
||||||
Url = "https://www.msn.com",
|
Url = "https://www.google.com",
|
||||||
//X509Certificate2ThumbprintOrSubjectName = "www.yourclientcertname.com OR yourcertificatethumbprint (only if the service you're proxying to requires it)",
|
//ClientX509Certificate2ThumbprintOrSubjectName = "www.yourclientcertname.com OR yourcertificatethumbprint (only if the service you're proxying to requires it)",
|
||||||
SaveMapping = true
|
SaveMapping = true,
|
||||||
|
SaveMappingToFile = false,
|
||||||
|
BlackListedHeaders = new [] { "dnt", "Content-Length" }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommandLineArgumentsParser" Version="3.0.10" />
|
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
<Folder Include="__admin\mappings\" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.1" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
@@ -21,13 +20,85 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
{
|
{
|
||||||
Urls = new[] { url1, url2, url3 },
|
Urls = new[] { url1, url2, url3 },
|
||||||
StartAdminInterface = true,
|
StartAdminInterface = true,
|
||||||
ReadStaticMappings = true
|
ReadStaticMappings = true,
|
||||||
|
WatchStaticMappings = true,
|
||||||
|
//ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
|
//{
|
||||||
|
// SaveMapping = true
|
||||||
|
//},
|
||||||
|
PreWireMockMiddlewareInit = app => { System.Console.WriteLine($"PreWireMockMiddlewareInit : {app.GetType()}"); },
|
||||||
|
PostWireMockMiddlewareInit = app => { System.Console.WriteLine($"PostWireMockMiddlewareInit : {app.GetType()}"); }
|
||||||
});
|
});
|
||||||
System.Console.WriteLine("FluentMockServer listening at {0}", string.Join(" and ", server.Urls));
|
System.Console.WriteLine("FluentMockServer listening at {0}", string.Join(",", server.Urls));
|
||||||
|
|
||||||
server.SetBasicAuthentication("a", "b");
|
server.SetBasicAuthentication("a", "b");
|
||||||
|
|
||||||
// server.AllowPartialMapping();
|
server.AllowPartialMapping();
|
||||||
|
|
||||||
|
// .WithHeader("Stef", "Stef")
|
||||||
|
//server
|
||||||
|
// .Given(Request.Create().WithPath("*"))
|
||||||
|
// .RespondWith(Response.Create()
|
||||||
|
// .WithProxy("http://restcountries.eu"));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request
|
||||||
|
.Create()
|
||||||
|
.WithPath("/jsonthings")
|
||||||
|
.WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]"))
|
||||||
|
.UsingPut())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBody(@"{ ""result"": ""JsonPathMatcher !!!""}"));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request
|
||||||
|
.Create()
|
||||||
|
.WithPath(new WildcardMatcher("/navision/OData/Company('My Company')/School*", true))
|
||||||
|
.WithParam("$filter", "(substringof(Code, 'WA')")
|
||||||
|
.UsingGet())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBody(@"{ ""result"": ""odata""}"));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/headers", "/headers_test").UsingPost().WithHeader("Content-Type", "application/json*"))
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithStatusCode(201)
|
||||||
|
//.WithHeader("MyHeader", "application/json", "application/json2")
|
||||||
|
.WithHeader("Content-Type", "application/json")
|
||||||
|
.WithBodyAsJson(new { result = "data:headers posted with 201" }));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/file").UsingGet())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBodyFromFile(@"c:\temp\x.json", false)
|
||||||
|
);
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/filecache").UsingGet())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBodyFromFile(@"c:\temp\x.json")
|
||||||
|
);
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/file_rel").UsingGet())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBodyFromFile("Program.cs", false)
|
||||||
|
);
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithHeader("ProxyThis", "true")
|
||||||
|
.UsingGet())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithProxy("http://www.google.com")
|
||||||
|
);
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/bodyasbytes.png")
|
||||||
|
.UsingGet())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithHeader("Content-Type", "image/png")
|
||||||
|
.WithBody(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTczbp9jAAAAJ0lEQVQoU2NgUPuPD6Hz0RCEAtJoiAxpCCBXGgmRIo0TofORkdp/AMiMdRVnV6O0AAAAAElFTkSuQmCC"))
|
||||||
|
);
|
||||||
|
|
||||||
server
|
server
|
||||||
.Given(Request.Create().WithPath("/oauth2/access").UsingPost().WithBody("grant_type=password;username=u;password=p"))
|
.Given(Request.Create().WithPath("/oauth2/access").UsingPost().WithBody("grant_type=password;username=u;password=p"))
|
||||||
@@ -56,14 +127,7 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
.RespondWith(Response.Create()
|
.RespondWith(Response.Create()
|
||||||
.WithStatusCode(201)
|
.WithStatusCode(201)
|
||||||
.WithHeader("Content-Type", "application/json")
|
.WithHeader("Content-Type", "application/json")
|
||||||
.WithBody(@"{ ""result"": ""data posted with FUNC 201""}"));
|
.WithBodyAsJson(new { result = "data posted with FUNC 201" }));
|
||||||
|
|
||||||
server
|
|
||||||
.Given(Request.Create().WithPath("/data", "/ax").UsingPost().WithHeader("Content-Type", "application/json*"))
|
|
||||||
.RespondWith(Response.Create()
|
|
||||||
.WithStatusCode(201)
|
|
||||||
.WithHeader("Content-Type", "application/json")
|
|
||||||
.WithBody(@"{ ""result"": ""data posted with 201""}"));
|
|
||||||
|
|
||||||
server
|
server
|
||||||
.Given(Request.Create().WithPath("/json").UsingPost().WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]")))
|
.Given(Request.Create().WithPath("/json").UsingPost().WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]")))
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
namespace WireMock.Net.ConsoleApplication
|
using System.IO;
|
||||||
|
using log4net.Config;
|
||||||
|
|
||||||
|
namespace WireMock.Net.ConsoleApplication
|
||||||
{
|
{
|
||||||
static class Program
|
static class Program
|
||||||
{
|
{
|
||||||
static void Main(params string[] args)
|
static void Main(params string[] args)
|
||||||
{
|
{
|
||||||
|
XmlConfigurator.Configure(new FileInfo("log4net.config"));
|
||||||
|
|
||||||
MainApp.Run();
|
MainApp.Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,20 +36,22 @@
|
|||||||
<ApplicationIcon>..\..\WireMock.Net-Logo.ico</ApplicationIcon>
|
<ApplicationIcon>..\..\WireMock.Net-Logo.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<HintPath>..\..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="SimMetrics.Net, Version=1.0.3.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="SimMetrics.Net, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\..\packages\SimMetrics.Net.1.0.3\lib\net45\SimMetrics.Net.dll</HintPath>
|
<HintPath>..\..\packages\SimMetrics.Net.1.0.4\lib\net45\SimMetrics.Net.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="WireMock.Net">
|
<Reference Include="System.XML" />
|
||||||
<HintPath>..\..\src\WireMock.Net\bin\$(Configuration)\net45\WireMock.Net.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="MainApp.cs" />
|
<Compile Include="MainApp.cs" />
|
||||||
@@ -60,6 +62,9 @@
|
|||||||
<None Include="App.config">
|
<None Include="App.config">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="log4net.config">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Include="packages.config">
|
<None Include="packages.config">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</None>
|
</None>
|
||||||
@@ -67,6 +72,16 @@
|
|||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj">
|
||||||
|
<Project>{b6269aac-170a-43d5-8b9a-579ded3d9a95}</Project>
|
||||||
|
<Name>WireMock.Net.StandAlone</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj">
|
||||||
|
<Project>{d3804228-91f4-4502-9595-39584e5a01ad}</Project>
|
||||||
|
<Name>WireMock.Net</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
20
examples/WireMock.Net.ConsoleApplication/log4net.config
Normal file
20
examples/WireMock.Net.ConsoleApplication/log4net.config
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<configSections>
|
||||||
|
<section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
|
||||||
|
</configSections>
|
||||||
|
<appSettings>
|
||||||
|
<add key="log4net.Internal.Debug" value="true"/>
|
||||||
|
</appSettings>
|
||||||
|
<log4net>
|
||||||
|
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
|
||||||
|
<layout type="log4net.Layout.PatternLayout">
|
||||||
|
<conversionPattern value="%date [%thread] %-5level %logger{1} - %message%newline" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
<root>
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="ConsoleAppender" />
|
||||||
|
</root>
|
||||||
|
</log4net>
|
||||||
|
</configuration>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="log4net" version="2.0.8" targetFramework="net452" />
|
||||||
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
|
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
|
||||||
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net452" />
|
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net452" />
|
||||||
<package id="SimMetrics.Net" version="1.0.3" targetFramework="net452" />
|
<package id="SimMetrics.Net" version="1.0.4" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -1,21 +1,31 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using log4net;
|
||||||
|
using log4net.Config;
|
||||||
|
using log4net.Repository;
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
|
|
||||||
namespace WireMock.Net.StandAlone.NETCoreApp
|
namespace WireMock.Net.StandAlone.NETCoreApp
|
||||||
{
|
{
|
||||||
class Program
|
static class Program
|
||||||
{
|
{
|
||||||
|
private static readonly ILoggerRepository LogRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
|
||||||
|
// private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
|
||||||
|
|
||||||
private static int sleepTime = 30000;
|
private static int sleepTime = 30000;
|
||||||
private static FluentMockServer server;
|
private static FluentMockServer _server;
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
server = StandAloneApp.Start(args);
|
XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config"));
|
||||||
|
|
||||||
|
_server = StandAloneApp.Start(args);
|
||||||
|
|
||||||
Console.WriteLine($"{DateTime.UtcNow} Press Ctrl+C to shut down");
|
Console.WriteLine($"{DateTime.UtcNow} Press Ctrl+C to shut down");
|
||||||
|
|
||||||
System.Console.CancelKeyPress += (s,e) =>
|
Console.CancelKeyPress += (s, e) =>
|
||||||
{
|
{
|
||||||
Stop("CancelKeyPress");
|
Stop("CancelKeyPress");
|
||||||
};
|
};
|
||||||
@@ -25,7 +35,7 @@ namespace WireMock.Net.StandAlone.NETCoreApp
|
|||||||
Stop("AssemblyLoadContext.Default.Unloading");
|
Stop("AssemblyLoadContext.Default.Unloading");
|
||||||
};
|
};
|
||||||
|
|
||||||
while(true)
|
while (true)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server running");
|
Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server running");
|
||||||
Thread.Sleep(sleepTime);
|
Thread.Sleep(sleepTime);
|
||||||
@@ -35,7 +45,7 @@ namespace WireMock.Net.StandAlone.NETCoreApp
|
|||||||
private static void Stop(string why)
|
private static void Stop(string why)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server stopping because '{why}'");
|
Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server stopping because '{why}'");
|
||||||
server.Stop();
|
_server.Stop();
|
||||||
Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server stopped");
|
Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server stopped");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,18 @@
|
|||||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="log4net" Version="2.0.8" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj" />
|
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="log4net.config">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
20
examples/WireMock.Net.StandAlone.NETCoreApp/log4net.config
Normal file
20
examples/WireMock.Net.StandAlone.NETCoreApp/log4net.config
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<configSections>
|
||||||
|
<section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
|
||||||
|
</configSections>
|
||||||
|
<appSettings>
|
||||||
|
<add key="log4net.Internal.Debug" value="true"/>
|
||||||
|
</appSettings>
|
||||||
|
<log4net>
|
||||||
|
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
|
||||||
|
<layout type="log4net.Layout.PatternLayout">
|
||||||
|
<conversionPattern value="%date [%thread] %-5level %logger{1} - %message%newline" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
<root>
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="ConsoleAppender" />
|
||||||
|
</root>
|
||||||
|
</log4net>
|
||||||
|
</configuration>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using log4net.Config;
|
||||||
|
|
||||||
namespace WireMock.Net.StandAlone.Net452
|
namespace WireMock.Net.StandAlone.Net452
|
||||||
{
|
{
|
||||||
@@ -6,6 +8,8 @@ namespace WireMock.Net.StandAlone.Net452
|
|||||||
{
|
{
|
||||||
static void Main(params string[] args)
|
static void Main(params string[] args)
|
||||||
{
|
{
|
||||||
|
XmlConfigurator.Configure(new FileInfo("log4net.config"));
|
||||||
|
|
||||||
StandAloneApp.Start(args);
|
StandAloneApp.Start(args);
|
||||||
|
|
||||||
Console.WriteLine("Press any key to stop the server");
|
Console.WriteLine("Press any key to stop the server");
|
||||||
|
|||||||
@@ -39,6 +39,9 @@
|
|||||||
<StartupObject>WireMock.Net.StandAlone.Net452.Program</StartupObject>
|
<StartupObject>WireMock.Net.StandAlone.Net452.Program</StartupObject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Numerics" />
|
<Reference Include="System.Numerics" />
|
||||||
@@ -50,6 +53,9 @@
|
|||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="log4net.config">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
20
examples/WireMock.Net.StandAlone.Net452/log4net.config
Normal file
20
examples/WireMock.Net.StandAlone.Net452/log4net.config
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<configSections>
|
||||||
|
<section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
|
||||||
|
</configSections>
|
||||||
|
<appSettings>
|
||||||
|
<add key="log4net.Internal.Debug" value="true"/>
|
||||||
|
</appSettings>
|
||||||
|
<log4net>
|
||||||
|
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
|
||||||
|
<layout type="log4net.Layout.PatternLayout">
|
||||||
|
<conversionPattern value="%date [%thread] %-5level %logger{1} - %message%newline" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
<root>
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="ConsoleAppender" />
|
||||||
|
</root>
|
||||||
|
</log4net>
|
||||||
|
</configuration>
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="log4net" version="2.0.8" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
||||||
22
examples/WireMock.Net.WebApplication/App.cs
Normal file
22
examples/WireMock.Net.WebApplication/App.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace WireMock.Net.WebApplication
|
||||||
|
{
|
||||||
|
public class App
|
||||||
|
{
|
||||||
|
private readonly IWireMockService _service;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public App(IWireMockService service, ILogger logger)
|
||||||
|
{
|
||||||
|
_service = service;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
_logger.LogInformation("WireMock.Net App running");
|
||||||
|
_service.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
examples/WireMock.Net.WebApplication/IWireMockService.cs
Normal file
7
examples/WireMock.Net.WebApplication/IWireMockService.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace WireMock.Net.WebApplication
|
||||||
|
{
|
||||||
|
public interface IWireMockService
|
||||||
|
{
|
||||||
|
void Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
57
examples/WireMock.Net.WebApplication/Program.cs
Normal file
57
examples/WireMock.Net.WebApplication/Program.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using WireMock.Settings;
|
||||||
|
|
||||||
|
namespace WireMock.Net.WebApplication
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
// Create service collection
|
||||||
|
var serviceCollection = new ServiceCollection();
|
||||||
|
ConfigureServices(serviceCollection);
|
||||||
|
|
||||||
|
// Create service provider
|
||||||
|
var serviceProvider = serviceCollection.BuildServiceProvider();
|
||||||
|
|
||||||
|
// Run app
|
||||||
|
serviceProvider.GetService<App>().Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureServices(IServiceCollection serviceCollection)
|
||||||
|
{
|
||||||
|
// Build configuration
|
||||||
|
var configuration = new ConfigurationBuilder()
|
||||||
|
.SetBasePath(AppContext.BaseDirectory)
|
||||||
|
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
||||||
|
.AddEnvironmentVariables() // <-- this is needed to to override settings via the Azure Portal App Settings
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
// Add LoggerFactory
|
||||||
|
var factory = new LoggerFactory();
|
||||||
|
serviceCollection.AddSingleton(factory
|
||||||
|
.AddConsole(configuration.GetSection("Logging"))
|
||||||
|
.AddDebug()
|
||||||
|
.AddAzureWebAppDiagnostics()
|
||||||
|
);
|
||||||
|
|
||||||
|
serviceCollection.AddSingleton(factory.CreateLogger("WireMock.Net Logger"));
|
||||||
|
|
||||||
|
// Add access to generic IConfigurationRoot
|
||||||
|
serviceCollection.AddSingleton(configuration);
|
||||||
|
|
||||||
|
// Add access to IFluentMockServerSettings
|
||||||
|
var settings = configuration.GetSection("FluentMockServerSettings").Get<FluentMockServerSettings>();
|
||||||
|
serviceCollection.AddSingleton<IFluentMockServerSettings>(settings);
|
||||||
|
|
||||||
|
// Add services
|
||||||
|
serviceCollection.AddTransient<IWireMockService, WireMockService>();
|
||||||
|
|
||||||
|
// Add app
|
||||||
|
serviceCollection.AddTransient<App>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:56513/",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchUrl": "__admin/settings",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WireMock.Net.WebApplication": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "__admin/settings",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"applicationUrl": "http://localhost:56514/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="wwwroot\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Update="appsettings.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
37
examples/WireMock.Net.WebApplication/WireMockService.cs
Normal file
37
examples/WireMock.Net.WebApplication/WireMockService.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using WireMock.Net.StandAlone;
|
||||||
|
using WireMock.Settings;
|
||||||
|
|
||||||
|
namespace WireMock.Net.WebApplication
|
||||||
|
{
|
||||||
|
public class WireMockService : IWireMockService
|
||||||
|
{
|
||||||
|
private static int sleepTime = 30000;
|
||||||
|
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly IFluentMockServerSettings _settings;
|
||||||
|
|
||||||
|
public WireMockService(ILogger logger, IFluentMockServerSettings settings)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
_logger.LogInformation("WireMock.Net server starting");
|
||||||
|
|
||||||
|
StandAloneApp.Start(_settings);
|
||||||
|
|
||||||
|
_logger.LogInformation($"WireMock.Net server settings {JsonConvert.SerializeObject(_settings)}");
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("WireMock.Net server running");
|
||||||
|
Thread.Sleep(sleepTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
examples/WireMock.Net.WebApplication/appsettings.json
Normal file
20
examples/WireMock.Net.WebApplication/appsettings.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"IncludeScopes": false,
|
||||||
|
"Debug": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Debug"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Console": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Debug"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"FluentMockServerSettings": {
|
||||||
|
"AdminUsername": "a",
|
||||||
|
"AdminPassword": "a",
|
||||||
|
"StartAdminInterface": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
using System;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
using WireMock.Settings;
|
using WireMock.Settings;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using log4net;
|
||||||
|
|
||||||
namespace WireMock.Net.StandAlone
|
namespace WireMock.Net.StandAlone
|
||||||
{
|
{
|
||||||
@@ -13,12 +12,14 @@ namespace WireMock.Net.StandAlone
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class StandAloneApp
|
public static class StandAloneApp
|
||||||
{
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(StandAloneApp));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start WireMock.Net standalone based on the FluentMockServerSettings.
|
/// Start WireMock.Net standalone Server based on the FluentMockServerSettings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="settings">The FluentMockServerSettings</param>
|
/// <param name="settings">The FluentMockServerSettings</param>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static FluentMockServer Start([NotNull] FluentMockServerSettings settings)
|
public static FluentMockServer Start([NotNull] IFluentMockServerSettings settings)
|
||||||
{
|
{
|
||||||
Check.NotNull(settings, nameof(settings));
|
Check.NotNull(settings, nameof(settings));
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ namespace WireMock.Net.StandAlone
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start WireMock.Net standalone based on the commandline arguments.
|
/// Start WireMock.Net standalone Server based on the commandline arguments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">The commandline arguments</param>
|
/// <param name="args">The commandline arguments</param>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
@@ -34,7 +35,7 @@ namespace WireMock.Net.StandAlone
|
|||||||
{
|
{
|
||||||
Check.NotNull(args, nameof(args));
|
Check.NotNull(args, nameof(args));
|
||||||
|
|
||||||
Console.WriteLine("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
|
Log.DebugFormat("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
|
||||||
|
|
||||||
var parser = new SimpleCommandLineParser();
|
var parser = new SimpleCommandLineParser();
|
||||||
parser.Parse(args);
|
parser.Parse(args);
|
||||||
@@ -43,6 +44,7 @@ namespace WireMock.Net.StandAlone
|
|||||||
{
|
{
|
||||||
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
|
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
|
||||||
ReadStaticMappings = parser.GetBoolValue("ReadStaticMappings"),
|
ReadStaticMappings = parser.GetBoolValue("ReadStaticMappings"),
|
||||||
|
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
|
||||||
AllowPartialMapping = parser.GetBoolValue("AllowPartialMapping", true),
|
AllowPartialMapping = parser.GetBoolValue("AllowPartialMapping", true),
|
||||||
AdminUsername = parser.GetStringValue("AdminUsername"),
|
AdminUsername = parser.GetStringValue("AdminUsername"),
|
||||||
AdminPassword = parser.GetStringValue("AdminPassword"),
|
AdminPassword = parser.GetStringValue("AdminPassword"),
|
||||||
@@ -66,15 +68,15 @@ namespace WireMock.Net.StandAlone
|
|||||||
{
|
{
|
||||||
Url = proxyURL,
|
Url = proxyURL,
|
||||||
SaveMapping = parser.GetBoolValue("SaveMapping"),
|
SaveMapping = parser.GetBoolValue("SaveMapping"),
|
||||||
X509Certificate2ThumbprintOrSubjectName = parser.GetStringValue("X509Certificate2ThumbprintOrSubjectName")
|
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
|
||||||
|
ClientX509Certificate2ThumbprintOrSubjectName = parser.GetStringValue("ClientX509Certificate2ThumbprintOrSubjectName"),
|
||||||
|
BlackListedHeaders = parser.GetValues("BlackListedHeaders")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
|
|
||||||
|
|
||||||
FluentMockServer server = Start(settings);
|
FluentMockServer server = Start(settings);
|
||||||
|
|
||||||
Console.WriteLine("WireMock.Net server listening at {0}", string.Join(" and ", server.Urls));
|
Log.InfoFormat("WireMock.Net server listening at {0}", string.Join(",", server.Urls));
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,33 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
|
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
|
||||||
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
|
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
|
||||||
<Version>1.0.2.4</Version>
|
<Version>1.0.3.3</Version>
|
||||||
<Authors>Stef Heyenrath</Authors>
|
<Authors>Stef Heyenrath</Authors>
|
||||||
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
|
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||||
<!-- <TargetFrameworks>netstandard1.3;netstandard2.0</TargetFrameworks> -->
|
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<AssemblyName>WireMock.Net.StandAlone</AssemblyName>
|
<AssemblyName>WireMock.Net.StandAlone</AssemblyName>
|
||||||
<PackageId>WireMock.Net.StandAlone</PackageId>
|
<PackageId>WireMock.Net.StandAlone</PackageId>
|
||||||
<PackageTags>tdd;mock;http;wiremock;test;server;unittest</PackageTags>
|
<PackageTags>tdd;mock;http;wiremock;test;server;unittest</PackageTags>
|
||||||
<PackageReleaseNotes></PackageReleaseNotes>
|
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
|
||||||
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/LICENSE</PackageLicenseUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
|
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
|
||||||
<DebugType>portable</DebugType>
|
|
||||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||||
<RootNamespace>WireMock.Net.StandAlone</RootNamespace>
|
<RootNamespace>WireMock.Net.StandAlone</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<IncludeSource>True</IncludeSource>
|
||||||
|
<IncludeSymbols>True</IncludeSymbols>
|
||||||
|
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' ">
|
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' ">
|
||||||
<DefineConstants>NETSTANDARD</DefineConstants>
|
<DefineConstants>NETSTANDARD</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -31,10 +36,7 @@
|
|||||||
<PackageReference Include="JetBrains.Annotations" Version="10.4.0">
|
<PackageReference Include="JetBrains.Annotations" Version="10.4.0">
|
||||||
<PrivateAssets>All</PrivateAssets>
|
<PrivateAssets>All</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<!-- <PackageReference Include="CommandLineArgumentsParser" Version="3.0.16" /> -->
|
<PackageReference Include="log4net" Version="2.0.8" />
|
||||||
<!-- <PackageReference Include="Marsonsoft.CommandLineParser" Version="1.0.34" /> -->
|
|
||||||
<!-- <PackageReference Include="BurnSystems.CommandLine" Version="1.1.0" /> -->
|
|
||||||
<!-- <ProjectReference Include="..\..\..\CommandLineParser\src\CommandLineArgumentsParser\CommandLineArgumentsParser.csproj" /> -->
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -10,29 +10,20 @@ namespace WireMock.Admin.Mappings
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the unique identifier.
|
/// Gets or sets the unique identifier.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The unique identifier.
|
|
||||||
/// </value>
|
|
||||||
public Guid? Guid { get; set; }
|
public Guid? Guid { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the unique title.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The unique title.
|
/// The unique title.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the priority.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The priority.
|
/// The priority.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public int? Priority { get; set; }
|
public int? Priority { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scenario.
|
/// The Scenario.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Scenario { get; set; }
|
public string Scenario { get; set; }
|
||||||
|
|
||||||
@@ -48,19 +39,13 @@ namespace WireMock.Admin.Mappings
|
|||||||
public object SetStateTo { get; set; }
|
public object SetStateTo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the request.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The request.
|
/// The request.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public RequestModel Request { get; set; }
|
public RequestModel Request { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the response.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The response.
|
/// The response.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public ResponseModel Response { get; set; }
|
public ResponseModel Response { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,79 +10,71 @@ namespace WireMock.Admin.Mappings
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the HTTP status.
|
/// Gets or sets the HTTP status.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The HTTP status.
|
|
||||||
/// </value>
|
|
||||||
public int? StatusCode { get; set; }
|
public int? StatusCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the body destination (SameAsSource, String or Bytes).
|
||||||
|
/// </summary>
|
||||||
|
public string BodyDestination { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body.
|
/// Gets or sets the body.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The body.
|
|
||||||
/// </value>
|
|
||||||
public string Body { get; set; }
|
public string Body { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body.
|
/// Gets or sets the body.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
public string BodyFromBase64 { get; set; }
|
||||||
/// The body.
|
|
||||||
/// </value>
|
|
||||||
public string BodyAsBase64 { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body (as JSON object).
|
/// Gets or sets the body (as JSON object).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The body.
|
|
||||||
/// </value>
|
|
||||||
public object BodyAsJson { get; set; }
|
public object BodyAsJson { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the body (as bytearray).
|
||||||
|
/// </summary>
|
||||||
|
public byte[] BodyAsBytes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the body as a file.
|
||||||
|
/// </summary>
|
||||||
|
public string BodyAsFile { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the body as file cached?
|
||||||
|
/// </summary>
|
||||||
|
public bool? BodyAsFileIsCached { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body encoding.
|
/// Gets or sets the body encoding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The body encoding.
|
|
||||||
/// </value>
|
|
||||||
public EncodingModel BodyEncoding { get; set; }
|
public EncodingModel BodyEncoding { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether [use transformer].
|
/// Gets or sets a value indicating whether [use transformer].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// <c>true</c> if [use transformer]; otherwise, <c>false</c>.
|
|
||||||
/// </value>
|
|
||||||
public bool UseTransformer { get; set; }
|
public bool UseTransformer { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the headers.
|
/// Gets or sets the headers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
public IDictionary<string, object> Headers { get; set; }
|
||||||
/// The headers.
|
|
||||||
/// </value>
|
|
||||||
public IDictionary<string, string> Headers { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Headers (Raw).
|
/// Gets or sets the Headers (Raw).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The Headers (Raw).
|
|
||||||
/// </value>
|
|
||||||
public string HeadersRaw { get; set; }
|
public string HeadersRaw { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the delay in milliseconds.
|
/// Gets or sets the delay in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The delay in milliseconds.
|
|
||||||
/// </value>
|
|
||||||
public int? Delay { get; set; }
|
public int? Delay { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Proxy URL.
|
/// Gets or sets the Proxy URL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>ProxyUrl</value>
|
|
||||||
public string ProxyUrl { get; set; }
|
public string ProxyUrl { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -8,51 +8,33 @@ namespace WireMock.Admin.Requests
|
|||||||
public class LogEntryModel
|
public class LogEntryModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the unique identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The unique identifier.
|
/// The unique identifier.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public Guid Guid { get; set; }
|
public Guid Guid { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the request.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The request.
|
/// The request.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public LogRequestModel Request { get; set; }
|
public LogRequestModel Request { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the response.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The response.
|
/// The response.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public LogResponseModel Response { get; set; }
|
public LogResponseModel Response { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the mapping unique identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The mapping unique identifier.
|
/// The mapping unique identifier.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public Guid? MappingGuid { get; set; }
|
public Guid? MappingGuid { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the mapping unique title.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The mapping unique title.
|
/// The mapping unique title.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public string MappingTitle { get; set; }
|
public string MappingTitle { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the request match result.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The request match result.
|
/// The request match result.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public LogRequestMatchModel RequestMatchResult { get; set; }
|
public LogRequestMatchModel RequestMatchResult { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,74 +11,63 @@ namespace WireMock.Admin.Requests
|
|||||||
public class LogRequestModel
|
public class LogRequestModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Client IP Address.
|
/// The Client IP Address.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ClientIP { get; set; }
|
public string ClientIP { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the DateTime.
|
/// The DateTime.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime DateTime { get; set; }
|
public DateTime DateTime { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Path.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The Path.
|
/// The Path.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the absolete URL.
|
///The absolete URL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The absolute URL.
|
|
||||||
/// </value>
|
|
||||||
public string AbsoluteUrl { get; set; }
|
public string AbsoluteUrl { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the query.
|
/// The query.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, WireMockList<string>> Query { get; set; }
|
public IDictionary<string, WireMockList<string>> Query { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the method.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The method.
|
/// The method.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public string Method { get; set; }
|
public string Method { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Headers.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The Headers.
|
/// The Headers.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public IDictionary<string, string> Headers { get; set; }
|
public IDictionary<string, WireMockList<string>> Headers { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Cookies.
|
/// Tthe Cookies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The Cookies.
|
|
||||||
/// </value>
|
|
||||||
public IDictionary<string, string> Cookies { get; set; }
|
public IDictionary<string, string> Cookies { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body.
|
/// The body (as string).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The body.
|
|
||||||
/// </value>
|
|
||||||
public string Body { get; set; }
|
public string Body { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body encoding.
|
/// The body (as JSON object).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
public object BodyAsJson { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body (as bytearray).
|
||||||
|
/// </summary>
|
||||||
|
public byte[] BodyAsBytes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
/// The body encoding.
|
/// The body encoding.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public EncodingModel BodyEncoding { get; set; }
|
public EncodingModel BodyEncoding { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.Admin.Requests
|
namespace WireMock.Admin.Requests
|
||||||
{
|
{
|
||||||
@@ -16,13 +17,38 @@ namespace WireMock.Admin.Requests
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the headers.
|
/// Gets the headers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, string> Headers { get; set; }
|
public IDictionary<string, WireMockList<string>> Headers { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body.
|
/// Gets or sets the body destination (SameAsSource, String or Bytes).
|
||||||
|
/// </summary>
|
||||||
|
public string BodyDestination { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body (as string).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Body { get; set; }
|
public string Body { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body (as JSON object).
|
||||||
|
/// </summary>
|
||||||
|
public object BodyAsJson { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body (as bytearray).
|
||||||
|
/// </summary>
|
||||||
|
public byte[] BodyAsBytes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the body as file.
|
||||||
|
/// </summary>
|
||||||
|
public string BodyAsFile { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the body as file cached?
|
||||||
|
/// </summary>
|
||||||
|
public bool? BodyAsFileIsCached { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the original body.
|
/// Gets or sets the original body.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ namespace WireMock.Client
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="mapping">MappingModel</param>
|
/// <param name="mapping">MappingModel</param>
|
||||||
[Post("__admin/mappings")]
|
[Post("__admin/mappings")]
|
||||||
|
[Header("Content-Type", "application/json")]
|
||||||
Task<string> PostMappingAsync([Body] MappingModel mapping);
|
Task<string> PostMappingAsync([Body] MappingModel mapping);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -103,7 +104,7 @@ namespace WireMock.Client
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>LogRequestModels</returns>
|
/// <returns>LogRequestModels</returns>
|
||||||
[Get("__admin/requests")]
|
[Get("__admin/requests")]
|
||||||
Task<IList<LogRequestModel>> GetRequestsAsync();
|
Task<IList<LogEntryModel>> GetRequestsAsync();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete all requests.
|
/// Delete all requests.
|
||||||
@@ -123,7 +124,7 @@ namespace WireMock.Client
|
|||||||
/// <param name="guid">The Guid</param>
|
/// <param name="guid">The Guid</param>
|
||||||
/// <returns>MappingModel</returns>
|
/// <returns>MappingModel</returns>
|
||||||
[Get("__admin/requests/{guid}")]
|
[Get("__admin/requests/{guid}")]
|
||||||
Task<LogRequestModel> GetRequestAsync([Path] Guid guid);
|
Task<LogEntryModel> GetRequestAsync([Path] Guid guid);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete a request based on the guid
|
/// Delete a request based on the guid
|
||||||
@@ -137,6 +138,25 @@ namespace WireMock.Client
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="model">The RequestModel</param>
|
/// <param name="model">The RequestModel</param>
|
||||||
[Post("__admin/requests/find")]
|
[Post("__admin/requests/find")]
|
||||||
Task<IList<LogRequestModel>> FindRequestsAsync([Body] RequestModel model);
|
[Header("Content-Type", "application/json")]
|
||||||
|
Task<IList<LogEntryModel>> FindRequestsAsync([Body] RequestModel model);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get all scenarios
|
||||||
|
/// </summary>
|
||||||
|
[Get("__admin/scenarios")]
|
||||||
|
Task<string> GetScenariosAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delete (reset) all scenarios
|
||||||
|
/// </summary>
|
||||||
|
[Delete("__admin/scenarios")]
|
||||||
|
Task<string> DeleteScenariosAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delete (reset) all scenarios
|
||||||
|
/// </summary>
|
||||||
|
[Post("__admin/scenarios")]
|
||||||
|
Task<string> ResetScenariosAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,10 +42,10 @@ namespace WireMock
|
|||||||
|
|
||||||
internal class ProxyAsyncResponseProvider : IResponseProvider
|
internal class ProxyAsyncResponseProvider : IResponseProvider
|
||||||
{
|
{
|
||||||
private readonly Func<RequestMessage, ProxyAndRecordSettings, Task<ResponseMessage>> _responseMessageFunc;
|
private readonly Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>> _responseMessageFunc;
|
||||||
private readonly ProxyAndRecordSettings _settings;
|
private readonly IProxyAndRecordSettings _settings;
|
||||||
|
|
||||||
public ProxyAsyncResponseProvider([NotNull] Func<RequestMessage, ProxyAndRecordSettings, Task<ResponseMessage>> responseMessageFunc, [NotNull] ProxyAndRecordSettings settings)
|
public ProxyAsyncResponseProvider([NotNull] Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>> responseMessageFunc, [NotNull] IProxyAndRecordSettings settings)
|
||||||
{
|
{
|
||||||
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
|
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
|
||||||
Check.NotNull(settings, nameof(settings));
|
Check.NotNull(settings, nameof(settings));
|
||||||
|
|||||||
@@ -1,87 +1,137 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Security.Authentication;
|
|
||||||
using System.Security.Cryptography.X509Certificates;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using WireMock.HttpsCertificate;
|
||||||
|
using WireMock.Util;
|
||||||
|
using WireMock.Validation;
|
||||||
|
|
||||||
namespace WireMock.Http
|
namespace WireMock.Http
|
||||||
{
|
{
|
||||||
internal static class HttpClientHelper
|
internal static class HttpClientHelper
|
||||||
{
|
{
|
||||||
|
public static HttpClient CreateHttpClient(string clientX509Certificate2ThumbprintOrSubjectName = null)
|
||||||
private static HttpClient CreateHttpClient(string clientX509Certificate2ThumbprintOrSubjectName = null)
|
|
||||||
{
|
{
|
||||||
|
#if NETSTANDARD || NET46
|
||||||
|
var handler = new HttpClientHandler
|
||||||
|
{
|
||||||
|
CheckCertificateRevocationList = false,
|
||||||
|
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
|
||||||
|
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
|
||||||
|
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
var handler = new WebRequestHandler
|
||||||
|
{
|
||||||
|
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
|
||||||
|
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(clientX509Certificate2ThumbprintOrSubjectName))
|
if (!string.IsNullOrEmpty(clientX509Certificate2ThumbprintOrSubjectName))
|
||||||
{
|
{
|
||||||
#if NETSTANDARD || NET46
|
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
|
||||||
var handler = new HttpClientHandler
|
|
||||||
{
|
|
||||||
ClientCertificateOptions = ClientCertificateOption.Manual,
|
|
||||||
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
|
|
||||||
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
|
|
||||||
};
|
|
||||||
|
|
||||||
var x509Certificate2 = CertificateUtil.GetCertificate(clientX509Certificate2ThumbprintOrSubjectName);
|
var x509Certificate2 = ClientCertificateHelper.GetCertificate(clientX509Certificate2ThumbprintOrSubjectName);
|
||||||
handler.ClientCertificates.Add(x509Certificate2);
|
handler.ClientCertificates.Add(x509Certificate2);
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
var handler = new WebRequestHandler
|
|
||||||
{
|
|
||||||
ClientCertificateOptions = ClientCertificateOption.Manual,
|
|
||||||
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
|
|
||||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
|
||||||
};
|
|
||||||
|
|
||||||
var x509Certificate2 = CertificateUtil.GetCertificate(clientX509Certificate2ThumbprintOrSubjectName);
|
|
||||||
handler.ClientCertificates.Add(x509Certificate2);
|
|
||||||
return new HttpClient(handler);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HttpClient();
|
// For proxy we shouldn't follow auto redirects
|
||||||
|
handler.AllowAutoRedirect = false;
|
||||||
|
|
||||||
|
// If UseCookies enabled, httpClient ignores Cookie header
|
||||||
|
handler.UseCookies = false;
|
||||||
|
|
||||||
|
var client = new HttpClient(handler);
|
||||||
|
#if NET452 || NET46
|
||||||
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
|
||||||
|
#endif
|
||||||
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<ResponseMessage> SendAsync(RequestMessage requestMessage, string url, string clientX509Certificate2ThumbprintOrSubjectName = null)
|
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url)
|
||||||
{
|
{
|
||||||
var client = CreateHttpClient(clientX509Certificate2ThumbprintOrSubjectName);
|
Check.NotNull(client, nameof(client));
|
||||||
|
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||||
|
|
||||||
|
var originalUri = new Uri(requestMessage.Url);
|
||||||
|
var requiredUri = new Uri(url);
|
||||||
|
|
||||||
var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);
|
var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);
|
||||||
|
|
||||||
|
WireMockList<string> contentTypeHeader = null;
|
||||||
|
bool contentTypeHeaderPresent = requestMessage.Headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (contentTypeHeaderPresent)
|
||||||
|
{
|
||||||
|
contentTypeHeader = requestMessage.Headers[HttpKnownHeaderNames.ContentType];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Body if present
|
||||||
|
if (requestMessage.BodyAsBytes != null)
|
||||||
|
{
|
||||||
|
httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);
|
||||||
|
}
|
||||||
|
else if (requestMessage.BodyAsJson != null)
|
||||||
|
{
|
||||||
|
httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson), requestMessage.BodyEncoding);
|
||||||
|
}
|
||||||
|
else if (requestMessage.Body != null)
|
||||||
|
{
|
||||||
|
httpRequestMessage.Content = new StringContent(requestMessage.Body, requestMessage.BodyEncoding);
|
||||||
|
}
|
||||||
|
|
||||||
// Overwrite the host header
|
// Overwrite the host header
|
||||||
httpRequestMessage.Headers.Host = new Uri(url).Authority;
|
httpRequestMessage.Headers.Host = requiredUri.Authority;
|
||||||
|
|
||||||
// Set headers if present
|
// Set headers if present
|
||||||
if (requestMessage.Headers != null)
|
if (requestMessage.Headers != null)
|
||||||
{
|
{
|
||||||
foreach (var headerName in requestMessage.Headers.Keys.Where(k => k.ToUpper() != "HOST"))
|
foreach (var header in requestMessage.Headers.Where(header => !string.Equals(header.Key, "HOST", StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
httpRequestMessage.Headers.Add(headerName, new[] { requestMessage.Headers[headerName] });
|
// Try to add to request headers. If failed - try to add to content headers
|
||||||
|
if (!httpRequestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value))
|
||||||
|
{
|
||||||
|
httpRequestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Body if present
|
|
||||||
if (requestMessage.BodyAsBytes != null && requestMessage.BodyAsBytes.Length > 0)
|
|
||||||
{
|
|
||||||
httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the URL
|
// Call the URL
|
||||||
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
|
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
|
||||||
|
|
||||||
|
// Create transform response
|
||||||
|
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
|
||||||
|
|
||||||
// Transform response
|
// Set both content and response headers, replacing URLs in values
|
||||||
var responseMessage = new ResponseMessage
|
var headers = (httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers) ?? Enumerable.Empty<KeyValuePair<string, IEnumerable<string>>>()).ToArray();
|
||||||
|
if (httpResponseMessage.Content != null)
|
||||||
{
|
{
|
||||||
StatusCode = (int)httpResponseMessage.StatusCode,
|
var stream = await httpResponseMessage.Content.ReadAsStreamAsync();
|
||||||
Body = await httpResponseMessage.Content.ReadAsStringAsync()
|
var body = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
|
||||||
};
|
responseMessage.Body = body.BodyAsString;
|
||||||
|
responseMessage.BodyAsJson = body.BodyAsJson;
|
||||||
|
responseMessage.BodyAsBytes = body.BodyAsBytes;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var header in httpResponseMessage.Headers)
|
foreach (var header in headers)
|
||||||
{
|
{
|
||||||
responseMessage.AddHeader(header.Key, header.Value.FirstOrDefault());
|
// If Location header contains absolute redirect URL, and base URL is one that we proxy to,
|
||||||
|
// we need to replace it to original one.
|
||||||
|
if (string.Equals(header.Key, HttpKnownHeaderNames.Location, StringComparison.OrdinalIgnoreCase)
|
||||||
|
&& Uri.TryCreate(header.Value.First(), UriKind.Absolute, out Uri absoluteLocationUri)
|
||||||
|
&& string.Equals(absoluteLocationUri.Host, requiredUri.Host, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var replacedLocationUri = new Uri(originalUri, absoluteLocationUri.PathAndQuery);
|
||||||
|
responseMessage.AddHeader(header.Key, replacedLocationUri.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
responseMessage.AddHeader(header.Key, header.Value.ToArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return responseMessage;
|
return responseMessage;
|
||||||
|
|||||||
96
src/WireMock.Net/Http/HttpKnownHeaderNames.cs
Normal file
96
src/WireMock.Net/Http/HttpKnownHeaderNames.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
namespace WireMock.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Copied from https://raw.githubusercontent.com/dotnet/corefx/master/src/Common/src/System/Net/HttpKnownHeaderNames.cs
|
||||||
|
/// </summary>
|
||||||
|
internal static class HttpKnownHeaderNames
|
||||||
|
{
|
||||||
|
public const string Accept = "Accept";
|
||||||
|
public const string AcceptCharset = "Accept-Charset";
|
||||||
|
public const string AcceptEncoding = "Accept-Encoding";
|
||||||
|
public const string AcceptLanguage = "Accept-Language";
|
||||||
|
public const string AcceptPatch = "Accept-Patch";
|
||||||
|
public const string AcceptRanges = "Accept-Ranges";
|
||||||
|
public const string AccessControlAllowCredentials = "Access-Control-Allow-Credentials";
|
||||||
|
public const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";
|
||||||
|
public const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
|
||||||
|
public const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
|
||||||
|
public const string AccessControlExposeHeaders = "Access-Control-Expose-Headers";
|
||||||
|
public const string AccessControlMaxAge = "Access-Control-Max-Age";
|
||||||
|
public const string Age = "Age";
|
||||||
|
public const string Allow = "Allow";
|
||||||
|
public const string AltSvc = "Alt-Svc";
|
||||||
|
public const string Authorization = "Authorization";
|
||||||
|
public const string CacheControl = "Cache-Control";
|
||||||
|
public const string Connection = "Connection";
|
||||||
|
public const string ContentDisposition = "Content-Disposition";
|
||||||
|
public const string ContentEncoding = "Content-Encoding";
|
||||||
|
public const string ContentLanguage = "Content-Language";
|
||||||
|
public const string ContentLength = "Content-Length";
|
||||||
|
public const string ContentLocation = "Content-Location";
|
||||||
|
public const string ContentMD5 = "Content-MD5";
|
||||||
|
public const string ContentRange = "Content-Range";
|
||||||
|
public const string ContentSecurityPolicy = "Content-Security-Policy";
|
||||||
|
public const string ContentType = "Content-Type";
|
||||||
|
public const string Cookie = "Cookie";
|
||||||
|
public const string Cookie2 = "Cookie2";
|
||||||
|
public const string Date = "Date";
|
||||||
|
public const string ETag = "ETag";
|
||||||
|
public const string Expect = "Expect";
|
||||||
|
public const string Expires = "Expires";
|
||||||
|
public const string From = "From";
|
||||||
|
public const string Host = "Host";
|
||||||
|
public const string IfMatch = "If-Match";
|
||||||
|
public const string IfModifiedSince = "If-Modified-Since";
|
||||||
|
public const string IfNoneMatch = "If-None-Match";
|
||||||
|
public const string IfRange = "If-Range";
|
||||||
|
public const string IfUnmodifiedSince = "If-Unmodified-Since";
|
||||||
|
public const string KeepAlive = "Keep-Alive";
|
||||||
|
public const string LastModified = "Last-Modified";
|
||||||
|
public const string Link = "Link";
|
||||||
|
public const string Location = "Location";
|
||||||
|
public const string MaxForwards = "Max-Forwards";
|
||||||
|
public const string Origin = "Origin";
|
||||||
|
public const string P3P = "P3P";
|
||||||
|
public const string Pragma = "Pragma";
|
||||||
|
public const string ProxyAuthenticate = "Proxy-Authenticate";
|
||||||
|
public const string ProxyAuthorization = "Proxy-Authorization";
|
||||||
|
public const string ProxyConnection = "Proxy-Connection";
|
||||||
|
public const string PublicKeyPins = "Public-Key-Pins";
|
||||||
|
public const string Range = "Range";
|
||||||
|
public const string Referer = "Referer"; // NB: The spelling-mistake "Referer" for "Referrer" must be matched.
|
||||||
|
public const string RetryAfter = "Retry-After";
|
||||||
|
public const string SecWebSocketAccept = "Sec-WebSocket-Accept";
|
||||||
|
public const string SecWebSocketExtensions = "Sec-WebSocket-Extensions";
|
||||||
|
public const string SecWebSocketKey = "Sec-WebSocket-Key";
|
||||||
|
public const string SecWebSocketProtocol = "Sec-WebSocket-Protocol";
|
||||||
|
public const string SecWebSocketVersion = "Sec-WebSocket-Version";
|
||||||
|
public const string Server = "Server";
|
||||||
|
public const string SetCookie = "Set-Cookie";
|
||||||
|
public const string SetCookie2 = "Set-Cookie2";
|
||||||
|
public const string StrictTransportSecurity = "Strict-Transport-Security";
|
||||||
|
public const string TE = "TE";
|
||||||
|
public const string TSV = "TSV";
|
||||||
|
public const string Trailer = "Trailer";
|
||||||
|
public const string TransferEncoding = "Transfer-Encoding";
|
||||||
|
public const string Upgrade = "Upgrade";
|
||||||
|
public const string UpgradeInsecureRequests = "Upgrade-Insecure-Requests";
|
||||||
|
public const string UserAgent = "User-Agent";
|
||||||
|
public const string Vary = "Vary";
|
||||||
|
public const string Via = "Via";
|
||||||
|
public const string WWWAuthenticate = "WWW-Authenticate";
|
||||||
|
public const string Warning = "Warning";
|
||||||
|
public const string XAspNetVersion = "X-AspNet-Version";
|
||||||
|
public const string XContentDuration = "X-Content-Duration";
|
||||||
|
public const string XContentTypeOptions = "X-Content-Type-Options";
|
||||||
|
public const string XFrameOptions = "X-Frame-Options";
|
||||||
|
public const string XMSEdgeRef = "X-MSEdge-Ref";
|
||||||
|
public const string XPoweredBy = "X-Powered-By";
|
||||||
|
public const string XRequestID = "X-Request-ID";
|
||||||
|
public const string XUACompatible = "X-UA-Compatible";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,18 +5,15 @@ using System.Text.RegularExpressions;
|
|||||||
namespace WireMock.Http
|
namespace WireMock.Http
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Utility class
|
/// Port Utility class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class PortUtil
|
public static class PortUtil
|
||||||
{
|
{
|
||||||
private static readonly Regex UrlDetailsRegex = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>\d+)?/", RegexOptions.Compiled);
|
private static readonly Regex UrlDetailsRegex = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>\d+)?/", RegexOptions.Compiled);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The find free TCP port.
|
/// Finds a free TCP port.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>
|
|
||||||
/// The <see cref="int"/>.
|
|
||||||
/// </returns>
|
|
||||||
/// <remarks>see http://stackoverflow.com/questions/138043/find-the-next-tcp-port-in-net.</remarks>
|
/// <remarks>see http://stackoverflow.com/questions/138043/find-the-next-tcp-port-in-net.</remarks>
|
||||||
public static int FindFreeTcpPort()
|
public static int FindFreeTcpPort()
|
||||||
{
|
{
|
||||||
@@ -40,7 +37,7 @@ namespace WireMock.Http
|
|||||||
public static bool TryExtractProtocolAndPort(string url, out string proto, out int port)
|
public static bool TryExtractProtocolAndPort(string url, out string proto, out int port)
|
||||||
{
|
{
|
||||||
proto = null;
|
proto = null;
|
||||||
port = -1;
|
port = 0;
|
||||||
|
|
||||||
Match m = UrlDetailsRegex.Match(url);
|
Match m = UrlDetailsRegex.Match(url);
|
||||||
if (m.Success)
|
if (m.Success)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
|
||||||
namespace WireMock.Http
|
namespace WireMock.HttpsCertificate
|
||||||
{
|
{
|
||||||
internal static class CertificateUtil
|
internal static class ClientCertificateHelper
|
||||||
{
|
{
|
||||||
public static X509Certificate2 GetCertificate(string thumbprintOrSubjectName)
|
public static X509Certificate2 GetCertificate(string thumbprintOrSubjectName)
|
||||||
{
|
{
|
||||||
91
src/WireMock.Net/HttpsCertificate/PublicCertificateHelper.cs
Normal file
91
src/WireMock.Net/HttpsCertificate/PublicCertificateHelper.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
|
||||||
|
namespace WireMock.HttpsCertificate
|
||||||
|
{
|
||||||
|
internal static class PublicCertificateHelper
|
||||||
|
{
|
||||||
|
// 1] Generate using https://www.pluralsight.com/blog/software-development/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net
|
||||||
|
// 2] Converted to Base64
|
||||||
|
private const string Data = @"MIIQMgIBAzCCD+4GCSqGSIb3DQEHAaCCD98Egg/bMIIP1zCCCogGCSqGSIb3DQEHAaCCCnkEggp1
|
||||||
|
MIIKcTCCCm0GCyqGSIb3DQEMCgECoIIJfjCCCXowHAYKKoZIhvcNAQwBAzAOBAi1j9x1jTfUewIC
|
||||||
|
B9AEgglYa48lP16+isiGEVT7zwN3XwaPwPOHZcQ7tRA/DA8LZnZbwU7XhtPObF5bZcHn4engX2An
|
||||||
|
ISFpe2S5XJ7BfHmsGOO7Bxj6C2IcZIPTefvAd9vWE0WUAGN11SLhJ3fB/ZRt3Nys7JCJzywQCkYK
|
||||||
|
dCA35V7WfETCLT6+ArtRU4qsjop2YXyUzcLw3OuumBAoRsazgUKz8rkZJbifkSikbdxs+Hupcf2I
|
||||||
|
NOOuKStKoqouqCO/vmRi8u8g0KQhf2LcQBSqLk6OZ8TQuv07W5tVO2Ky5qCYu6aXBBlHhGSY9fGL
|
||||||
|
vqaYcxMcVJQpXUUL6nSWCoaLdaAAB+Anw1Tpbd47W7ieTK5Yq2IROPQIr1mk8nvFbxoTcBuIQ6oU
|
||||||
|
RiiLX+mb3hYgbTL3LqDmmm9FFI8enJu6pUxP8iKKROtCqhYXhF1i3EwReBzJzpDGZ+y4rJxb0Es4
|
||||||
|
sPVc/TaVPSJCTmgcKzwps7M12uxm8G9Dv3lKgZVmgDRivovCJFxHdCdgCYB08FvNWuFtXO+schsE
|
||||||
|
N0nY2i07A2joaJC18yvoNGZ+ySBTBPOBN+5XbiQs0vsQ4MfLETb2O2dFjwE/tErgo6RWYg2qQNAe
|
||||||
|
DSh2wHzI0YJM3PqaUR0Q9KnjEWc92hsLI34KnuNkNkVk4NEjPOetxeIBcYN7CDD6tTxp42sU++bT
|
||||||
|
o9zyjy1BPS+LuEblxDTSlVPb0dxvkwNBXBi0RXIOWfD15BWcV1Uv972jB6To1XPDIOc+eq7fa5yn
|
||||||
|
HRW/GYdGPmOYKietdw6V3t2Et9cPlw4v08IelucF06Ju2a73QtidtkA89vxjn7qOEVACAXpsiMsM
|
||||||
|
4JCcAzF7jh0U2mskSB14I9HcZh1Sei0J2ZULcXNyuIw9nsWp8vrH04OOoUDe7/UpX7c8+A+tqDUy
|
||||||
|
1W2V1dJDhlwu2SXL5jJFBK4P9p2e+XyHJ+AcYXrHQIKxqoCgvnywT4HnI2bvZ1+lmIR99mp1Cvzj
|
||||||
|
RUgJaqhI7u6WH3i6fmkA92hF8MP5WDYTGwjsHPrCg6Xkqykuvub4osu+gLq5t+JC9rOczgrRNYXg
|
||||||
|
54FMzlCyQxTfgY6IRwPH/xYHKGbViFF+jA4ksLMRjI2XOV4swbI232SxMoQQDNsjx1la2nZM3P5z
|
||||||
|
g7zpmaiyzY44q3kU1viMMR7qM/w1S6nTW0ZkzTXk8Gttor/0JWT1K8KgwK02B6Q9zNwfK60a0cQm
|
||||||
|
SbA/dXkWapuIzQLz+ZUPyG/1EP5KuKNnsp0hfVi8TTgOFceoV9kyIhrTQNI0o5O91dqkyWd/bMl2
|
||||||
|
OnrnRnhka6f839zJKUpWPTfRX9RMJTk/5HVcL/qsHYcJedZyPawJjMU+cxW1ZZjr1Lo6M0fjKuTI
|
||||||
|
Askg0ZKS0FJ60jTKnc1DmldQLtieHh1UTdty+yn1A0rGnrFEyN7if2/d1EduWJaf6bvWzfH+d/36
|
||||||
|
1gDwp4OXi0qWu7c5zByGZi2j2sFo4v0cGgjPZUJvF5z0V8OkE15DiA4xtTSkIjCnEmOhODViwrfc
|
||||||
|
ONvHB+inBW9wLp26qFgNcYrYxP2FC54pPCxO+KJaAJrtfE3A4lkboB7V0xFu23ecOy4n2gho39tg
|
||||||
|
Bxkt1Xj3GCLgeKvcYLzOPytZldXDTtoCcsm5uhCmBHEmPUsnLc7Tt1cFflFtWTOjtyv0Lk8Qu2BU
|
||||||
|
B/hSSgjZRpqE+hzjtghjXdFOT5wKULvtUz5eu+lH7kjGghQbF962vLcRCsr+tMPba6MFqhy5Q+dM
|
||||||
|
NcHc+HIx2WiuRZ6jdCZSUpH3f1+kH6XYj2P3/F0kLBRAMPGKbXpIi9Px4AVDEDClL77mDpVgeEoh
|
||||||
|
kkVh5zvk2PsEPonmTFK0kQE8Q4cYFWTKa9lAE4Wc35EzvpKFdTwQKhr5kN7tEq17n5wJt/499164
|
||||||
|
ho0+LjzYy62JI/fv3RPISL0gXr2INLW7fgZ5KNjcnu/AITJu3ycw/XH8BKsx4dcbBgBdrKY8afEn
|
||||||
|
IZ1EIv/TuNvmifmAEGX/DWuVmZIOU6pTystzTQwfz0wko3lUKjkPM40RLN9o6lddV6fM3QNtK0ac
|
||||||
|
hqOOmG68LzI1U33nvUBol/FeEV0DLvGjvsIRC/TCtDu5Vk2tKS13p9kNj4owJK8d343PZ/eyi/Oe
|
||||||
|
sNZCCJJuj4iIodekm1hzj7zc6ZLNudgab/WkF7TbWDOhDPwG1gE/McffGNWPFlwsaopoZaH8E8tl
|
||||||
|
QSOnHqAiNa7B3ifxMrGDWHDlxkWddClbKd9ujL4mgB88Wo8JceLawDOcSVGImvWGxsrK2RX7FK57
|
||||||
|
GQYuc0zcq3NH4jpoOyS+vpMeigTPDOvQdqjGgEUW3aXdA8Ma0KYVEyAhK/rFXw8FelGREM2ku1kN
|
||||||
|
kziOTAe52SWqcrv6NUPfo1/Uc6u7KpwQrcDlFZWxPCKomeRQTm6AmP2QHMgl2gaUbmuBF/C9Ccl2
|
||||||
|
1Iqh8vUdDT3lHdf5I5SjRPJJXX2/0/oUFmwIC5AFp8/XXnIG05BER1X2Y+SL15QHW7lYsvd4ZKTv
|
||||||
|
tvYaZNWajgAVZl8gJYFUQG+U+cFYcpHhf6SGzcuwcmQJGxptZAVnRtDzNjJ04vJB616/uoI2Qkp2
|
||||||
|
ysGAjDNlwgeckmU7TSYoYaML29pRupTTQqKItyFDuebUpSKBTxsEFIJBCTErA8TD8I9T5nzT+rTy
|
||||||
|
+Lpp9mqcxQR1RhxgTx5bE7D4igdblobX0IONARg4EIAk8xj1Ba3k4skdjAQcJOHKd+xVo+vsrIqg
|
||||||
|
a+ycemROE5F3D3s21ozMOn1Dy8iIeQusJQTSkP82+wHYWXRg59N0cq/40CaJskK+yp7afOWFoCqY
|
||||||
|
T/D9OGlfeIIiLivwMh8naPZyM4+pd/CFZwcWoGtIno04nWWR/xQVe17jqPMov1xonC2E3AcKxUXl
|
||||||
|
PMdZoOARkR+KHZnoBZ/vjqxeDPARKupijkw5QQI3jNmd5IELjcL8OraHlo+e884mRsa/66J7p94D
|
||||||
|
bidzjiVLUhCsZnVks9eZF6PIEg49eq/+w8ph3X7XBNnZYAbgola/0yy/PlPzgJ3p/AgXMoGr+HXO
|
||||||
|
p2WAs1WRo9mAdeOBMrAMvXKFD04bZPNHke0Ri03O5U7NRRs1T0LnqdZHyF39As8FiktfJl1bn/U0
|
||||||
|
sUjhc4fDNnDaBN8VF8VsEa7UolRC6NqQ1oHaeEZRoq0li6NbXIXdxIIT4bbqwajqFkvvO6qc6SEG
|
||||||
|
iAlUzTGB2zATBgkqhkiG9w0BCRUxBgQEAQAAADBXBgkqhkiG9w0BCRQxSh5IADcAOAA1ADAAZABj
|
||||||
|
ADAAYwAtAGIAZQBmAGIALQA0AGEANQBiAC0AOAA5ADcAMAAtAGIAZAA5ADkAOQAxADEAOQA2AGIA
|
||||||
|
YgA1MGsGCSsGAQQBgjcRATFeHlwATQBpAGMAcgBvAHMAbwBmAHQAIABFAG4AaABhAG4AYwBlAGQA
|
||||||
|
IABDAHIAeQBwAHQAbwBnAHIAYQBwAGgAaQBjACAAUAByAG8AdgBpAGQAZQByACAAdgAxAC4AMDCC
|
||||||
|
BUcGCSqGSIb3DQEHBqCCBTgwggU0AgEAMIIFLQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMwDgQI
|
||||||
|
Amt1zAZpKWkCAgfQgIIFAJoBLiXPEZGuUfsyM2ed66sBIirBctHbhyydZsQDT8V2crq6AI3P0dBT
|
||||||
|
Agf/MouK/JcAfdGEEpU6SKxqZBDZoTRbyK7VdW5YiKGUurFGf66L9K3c4MHhVLMWnSkwK+0gwiIB
|
||||||
|
RB82Or4ru0cSQbF32vsuJgJY9Ax4YODKokPFUzZjPrmch4AgZWKxslDFDq4xs3tpLIeZbALWYdrR
|
||||||
|
PUZaReO+NaLfNKwTZsinzjPkCst7R1Jfjf1abikPrOMPgYFUiQL7GNQFbefeJu9SCXlj09u/qw+l
|
||||||
|
uLrwEyMamG0cgjrWbMOohGtvAuHqeZIIWuLnGE2quq7Ah/U55lliZn3IFgs1n6FalW/XGH0T0aRA
|
||||||
|
im6f1EgxtJShBNdG6qNrkzYMyY2Xvpk82qtmvMbhJMDstpovsdT1rZ6OGfsyJAlG94BcCWC2wuvW
|
||||||
|
MYs6H7AirBG/iocNm7JwSBQ7wjl0keH9vuHDQsI+uu9yWGuyZK6MmxDEOEMZRndU0GrlLIp7zQx8
|
||||||
|
gPeagKqSHhPK0ghHhDilMyToE3Euvi5jneh90eofWK6E4E8KtQTWvFeCe9fYRhMaflH9lwfHfXPo
|
||||||
|
9J+7GZLRF/MDTlE8jzWoP5csUxV3jnXQkTUOfHvO7QK6POKwLGkCyZ5wKFydyYdTekG+KU2Vml2y
|
||||||
|
s6pZ+kME1VMYiHRF3CaXX1ZYKikEdnuB1Qp8BE2uKQTaYO4Wns0vQIVRWTrk/Gp5RXu1ihzoTiFb
|
||||||
|
YqLFROQTM+dVTUk3C6W82OroNwofW5ErZwpbdgJJ83gbPLr9W4KZ6YegvEWFT1MawnIYDC6RSKtg
|
||||||
|
fI1blSZOo1SIF6+nR0gFPivSEGBJHclIg7TtvGSB1q7TQFS4W5l+AHdgGPqqURnjuJ7/DVFZHqEV
|
||||||
|
jJM1QEvH/RY1rDXP8FZC6CZR/Le7tVm5o8bHnlU4gyStvNyLXHCP6o3gHmaBcfYmqJr/0ZEKnwnd
|
||||||
|
MBmdIgwQ3+JnKvjAeDe8Z/l0U03CbzeyN3TgUolDlUGVDF2FdPZqrVsLKw6VJv3hoFZmgEbb1fDq
|
||||||
|
Jblc82lrYIEW8E7ltRLDyNDmRdyaqkqw0e7SygXXxv6SKerxoJ5E1NyJdHeQXSahRrsj5UZpxlTE
|
||||||
|
ylb3upIF0F006w2D5J7xUDktPetVgM97dN3whbOrzWPPkn5CTZMaUdYGTYQK3/K/jQSKuXcaM04A
|
||||||
|
EWmcQOQ/5Quco/aMYWTTwFI9+bKZayZKHqQjNKuwss+iWTW2b26cA2XAr2XWCL9PEybVRK/5n4km
|
||||||
|
5qkGIMjjczZxNy1+H1QoEOwkGVzQd390ktQajJBFcf9wBO+Ar14EgPKvdL4DRvCvXOK3CtrgbAq6
|
||||||
|
GK7uULRrz9t/5lu27ba5wcwxg6bFhgCsJsoSCJnLCR7H+QMB4LhnWA10U4hFWCamCKFoGkiXW6yV
|
||||||
|
OF4x+0D0MmrjrrAGi05KzfrsXNtRG0xbkmvrsjqzmsOKyjvtiBCrR0S6NUtKhyxoiz5bCCm+d8rm
|
||||||
|
jaPk9q01k52pjJAKYW0f+5+r15LamBecnjXtJ07LCl6cMA1Cj4L0mQUSefyFi666GC3TmhzHwhnj
|
||||||
|
SV64nTApS0gBsc6c18fUBsMcUj5nCNclIzfxwnARd/30yg22r09nUY2gtQTwk/W6VCpAH+7yZkH1
|
||||||
|
TLNGa+UmMnPsnBjlAJ6l9VPsa4uJM2DIQKtZXWq4DkhSAYKF6joIP7nKMDswHzAHBgUrDgMCGgQU
|
||||||
|
wTM1Z+CJZG9xAcf1zAVGl4ggYyYEFGBFyJ8VBwijS2zy1qwN1WYGtcWoAgIH0A==
|
||||||
|
";
|
||||||
|
|
||||||
|
public static X509Certificate2 GetX509Certificate2()
|
||||||
|
{
|
||||||
|
byte[] data = Convert.FromBase64String(Data);
|
||||||
|
return new X509Certificate2(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,25 +13,21 @@ namespace WireMock
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the unique identifier.
|
/// Gets the unique identifier.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The unique identifier.
|
|
||||||
/// </value>
|
|
||||||
public Guid Guid { get; }
|
public Guid Guid { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the unique title.
|
/// Gets the unique title.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The unique title.
|
|
||||||
/// </value>
|
|
||||||
public string Title { get; }
|
public string Title { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The full filename path for this mapping (only defined for static mappings).
|
||||||
|
/// </summary>
|
||||||
|
public string Path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the priority.
|
/// Gets the priority.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The priority.
|
|
||||||
/// </value>
|
|
||||||
public int Priority { get; }
|
public int Priority { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -72,17 +68,19 @@ namespace WireMock
|
|||||||
/// Initializes a new instance of the <see cref="Mapping"/> class.
|
/// Initializes a new instance of the <see cref="Mapping"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="guid">The unique identifier.</param>
|
/// <param name="guid">The unique identifier.</param>
|
||||||
/// <param name="title">The unique title (can be null_.</param>
|
/// <param name="title">The unique title (can be null).</param>
|
||||||
|
/// <param name="path">The full file path from this mapping title (can be null).</param>
|
||||||
/// <param name="requestMatcher">The request matcher.</param>
|
/// <param name="requestMatcher">The request matcher.</param>
|
||||||
/// <param name="provider">The provider.</param>
|
/// <param name="provider">The provider.</param>
|
||||||
/// <param name="priority">The priority for this mapping.</param>
|
/// <param name="priority">The priority for this mapping.</param>
|
||||||
/// <param name="scenario">The scenario. [Optional]</param>
|
/// <param name="scenario">The scenario. [Optional]</param>
|
||||||
/// <param name="executionConditionState">State in which the current mapping can occur. [Optional]</param>
|
/// <param name="executionConditionState">State in which the current mapping can occur. [Optional]</param>
|
||||||
/// <param name="nextState">The next state which will occur after the current mapping execution. [Optional]</param>
|
/// <param name="nextState">The next state which will occur after the current mapping execution. [Optional]</param>
|
||||||
public Mapping(Guid guid, [CanBeNull] string title, IRequestMatcher requestMatcher, IResponseProvider provider, int priority, [CanBeNull] string scenario, [CanBeNull] object executionConditionState, [CanBeNull] object nextState)
|
public Mapping(Guid guid, [CanBeNull] string title, [CanBeNull] string path, IRequestMatcher requestMatcher, IResponseProvider provider, int priority, [CanBeNull] string scenario, [CanBeNull] object executionConditionState, [CanBeNull] object nextState)
|
||||||
{
|
{
|
||||||
Guid = guid;
|
Guid = guid;
|
||||||
Title = title;
|
Title = title;
|
||||||
|
Path = path;
|
||||||
RequestMatcher = requestMatcher;
|
RequestMatcher = requestMatcher;
|
||||||
Provider = provider;
|
Provider = provider;
|
||||||
Priority = priority;
|
Priority = priority;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ namespace WireMock.Matchers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// ExactMatcher
|
/// ExactMatcher
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="IMatcher" />
|
/// <seealso cref="IStringMatcher" />
|
||||||
public class ExactMatcher : IMatcher
|
public class ExactMatcher : IStringMatcher
|
||||||
{
|
{
|
||||||
private readonly string[] _values;
|
private readonly string[] _values;
|
||||||
|
|
||||||
@@ -23,29 +23,19 @@ namespace WireMock.Matchers
|
|||||||
_values = values;
|
_values = values;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||||
/// Determines whether the specified input is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The input.</param>
|
|
||||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
|
||||||
public double IsMatch(string input)
|
public double IsMatch(string input)
|
||||||
{
|
{
|
||||||
return MatchScores.ToScore(_values.Select(value => value.Equals(input)));
|
return MatchScores.ToScore(_values.Select(value => value.Equals(input)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||||
/// Gets the value.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Patterns</returns>
|
|
||||||
public string[] GetPatterns()
|
public string[] GetPatterns()
|
||||||
{
|
{
|
||||||
return _values;
|
return _values;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMatcher.GetName"/>
|
||||||
/// Gets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Name</returns>
|
|
||||||
public string GetName()
|
public string GetName()
|
||||||
{
|
{
|
||||||
return "ExactMatcher";
|
return "ExactMatcher";
|
||||||
|
|||||||
46
src/WireMock.Net/Matchers/ExactObjectMatcher.cs
Normal file
46
src/WireMock.Net/Matchers/ExactObjectMatcher.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace WireMock.Matchers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ExactMatcher
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="IObjectMatcher" />
|
||||||
|
public class ExactObjectMatcher : IObjectMatcher
|
||||||
|
{
|
||||||
|
private readonly object _object;
|
||||||
|
private readonly byte[] _bytes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value.</param>
|
||||||
|
public ExactObjectMatcher([NotNull] object value)
|
||||||
|
{
|
||||||
|
_object = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value.</param>
|
||||||
|
public ExactObjectMatcher([NotNull] byte[] value)
|
||||||
|
{
|
||||||
|
_bytes = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||||
|
public double IsMatch(object input)
|
||||||
|
{
|
||||||
|
bool equals = _object != null ? Equals(_object, input) : _bytes.SequenceEqual((byte[])input);
|
||||||
|
return MatchScores.ToScore(equals);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IMatcher.GetName"/>
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "ExactObjectMatcher";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,19 +5,6 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IMatcher
|
public interface IMatcher
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Determines whether the specified input is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The input.</param>
|
|
||||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
|
||||||
double IsMatch(string input);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the patterns.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Patterns</returns>
|
|
||||||
string[] GetPatterns();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name.
|
/// Gets the name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
15
src/WireMock.Net/Matchers/IObjectMatcher.cs
Normal file
15
src/WireMock.Net/Matchers/IObjectMatcher.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace WireMock.Matchers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// IObjectMatcher
|
||||||
|
/// </summary>
|
||||||
|
public interface IObjectMatcher : IMatcher
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified input is match.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">The input.</param>
|
||||||
|
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
||||||
|
double IsMatch(object input);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/WireMock.Net/Matchers/IStringMatcher.cs
Normal file
21
src/WireMock.Net/Matchers/IStringMatcher.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
namespace WireMock.Matchers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// IStringMatcher
|
||||||
|
/// </summary>
|
||||||
|
public interface IStringMatcher : IMatcher
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified input is match.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">The input.</param>
|
||||||
|
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
||||||
|
double IsMatch(string input);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the patterns.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Patterns</returns>
|
||||||
|
string[] GetPatterns();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,8 +10,9 @@ namespace WireMock.Matchers
|
|||||||
/// JSONPathMatcher
|
/// JSONPathMatcher
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="IMatcher" />
|
/// <seealso cref="IMatcher" />
|
||||||
public class JsonPathMatcher : IMatcher
|
public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||||
{
|
{
|
||||||
|
// private readonly object _jsonPattern;
|
||||||
private readonly string[] _patterns;
|
private readonly string[] _patterns;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -25,15 +26,20 @@ namespace WireMock.Matchers
|
|||||||
_patterns = patterns;
|
_patterns = patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
//public JsonPathMatcher([NotNull] object jsonPattern)
|
||||||
/// Determines whether the specified input is match.
|
//{
|
||||||
/// </summary>
|
// Check.NotNull(jsonPattern, nameof(jsonPattern));
|
||||||
/// <param name="input">The input string</param>
|
|
||||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
// _jsonPattern = jsonPattern;
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||||
public double IsMatch(string input)
|
public double IsMatch(string input)
|
||||||
{
|
{
|
||||||
if (input == null)
|
if (input == null)
|
||||||
|
{
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -47,19 +53,33 @@ namespace WireMock.Matchers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||||
/// Gets the patterns.
|
public double IsMatch(object input)
|
||||||
/// </summary>
|
{
|
||||||
/// <returns>Pattern</returns>
|
if (input == null)
|
||||||
|
{
|
||||||
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var o = input as JObject ?? JObject.FromObject(input);
|
||||||
|
|
||||||
|
return MatchScores.ToScore(_patterns.Select(p => o.SelectToken(p) != null));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||||
public string[] GetPatterns()
|
public string[] GetPatterns()
|
||||||
{
|
{
|
||||||
return _patterns;
|
return _patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMatcher.GetName"/>
|
||||||
/// Gets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Name</returns>
|
|
||||||
public string GetName()
|
public string GetName()
|
||||||
{
|
{
|
||||||
return "JsonPathMatcher";
|
return "JsonPathMatcher";
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ namespace WireMock.Matchers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Regular Expression Matcher
|
/// Regular Expression Matcher
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="IMatcher" />
|
/// <seealso cref="IStringMatcher" />
|
||||||
public class RegexMatcher : IMatcher
|
public class RegexMatcher : IStringMatcher
|
||||||
{
|
{
|
||||||
private readonly string[] _patterns;
|
private readonly string[] _patterns;
|
||||||
private readonly Regex[] _expressions;
|
private readonly Regex[] _expressions;
|
||||||
@@ -37,20 +37,20 @@ namespace WireMock.Matchers
|
|||||||
|
|
||||||
RegexOptions options = RegexOptions.Compiled;
|
RegexOptions options = RegexOptions.Compiled;
|
||||||
if (ignoreCase)
|
if (ignoreCase)
|
||||||
|
{
|
||||||
options |= RegexOptions.IgnoreCase;
|
options |= RegexOptions.IgnoreCase;
|
||||||
|
}
|
||||||
|
|
||||||
_expressions = patterns.Select(p => new Regex(p, options)).ToArray();
|
_expressions = patterns.Select(p => new Regex(p, options)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||||
/// Determines whether the specified input is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The input string</param>
|
|
||||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
|
||||||
public double IsMatch(string input)
|
public double IsMatch(string input)
|
||||||
{
|
{
|
||||||
if (input == null)
|
if (input == null)
|
||||||
|
{
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -62,21 +62,13 @@ namespace WireMock.Matchers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||||
/// Gets the patterns.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Pattern</returns>
|
|
||||||
public virtual string[] GetPatterns()
|
public virtual string[] GetPatterns()
|
||||||
{
|
{
|
||||||
return _patterns;
|
return _patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMatcher.GetName"/>
|
||||||
/// Gets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// Name
|
|
||||||
/// </returns>
|
|
||||||
public virtual string GetName()
|
public virtual string GetName()
|
||||||
{
|
{
|
||||||
return "RegexMatcher";
|
return "RegexMatcher";
|
||||||
|
|||||||
@@ -9,21 +9,21 @@ namespace WireMock.Matchers.Request
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RequestMessageBodyMatcher : IRequestMatcher
|
public class RequestMessageBodyMatcher : IRequestMatcher
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The body as byte[].
|
|
||||||
/// </summary>
|
|
||||||
private readonly byte[] _bodyData;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The body function
|
/// The body function
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<string, bool> Func { get; }
|
public Func<string, bool> Func { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The body data function
|
/// The body data function for byte[]
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<byte[], bool> DataFunc { get; }
|
public Func<byte[], bool> DataFunc { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body data function for json
|
||||||
|
/// </summary>
|
||||||
|
public Func<object, bool> JsonFunc { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The matcher.
|
/// The matcher.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -32,9 +32,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="body">
|
/// <param name="body">The body.</param>
|
||||||
/// The body Regex pattern.
|
|
||||||
/// </param>
|
|
||||||
public RequestMessageBodyMatcher([NotNull] string body) : this(new SimMetricsMatcher(body))
|
public RequestMessageBodyMatcher([NotNull] string body) : this(new SimMetricsMatcher(body))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -42,21 +40,23 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="body">
|
/// <param name="body">The body.</param>
|
||||||
/// The body Regex pattern.
|
public RequestMessageBodyMatcher([NotNull] byte[] body) : this(new ExactObjectMatcher(body))
|
||||||
/// </param>
|
|
||||||
public RequestMessageBodyMatcher([NotNull] byte[] body)
|
|
||||||
{
|
{
|
||||||
Check.NotNull(body, nameof(body));
|
|
||||||
_bodyData = body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="func">
|
/// <param name="body">The body.</param>
|
||||||
/// The body func.
|
public RequestMessageBodyMatcher([NotNull] object body) : this(new ExactObjectMatcher(body))
|
||||||
/// </param>
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The function.</param>
|
||||||
public RequestMessageBodyMatcher([NotNull] Func<string, bool> func)
|
public RequestMessageBodyMatcher([NotNull] Func<string, bool> func)
|
||||||
{
|
{
|
||||||
Check.NotNull(func, nameof(func));
|
Check.NotNull(func, nameof(func));
|
||||||
@@ -66,9 +66,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="func">
|
/// <param name="func">The function.</param>
|
||||||
/// The body func.
|
|
||||||
/// </param>
|
|
||||||
public RequestMessageBodyMatcher([NotNull] Func<byte[], bool> func)
|
public RequestMessageBodyMatcher([NotNull] Func<byte[], bool> func)
|
||||||
{
|
{
|
||||||
Check.NotNull(func, nameof(func));
|
Check.NotNull(func, nameof(func));
|
||||||
@@ -78,23 +76,24 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matcher">
|
/// <param name="func">The function.</param>
|
||||||
/// The body matcher.
|
public RequestMessageBodyMatcher([NotNull] Func<object, bool> func)
|
||||||
/// </param>
|
{
|
||||||
|
Check.NotNull(func, nameof(func));
|
||||||
|
JsonFunc = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matcher">The matcher.</param>
|
||||||
public RequestMessageBodyMatcher([NotNull] IMatcher matcher)
|
public RequestMessageBodyMatcher([NotNull] IMatcher matcher)
|
||||||
{
|
{
|
||||||
Check.NotNull(matcher, nameof(matcher));
|
Check.NotNull(matcher, nameof(matcher));
|
||||||
Matcher = matcher;
|
Matcher = matcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <see cref="IRequestMatcher.GetMatchingScore"/>
|
||||||
/// Determines whether the specified RequestMessage is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="requestMessage">The RequestMessage.</param>
|
|
||||||
/// <param name="requestMatchResult">The RequestMatchResult.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// A value between 0.0 - 1.0 of the similarity.
|
|
||||||
/// </returns>
|
|
||||||
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||||
{
|
{
|
||||||
double score = IsMatch(requestMessage);
|
double score = IsMatch(requestMessage);
|
||||||
@@ -103,17 +102,43 @@ namespace WireMock.Matchers.Request
|
|||||||
|
|
||||||
private double IsMatch(RequestMessage requestMessage)
|
private double IsMatch(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
if (Matcher != null)
|
if (requestMessage.Body != null)
|
||||||
return Matcher.IsMatch(requestMessage.Body);
|
{
|
||||||
|
var stringMatcher = Matcher as IStringMatcher;
|
||||||
|
if (stringMatcher != null)
|
||||||
|
{
|
||||||
|
return stringMatcher.IsMatch(requestMessage.Body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_bodyData != null)
|
var objectMatcher = Matcher as IObjectMatcher;
|
||||||
return MatchScores.ToScore(requestMessage.BodyAsBytes == _bodyData);
|
if (objectMatcher != null)
|
||||||
|
{
|
||||||
|
if (requestMessage.BodyAsJson != null)
|
||||||
|
{
|
||||||
|
return objectMatcher.IsMatch(requestMessage.BodyAsJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestMessage.BodyAsBytes != null)
|
||||||
|
{
|
||||||
|
return objectMatcher.IsMatch(requestMessage.BodyAsBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Func != null)
|
if (Func != null)
|
||||||
|
{
|
||||||
return MatchScores.ToScore(requestMessage.Body != null && Func(requestMessage.Body));
|
return MatchScores.ToScore(requestMessage.Body != null && Func(requestMessage.Body));
|
||||||
|
}
|
||||||
|
|
||||||
if (DataFunc != null && requestMessage.BodyAsBytes != null)
|
if (DataFunc != null)
|
||||||
|
{
|
||||||
return MatchScores.ToScore(requestMessage.BodyAsBytes != null && DataFunc(requestMessage.BodyAsBytes));
|
return MatchScores.ToScore(requestMessage.BodyAsBytes != null && DataFunc(requestMessage.BodyAsBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JsonFunc != null)
|
||||||
|
{
|
||||||
|
return MatchScores.ToScore(requestMessage.BodyAsJson != null && JsonFunc(requestMessage.BodyAsJson));
|
||||||
|
}
|
||||||
|
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The matchers.
|
/// The matchers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<IMatcher> Matchers { get; }
|
public IReadOnlyList<IStringMatcher> Matchers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ClientIP functions.
|
/// The ClientIP functions.
|
||||||
@@ -25,7 +25,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="clientIPs">The clientIPs.</param>
|
/// <param name="clientIPs">The clientIPs.</param>
|
||||||
public RequestMessageClientIPMatcher([NotNull] params string[] clientIPs) : this(clientIPs.Select(ip => new WildcardMatcher(ip)).ToArray())
|
public RequestMessageClientIPMatcher([NotNull] params string[] clientIPs) : this(clientIPs.Select(ip => new WildcardMatcher(ip)).Cast<IStringMatcher>().ToArray())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
public RequestMessageClientIPMatcher([NotNull] params IMatcher[] matchers)
|
public RequestMessageClientIPMatcher([NotNull] params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotNull(matchers, nameof(matchers));
|
Check.NotNull(matchers, nameof(matchers));
|
||||||
Matchers = matchers;
|
Matchers = matchers;
|
||||||
@@ -49,14 +49,7 @@ namespace WireMock.Matchers.Request
|
|||||||
Funcs = funcs;
|
Funcs = funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||||
/// Determines whether the specified RequestMessage is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="requestMessage">The RequestMessage.</param>
|
|
||||||
/// <param name="requestMatchResult">The RequestMatchResult.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// A value between 0.0 - 1.0 of the similarity.
|
|
||||||
/// </returns>
|
|
||||||
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||||
{
|
{
|
||||||
double score = IsMatch(requestMessage);
|
double score = IsMatch(requestMessage);
|
||||||
@@ -66,10 +59,14 @@ namespace WireMock.Matchers.Request
|
|||||||
private double IsMatch(RequestMessage requestMessage)
|
private double IsMatch(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
if (Matchers != null)
|
if (Matchers != null)
|
||||||
|
{
|
||||||
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.ClientIP));
|
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.ClientIP));
|
||||||
|
}
|
||||||
|
|
||||||
if (Funcs != null)
|
if (Funcs != null)
|
||||||
|
{
|
||||||
return MatchScores.ToScore(requestMessage.ClientIP != null && Funcs.Any(func => func(requestMessage.ClientIP)));
|
return MatchScores.ToScore(requestMessage.ClientIP != null && Funcs.Any(func => func(requestMessage.ClientIP)));
|
||||||
|
}
|
||||||
|
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <value>
|
/// <value>
|
||||||
/// The matchers.
|
/// The matchers.
|
||||||
/// </value>
|
/// </value>
|
||||||
public IMatcher[] Matchers { get; }
|
public IStringMatcher[] Matchers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
||||||
@@ -38,7 +38,7 @@ namespace WireMock.Matchers.Request
|
|||||||
Check.NotNull(pattern, nameof(pattern));
|
Check.NotNull(pattern, nameof(pattern));
|
||||||
|
|
||||||
Name = name;
|
Name = name;
|
||||||
Matchers = new IMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
|
Matchers = new IStringMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -46,7 +46,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
public RequestMessageCookieMatcher([NotNull] string name, [NotNull] params IMatcher[] matchers)
|
public RequestMessageCookieMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotNull(name, nameof(name));
|
Check.NotNull(name, nameof(name));
|
||||||
Check.NotNull(matchers, nameof(matchers));
|
Check.NotNull(matchers, nameof(matchers));
|
||||||
@@ -83,16 +83,24 @@ namespace WireMock.Matchers.Request
|
|||||||
private double IsMatch(RequestMessage requestMessage)
|
private double IsMatch(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
if (requestMessage.Cookies == null)
|
if (requestMessage.Cookies == null)
|
||||||
|
{
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
if (Funcs != null)
|
if (Funcs != null)
|
||||||
|
{
|
||||||
return MatchScores.ToScore(Funcs.Any(f => f(requestMessage.Cookies)));
|
return MatchScores.ToScore(Funcs.Any(f => f(requestMessage.Cookies)));
|
||||||
|
}
|
||||||
|
|
||||||
if (Matchers == null)
|
if (Matchers == null)
|
||||||
|
{
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
if (!requestMessage.Cookies.ContainsKey(Name))
|
if (!requestMessage.Cookies.ContainsKey(Name))
|
||||||
|
{
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
string value = requestMessage.Cookies[Name];
|
string value = requestMessage.Cookies[Name];
|
||||||
return Matchers.Max(m => m.IsMatch(value));
|
return Matchers.Max(m => m.IsMatch(value));
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using WireMock.Util;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
|
|
||||||
namespace WireMock.Matchers.Request
|
namespace WireMock.Matchers.Request
|
||||||
@@ -9,12 +10,13 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The request header matcher.
|
/// The request header matcher.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <inheritdoc cref="IRequestMatcher"/>
|
||||||
public class RequestMessageHeaderMatcher : IRequestMatcher
|
public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The functions
|
/// The functions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<IDictionary<string, string>, bool>[] Funcs { get; }
|
public Func<IDictionary<string, string[]>, bool>[] Funcs { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name
|
/// The name
|
||||||
@@ -24,21 +26,36 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <value>
|
/// <value>
|
||||||
/// The matchers.
|
/// The matchers.
|
||||||
/// </value>
|
/// </value>
|
||||||
public IMatcher[] Matchers { get; }
|
public IStringMatcher[] Matchers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="pattern">The pattern.</param>
|
/// <param name="pattern">The pattern.</param>
|
||||||
/// <param name="ignoreCase">The ignoreCase.</param>
|
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
|
||||||
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
|
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
|
||||||
{
|
{
|
||||||
Check.NotNull(name, nameof(name));
|
Check.NotNull(name, nameof(name));
|
||||||
Check.NotNull(pattern, nameof(pattern));
|
Check.NotNull(pattern, nameof(pattern));
|
||||||
|
|
||||||
Name = name;
|
Name = name;
|
||||||
Matchers = new IMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
|
Matchers = new IStringMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name.</param>
|
||||||
|
/// <param name="patterns">The patterns.</param>
|
||||||
|
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
|
||||||
|
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string[] patterns, bool ignoreCase = true)
|
||||||
|
{
|
||||||
|
Check.NotNull(name, nameof(name));
|
||||||
|
Check.NotNull(patterns, nameof(patterns));
|
||||||
|
|
||||||
|
Name = name;
|
||||||
|
Matchers = patterns.Select(pattern => new WildcardMatcher(pattern, ignoreCase)).Cast<IStringMatcher>().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -46,7 +63,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] params IMatcher[] matchers)
|
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotNull(name, nameof(name));
|
Check.NotNull(name, nameof(name));
|
||||||
Check.NotNull(matchers, nameof(matchers));
|
Check.NotNull(matchers, nameof(matchers));
|
||||||
@@ -59,21 +76,14 @@ namespace WireMock.Matchers.Request
|
|||||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="funcs">The funcs.</param>
|
/// <param name="funcs">The funcs.</param>
|
||||||
public RequestMessageHeaderMatcher([NotNull] params Func<IDictionary<string, string>, bool>[] funcs)
|
public RequestMessageHeaderMatcher([NotNull] params Func<IDictionary<string, string[]>, bool>[] funcs)
|
||||||
{
|
{
|
||||||
Check.NotNull(funcs, nameof(funcs));
|
Check.NotNull(funcs, nameof(funcs));
|
||||||
|
|
||||||
Funcs = funcs;
|
Funcs = funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||||
/// Determines whether the specified RequestMessage is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="requestMessage">The RequestMessage.</param>
|
|
||||||
/// <param name="requestMatchResult">The RequestMatchResult.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// A value between 0.0 - 1.0 of the similarity.
|
|
||||||
/// </returns>
|
|
||||||
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||||
{
|
{
|
||||||
double score = IsMatch(requestMessage);
|
double score = IsMatch(requestMessage);
|
||||||
@@ -83,19 +93,27 @@ namespace WireMock.Matchers.Request
|
|||||||
private double IsMatch(RequestMessage requestMessage)
|
private double IsMatch(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
if (requestMessage.Headers == null)
|
if (requestMessage.Headers == null)
|
||||||
|
{
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
if (Funcs != null)
|
if (Funcs != null)
|
||||||
return MatchScores.ToScore(Funcs.Any(f => f(requestMessage.Headers)));
|
{
|
||||||
|
return MatchScores.ToScore(Funcs.Any(f => f(requestMessage.Headers.ToDictionary(entry => entry.Key, entry => entry.Value.ToArray()))));
|
||||||
|
}
|
||||||
|
|
||||||
if (Matchers == null)
|
if (Matchers == null)
|
||||||
|
{
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
if (!requestMessage.Headers.ContainsKey(Name))
|
if (!requestMessage.Headers.ContainsKey(Name))
|
||||||
|
{
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
string value = requestMessage.Headers[Name];
|
WireMockList<string> list = requestMessage.Headers[Name];
|
||||||
return Matchers.Max(m => m.IsMatch(value));
|
return Matchers.Max(m => list.Max(value => m.IsMatch(value))); // TODO : is this correct ?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,12 +30,8 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">
|
/// <param name="key">The key.</param>
|
||||||
/// The key.
|
/// <param name="values">The values.</param>
|
||||||
/// </param>
|
|
||||||
/// <param name="values">
|
|
||||||
/// The values.
|
|
||||||
/// </param>
|
|
||||||
public RequestMessageParamMatcher([NotNull] string key, [CanBeNull] IEnumerable<string> values)
|
public RequestMessageParamMatcher([NotNull] string key, [CanBeNull] IEnumerable<string> values)
|
||||||
{
|
{
|
||||||
Check.NotNull(key, nameof(key));
|
Check.NotNull(key, nameof(key));
|
||||||
@@ -51,17 +47,11 @@ namespace WireMock.Matchers.Request
|
|||||||
public RequestMessageParamMatcher([NotNull] params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
|
public RequestMessageParamMatcher([NotNull] params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
|
||||||
{
|
{
|
||||||
Check.NotNull(funcs, nameof(funcs));
|
Check.NotNull(funcs, nameof(funcs));
|
||||||
|
|
||||||
Funcs = funcs;
|
Funcs = funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||||
/// Determines whether the specified RequestMessage is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="requestMessage">The RequestMessage.</param>
|
|
||||||
/// <param name="requestMatchResult">The RequestMatchResult.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// A value between 0.0 - 1.0 of the similarity.
|
|
||||||
/// </returns>
|
|
||||||
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||||
{
|
{
|
||||||
double score = IsMatch(requestMessage);
|
double score = IsMatch(requestMessage);
|
||||||
@@ -71,7 +61,9 @@ namespace WireMock.Matchers.Request
|
|||||||
private double IsMatch(RequestMessage requestMessage)
|
private double IsMatch(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
if (Funcs != null)
|
if (Funcs != null)
|
||||||
|
{
|
||||||
return MatchScores.ToScore(requestMessage.Query != null && Funcs.Any(f => f(requestMessage.Query)));
|
return MatchScores.ToScore(requestMessage.Query != null && Funcs.Any(f => f(requestMessage.Query)));
|
||||||
|
}
|
||||||
|
|
||||||
List<string> values = requestMessage.GetParameter(Key);
|
List<string> values = requestMessage.GetParameter(Key);
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The matcher.
|
/// The matcher.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<IMatcher> Matchers { get; }
|
public IReadOnlyList<IStringMatcher> Matchers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path functions
|
/// The path functions
|
||||||
@@ -25,7 +25,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="paths">The paths.</param>
|
/// <param name="paths">The paths.</param>
|
||||||
public RequestMessagePathMatcher([NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(path)).ToArray())
|
public RequestMessagePathMatcher([NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(path)).Cast<IStringMatcher>().ToArray())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
public RequestMessagePathMatcher([NotNull] params IMatcher[] matchers)
|
public RequestMessagePathMatcher([NotNull] params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotNull(matchers, nameof(matchers));
|
Check.NotNull(matchers, nameof(matchers));
|
||||||
Matchers = matchers;
|
Matchers = matchers;
|
||||||
@@ -49,14 +49,7 @@ namespace WireMock.Matchers.Request
|
|||||||
Funcs = funcs;
|
Funcs = funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||||
/// Determines whether the specified RequestMessage is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="requestMessage">The RequestMessage.</param>
|
|
||||||
/// <param name="requestMatchResult">The RequestMatchResult.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// A value between 0.0 - 1.0 of the similarity.
|
|
||||||
/// </returns>
|
|
||||||
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||||
{
|
{
|
||||||
double score = IsMatch(requestMessage);
|
double score = IsMatch(requestMessage);
|
||||||
@@ -66,10 +59,14 @@ namespace WireMock.Matchers.Request
|
|||||||
private double IsMatch(RequestMessage requestMessage)
|
private double IsMatch(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
if (Matchers != null)
|
if (Matchers != null)
|
||||||
|
{
|
||||||
return Matchers.Max(m => m.IsMatch(requestMessage.Path));
|
return Matchers.Max(m => m.IsMatch(requestMessage.Path));
|
||||||
|
}
|
||||||
|
|
||||||
if (Funcs != null)
|
if (Funcs != null)
|
||||||
|
{
|
||||||
return MatchScores.ToScore(requestMessage.Path != null && Funcs.Any(func => func(requestMessage.Path)));
|
return MatchScores.ToScore(requestMessage.Path != null && Funcs.Any(func => func(requestMessage.Path)));
|
||||||
|
}
|
||||||
|
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The matchers.
|
/// The matchers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<IMatcher> Matchers { get; }
|
public IReadOnlyList<IStringMatcher> Matchers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The url functions.
|
/// The url functions.
|
||||||
@@ -25,7 +25,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="urls">The urls.</param>
|
/// <param name="urls">The urls.</param>
|
||||||
public RequestMessageUrlMatcher([NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(url)).ToArray())
|
public RequestMessageUrlMatcher([NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(url)).Cast<IStringMatcher>().ToArray())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
public RequestMessageUrlMatcher([NotNull] params IMatcher[] matchers)
|
public RequestMessageUrlMatcher([NotNull] params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotNull(matchers, nameof(matchers));
|
Check.NotNull(matchers, nameof(matchers));
|
||||||
Matchers = matchers;
|
Matchers = matchers;
|
||||||
@@ -49,14 +49,7 @@ namespace WireMock.Matchers.Request
|
|||||||
Funcs = funcs;
|
Funcs = funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||||
/// Determines whether the specified RequestMessage is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="requestMessage">The RequestMessage.</param>
|
|
||||||
/// <param name="requestMatchResult">The RequestMatchResult.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// A value between 0.0 - 1.0 of the similarity.
|
|
||||||
/// </returns>
|
|
||||||
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||||
{
|
{
|
||||||
double score = IsMatch(requestMessage);
|
double score = IsMatch(requestMessage);
|
||||||
@@ -66,10 +59,14 @@ namespace WireMock.Matchers.Request
|
|||||||
private double IsMatch(RequestMessage requestMessage)
|
private double IsMatch(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
if (Matchers != null)
|
if (Matchers != null)
|
||||||
|
{
|
||||||
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.Url));
|
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.Url));
|
||||||
|
}
|
||||||
|
|
||||||
if (Funcs != null)
|
if (Funcs != null)
|
||||||
|
{
|
||||||
return MatchScores.ToScore(requestMessage.Url != null && Funcs.Any(func => func(requestMessage.Url)));
|
return MatchScores.ToScore(requestMessage.Url != null && Funcs.Any(func => func(requestMessage.Url)));
|
||||||
|
}
|
||||||
|
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ namespace WireMock.Matchers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// SimMetricsMatcher
|
/// SimMetricsMatcher
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="IMatcher" />
|
/// <seealso cref="IStringMatcher" />
|
||||||
public class SimMetricsMatcher : IMatcher
|
public class SimMetricsMatcher : IStringMatcher
|
||||||
{
|
{
|
||||||
private readonly string[] _patterns;
|
private readonly string[] _patterns;
|
||||||
private readonly SimMetricType _simMetricType;
|
private readonly SimMetricType _simMetricType;
|
||||||
@@ -32,17 +32,13 @@ namespace WireMock.Matchers
|
|||||||
/// <param name="simMetricType">The SimMetric Type</param>
|
/// <param name="simMetricType">The SimMetric Type</param>
|
||||||
public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein)
|
public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(patterns, nameof(patterns));
|
Check.NotNullOrEmpty(patterns, nameof(patterns));
|
||||||
|
|
||||||
_patterns = patterns;
|
_patterns = patterns;
|
||||||
_simMetricType = simMetricType;
|
_simMetricType = simMetricType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||||
/// Determines whether the specified input is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The input string</param>
|
|
||||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
|
||||||
public double IsMatch(string input)
|
public double IsMatch(string input)
|
||||||
{
|
{
|
||||||
IStringMetric m = GetStringMetricType();
|
IStringMetric m = GetStringMetricType();
|
||||||
@@ -93,19 +89,13 @@ namespace WireMock.Matchers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||||
/// Gets the pattern.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Pattern</returns>
|
|
||||||
public string[] GetPatterns()
|
public string[] GetPatterns()
|
||||||
{
|
{
|
||||||
return _patterns;
|
return _patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMatcher.GetName"/>
|
||||||
/// Gets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Name</returns>
|
|
||||||
public string GetName()
|
public string GetName()
|
||||||
{
|
{
|
||||||
return $"SimMetricsMatcher.{_simMetricType}";
|
return $"SimMetricsMatcher.{_simMetricType}";
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace WireMock.Matchers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// WildcardMatcher
|
/// WildcardMatcher
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="IMatcher" />
|
/// <seealso cref="RegexMatcher" />
|
||||||
public class WildcardMatcher : RegexMatcher
|
public class WildcardMatcher : RegexMatcher
|
||||||
{
|
{
|
||||||
private readonly string[] _patterns;
|
private readonly string[] _patterns;
|
||||||
@@ -31,21 +31,13 @@ namespace WireMock.Matchers
|
|||||||
_patterns = patterns;
|
_patterns = patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||||
/// Gets the pattern.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Pattern</returns>
|
|
||||||
public override string[] GetPatterns()
|
public override string[] GetPatterns()
|
||||||
{
|
{
|
||||||
return _patterns;
|
return _patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMatcher.GetName"/>
|
||||||
/// Gets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// Name
|
|
||||||
/// </returns>
|
|
||||||
public override string GetName()
|
public override string GetName()
|
||||||
{
|
{
|
||||||
return "WildcardMatcher";
|
return "WildcardMatcher";
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ namespace WireMock.Matchers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// XPath2Matcher
|
/// XPath2Matcher
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="WireMock.Matchers.IMatcher" />
|
/// <seealso cref="IStringMatcher" />
|
||||||
public class XPathMatcher : IMatcher
|
public class XPathMatcher : IStringMatcher
|
||||||
{
|
{
|
||||||
private readonly string[] _patterns;
|
private readonly string[] _patterns;
|
||||||
|
|
||||||
@@ -28,15 +28,13 @@ namespace WireMock.Matchers
|
|||||||
_patterns = patterns;
|
_patterns = patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||||
/// Determines whether the specified input is match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The input string</param>
|
|
||||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
|
||||||
public double IsMatch(string input)
|
public double IsMatch(string input)
|
||||||
{
|
{
|
||||||
if (input == null)
|
if (input == null)
|
||||||
|
{
|
||||||
return MatchScores.Mismatch;
|
return MatchScores.Mismatch;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -53,19 +51,13 @@ namespace WireMock.Matchers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||||
/// Gets the patterns.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Patterns</returns>
|
|
||||||
public string[] GetPatterns()
|
public string[] GetPatterns()
|
||||||
{
|
{
|
||||||
return _patterns;
|
return _patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMatcher.GetName"/>
|
||||||
/// Gets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Name</returns>
|
|
||||||
public string GetName()
|
public string GetName()
|
||||||
{
|
{
|
||||||
return "XPathMatcher";
|
return "XPathMatcher";
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
#if NETSTANDARD
|
#if NETSTANDARD
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using WireMock.Http;
|
using WireMock.Http;
|
||||||
|
using WireMock.HttpsCertificate;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
|
|
||||||
namespace WireMock.Owin
|
namespace WireMock.Owin
|
||||||
@@ -14,7 +18,7 @@ namespace WireMock.Owin
|
|||||||
{
|
{
|
||||||
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||||
private readonly WireMockMiddlewareOptions _options;
|
private readonly WireMockMiddlewareOptions _options;
|
||||||
private readonly string[] _uriPrefixes;
|
private readonly string[] _urls;
|
||||||
|
|
||||||
private IWebHost _host;
|
private IWebHost _host;
|
||||||
|
|
||||||
@@ -27,7 +31,7 @@ namespace WireMock.Owin
|
|||||||
public AspNetCoreSelfHost([NotNull] WireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
|
public AspNetCoreSelfHost([NotNull] WireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
|
||||||
{
|
{
|
||||||
Check.NotNull(options, nameof(options));
|
Check.NotNull(options, nameof(options));
|
||||||
Check.NotEmpty(uriPrefixes, nameof(uriPrefixes));
|
Check.NotNullOrEmpty(uriPrefixes, nameof(uriPrefixes));
|
||||||
|
|
||||||
foreach (string uriPrefix in uriPrefixes)
|
foreach (string uriPrefix in uriPrefixes)
|
||||||
{
|
{
|
||||||
@@ -38,7 +42,7 @@ namespace WireMock.Owin
|
|||||||
}
|
}
|
||||||
|
|
||||||
_options = options;
|
_options = options;
|
||||||
_uriPrefixes = uriPrefixes;
|
_urls = uriPrefixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task StartAsync()
|
public Task StartAsync()
|
||||||
@@ -46,14 +50,46 @@ namespace WireMock.Owin
|
|||||||
_host = new WebHostBuilder()
|
_host = new WebHostBuilder()
|
||||||
.Configure(appBuilder =>
|
.Configure(appBuilder =>
|
||||||
{
|
{
|
||||||
|
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
|
||||||
|
|
||||||
|
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||||
|
|
||||||
appBuilder.UseMiddleware<WireMockMiddleware>(_options);
|
appBuilder.UseMiddleware<WireMockMiddleware>(_options);
|
||||||
|
|
||||||
|
_options.PostWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||||
})
|
})
|
||||||
.UseKestrel()
|
.UseKestrel(options =>
|
||||||
.UseUrls(_uriPrefixes)
|
{
|
||||||
|
#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)))
|
||||||
|
{
|
||||||
|
PortUtil.TryExtractProtocolAndPort(url, out string host, out int port);
|
||||||
|
options.Listen(IPAddress.Loopback, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string url in _urls.Where(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
PortUtil.TryExtractProtocolAndPort(url, out string host, out int port);
|
||||||
|
options.Listen(IPAddress.Loopback, port, listenOptions =>
|
||||||
|
{
|
||||||
|
listenOptions.UseHttps(PublicCertificateHelper.GetX509Certificate2());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
})
|
||||||
|
#if NETSTANDARD1_3
|
||||||
|
.UseUrls(_urls)
|
||||||
|
#endif
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
#if NETSTANDARD1_3
|
#if NETSTANDARD1_3
|
||||||
System.Console.WriteLine("WireMock.Net server using netstandard1.3");
|
Console.WriteLine("WireMock.Net server using netstandard1.3");
|
||||||
return Task.Run(() =>
|
return Task.Run(() =>
|
||||||
{
|
{
|
||||||
_host.Run(_cts.Token);
|
_host.Run(_cts.Token);
|
||||||
@@ -62,7 +98,11 @@ namespace WireMock.Owin
|
|||||||
#else
|
#else
|
||||||
System.Console.WriteLine("WireMock.Net server using netstandard2.0");
|
System.Console.WriteLine("WireMock.Net server using netstandard2.0");
|
||||||
IsStarted = true;
|
IsStarted = true;
|
||||||
return _host.RunAsync(_cts.Token);
|
return Task.Run(() =>
|
||||||
|
{
|
||||||
|
_host.Run();
|
||||||
|
IsStarted = true;
|
||||||
|
}, _cts.Token);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
52
src/WireMock.Net/Owin/GlobalExceptionMiddleware.cs
Normal file
52
src/WireMock.Net/Owin/GlobalExceptionMiddleware.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using log4net;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
#if !NETSTANDARD
|
||||||
|
using Microsoft.Owin;
|
||||||
|
#else
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace WireMock.Owin
|
||||||
|
{
|
||||||
|
#if !NETSTANDARD
|
||||||
|
internal class GlobalExceptionMiddleware : OwinMiddleware
|
||||||
|
#else
|
||||||
|
internal class GlobalExceptionMiddleware
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(GlobalExceptionMiddleware));
|
||||||
|
#if !NETSTANDARD
|
||||||
|
public GlobalExceptionMiddleware(OwinMiddleware next) : base(next) { }
|
||||||
|
#else
|
||||||
|
public GlobalExceptionMiddleware(RequestDelegate next)
|
||||||
|
{
|
||||||
|
Next = next;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NETSTANDARD
|
||||||
|
public RequestDelegate Next { get; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private readonly OwinResponseMapper _responseMapper = new OwinResponseMapper();
|
||||||
|
|
||||||
|
#if !NETSTANDARD
|
||||||
|
public override async Task Invoke(IOwinContext ctx)
|
||||||
|
#else
|
||||||
|
public async Task Invoke(HttpContext ctx)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Next?.Invoke(ctx);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("HttpStatusCode set to 500", ex);
|
||||||
|
await _responseMapper.MapAsync(new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) }, ctx.Response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using WireMock.Util;
|
||||||
#if !NETSTANDARD
|
#if !NETSTANDARD
|
||||||
using Microsoft.Owin;
|
using Microsoft.Owin;
|
||||||
#else
|
#else
|
||||||
@@ -16,7 +17,7 @@ namespace WireMock.Owin
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// OwinRequestMapper
|
/// OwinRequestMapper
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OwinRequestMapper
|
internal class OwinRequestMapper
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MapAsync IOwinRequest to RequestMessage
|
/// MapAsync IOwinRequest to RequestMessage
|
||||||
@@ -43,32 +44,49 @@ namespace WireMock.Owin
|
|||||||
#endif
|
#endif
|
||||||
string method = request.Method;
|
string method = request.Method;
|
||||||
|
|
||||||
string bodyAsString = null;
|
Dictionary<string, string[]> headers = null;
|
||||||
byte[] body = null;
|
if (request.Headers.Any())
|
||||||
Encoding bodyEncoding = null;
|
|
||||||
if (request.Body != null)
|
|
||||||
{
|
{
|
||||||
using (var streamReader = new StreamReader(request.Body))
|
headers = new Dictionary<string, string[]>();
|
||||||
|
foreach (var header in request.Headers)
|
||||||
{
|
{
|
||||||
bodyAsString = await streamReader.ReadToEndAsync();
|
headers.Add(header.Key, header.Value);
|
||||||
bodyEncoding = streamReader.CurrentEncoding;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body = bodyEncoding.GetBytes(bodyAsString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var listenerHeaders = request.Headers;
|
IDictionary<string, string> cookies = null;
|
||||||
|
if (request.Cookies.Any())
|
||||||
|
{
|
||||||
|
cookies = new Dictionary<string, string>();
|
||||||
|
foreach (var cookie in request.Cookies)
|
||||||
|
{
|
||||||
|
cookies.Add(cookie.Key, cookie.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var headers = new Dictionary<string, string>();
|
BodyData body = null;
|
||||||
foreach (var header in listenerHeaders)
|
if (request.Body != null && ShouldParseBody(method))
|
||||||
headers.Add(header.Key, header.Value.FirstOrDefault());
|
{
|
||||||
|
body = await BodyParser.Parse(request.Body, request.ContentType);
|
||||||
|
}
|
||||||
|
|
||||||
var cookies = new Dictionary<string, string>();
|
return new RequestMessage(url, method, clientIP, body, headers, cookies) { DateTime = DateTime.Now };
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var cookie in request.Cookies)
|
private bool ShouldParseBody(string method)
|
||||||
cookies.Add(cookie.Key, cookie.Value);
|
{
|
||||||
|
/*
|
||||||
return new RequestMessage(url, method, clientIP, body, bodyAsString, bodyEncoding, headers, cookies) { DateTime = DateTime.Now };
|
HEAD - No defined body semantics.
|
||||||
|
GET - No defined body semantics.
|
||||||
|
PUT - Body supported.
|
||||||
|
POST - Body supported.
|
||||||
|
DELETE - No defined body semantics.
|
||||||
|
TRACE - Body not supported.
|
||||||
|
OPTIONS - Body supported but no semantics on usage (maybe in the future).
|
||||||
|
CONNECT - No defined body semantics
|
||||||
|
PATCH - Body supported.
|
||||||
|
*/
|
||||||
|
return new[] { "PUT", "POST", "OPTIONS", "PATCH" }.Contains(method.ToUpper());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
using System.IO;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using WireMock.Util;
|
||||||
#if !NETSTANDARD
|
#if !NETSTANDARD
|
||||||
using Microsoft.Owin;
|
using Microsoft.Owin;
|
||||||
#else
|
#else
|
||||||
@@ -17,6 +21,19 @@ namespace WireMock.Owin
|
|||||||
{
|
{
|
||||||
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
|
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/239725/cannot-set-some-http-headers-when-using-system-net-webrequest
|
||||||
|
#if !NETSTANDARD
|
||||||
|
private static readonly IDictionary<string, Action<IOwinResponse, WireMockList<string>>> RestrictedResponseHeaders = new Dictionary<string, Action<IOwinResponse, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase) {
|
||||||
|
#else
|
||||||
|
private static readonly IDictionary<string, Action<HttpResponse, WireMockList<string>>> RestrictedResponseHeaders = new Dictionary<string, Action<HttpResponse, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase) {
|
||||||
|
#endif
|
||||||
|
{ "Content-Length", null },
|
||||||
|
{ "Content-Type", (r, v) => r.ContentType = v.FirstOrDefault() },
|
||||||
|
{ "Keep-Alive", null },
|
||||||
|
{ "Transfer-Encoding", null },
|
||||||
|
{ "WWW-Authenticate", null }
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MapAsync ResponseMessage to OwinResponse
|
/// MapAsync ResponseMessage to OwinResponse
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -32,13 +49,54 @@ namespace WireMock.Owin
|
|||||||
{
|
{
|
||||||
response.StatusCode = responseMessage.StatusCode;
|
response.StatusCode = responseMessage.StatusCode;
|
||||||
|
|
||||||
responseMessage.Headers.ToList().ForEach(pair => response.Headers.Append(pair.Key, pair.Value));
|
// Set headers
|
||||||
|
foreach (var pair in responseMessage.Headers)
|
||||||
|
{
|
||||||
|
if (RestrictedResponseHeaders.ContainsKey(pair.Key))
|
||||||
|
{
|
||||||
|
RestrictedResponseHeaders[pair.Key]?.Invoke(response, pair.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if !NETSTANDARD
|
||||||
|
response.Headers.AppendValues(pair.Key, pair.Value.ToArray());
|
||||||
|
#else
|
||||||
|
response.Headers.Append(pair.Key, pair.Value.ToArray());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (responseMessage.Body == null)
|
if (responseMessage.Body == null && responseMessage.BodyAsBytes == null && responseMessage.BodyAsFile == null && responseMessage.BodyAsJson == null)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Encoding encoding = responseMessage.BodyEncoding ?? _utf8NoBom;
|
if (responseMessage.BodyAsBytes != null)
|
||||||
using (var writer = new StreamWriter(response.Body, encoding))
|
{
|
||||||
|
await response.Body.WriteAsync(responseMessage.BodyAsBytes, 0, responseMessage.BodyAsBytes.Length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseMessage.BodyAsFile != null)
|
||||||
|
{
|
||||||
|
byte[] bytes = File.ReadAllBytes(responseMessage.BodyAsFile);
|
||||||
|
|
||||||
|
await response.Body.WriteAsync(bytes, 0, bytes.Length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseMessage.BodyAsJson != null)
|
||||||
|
{
|
||||||
|
string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyAsJson, new JsonSerializerSettings { Formatting = Formatting.None, NullValueHandling = NullValueHandling.Ignore });
|
||||||
|
using (var writer = new StreamWriter(response.Body, responseMessage.BodyEncoding ?? _utf8NoBom))
|
||||||
|
{
|
||||||
|
await writer.WriteAsync(jsonBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var writer = new StreamWriter(response.Body, responseMessage.BodyEncoding ?? _utf8NoBom))
|
||||||
{
|
{
|
||||||
await writer.WriteAsync(responseMessage.Body);
|
await writer.WriteAsync(responseMessage.Body);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace WireMock.Owin
|
|||||||
public OwinSelfHost([NotNull] WireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
|
public OwinSelfHost([NotNull] WireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
|
||||||
{
|
{
|
||||||
Check.NotNull(options, nameof(options));
|
Check.NotNull(options, nameof(options));
|
||||||
Check.NotEmpty(uriPrefixes, nameof(uriPrefixes));
|
Check.NotNullOrEmpty(uriPrefixes, nameof(uriPrefixes));
|
||||||
|
|
||||||
foreach (string uriPrefix in uriPrefixes)
|
foreach (string uriPrefix in uriPrefixes)
|
||||||
{
|
{
|
||||||
@@ -57,11 +57,14 @@ namespace WireMock.Owin
|
|||||||
|
|
||||||
private void StartServers()
|
private void StartServers()
|
||||||
{
|
{
|
||||||
System.Console.WriteLine("WireMock.Net server using .net 4.5.x or .net 4.6.x");
|
Console.WriteLine("WireMock.Net server using .net 4.5.x or higher");
|
||||||
|
|
||||||
Action<IAppBuilder> startup = app =>
|
Action<IAppBuilder> startup = app =>
|
||||||
{
|
{
|
||||||
|
app.Use<GlobalExceptionMiddleware>();
|
||||||
|
_options.PreWireMockMiddlewareInit?.Invoke(app);
|
||||||
app.Use<WireMockMiddleware>(_options);
|
app.Use<WireMockMiddleware>(_options);
|
||||||
|
_options.PostWireMockMiddlewareInit?.Invoke(app);
|
||||||
};
|
};
|
||||||
|
|
||||||
var servers = new List<IDisposable>();
|
var servers = new List<IDisposable>();
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ using System.Threading.Tasks;
|
|||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
using WireMock.Matchers.Request;
|
using WireMock.Matchers.Request;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using log4net;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
|
using WireMock.Util;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using WireMock.Http;
|
||||||
#if !NETSTANDARD
|
#if !NETSTANDARD
|
||||||
using Microsoft.Owin;
|
using Microsoft.Owin;
|
||||||
#else
|
#else
|
||||||
@@ -18,6 +22,7 @@ namespace WireMock.Owin
|
|||||||
internal class WireMockMiddleware
|
internal class WireMockMiddleware
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(WireMockMiddleware));
|
||||||
private static readonly Task CompletedTask = Task.FromResult(false);
|
private static readonly Task CompletedTask = Task.FromResult(false);
|
||||||
private readonly WireMockMiddlewareOptions _options;
|
private readonly WireMockMiddlewareOptions _options;
|
||||||
|
|
||||||
@@ -50,7 +55,7 @@ namespace WireMock.Owin
|
|||||||
RequestMatchResult requestMatchResult = null;
|
RequestMatchResult requestMatchResult = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (var mapping in _options.Mappings.Where(m => m.Scenario != null))
|
foreach (var mapping in _options.Mappings.Values.Where(m => m?.Scenario != null))
|
||||||
{
|
{
|
||||||
// Set start
|
// Set start
|
||||||
if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)
|
if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)
|
||||||
@@ -59,7 +64,7 @@ namespace WireMock.Owin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var mappings = _options.Mappings
|
var mappings = _options.Mappings.Values
|
||||||
.Select(m => new
|
.Select(m => new
|
||||||
{
|
{
|
||||||
Mapping = m,
|
Mapping = m,
|
||||||
@@ -93,6 +98,7 @@ namespace WireMock.Owin
|
|||||||
if (targetMapping == null)
|
if (targetMapping == null)
|
||||||
{
|
{
|
||||||
logRequest = true;
|
logRequest = true;
|
||||||
|
Log.Warn("HttpStatusCode set to 404 : No matching mapping found");
|
||||||
response = new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" };
|
response = new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" };
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -101,9 +107,10 @@ namespace WireMock.Owin
|
|||||||
|
|
||||||
if (targetMapping.IsAdminInterface && _options.AuthorizationMatcher != null)
|
if (targetMapping.IsAdminInterface && _options.AuthorizationMatcher != null)
|
||||||
{
|
{
|
||||||
bool present = request.Headers.TryGetValue("Authorization", out string authorization);
|
bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList<string> authorization);
|
||||||
if (!present || _options.AuthorizationMatcher.IsMatch(authorization) < MatchScores.Perfect)
|
if (!present || _options.AuthorizationMatcher.IsMatch(authorization.ToString()) < MatchScores.Perfect)
|
||||||
{
|
{
|
||||||
|
Log.Error("HttpStatusCode set to 401");
|
||||||
response = new ResponseMessage { StatusCode = 401 };
|
response = new ResponseMessage { StatusCode = 401 };
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -123,7 +130,8 @@ namespace WireMock.Owin
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
response = new ResponseMessage { StatusCode = 500, Body = ex.ToString() };
|
Log.Error("HttpStatusCode set to 500", ex);
|
||||||
|
response = new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) };
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
|
using WireMock.Util;
|
||||||
|
#if !NETSTANDARD
|
||||||
|
using Owin;
|
||||||
|
#else
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace WireMock.Owin
|
namespace WireMock.Owin
|
||||||
{
|
{
|
||||||
@@ -11,18 +17,28 @@ namespace WireMock.Owin
|
|||||||
{
|
{
|
||||||
public TimeSpan? RequestProcessingDelay { get; set; }
|
public TimeSpan? RequestProcessingDelay { get; set; }
|
||||||
|
|
||||||
public IMatcher AuthorizationMatcher { get; set; }
|
public IStringMatcher AuthorizationMatcher { get; set; }
|
||||||
|
|
||||||
public bool AllowPartialMapping { get; set; }
|
public bool AllowPartialMapping { get; set; }
|
||||||
|
|
||||||
public IList<Mapping> Mappings { get; set; } = new List<Mapping>();
|
public IDictionary<Guid, Mapping> Mappings { get; set; } = new ConcurrentDictionary<Guid, Mapping>();
|
||||||
|
|
||||||
public ObservableCollection<LogEntry> LogEntries { get; } = new ObservableCollection<LogEntry>();
|
public ObservableCollection<LogEntry> LogEntries { get; } = new ConcurentObservableCollection<LogEntry>();
|
||||||
|
|
||||||
public int? RequestLogExpirationDuration { get; set; }
|
public int? RequestLogExpirationDuration { get; set; }
|
||||||
|
|
||||||
public int? MaxRequestLogCount { get; set; }
|
public int? MaxRequestLogCount { get; set; }
|
||||||
|
|
||||||
public IDictionary<string, object> Scenarios { get; } = new ConcurrentDictionary<string, object>();
|
public IDictionary<string, object> Scenarios { get; } = new ConcurrentDictionary<string, object>();
|
||||||
|
|
||||||
|
#if !NETSTANDARD
|
||||||
|
public Action<IAppBuilder> PreWireMockMiddlewareInit { get; set; }
|
||||||
|
|
||||||
|
public Action<IAppBuilder> PostWireMockMiddlewareInit { get; set; }
|
||||||
|
#else
|
||||||
|
public Action<IApplicationBuilder> PreWireMockMiddlewareInit { get; set; }
|
||||||
|
|
||||||
|
public Action<IApplicationBuilder> PostWireMockMiddlewareInit { get; set; }
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,38 +10,52 @@ namespace WireMock.RequestBuilders
|
|||||||
public interface IBodyRequestBuilder
|
public interface IBodyRequestBuilder
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with body.
|
/// WithBody: IMatcher
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matcher">The matcher.</param>
|
/// <param name="matcher">The matcher.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithBody([NotNull] IMatcher matcher);
|
IRequestBuilder WithBody([NotNull] IMatcher matcher);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with body.
|
/// WithBody: Body as string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="body">The body.</param>
|
/// <param name="body">The body.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithBody(string body);
|
IRequestBuilder WithBody(string body);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with body byte[].
|
/// WithBody: Body as byte[]
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="body">The body as byte[].</param>
|
/// <param name="body">The body.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithBody(byte[] body);
|
IRequestBuilder WithBody(byte[] body);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with body string func.
|
/// WithBody: Body as object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="body">The body string function.</param>
|
/// <param name="body">The body.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithBody([NotNull] Func<string, bool> body);
|
IRequestBuilder WithBody(object body);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with body byte[] func.
|
///WithBody: func (string)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="body">The body byte[] function.</param>
|
/// <param name="func">The function.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithBody([NotNull] Func<byte[], bool> body);
|
IRequestBuilder WithBody([NotNull] Func<string, bool> func);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///WithBody: func (byte[])
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The function.</param>
|
||||||
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
|
IRequestBuilder WithBody([NotNull] Func<byte[], bool> func);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///WithBody: func (object)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The function.</param>
|
||||||
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
|
IRequestBuilder WithBody([NotNull] Func<object, bool> func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithClientIP([NotNull] params IMatcher[] matchers);
|
IRequestBuilder WithClientIP([NotNull] params IStringMatcher[] matchers);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with ClientIP.
|
/// The with ClientIP.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace WireMock.RequestBuilders
|
|||||||
public interface IHeadersAndCookiesRequestBuilder : IBodyRequestBuilder, IRequestMatcher, IParamsRequestBuilder
|
public interface IHeadersAndCookiesRequestBuilder : IBodyRequestBuilder, IRequestMatcher, IParamsRequestBuilder
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with header.
|
/// Add Header matching based on name, pattern and ignoreCase.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="pattern">The pattern.</param>
|
/// <param name="pattern">The pattern.</param>
|
||||||
@@ -20,20 +20,29 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithHeader([NotNull] string name, string pattern, bool ignoreCase = true);
|
IRequestBuilder WithHeader([NotNull] string name, string pattern, bool ignoreCase = true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add Header matching based on name, patterns and ignoreCase.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name.</param>
|
||||||
|
/// <param name="patterns">The patterns.</param>
|
||||||
|
/// <param name="ignoreCase">ignore Case</param>
|
||||||
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
|
IRequestBuilder WithHeader([NotNull] string name, string[] patterns, bool ignoreCase = true);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with header.
|
/// The with header.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithHeader([NotNull] string name, [NotNull] params IMatcher[] matchers);
|
IRequestBuilder WithHeader([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with header.
|
/// The with header.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="funcs">The headers funcs.</param>
|
/// <param name="funcs">The headers funcs.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string>, bool>[] funcs);
|
IRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string[]>, bool>[] funcs);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with cookie.
|
/// The with cookie.
|
||||||
@@ -50,7 +59,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IMatcher[] matchers);
|
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with cookie.
|
/// The with cookie.
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IMethodRequestBuilder : IHeadersAndCookiesRequestBuilder
|
public interface IMethodRequestBuilder : IHeadersAndCookiesRequestBuilder
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The using delete.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The <see cref="IRequestBuilder"/>.
|
||||||
|
/// </returns>
|
||||||
|
IRequestBuilder UsingDelete();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The using get.
|
/// The using get.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -15,6 +23,14 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </returns>
|
/// </returns>
|
||||||
IRequestBuilder UsingGet();
|
IRequestBuilder UsingGet();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The using head.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The <see cref="IRequestBuilder"/>.
|
||||||
|
/// </returns>
|
||||||
|
IRequestBuilder UsingHead();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The using post.
|
/// The using post.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -24,12 +40,12 @@ namespace WireMock.RequestBuilders
|
|||||||
IRequestBuilder UsingPost();
|
IRequestBuilder UsingPost();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The using delete.
|
/// The using patch.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The <see cref="IRequestBuilder"/>.
|
/// The <see cref="IRequestBuilder"/>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
IRequestBuilder UsingDelete();
|
IRequestBuilder UsingPatch();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The using put.
|
/// The using put.
|
||||||
@@ -39,14 +55,6 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </returns>
|
/// </returns>
|
||||||
IRequestBuilder UsingPut();
|
IRequestBuilder UsingPut();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The using head.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// The <see cref="IRequestBuilder"/>.
|
|
||||||
/// </returns>
|
|
||||||
IRequestBuilder UsingHead();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The using any verb.
|
/// The using any verb.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithPath([NotNull] params IMatcher[] matchers);
|
IRequestBuilder WithPath([NotNull] params IStringMatcher[] matchers);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with path.
|
/// The with path.
|
||||||
@@ -35,7 +35,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithUrl([NotNull] params IMatcher[] matchers);
|
IRequestBuilder WithUrl([NotNull] params IStringMatcher[] matchers);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with url.
|
/// The with url.
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithClientIP(params IMatcher[] matchers)
|
public IRequestBuilder WithClientIP(params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(matchers, nameof(matchers));
|
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageClientIPMatcher(matchers));
|
_requestMatchers.Add(new RequestMessageClientIPMatcher(matchers));
|
||||||
return this;
|
return this;
|
||||||
@@ -74,7 +74,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithClientIP(params string[] clientIPs)
|
public IRequestBuilder WithClientIP(params string[] clientIPs)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(clientIPs, nameof(clientIPs));
|
Check.NotNullOrEmpty(clientIPs, nameof(clientIPs));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageClientIPMatcher(clientIPs));
|
_requestMatchers.Add(new RequestMessageClientIPMatcher(clientIPs));
|
||||||
return this;
|
return this;
|
||||||
@@ -87,7 +87,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithClientIP(params Func<string, bool>[] funcs)
|
public IRequestBuilder WithClientIP(params Func<string, bool>[] funcs)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(funcs, nameof(funcs));
|
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageClientIPMatcher(funcs));
|
_requestMatchers.Add(new RequestMessageClientIPMatcher(funcs));
|
||||||
return this;
|
return this;
|
||||||
@@ -98,9 +98,9 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithPath(params IMatcher[] matchers)
|
public IRequestBuilder WithPath(params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(matchers, nameof(matchers));
|
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessagePathMatcher(matchers));
|
_requestMatchers.Add(new RequestMessagePathMatcher(matchers));
|
||||||
return this;
|
return this;
|
||||||
@@ -113,7 +113,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithPath(params string[] paths)
|
public IRequestBuilder WithPath(params string[] paths)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(paths, nameof(paths));
|
Check.NotNullOrEmpty(paths, nameof(paths));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessagePathMatcher(paths));
|
_requestMatchers.Add(new RequestMessagePathMatcher(paths));
|
||||||
return this;
|
return this;
|
||||||
@@ -126,7 +126,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithPath(params Func<string, bool>[] funcs)
|
public IRequestBuilder WithPath(params Func<string, bool>[] funcs)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(funcs, nameof(funcs));
|
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessagePathMatcher(funcs));
|
_requestMatchers.Add(new RequestMessagePathMatcher(funcs));
|
||||||
return this;
|
return this;
|
||||||
@@ -137,9 +137,9 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithUrl(params IMatcher[] matchers)
|
public IRequestBuilder WithUrl(params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(matchers, nameof(matchers));
|
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageUrlMatcher(matchers));
|
_requestMatchers.Add(new RequestMessageUrlMatcher(matchers));
|
||||||
return this;
|
return this;
|
||||||
@@ -152,7 +152,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithUrl(params string[] urls)
|
public IRequestBuilder WithUrl(params string[] urls)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(urls, nameof(urls));
|
Check.NotNullOrEmpty(urls, nameof(urls));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageUrlMatcher(urls));
|
_requestMatchers.Add(new RequestMessageUrlMatcher(urls));
|
||||||
return this;
|
return this;
|
||||||
@@ -165,76 +165,55 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithUrl(params Func<string, bool>[] funcs)
|
public IRequestBuilder WithUrl(params Func<string, bool>[] funcs)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(funcs, nameof(funcs));
|
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageUrlMatcher(funcs));
|
_requestMatchers.Add(new RequestMessageUrlMatcher(funcs));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete"/>
|
||||||
/// The using get.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// The <see cref="IRequestBuilder"/>.
|
|
||||||
/// </returns>
|
|
||||||
public IRequestBuilder UsingGet()
|
|
||||||
{
|
|
||||||
_requestMatchers.Add(new RequestMessageMethodMatcher("get"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The using post.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// The <see cref="IRequestBuilder"/>.
|
|
||||||
/// </returns>
|
|
||||||
public IRequestBuilder UsingPost()
|
|
||||||
{
|
|
||||||
_requestMatchers.Add(new RequestMessageMethodMatcher("post"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The using put.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// The <see cref="IRequestBuilder"/>.
|
|
||||||
/// </returns>
|
|
||||||
public IRequestBuilder UsingPut()
|
|
||||||
{
|
|
||||||
_requestMatchers.Add(new RequestMessageMethodMatcher("put"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The using delete.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// The <see cref="IRequestBuilder"/>.
|
|
||||||
/// </returns>
|
|
||||||
public IRequestBuilder UsingDelete()
|
public IRequestBuilder UsingDelete()
|
||||||
{
|
{
|
||||||
_requestMatchers.Add(new RequestMessageMethodMatcher("delete"));
|
_requestMatchers.Add(new RequestMessageMethodMatcher("delete"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet"/>
|
||||||
/// The using head.
|
public IRequestBuilder UsingGet()
|
||||||
/// </summary>
|
{
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
_requestMatchers.Add(new RequestMessageMethodMatcher("get"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead"/>
|
||||||
public IRequestBuilder UsingHead()
|
public IRequestBuilder UsingHead()
|
||||||
{
|
{
|
||||||
_requestMatchers.Add(new RequestMessageMethodMatcher("head"));
|
_requestMatchers.Add(new RequestMessageMethodMatcher("head"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost"/>
|
||||||
/// The using any verb.
|
public IRequestBuilder UsingPost()
|
||||||
/// </summary>
|
{
|
||||||
/// <returns>
|
_requestMatchers.Add(new RequestMessageMethodMatcher("post"));
|
||||||
/// The <see cref="IRequestBuilder"/>.
|
return this;
|
||||||
/// </returns>
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch"/>
|
||||||
|
public IRequestBuilder UsingPatch()
|
||||||
|
{
|
||||||
|
_requestMatchers.Add(new RequestMessageMethodMatcher("patch"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut"/>
|
||||||
|
public IRequestBuilder UsingPut()
|
||||||
|
{
|
||||||
|
_requestMatchers.Add(new RequestMessageMethodMatcher("put"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
|
||||||
public IRequestBuilder UsingAnyVerb()
|
public IRequestBuilder UsingAnyVerb()
|
||||||
{
|
{
|
||||||
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
|
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
|
||||||
@@ -246,80 +225,37 @@ namespace WireMock.RequestBuilders
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb"/>
|
||||||
/// The using verb.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="verbs">The verbs.</param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
public IRequestBuilder UsingVerb(params string[] verbs)
|
public IRequestBuilder UsingVerb(params string[] verbs)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(verbs, nameof(verbs));
|
Check.NotNullOrEmpty(verbs, nameof(verbs));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageMethodMatcher(verbs));
|
_requestMatchers.Add(new RequestMessageMethodMatcher(verbs));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string)"/>
|
||||||
/// The with body.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="body">
|
|
||||||
/// The body.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
public IRequestBuilder WithBody(string body)
|
public IRequestBuilder WithBody(string body)
|
||||||
{
|
{
|
||||||
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
|
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[])"/>
|
||||||
/// The with body byte[].
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="body">
|
|
||||||
/// The body as byte[].
|
|
||||||
/// </param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
public IRequestBuilder WithBody(byte[] body)
|
public IRequestBuilder WithBody(byte[] body)
|
||||||
{
|
{
|
||||||
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
|
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object)"/>
|
||||||
/// The with body.
|
public IRequestBuilder WithBody(object body)
|
||||||
/// </summary>
|
|
||||||
/// <param name="func">
|
|
||||||
/// The body function.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
public IRequestBuilder WithBody(Func<string, bool> func)
|
|
||||||
{
|
{
|
||||||
Check.NotNull(func, nameof(func));
|
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher)"/>
|
||||||
/// The with body.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="func">
|
|
||||||
/// The body function.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
public IRequestBuilder WithBody(Func<byte[], bool> func)
|
|
||||||
{
|
|
||||||
Check.NotNull(func, nameof(func));
|
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The with body.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="matcher">The matcher.</param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder" />.</returns>
|
|
||||||
public IRequestBuilder WithBody(IMatcher matcher)
|
public IRequestBuilder WithBody(IMatcher matcher)
|
||||||
{
|
{
|
||||||
Check.NotNull(matcher, nameof(matcher));
|
Check.NotNull(matcher, nameof(matcher));
|
||||||
@@ -328,16 +264,34 @@ namespace WireMock.RequestBuilders
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{string, bool})"/>
|
||||||
/// The with parameters.
|
public IRequestBuilder WithBody(Func<string, bool> func)
|
||||||
/// </summary>
|
{
|
||||||
/// <param name="key">
|
Check.NotNull(func, nameof(func));
|
||||||
/// The key.
|
|
||||||
/// </param>
|
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||||
/// <param name="values">
|
return this;
|
||||||
/// The values.
|
}
|
||||||
/// </param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, string[])"/>
|
||||||
public IRequestBuilder WithParam(string key, params string[] values)
|
public IRequestBuilder WithParam(string key, params string[] values)
|
||||||
{
|
{
|
||||||
Check.NotNull(key, nameof(key));
|
Check.NotNull(key, nameof(key));
|
||||||
@@ -346,26 +300,16 @@ namespace WireMock.RequestBuilders
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(Func{IDictionary{string, WireMockList{string}}, bool}[])"/>
|
||||||
/// The with parameters.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="funcs">The funcs.</param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
public IRequestBuilder WithParam(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
|
public IRequestBuilder WithParam(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(funcs, nameof(funcs));
|
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageParamMatcher(funcs));
|
_requestMatchers.Add(new RequestMessageParamMatcher(funcs));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string,string,bool)"/>
|
||||||
/// With header.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">The name.</param>
|
|
||||||
/// <param name="pattern">The pattern.</param>
|
|
||||||
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true)
|
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true)
|
||||||
{
|
{
|
||||||
Check.NotNull(name, nameof(name));
|
Check.NotNull(name, nameof(name));
|
||||||
@@ -375,16 +319,26 @@ namespace WireMock.RequestBuilders
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string,string[],bool)"/>
|
||||||
|
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true)
|
||||||
|
{
|
||||||
|
Check.NotNull(name, nameof(name));
|
||||||
|
Check.NotNull(patterns, nameof(patterns));
|
||||||
|
|
||||||
|
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, patterns, ignoreCase));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// With header.
|
/// With header.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithHeader(string name, params IMatcher[] matchers)
|
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotNull(name, nameof(name));
|
Check.NotNull(name, nameof(name));
|
||||||
Check.NotEmpty(matchers, nameof(matchers));
|
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, matchers));
|
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, matchers));
|
||||||
return this;
|
return this;
|
||||||
@@ -395,9 +349,9 @@ namespace WireMock.RequestBuilders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="funcs">The funcs.</param>
|
/// <param name="funcs">The funcs.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithHeader(params Func<IDictionary<string, string>, bool>[] funcs)
|
public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(funcs, nameof(funcs));
|
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
|
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
|
||||||
return this;
|
return this;
|
||||||
@@ -422,9 +376,9 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithCookie(string name, params IMatcher[] matchers)
|
public IRequestBuilder WithCookie(string name, params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(matchers, nameof(matchers));
|
Check.NotNullOrEmpty(matchers, nameof(matchers));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageCookieMatcher(name, matchers));
|
_requestMatchers.Add(new RequestMessageCookieMatcher(name, matchers));
|
||||||
return this;
|
return this;
|
||||||
@@ -437,7 +391,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
|
public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(funcs, nameof(funcs));
|
Check.NotNullOrEmpty(funcs, nameof(funcs));
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageCookieMatcher(funcs));
|
_requestMatchers.Add(new RequestMessageCookieMatcher(funcs));
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Net;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace WireMock
|
namespace WireMock
|
||||||
{
|
{
|
||||||
@@ -41,7 +42,7 @@ namespace WireMock
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the headers.
|
/// Gets the headers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, string> Headers { get; }
|
public IDictionary<string, WireMockList<string>> Headers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the cookies.
|
/// Gets the cookies.
|
||||||
@@ -51,23 +52,88 @@ namespace WireMock
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the query.
|
/// Gets the query.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, WireMockList<string>> Query { get; } = new Dictionary<string, WireMockList<string>>();
|
public IDictionary<string, WireMockList<string>> Query { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the bodyAsBytes.
|
/// Gets the raw query.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte[] BodyAsBytes { get; }
|
public string RawQuery { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the body.
|
/// The body as string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Body { get; }
|
public string Body { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the body encoding.
|
/// The body (as JSON object).
|
||||||
|
/// </summary>
|
||||||
|
public object BodyAsJson { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body (as bytearray).
|
||||||
|
/// </summary>
|
||||||
|
public byte[] BodyAsBytes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Host
|
||||||
|
/// </summary>
|
||||||
|
public string Host { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the protocol
|
||||||
|
/// </summary>
|
||||||
|
public string Protocol { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the port
|
||||||
|
/// </summary>
|
||||||
|
public int Port { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the origin
|
||||||
|
/// </summary>
|
||||||
|
public string Origin { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body encoding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Encoding BodyEncoding { get; }
|
public Encoding BodyEncoding { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="url">The original url.</param>
|
||||||
|
/// <param name="method">The HTTP method.</param>
|
||||||
|
/// <param name="clientIP">The client IP Address.</param>
|
||||||
|
/// <param name="body">The body.</param>
|
||||||
|
/// <param name="headers">The headers.</param>
|
||||||
|
/// <param name="cookies">The cookies.</param>
|
||||||
|
public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyData body, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
|
||||||
|
{
|
||||||
|
Check.NotNull(url, nameof(url));
|
||||||
|
Check.NotNull(method, nameof(method));
|
||||||
|
Check.NotNull(clientIP, nameof(clientIP));
|
||||||
|
|
||||||
|
Url = url.ToString();
|
||||||
|
Protocol = url.Scheme;
|
||||||
|
Host = url.Host;
|
||||||
|
Port = url.Port;
|
||||||
|
Origin = $"{url.Scheme}://{url.Host}:{url.Port}";
|
||||||
|
Path = WebUtility.UrlDecode(url.AbsolutePath);
|
||||||
|
Method = method.ToLower();
|
||||||
|
ClientIP = clientIP;
|
||||||
|
|
||||||
|
Body = body?.BodyAsString;
|
||||||
|
BodyEncoding = body?.Encoding;
|
||||||
|
BodyAsJson = body?.BodyAsJson;
|
||||||
|
BodyAsBytes = body?.BodyAsBytes;
|
||||||
|
|
||||||
|
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||||
|
Cookies = cookies;
|
||||||
|
RawQuery = WebUtility.UrlDecode(url.Query);
|
||||||
|
Query = ParseQuery(RawQuery);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -79,58 +145,72 @@ namespace WireMock
|
|||||||
/// <param name="bodyEncoding">The body encoding</param>
|
/// <param name="bodyEncoding">The body encoding</param>
|
||||||
/// <param name="headers">The headers.</param>
|
/// <param name="headers">The headers.</param>
|
||||||
/// <param name="cookies">The cookies.</param>
|
/// <param name="cookies">The cookies.</param>
|
||||||
public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] byte[] bodyAsBytes = null, [CanBeNull] string body = null, [CanBeNull] Encoding bodyEncoding = null, [CanBeNull] IDictionary<string, string> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
|
public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] byte[] bodyAsBytes = null, [CanBeNull] string body = null, [CanBeNull] Encoding bodyEncoding = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
|
||||||
{
|
{
|
||||||
Check.NotNull(url, nameof(url));
|
Check.NotNull(url, nameof(url));
|
||||||
Check.NotNull(method, nameof(method));
|
Check.NotNull(method, nameof(method));
|
||||||
Check.NotNull(clientIP, nameof(clientIP));
|
Check.NotNull(clientIP, nameof(clientIP));
|
||||||
|
|
||||||
Url = url.ToString();
|
Url = url.ToString();
|
||||||
Path = url.AbsolutePath;
|
Protocol = url.Scheme;
|
||||||
|
Host = url.Host;
|
||||||
|
Port = url.Port;
|
||||||
|
Origin = $"{url.Scheme}://{url.Host}:{url.Port}";
|
||||||
|
Path = WebUtility.UrlDecode(url.AbsolutePath);
|
||||||
Method = method.ToLower();
|
Method = method.ToLower();
|
||||||
ClientIP = clientIP;
|
ClientIP = clientIP;
|
||||||
BodyAsBytes = bodyAsBytes;
|
BodyAsBytes = bodyAsBytes;
|
||||||
Body = body;
|
Body = body;
|
||||||
BodyEncoding = bodyEncoding;
|
BodyEncoding = bodyEncoding;
|
||||||
Headers = headers;
|
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||||
Cookies = cookies;
|
Cookies = cookies;
|
||||||
|
RawQuery = WebUtility.UrlDecode(url.Query);
|
||||||
|
Query = ParseQuery(RawQuery);
|
||||||
|
}
|
||||||
|
|
||||||
string query = url.Query;
|
private static IDictionary<string, WireMockList<string>> ParseQuery(string queryString)
|
||||||
if (!string.IsNullOrEmpty(query))
|
{
|
||||||
|
if (string.IsNullOrEmpty(queryString))
|
||||||
{
|
{
|
||||||
if (query.StartsWith("?"))
|
return null;
|
||||||
{
|
|
||||||
query = query.Substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Query = query.Split('&').Aggregate(
|
|
||||||
new Dictionary<string, WireMockList<string>>(),
|
|
||||||
(dict, term) =>
|
|
||||||
{
|
|
||||||
var parts = term.Split('=');
|
|
||||||
string key = parts[0];
|
|
||||||
if (!dict.ContainsKey(key))
|
|
||||||
{
|
|
||||||
dict.Add(key, new WireMockList<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parts.Length == 2)
|
|
||||||
{
|
|
||||||
dict[key].Add(parts[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queryString.StartsWith("?"))
|
||||||
|
{
|
||||||
|
queryString = queryString.Substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryString.Split('&').Aggregate(new Dictionary<string, WireMockList<string>>(),
|
||||||
|
(dict, term) =>
|
||||||
|
{
|
||||||
|
var parts = term.Split('=');
|
||||||
|
string key = parts[0];
|
||||||
|
if (!dict.ContainsKey(key))
|
||||||
|
{
|
||||||
|
dict.Add(key, new WireMockList<string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts.Length == 2)
|
||||||
|
{
|
||||||
|
dict[key].Add(parts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dict;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The get a query parameter.
|
/// Get a query parameter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">The key.</param>
|
/// <param name="key">The key.</param>
|
||||||
/// <returns>The query parameter.</returns>
|
/// <returns>The query parameter.</returns>
|
||||||
public List<string> GetParameter(string key)
|
public List<string> GetParameter(string key)
|
||||||
{
|
{
|
||||||
|
if (Query == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Query.ContainsKey(key) ? Query[key] : null;
|
return Query.ContainsKey(key) ? Query[key] : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
src/WireMock.Net/ResponseBuilders/BodyDestinationFormat.cs
Normal file
23
src/WireMock.Net/ResponseBuilders/BodyDestinationFormat.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
namespace WireMock.ResponseBuilders
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the BodyDestinationFormat
|
||||||
|
/// </summary>
|
||||||
|
public static class BodyDestinationFormat
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Same as source (no conversion)
|
||||||
|
/// </summary>
|
||||||
|
public const string SameAsSource = "SameAsSource";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert to string
|
||||||
|
/// </summary>
|
||||||
|
public const string String = "String";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert to bytes
|
||||||
|
/// </summary>
|
||||||
|
public const string Bytes = "Bytes";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Text;
|
using System;
|
||||||
|
using System.Text;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
namespace WireMock.ResponseBuilders
|
namespace WireMock.ResponseBuilders
|
||||||
@@ -9,15 +10,25 @@ namespace WireMock.ResponseBuilders
|
|||||||
public interface IBodyResponseBuilder : ITransformResponseBuilder
|
public interface IBodyResponseBuilder : ITransformResponseBuilder
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with body.
|
/// WithBody : Create a ... response based on a string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="body">The body.</param>
|
/// <param name="body">The body.</param>
|
||||||
|
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||||
/// <param name="encoding">The body encoding.</param>
|
/// <param name="encoding">The body encoding.</param>
|
||||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
IResponseBuilder WithBody([NotNull] string body, [CanBeNull] Encoding encoding = null);
|
IResponseBuilder WithBody([NotNull] string body, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with body as Json.
|
/// WithBody : Create a ... response based on a bytearray.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="body">The body.</param>
|
||||||
|
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||||
|
/// <param name="encoding">The body encoding.</param>
|
||||||
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
|
IResponseBuilder WithBody([NotNull] byte[] body, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WithBody : Create a string response based on a object (which will be converted to a JSON string).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="body">The body.</param>
|
/// <param name="body">The body.</param>
|
||||||
/// <param name="encoding">The body encoding.</param>
|
/// <param name="encoding">The body encoding.</param>
|
||||||
@@ -25,11 +36,20 @@ namespace WireMock.ResponseBuilders
|
|||||||
IResponseBuilder WithBodyAsJson([NotNull] object body, [CanBeNull] Encoding encoding = null);
|
IResponseBuilder WithBodyAsJson([NotNull] object body, [CanBeNull] Encoding encoding = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with body as base64.
|
/// WithBody : Create a string response based on a Base64 string (which will be decoded to a normal string).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bodyAsbase64">The body asbase64.</param>
|
/// <param name="bodyAsbase64">The body.</param>
|
||||||
/// <param name="encoding">The Encoding.</param>
|
/// <param name="encoding">The Encoding.</param>
|
||||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
IResponseBuilder WithBodyAsBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
|
[Obsolete]
|
||||||
|
IResponseBuilder WithBodyFromBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WithBodyFromFile : Create a ... response based on a File.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">The filename.</param>
|
||||||
|
/// <param name="cache">Defines if this file is cached in memory or retrieved from disk everytime the response is created.</param>
|
||||||
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
|
IResponseBuilder WithBodyFromFile([NotNull] string filename, bool cache = true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.ResponseBuilders
|
namespace WireMock.ResponseBuilders
|
||||||
{
|
{
|
||||||
@@ -12,15 +13,29 @@ namespace WireMock.ResponseBuilders
|
|||||||
/// The with header.
|
/// The with header.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="values">The values.</param>
|
||||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||||
IResponseBuilder WithHeader([NotNull] string name, string value);
|
IResponseBuilder WithHeader([NotNull] string name, params string[] values);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The with headers.
|
/// The with headers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="headers">The headers.</param>
|
/// <param name="headers">The headers.</param>
|
||||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||||
IResponseBuilder WithHeaders([NotNull] IDictionary<string,string> headers);
|
IResponseBuilder WithHeaders([NotNull] IDictionary<string, string> headers);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The with headers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="headers">The headers.</param>
|
||||||
|
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||||
|
IResponseBuilder WithHeaders([NotNull] IDictionary<string, string[]> headers);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The with headers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="headers">The headers.</param>
|
||||||
|
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||||
|
IResponseBuilder WithHeaders([NotNull] IDictionary<string, WireMockList<string>> headers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using WireMock.Settings;
|
||||||
|
|
||||||
namespace WireMock.ResponseBuilders
|
namespace WireMock.ResponseBuilders
|
||||||
{
|
{
|
||||||
@@ -8,11 +9,18 @@ namespace WireMock.ResponseBuilders
|
|||||||
public interface IProxyResponseBuilder : IStatusCodeResponseBuilder
|
public interface IProxyResponseBuilder : IStatusCodeResponseBuilder
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// With Proxy URL using X509Certificate2.
|
/// WithProxy URL using Client X509Certificate2.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="proxyUrl">The proxy url.</param>
|
/// <param name="proxyUrl">The proxy url.</param>
|
||||||
/// <param name="clientX509Certificate2ThumbprintOrSubjectName">The X509Certificate2 file to use for client authentication.</param>
|
/// <param name="clientX509Certificate2ThumbprintOrSubjectName">The X509Certificate2 file to use for client authentication.</param>
|
||||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
IResponseBuilder WithProxy([NotNull] string proxyUrl, [CanBeNull] string clientX509Certificate2ThumbprintOrSubjectName = null);
|
IResponseBuilder WithProxy([NotNull] string proxyUrl, [CanBeNull] string clientX509Certificate2ThumbprintOrSubjectName = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WithProxy using IProxyAndRecordSettings.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="settings">The IProxyAndRecordSettings.</param>
|
||||||
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
|
IResponseBuilder WithProxy([NotNull] IProxyAndRecordSettings settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using WireMock.Validation;
|
|
||||||
using WireMock.Http;
|
using WireMock.Http;
|
||||||
|
using WireMock.Settings;
|
||||||
using WireMock.Transformers;
|
using WireMock.Transformers;
|
||||||
|
using WireMock.Util;
|
||||||
|
using WireMock.Validation;
|
||||||
|
|
||||||
namespace WireMock.ResponseBuilders
|
namespace WireMock.ResponseBuilders
|
||||||
{
|
{
|
||||||
@@ -16,6 +21,8 @@ namespace WireMock.ResponseBuilders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class Response : IResponseBuilder
|
public class Response : IResponseBuilder
|
||||||
{
|
{
|
||||||
|
private HttpClient _httpClientForProxy;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The delay
|
/// The delay
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -37,7 +44,7 @@ namespace WireMock.ResponseBuilders
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The client X509Certificate2 Thumbprint or SubjectName to use.
|
/// The client X509Certificate2 Thumbprint or SubjectName to use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string X509Certificate2ThumbprintOrSubjectName { get; private set; }
|
public string ClientX509Certificate2ThumbprintOrSubjectName { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the response message.
|
/// Gets the response message.
|
||||||
@@ -125,137 +132,183 @@ namespace WireMock.ResponseBuilders
|
|||||||
return WithStatusCode((int)HttpStatusCode.NotFound);
|
return WithStatusCode((int)HttpStatusCode.NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IHeadersResponseBuilder.WithHeader(string, string[])"/>
|
||||||
/// The with header.
|
public IResponseBuilder WithHeader(string name, params string[] values)
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">The name.</param>
|
|
||||||
/// <param name="value">The value.</param>
|
|
||||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
|
||||||
public IResponseBuilder WithHeader(string name, string value)
|
|
||||||
{
|
{
|
||||||
Check.NotNull(name, nameof(name));
|
Check.NotNull(name, nameof(name));
|
||||||
|
|
||||||
ResponseMessage.AddHeader(name, value);
|
ResponseMessage.AddHeader(name, values);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IHeadersResponseBuilder.WithHeaders(IDictionary{string, string})"/>
|
||||||
/// The with headers.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="headers">The headers.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IResponseBuilder WithHeaders(IDictionary<string, string> headers)
|
public IResponseBuilder WithHeaders(IDictionary<string, string> headers)
|
||||||
|
{
|
||||||
|
Check.NotNull(headers, nameof(headers));
|
||||||
|
|
||||||
|
ResponseMessage.Headers = headers.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IHeadersResponseBuilder.WithHeaders(IDictionary{string, string[]})"/>
|
||||||
|
public IResponseBuilder WithHeaders(IDictionary<string, string[]> headers)
|
||||||
|
{
|
||||||
|
Check.NotNull(headers, nameof(headers));
|
||||||
|
|
||||||
|
ResponseMessage.Headers = headers.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IHeadersResponseBuilder.WithHeaders(IDictionary{string, WireMockList{string}})"/>
|
||||||
|
public IResponseBuilder WithHeaders(IDictionary<string, WireMockList<string>> headers)
|
||||||
{
|
{
|
||||||
ResponseMessage.Headers = headers;
|
ResponseMessage.Headers = headers;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(byte[], string, Encoding)"/>
|
||||||
/// The with body.
|
public IResponseBuilder WithBody(byte[] body, string destination, Encoding encoding = null)
|
||||||
/// </summary>
|
|
||||||
/// <param name="body">The body.</param>
|
|
||||||
/// <param name="encoding">The body encoding.</param>
|
|
||||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
|
||||||
public IResponseBuilder WithBody(string body, Encoding encoding = null)
|
|
||||||
{
|
{
|
||||||
Check.NotNull(body, nameof(body));
|
Check.NotNull(body, nameof(body));
|
||||||
|
|
||||||
ResponseMessage.Body = body;
|
ResponseMessage.BodyDestination = destination;
|
||||||
ResponseMessage.BodyEncoding = encoding ?? Encoding.UTF8;
|
|
||||||
|
switch (destination)
|
||||||
|
{
|
||||||
|
case BodyDestinationFormat.String:
|
||||||
|
var enc = encoding ?? Encoding.UTF8;
|
||||||
|
ResponseMessage.BodyAsBytes = null;
|
||||||
|
ResponseMessage.Body = enc.GetString(body);
|
||||||
|
ResponseMessage.BodyEncoding = enc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ResponseMessage.BodyAsBytes = body;
|
||||||
|
ResponseMessage.BodyEncoding = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromFile"/>
|
||||||
/// The with body (AsJson object).
|
public IResponseBuilder WithBodyFromFile(string filename, bool cache = true)
|
||||||
/// </summary>
|
{
|
||||||
/// <param name="body">The body.</param>
|
Check.NotNull(filename, nameof(filename));
|
||||||
/// <param name="encoding">The body encoding.</param>
|
|
||||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
ResponseMessage.BodyEncoding = null;
|
||||||
|
ResponseMessage.BodyAsFileIsCached = cache;
|
||||||
|
|
||||||
|
if (cache)
|
||||||
|
{
|
||||||
|
ResponseMessage.Body = null;
|
||||||
|
ResponseMessage.BodyAsBytes = File.ReadAllBytes(filename);
|
||||||
|
ResponseMessage.BodyAsFile = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResponseMessage.Body = null;
|
||||||
|
ResponseMessage.BodyAsBytes = null;
|
||||||
|
ResponseMessage.BodyAsFile = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(string, string, Encoding)"/>
|
||||||
|
public IResponseBuilder WithBody(string body, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null)
|
||||||
|
{
|
||||||
|
Check.NotNull(body, nameof(body));
|
||||||
|
|
||||||
|
encoding = encoding ?? Encoding.UTF8;
|
||||||
|
|
||||||
|
ResponseMessage.BodyDestination = destination;
|
||||||
|
|
||||||
|
switch (destination)
|
||||||
|
{
|
||||||
|
case BodyDestinationFormat.Bytes:
|
||||||
|
ResponseMessage.Body = null;
|
||||||
|
ResponseMessage.BodyAsBytes = encoding.GetBytes(body);
|
||||||
|
ResponseMessage.BodyEncoding = encoding;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ResponseMessage.Body = body;
|
||||||
|
ResponseMessage.BodyAsBytes = null;
|
||||||
|
ResponseMessage.BodyEncoding = encoding;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson"/>
|
||||||
public IResponseBuilder WithBodyAsJson(object body, Encoding encoding = null)
|
public IResponseBuilder WithBodyAsJson(object body, Encoding encoding = null)
|
||||||
{
|
{
|
||||||
Check.NotNull(body, nameof(body));
|
Check.NotNull(body, nameof(body));
|
||||||
|
|
||||||
string jsonBody = JsonConvert.SerializeObject(body, new JsonSerializerSettings { Formatting = Formatting.None, NullValueHandling = NullValueHandling.Ignore });
|
ResponseMessage.BodyDestination = null;
|
||||||
|
ResponseMessage.BodyAsJson = body;
|
||||||
if (encoding != null && !encoding.Equals(Encoding.UTF8))
|
ResponseMessage.BodyEncoding = encoding;
|
||||||
{
|
|
||||||
jsonBody = encoding.GetString(Encoding.UTF8.GetBytes(jsonBody));
|
|
||||||
ResponseMessage.BodyEncoding = encoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResponseMessage.Body = jsonBody;
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromBase64"/>
|
||||||
/// The with body as base64.
|
public IResponseBuilder WithBodyFromBase64(string bodyAsbase64, Encoding encoding = null)
|
||||||
/// </summary>
|
|
||||||
/// <param name="bodyAsbase64">The body asbase64.</param>
|
|
||||||
/// <param name="encoding">The Encoding.</param>
|
|
||||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
|
||||||
public IResponseBuilder WithBodyAsBase64(string bodyAsbase64, Encoding encoding = null)
|
|
||||||
{
|
{
|
||||||
Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));
|
Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));
|
||||||
|
|
||||||
encoding = encoding ?? Encoding.UTF8;
|
encoding = encoding ?? Encoding.UTF8;
|
||||||
|
|
||||||
|
ResponseMessage.BodyDestination = null;
|
||||||
ResponseMessage.Body = encoding.GetString(Convert.FromBase64String(bodyAsbase64));
|
ResponseMessage.Body = encoding.GetString(Convert.FromBase64String(bodyAsbase64));
|
||||||
ResponseMessage.BodyEncoding = encoding;
|
ResponseMessage.BodyEncoding = encoding;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer"/>
|
||||||
/// The with transformer.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// The <see cref="IResponseBuilder"/>.
|
|
||||||
/// </returns>
|
|
||||||
public IResponseBuilder WithTransformer()
|
public IResponseBuilder WithTransformer()
|
||||||
{
|
{
|
||||||
UseTransformer = true;
|
UseTransformer = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IDelayResponseBuilder.WithDelay(TimeSpan)"/>
|
||||||
/// The with delay.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="delay">The TimeSpan to delay.</param>
|
|
||||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
|
||||||
public IResponseBuilder WithDelay(TimeSpan delay)
|
public IResponseBuilder WithDelay(TimeSpan delay)
|
||||||
{
|
{
|
||||||
Check.Condition(delay, d => d > TimeSpan.Zero, nameof(delay));
|
Check.Condition(delay, d => d > TimeSpan.Zero, nameof(delay));
|
||||||
|
|
||||||
Delay = delay;
|
Delay = delay;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IDelayResponseBuilder.WithDelay(int)"/>
|
||||||
/// The with delay.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="milliseconds">The milliseconds to delay.</param>
|
|
||||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
|
||||||
public IResponseBuilder WithDelay(int milliseconds)
|
public IResponseBuilder WithDelay(int milliseconds)
|
||||||
{
|
{
|
||||||
return WithDelay(TimeSpan.FromMilliseconds(milliseconds));
|
return WithDelay(TimeSpan.FromMilliseconds(milliseconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IProxyResponseBuilder.WithProxy(string, string)"/>
|
||||||
/// With Proxy URL.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="proxyUrl">The proxy url.</param>
|
|
||||||
/// <param name="clientX509Certificate2ThumbprintOrSubjectName">The X509Certificate2 file to use for client authentication.</param>
|
|
||||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
|
||||||
public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2ThumbprintOrSubjectName = null)
|
public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2ThumbprintOrSubjectName = null)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(proxyUrl, nameof(proxyUrl));
|
Check.NotNullOrEmpty(proxyUrl, nameof(proxyUrl));
|
||||||
|
|
||||||
ProxyUrl = proxyUrl;
|
ProxyUrl = proxyUrl;
|
||||||
X509Certificate2ThumbprintOrSubjectName = clientX509Certificate2ThumbprintOrSubjectName;
|
ClientX509Certificate2ThumbprintOrSubjectName = clientX509Certificate2ThumbprintOrSubjectName;
|
||||||
|
_httpClientForProxy = HttpClientHelper.CreateHttpClient(clientX509Certificate2ThumbprintOrSubjectName);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IProxyResponseBuilder.WithProxy(IProxyAndRecordSettings)"/>
|
||||||
|
public IResponseBuilder WithProxy(IProxyAndRecordSettings settings)
|
||||||
|
{
|
||||||
|
Check.NotNull(settings, nameof(settings));
|
||||||
|
|
||||||
|
return WithProxy(settings.Url, settings.ClientX509Certificate2ThumbprintOrSubjectName);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The provide response.
|
/// The provide response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -266,14 +319,17 @@ namespace WireMock.ResponseBuilders
|
|||||||
Check.NotNull(requestMessage, nameof(requestMessage));
|
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||||
|
|
||||||
if (Delay != null)
|
if (Delay != null)
|
||||||
|
{
|
||||||
await Task.Delay(Delay.Value);
|
await Task.Delay(Delay.Value);
|
||||||
|
}
|
||||||
|
|
||||||
if (ProxyUrl != null)
|
if (ProxyUrl != null && _httpClientForProxy != null)
|
||||||
{
|
{
|
||||||
var requestUri = new Uri(requestMessage.Url);
|
var requestUri = new Uri(requestMessage.Url);
|
||||||
var proxyUri = new Uri(ProxyUrl);
|
var proxyUri = new Uri(ProxyUrl);
|
||||||
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
|
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
|
||||||
return await HttpClientHelper.SendAsync(requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri, X509Certificate2ThumbprintOrSubjectName);
|
|
||||||
|
return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UseTransformer)
|
if (UseTransformer)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using WireMock.Util;
|
||||||
|
using WireMock.Validation;
|
||||||
|
|
||||||
namespace WireMock
|
namespace WireMock
|
||||||
{
|
{
|
||||||
@@ -12,7 +15,7 @@ namespace WireMock
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the headers.
|
/// Gets the headers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, string> Headers { get; set; } = new ConcurrentDictionary<string, string>();
|
public IDictionary<string, WireMockList<string>> Headers { get; set; } = new ConcurrentDictionary<string, WireMockList<string>>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the status code.
|
/// Gets or sets the status code.
|
||||||
@@ -25,27 +28,64 @@ namespace WireMock
|
|||||||
public string BodyOriginal { get; set; }
|
public string BodyOriginal { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body.
|
/// Gets or sets the body destination (SameAsSource, String or Bytes).
|
||||||
|
/// </summary>
|
||||||
|
public string BodyDestination { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the body as a string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Body { get; set; }
|
public string Body { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the body as a json object.
|
||||||
|
/// </summary>
|
||||||
|
public object BodyAsJson { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the body as bytes.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] BodyAsBytes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the body as a file.
|
||||||
|
/// </summary>
|
||||||
|
public string BodyAsFile { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the body as file cached?
|
||||||
|
/// </summary>
|
||||||
|
public bool? BodyAsFileIsCached { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body encoding.
|
/// Gets or sets the body encoding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Encoding BodyEncoding { get; set; } = new UTF8Encoding(false);
|
public Encoding BodyEncoding { get; set; } = new UTF8Encoding(false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The add header.
|
/// Adds the header.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">
|
/// <param name="name">The name.</param>
|
||||||
/// The name.
|
/// <param name="value">The value.</param>
|
||||||
/// </param>
|
|
||||||
/// <param name="value">
|
|
||||||
/// The value.
|
|
||||||
/// </param>
|
|
||||||
public void AddHeader(string name, string value)
|
public void AddHeader(string name, string value)
|
||||||
{
|
{
|
||||||
Headers.Add(name, value);
|
Headers.Add(name, new WireMockList<string>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the header.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name.</param>
|
||||||
|
/// <param name="values">The values.</param>
|
||||||
|
public void AddHeader(string name, params string[] values)
|
||||||
|
{
|
||||||
|
Check.NotNullOrEmpty(values, nameof(values));
|
||||||
|
|
||||||
|
var newHeaderValues = Headers.TryGetValue(name, out WireMockList<string> existingValues)
|
||||||
|
? values.Union(existingValues).ToArray()
|
||||||
|
: values;
|
||||||
|
|
||||||
|
Headers[name] = new WireMockList<string>(newHeaderValues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ using WireMock.Matchers;
|
|||||||
using WireMock.Matchers.Request;
|
using WireMock.Matchers.Request;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
using WireMock.ResponseBuilders;
|
using WireMock.ResponseBuilders;
|
||||||
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.Serialization
|
namespace WireMock.Serialization
|
||||||
{
|
{
|
||||||
@@ -78,7 +79,7 @@ namespace WireMock.Serialization
|
|||||||
Funcs = Map(pm.Funcs)
|
Funcs = Map(pm.Funcs)
|
||||||
}).ToList() : null,
|
}).ToList() : null,
|
||||||
|
|
||||||
Body = methodMatcher?.Methods != null && methodMatcher.Methods.Count(m => m == "get") == 1 ? null : new BodyModel
|
Body = methodMatcher?.Methods != null && methodMatcher.Methods.Any(m => m == "get") ? null : new BodyModel
|
||||||
{
|
{
|
||||||
Matcher = bodyMatcher != null ? Map(bodyMatcher.Matcher) : null,
|
Matcher = bodyMatcher != null ? Map(bodyMatcher.Matcher) : null,
|
||||||
Func = bodyMatcher != null ? Map(bodyMatcher.Func) : null,
|
Func = bodyMatcher != null ? Map(bodyMatcher.Func) : null,
|
||||||
@@ -95,44 +96,78 @@ namespace WireMock.Serialization
|
|||||||
{
|
{
|
||||||
mappingModel.Response.StatusCode = null;
|
mappingModel.Response.StatusCode = null;
|
||||||
mappingModel.Response.Headers = null;
|
mappingModel.Response.Headers = null;
|
||||||
|
mappingModel.Response.BodyDestination = null;
|
||||||
|
mappingModel.Response.BodyAsJson = null;
|
||||||
mappingModel.Response.Body = null;
|
mappingModel.Response.Body = null;
|
||||||
|
mappingModel.Response.BodyAsBytes = null;
|
||||||
|
mappingModel.Response.BodyAsFile = null;
|
||||||
|
mappingModel.Response.BodyAsFileIsCached = null;
|
||||||
mappingModel.Response.UseTransformer = false;
|
mappingModel.Response.UseTransformer = false;
|
||||||
mappingModel.Response.BodyEncoding = null;
|
mappingModel.Response.BodyEncoding = null;
|
||||||
mappingModel.Response.ProxyUrl = response.ProxyUrl;
|
mappingModel.Response.ProxyUrl = response.ProxyUrl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
|
||||||
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
|
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
|
||||||
mappingModel.Response.Headers = response.ResponseMessage.Headers;
|
mappingModel.Response.Headers = Map(response.ResponseMessage.Headers);
|
||||||
|
mappingModel.Response.BodyAsJson = response.ResponseMessage.BodyAsJson;
|
||||||
mappingModel.Response.Body = response.ResponseMessage.Body;
|
mappingModel.Response.Body = response.ResponseMessage.Body;
|
||||||
|
mappingModel.Response.BodyAsBytes = response.ResponseMessage.BodyAsBytes;
|
||||||
|
mappingModel.Response.BodyAsFile = response.ResponseMessage.BodyAsFile;
|
||||||
|
mappingModel.Response.BodyAsFileIsCached = response.ResponseMessage.BodyAsFileIsCached;
|
||||||
mappingModel.Response.UseTransformer = response.UseTransformer;
|
mappingModel.Response.UseTransformer = response.UseTransformer;
|
||||||
mappingModel.Response.BodyEncoding = response.ResponseMessage.BodyEncoding != null
|
|
||||||
? new EncodingModel
|
if (response.ResponseMessage.BodyEncoding != null)
|
||||||
|
{
|
||||||
|
mappingModel.Response.BodyEncoding = new EncodingModel
|
||||||
{
|
{
|
||||||
EncodingName = response.ResponseMessage.BodyEncoding.EncodingName,
|
EncodingName = response.ResponseMessage.BodyEncoding.EncodingName,
|
||||||
CodePage = response.ResponseMessage.BodyEncoding.CodePage,
|
CodePage = response.ResponseMessage.BodyEncoding.CodePage,
|
||||||
WebName = response.ResponseMessage.BodyEncoding.WebName
|
WebName = response.ResponseMessage.BodyEncoding.WebName
|
||||||
}
|
};
|
||||||
: null;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mappingModel;
|
return mappingModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MatcherModel[] Map([CanBeNull] IEnumerable<IMatcher> matchers)
|
private static IDictionary<string, object> Map(IDictionary<string, WireMockList<string>> dictionary)
|
||||||
|
{
|
||||||
|
if (dictionary == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newDictionary = new Dictionary<string, object>();
|
||||||
|
foreach (var entry in dictionary)
|
||||||
|
{
|
||||||
|
object value = entry.Value.Count == 1 ? (object)entry.Value.ToString() : entry.Value;
|
||||||
|
newDictionary.Add(entry.Key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MatcherModel[] Map([CanBeNull] IEnumerable<IMatcher> matchers)
|
||||||
{
|
{
|
||||||
if (matchers == null || !matchers.Any())
|
if (matchers == null || !matchers.Any())
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return matchers.Select(Map).Where(x => x != null).ToArray();
|
return matchers.Select(Map).Where(x => x != null).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MatcherModel Map([CanBeNull] IMatcher matcher)
|
private static MatcherModel Map([CanBeNull] IMatcher matcher)
|
||||||
{
|
{
|
||||||
if (matcher == null)
|
if (matcher == null)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var patterns = matcher.GetPatterns();
|
IStringMatcher stringMatcher = matcher as IStringMatcher;
|
||||||
|
string[] patterns = stringMatcher != null ? stringMatcher.GetPatterns() : new string[0];
|
||||||
|
|
||||||
return new MatcherModel
|
return new MatcherModel
|
||||||
{
|
{
|
||||||
@@ -142,7 +177,7 @@ namespace WireMock.Serialization
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string[] Map<T>([CanBeNull] IEnumerable<Func<T, bool>> funcs)
|
private static string[] Map<T>([CanBeNull] IEnumerable<Func<T, bool>> funcs)
|
||||||
{
|
{
|
||||||
if (funcs == null || !funcs.Any())
|
if (funcs == null || !funcs.Any())
|
||||||
return null;
|
return null;
|
||||||
@@ -150,7 +185,7 @@ namespace WireMock.Serialization
|
|||||||
return funcs.Select(Map).Where(x => x != null).ToArray();
|
return funcs.Select(Map).Where(x => x != null).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Map<T>([CanBeNull] Func<T, bool> func)
|
private static string Map<T>([CanBeNull] Func<T, bool> func)
|
||||||
{
|
{
|
||||||
return func?.ToString();
|
return func?.ToString();
|
||||||
}
|
}
|
||||||
@@ -158,7 +193,9 @@ namespace WireMock.Serialization
|
|||||||
public static IMatcher Map([CanBeNull] MatcherModel matcher)
|
public static IMatcher Map([CanBeNull] MatcherModel matcher)
|
||||||
{
|
{
|
||||||
if (matcher == null)
|
if (matcher == null)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var parts = matcher.Name.Split('.');
|
var parts = matcher.Name.Split('.');
|
||||||
string matcherName = parts[0];
|
string matcherName = parts[0];
|
||||||
|
|||||||
@@ -2,23 +2,25 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
using WireMock.Admin.Requests;
|
using WireMock.Admin.Requests;
|
||||||
using WireMock.Admin.Settings;
|
using WireMock.Admin.Settings;
|
||||||
|
using WireMock.Http;
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
using WireMock.Matchers.Request;
|
using WireMock.Matchers.Request;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
using WireMock.ResponseBuilders;
|
using WireMock.ResponseBuilders;
|
||||||
|
using WireMock.Serialization;
|
||||||
|
using WireMock.Settings;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
using WireMock.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using WireMock.Settings;
|
|
||||||
using WireMock.Serialization;
|
|
||||||
|
|
||||||
namespace WireMock.Server
|
namespace WireMock.Server
|
||||||
{
|
{
|
||||||
@@ -28,6 +30,7 @@ namespace WireMock.Server
|
|||||||
public partial class FluentMockServer
|
public partial class FluentMockServer
|
||||||
{
|
{
|
||||||
private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings");
|
private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings");
|
||||||
|
private const string ContentTypeJson = "application/json";
|
||||||
private const string AdminMappings = "/__admin/mappings";
|
private const string AdminMappings = "/__admin/mappings";
|
||||||
private const string AdminRequests = "/__admin/requests";
|
private const string AdminRequests = "/__admin/requests";
|
||||||
private const string AdminSettings = "/__admin/settings";
|
private const string AdminSettings = "/__admin/settings";
|
||||||
@@ -41,56 +44,17 @@ namespace WireMock.Server
|
|||||||
NullValueHandling = NullValueHandling.Ignore,
|
NullValueHandling = NullValueHandling.Ignore,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
#region InitAdmin
|
||||||
/// Reads the static mappings from a folder.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
|
|
||||||
[PublicAPI]
|
|
||||||
public void ReadStaticMappings([CanBeNull] string folder = null)
|
|
||||||
{
|
|
||||||
if (folder == null)
|
|
||||||
folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
|
||||||
|
|
||||||
if (!Directory.Exists(folder))
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))
|
|
||||||
{
|
|
||||||
ReadStaticMapping(filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reads the static mapping.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filename">The filename.</param>
|
|
||||||
[PublicAPI]
|
|
||||||
public void ReadStaticMapping([NotNull] string filename)
|
|
||||||
{
|
|
||||||
Check.NotNull(filename, nameof(filename));
|
|
||||||
|
|
||||||
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(filename);
|
|
||||||
|
|
||||||
if (Guid.TryParse(filenameWithoutExtension, out var guidFromFilename))
|
|
||||||
{
|
|
||||||
DeserializeAndAddMapping(File.ReadAllText(filename), guidFromFilename);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DeserializeAndAddMapping(File.ReadAllText(filename));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitAdmin()
|
private void InitAdmin()
|
||||||
{
|
{
|
||||||
// __admin/settings
|
// __admin/settings
|
||||||
Given(Request.Create().WithPath(AdminSettings).UsingGet()).RespondWith(new DynamicResponseProvider(SettingsGet));
|
Given(Request.Create().WithPath(AdminSettings).UsingGet()).RespondWith(new DynamicResponseProvider(SettingsGet));
|
||||||
Given(Request.Create().WithPath(AdminSettings).UsingVerb("PUT", "POST").WithHeader("Content-Type", "application/json")).RespondWith(new DynamicResponseProvider(SettingsUpdate));
|
Given(Request.Create().WithPath(AdminSettings).UsingVerb("PUT", "POST").WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).RespondWith(new DynamicResponseProvider(SettingsUpdate));
|
||||||
|
|
||||||
|
|
||||||
// __admin/mappings
|
// __admin/mappings
|
||||||
Given(Request.Create().WithPath(AdminMappings).UsingGet()).RespondWith(new DynamicResponseProvider(MappingsGet));
|
Given(Request.Create().WithPath(AdminMappings).UsingGet()).RespondWith(new DynamicResponseProvider(MappingsGet));
|
||||||
Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader("Content-Type", "application/json")).RespondWith(new DynamicResponseProvider(MappingsPost));
|
Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).RespondWith(new DynamicResponseProvider(MappingsPost));
|
||||||
Given(Request.Create().WithPath(AdminMappings).UsingDelete()).RespondWith(new DynamicResponseProvider(MappingsDelete));
|
Given(Request.Create().WithPath(AdminMappings).UsingDelete()).RespondWith(new DynamicResponseProvider(MappingsDelete));
|
||||||
|
|
||||||
// __admin/mappings/reset
|
// __admin/mappings/reset
|
||||||
@@ -98,7 +62,7 @@ namespace WireMock.Server
|
|||||||
|
|
||||||
// __admin/mappings/{guid}
|
// __admin/mappings/{guid}
|
||||||
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponseProvider(MappingGet));
|
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponseProvider(MappingGet));
|
||||||
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingPut().WithHeader("Content-Type", "application/json")).RespondWith(new DynamicResponseProvider(MappingPut));
|
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).RespondWith(new DynamicResponseProvider(MappingPut));
|
||||||
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicResponseProvider(MappingDelete));
|
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicResponseProvider(MappingDelete));
|
||||||
|
|
||||||
// __admin/mappings/save
|
// __admin/mappings/save
|
||||||
@@ -127,39 +91,160 @@ namespace WireMock.Server
|
|||||||
// __admin/scenarios/reset
|
// __admin/scenarios/reset
|
||||||
Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).RespondWith(new DynamicResponseProvider(ScenariosReset));
|
Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).RespondWith(new DynamicResponseProvider(ScenariosReset));
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region StaticMappings
|
||||||
|
/// <summary>
|
||||||
|
/// Reads the static mappings from a folder.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
|
||||||
|
[PublicAPI]
|
||||||
|
public void ReadStaticMappings([CanBeNull] string folder = null)
|
||||||
|
{
|
||||||
|
if (folder == null)
|
||||||
|
{
|
||||||
|
folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(folder))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))
|
||||||
|
{
|
||||||
|
Log.InfoFormat("Reading Static MappingFile : '{0}'", filename);
|
||||||
|
ReadStaticMappingAndAddOrUpdate(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Watches the static mappings for changes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
|
||||||
|
[PublicAPI]
|
||||||
|
public void WatchStaticMappings([CanBeNull] string folder = null)
|
||||||
|
{
|
||||||
|
if (folder == null)
|
||||||
|
{
|
||||||
|
folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(folder))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.InfoFormat("Watching folder '{0}' for new, updated and deleted MappingFiles.", folder);
|
||||||
|
|
||||||
|
var watcher = new EnhancedFileSystemWatcher(folder, "*.json", 1000);
|
||||||
|
watcher.Created += (sender, args) =>
|
||||||
|
{
|
||||||
|
Log.InfoFormat("New MappingFile created : '{0}'", args.FullPath);
|
||||||
|
ReadStaticMappingAndAddOrUpdate(args.FullPath);
|
||||||
|
};
|
||||||
|
watcher.Changed += (sender, args) =>
|
||||||
|
{
|
||||||
|
Log.InfoFormat("New MappingFile updated : '{0}'", args.FullPath);
|
||||||
|
ReadStaticMappingAndAddOrUpdate(args.FullPath);
|
||||||
|
};
|
||||||
|
watcher.Deleted += (sender, args) =>
|
||||||
|
{
|
||||||
|
Log.InfoFormat("New MappingFile deleted : '{0}'", args.FullPath);
|
||||||
|
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(args.FullPath);
|
||||||
|
|
||||||
|
if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
|
||||||
|
{
|
||||||
|
DeleteMapping(guidFromFilename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeleteMapping(args.FullPath);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
watcher.EnableRaisingEvents = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a static mapping file and adds or updates the mapping.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path.</param>
|
||||||
|
[PublicAPI]
|
||||||
|
public void ReadStaticMappingAndAddOrUpdate([NotNull] string path)
|
||||||
|
{
|
||||||
|
Check.NotNull(path, nameof(path));
|
||||||
|
|
||||||
|
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);
|
||||||
|
|
||||||
|
MappingModel mappingModel = JsonConvert.DeserializeObject<MappingModel>(FileHelper.ReadAllText(path));
|
||||||
|
if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
|
||||||
|
{
|
||||||
|
DeserializeAndAddOrUpdateMapping(mappingModel, guidFromFilename, path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeserializeAndAddOrUpdateMapping(mappingModel, null, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Proxy and Record
|
#region Proxy and Record
|
||||||
private void InitProxyAndRecord(ProxyAndRecordSettings settings)
|
private HttpClient _httpClientForProxy;
|
||||||
|
|
||||||
|
private void InitProxyAndRecord(IProxyAndRecordSettings settings)
|
||||||
{
|
{
|
||||||
|
_httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ClientX509Certificate2ThumbprintOrSubjectName);
|
||||||
Given(Request.Create().WithPath("/*").UsingAnyVerb()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
|
Given(Request.Create().WithPath("/*").UsingAnyVerb()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, ProxyAndRecordSettings settings)
|
private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, IProxyAndRecordSettings settings)
|
||||||
{
|
{
|
||||||
var requestUri = new Uri(requestMessage.Url);
|
var requestUri = new Uri(requestMessage.Url);
|
||||||
var proxyUri = new Uri(settings.Url);
|
var proxyUri = new Uri(settings.Url);
|
||||||
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
|
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
|
||||||
|
|
||||||
var responseMessage = await HttpClientHelper.SendAsync(requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri, settings.X509Certificate2ThumbprintOrSubjectName);
|
var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
|
||||||
|
|
||||||
if (settings.SaveMapping)
|
if (settings.SaveMapping)
|
||||||
{
|
{
|
||||||
var mapping = ToMapping(requestMessage, responseMessage);
|
var mapping = ToMapping(requestMessage, responseMessage, settings.BlackListedHeaders ?? new string[] { });
|
||||||
SaveMappingToFile(mapping);
|
_options.Mappings.Add(mapping.Guid, mapping);
|
||||||
|
|
||||||
|
if (settings.SaveMappingToFile)
|
||||||
|
{
|
||||||
|
SaveMappingToFile(mapping);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return responseMessage;
|
return responseMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage)
|
private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage, string[] blacklistedHeaders)
|
||||||
{
|
{
|
||||||
var request = (Request)Request.Create();
|
var request = Request.Create();
|
||||||
request.WithPath(requestMessage.Path);
|
request.WithPath(requestMessage.Path);
|
||||||
request.UsingVerb(requestMessage.Method);
|
request.UsingVerb(requestMessage.Method);
|
||||||
|
|
||||||
var response = (Response)Response.Create(responseMessage);
|
requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray()));
|
||||||
|
requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, value));
|
||||||
|
|
||||||
return new Mapping(Guid.NewGuid(), string.Empty, request, response, 0, null, null, null);
|
requestMessage.Headers.Loop((key, value) =>
|
||||||
|
{
|
||||||
|
if (!blacklistedHeaders.Any(b => string.Equals(key, b, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
request.WithHeader(key, value.ToArray());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (requestMessage.Body != null)
|
||||||
|
{
|
||||||
|
request.WithBody(new ExactMatcher(requestMessage.Body));
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = Response.Create(responseMessage);
|
||||||
|
|
||||||
|
return new Mapping(Guid.NewGuid(), string.Empty, null, request, response, 0, null, null, null);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -179,7 +264,7 @@ namespace WireMock.Server
|
|||||||
|
|
||||||
private ResponseMessage SettingsUpdate(RequestMessage requestMessage)
|
private ResponseMessage SettingsUpdate(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
var settings = JsonConvert.DeserializeObject<SettingsModel>(requestMessage.Body);
|
var settings = requestMessage.Body != null ? JsonConvert.DeserializeObject<SettingsModel>(requestMessage.Body) : ((JObject)requestMessage.BodyAsJson).ToObject<SettingsModel>();
|
||||||
|
|
||||||
if (settings.AllowPartialMapping != null)
|
if (settings.AllowPartialMapping != null)
|
||||||
_options.AllowPartialMapping = settings.AllowPartialMapping.Value;
|
_options.AllowPartialMapping = settings.AllowPartialMapping.Value;
|
||||||
@@ -202,7 +287,10 @@ namespace WireMock.Server
|
|||||||
var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);
|
var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);
|
||||||
|
|
||||||
if (mapping == null)
|
if (mapping == null)
|
||||||
|
{
|
||||||
|
Log.Warn("HttpStatusCode set to 404 : Mapping not found");
|
||||||
return new ResponseMessage { StatusCode = 404, Body = "Mapping not found" };
|
return new ResponseMessage { StatusCode = 404, Body = "Mapping not found" };
|
||||||
|
}
|
||||||
|
|
||||||
var model = MappingConverter.ToMappingModel(mapping);
|
var model = MappingConverter.ToMappingModel(mapping);
|
||||||
|
|
||||||
@@ -212,23 +300,9 @@ namespace WireMock.Server
|
|||||||
private ResponseMessage MappingPut(RequestMessage requestMessage)
|
private ResponseMessage MappingPut(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));
|
Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));
|
||||||
var mappingModel = JsonConvert.DeserializeObject<MappingModel>(requestMessage.Body);
|
|
||||||
|
|
||||||
if (mappingModel.Request == null)
|
MappingModel mappingModel = requestMessage.Body != null ? JsonConvert.DeserializeObject<MappingModel>(requestMessage.Body) : ((JObject)requestMessage.BodyAsJson).ToObject<MappingModel>();
|
||||||
return new ResponseMessage { StatusCode = 400, Body = "Request missing" };
|
DeserializeAndAddOrUpdateMapping(mappingModel, guid);
|
||||||
|
|
||||||
if (mappingModel.Response == null)
|
|
||||||
return new ResponseMessage { StatusCode = 400, Body = "Response missing" };
|
|
||||||
|
|
||||||
var requestBuilder = InitRequestBuilder(mappingModel.Request);
|
|
||||||
var responseBuilder = InitResponseBuilder(mappingModel.Response);
|
|
||||||
|
|
||||||
IRespondWithAProvider respondProvider = Given(requestBuilder).WithGuid(guid);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(mappingModel.Title))
|
|
||||||
respondProvider = respondProvider.WithTitle(mappingModel.Title);
|
|
||||||
|
|
||||||
respondProvider.RespondWith(responseBuilder);
|
|
||||||
|
|
||||||
return new ResponseMessage { Body = "Mapping added or updated" };
|
return new ResponseMessage { Body = "Mapping added or updated" };
|
||||||
}
|
}
|
||||||
@@ -238,7 +312,9 @@ namespace WireMock.Server
|
|||||||
Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
|
Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
|
||||||
|
|
||||||
if (DeleteMapping(guid))
|
if (DeleteMapping(guid))
|
||||||
|
{
|
||||||
return new ResponseMessage { Body = "Mapping removed" };
|
return new ResponseMessage { Body = "Mapping removed" };
|
||||||
|
}
|
||||||
|
|
||||||
return new ResponseMessage { Body = "Mapping not found" };
|
return new ResponseMessage { Body = "Mapping not found" };
|
||||||
}
|
}
|
||||||
@@ -259,13 +335,17 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
string folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
string folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||||
if (!Directory.Exists(folder))
|
if (!Directory.Exists(folder))
|
||||||
|
{
|
||||||
Directory.CreateDirectory(folder);
|
Directory.CreateDirectory(folder);
|
||||||
|
}
|
||||||
|
|
||||||
var model = MappingConverter.ToMappingModel(mapping);
|
var model = MappingConverter.ToMappingModel(mapping);
|
||||||
string json = JsonConvert.SerializeObject(model, _settings);
|
|
||||||
string filename = !string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToString();
|
string filename = !string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToString();
|
||||||
|
|
||||||
File.WriteAllText(Path.Combine(folder, filename + ".json"), json);
|
string filePath = Path.Combine(folder, filename + ".json");
|
||||||
|
Log.InfoFormat("Saving Mapping to file {0}", filePath);
|
||||||
|
|
||||||
|
File.WriteAllText(filePath, JsonConvert.SerializeObject(model, _settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string SanitizeFileName(string name, char replaceChar = '_')
|
private static string SanitizeFileName(string name, char replaceChar = '_')
|
||||||
@@ -289,24 +369,25 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DeserializeAndAddMapping(requestMessage.Body);
|
MappingModel mappingModel = requestMessage.Body != null ? JsonConvert.DeserializeObject<MappingModel>(requestMessage.Body) : ((JObject)requestMessage.BodyAsJson).ToObject<MappingModel>();
|
||||||
|
DeserializeAndAddOrUpdateMapping(mappingModel);
|
||||||
}
|
}
|
||||||
catch (ArgumentException a)
|
catch (ArgumentException a)
|
||||||
{
|
{
|
||||||
|
Log.Error("HttpStatusCode set to 400", a);
|
||||||
return new ResponseMessage { StatusCode = 400, Body = a.Message };
|
return new ResponseMessage { StatusCode = 400, Body = a.Message };
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
Log.Error("HttpStatusCode set to 500", e);
|
||||||
return new ResponseMessage { StatusCode = 500, Body = e.ToString() };
|
return new ResponseMessage { StatusCode = 500, Body = e.ToString() };
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ResponseMessage { StatusCode = 201, Body = "Mapping added" };
|
return new ResponseMessage { StatusCode = 201, Body = "Mapping added" };
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeserializeAndAddMapping(string json, Guid? guid = null)
|
private void DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null)
|
||||||
{
|
{
|
||||||
var mappingModel = JsonConvert.DeserializeObject<MappingModel>(json);
|
|
||||||
|
|
||||||
Check.NotNull(mappingModel, nameof(mappingModel));
|
Check.NotNull(mappingModel, nameof(mappingModel));
|
||||||
Check.NotNull(mappingModel.Request, nameof(mappingModel.Request));
|
Check.NotNull(mappingModel.Request, nameof(mappingModel.Request));
|
||||||
Check.NotNull(mappingModel.Response, nameof(mappingModel.Response));
|
Check.NotNull(mappingModel.Response, nameof(mappingModel.Response));
|
||||||
@@ -325,11 +406,20 @@ namespace WireMock.Server
|
|||||||
respondProvider = respondProvider.WithGuid(mappingModel.Guid.Value);
|
respondProvider = respondProvider.WithGuid(mappingModel.Guid.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (path != null)
|
||||||
|
{
|
||||||
|
respondProvider = respondProvider.WithPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(mappingModel.Title))
|
if (!string.IsNullOrEmpty(mappingModel.Title))
|
||||||
|
{
|
||||||
respondProvider = respondProvider.WithTitle(mappingModel.Title);
|
respondProvider = respondProvider.WithTitle(mappingModel.Title);
|
||||||
|
}
|
||||||
|
|
||||||
if (mappingModel.Priority != null)
|
if (mappingModel.Priority != null)
|
||||||
|
{
|
||||||
respondProvider = respondProvider.AtPriority(mappingModel.Priority.Value);
|
respondProvider = respondProvider.AtPriority(mappingModel.Priority.Value);
|
||||||
|
}
|
||||||
|
|
||||||
if (mappingModel.Scenario != null)
|
if (mappingModel.Scenario != null)
|
||||||
{
|
{
|
||||||
@@ -358,7 +448,10 @@ namespace WireMock.Server
|
|||||||
var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid);
|
var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid);
|
||||||
|
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
return new ResponseMessage { StatusCode = 404, Body = "Request not found" };
|
{
|
||||||
|
Log.Warn("HttpStatusCode set to 404 : Request not found");
|
||||||
|
return new ResponseMessage {StatusCode = 404, Body = "Request not found"};
|
||||||
|
}
|
||||||
|
|
||||||
var model = ToLogEntryModel(entry);
|
var model = ToLogEntryModel(entry);
|
||||||
|
|
||||||
@@ -400,6 +493,8 @@ namespace WireMock.Server
|
|||||||
Query = logEntry.RequestMessage.Query,
|
Query = logEntry.RequestMessage.Query,
|
||||||
Method = logEntry.RequestMessage.Method,
|
Method = logEntry.RequestMessage.Method,
|
||||||
Body = logEntry.RequestMessage.Body,
|
Body = logEntry.RequestMessage.Body,
|
||||||
|
BodyAsJson = logEntry.RequestMessage.BodyAsJson,
|
||||||
|
BodyAsBytes = logEntry.RequestMessage.BodyAsBytes,
|
||||||
Headers = logEntry.RequestMessage.Headers,
|
Headers = logEntry.RequestMessage.Headers,
|
||||||
Cookies = logEntry.RequestMessage.Cookies,
|
Cookies = logEntry.RequestMessage.Cookies,
|
||||||
BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel
|
BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel
|
||||||
@@ -412,8 +507,13 @@ namespace WireMock.Server
|
|||||||
Response = new LogResponseModel
|
Response = new LogResponseModel
|
||||||
{
|
{
|
||||||
StatusCode = logEntry.ResponseMessage.StatusCode,
|
StatusCode = logEntry.ResponseMessage.StatusCode,
|
||||||
|
BodyDestination = logEntry.ResponseMessage.BodyDestination,
|
||||||
Body = logEntry.ResponseMessage.Body,
|
Body = logEntry.ResponseMessage.Body,
|
||||||
|
BodyAsJson = logEntry.ResponseMessage.BodyAsJson,
|
||||||
|
BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
|
||||||
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
|
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
|
||||||
|
BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
|
||||||
|
BodyAsFileIsCached = logEntry.ResponseMessage.BodyAsFileIsCached,
|
||||||
Headers = logEntry.ResponseMessage.Headers,
|
Headers = logEntry.ResponseMessage.Headers,
|
||||||
BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
|
BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
|
||||||
{
|
{
|
||||||
@@ -450,7 +550,7 @@ namespace WireMock.Server
|
|||||||
#region Requests/find
|
#region Requests/find
|
||||||
private ResponseMessage RequestsFind(RequestMessage requestMessage)
|
private ResponseMessage RequestsFind(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
var requestModel = JsonConvert.DeserializeObject<RequestModel>(requestMessage.Body);
|
var requestModel = requestMessage.Body != null ? JsonConvert.DeserializeObject<RequestModel>(requestMessage.Body) : ((JObject)requestMessage.BodyAsJson).ToObject<RequestModel>();
|
||||||
|
|
||||||
var request = (Request)InitRequestBuilder(requestModel);
|
var request = (Request)InitRequestBuilder(requestModel);
|
||||||
|
|
||||||
@@ -464,7 +564,7 @@ namespace WireMock.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key);
|
var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(ToLogEntryModel);
|
||||||
|
|
||||||
return ToJson(result);
|
return ToJson(result);
|
||||||
}
|
}
|
||||||
@@ -506,7 +606,7 @@ namespace WireMock.Server
|
|||||||
var clientIPModel = JsonUtils.ParseJTokenToObject<ClientIPModel>(requestModel.ClientIP);
|
var clientIPModel = JsonUtils.ParseJTokenToObject<ClientIPModel>(requestModel.ClientIP);
|
||||||
if (clientIPModel?.Matchers != null)
|
if (clientIPModel?.Matchers != null)
|
||||||
{
|
{
|
||||||
requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MappingConverter.Map).ToArray());
|
requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -515,12 +615,16 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
string path = requestModel.Path as string;
|
string path = requestModel.Path as string;
|
||||||
if (path != null)
|
if (path != null)
|
||||||
|
{
|
||||||
requestBuilder = requestBuilder.WithPath(path);
|
requestBuilder = requestBuilder.WithPath(path);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(requestModel.Path);
|
var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(requestModel.Path);
|
||||||
if (pathModel?.Matchers != null)
|
if (pathModel?.Matchers != null)
|
||||||
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MappingConverter.Map).ToArray());
|
{
|
||||||
|
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,23 +632,29 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
string url = requestModel.Url as string;
|
string url = requestModel.Url as string;
|
||||||
if (url != null)
|
if (url != null)
|
||||||
|
{
|
||||||
requestBuilder = requestBuilder.WithUrl(url);
|
requestBuilder = requestBuilder.WithUrl(url);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(requestModel.Url);
|
var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(requestModel.Url);
|
||||||
if (urlModel?.Matchers != null)
|
if (urlModel?.Matchers != null)
|
||||||
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MappingConverter.Map).ToArray());
|
{
|
||||||
|
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestModel.Methods != null)
|
if (requestModel.Methods != null)
|
||||||
|
{
|
||||||
requestBuilder = requestBuilder.UsingVerb(requestModel.Methods);
|
requestBuilder = requestBuilder.UsingVerb(requestModel.Methods);
|
||||||
|
}
|
||||||
|
|
||||||
if (requestModel.Headers != null)
|
if (requestModel.Headers != null)
|
||||||
{
|
{
|
||||||
foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))
|
foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))
|
||||||
{
|
{
|
||||||
requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MappingConverter.Map).ToArray());
|
requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,7 +662,7 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
|
foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
|
||||||
{
|
{
|
||||||
requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MappingConverter.Map).ToArray());
|
requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,7 +709,12 @@ namespace WireMock.Server
|
|||||||
|
|
||||||
if (responseModel.Headers != null)
|
if (responseModel.Headers != null)
|
||||||
{
|
{
|
||||||
responseBuilder = responseBuilder.WithHeaders(responseModel.Headers);
|
foreach (var entry in responseModel.Headers)
|
||||||
|
{
|
||||||
|
responseBuilder = entry.Value is string value ?
|
||||||
|
responseBuilder.WithHeader(entry.Key, value) :
|
||||||
|
responseBuilder.WithHeader(entry.Key, JsonUtils.ParseJTokenToObject<string[]>(entry.Value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (responseModel.HeadersRaw != null)
|
else if (responseModel.HeadersRaw != null)
|
||||||
{
|
{
|
||||||
@@ -612,17 +727,21 @@ namespace WireMock.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseModel.Body != null)
|
if (responseModel.BodyAsBytes != null)
|
||||||
{
|
{
|
||||||
responseBuilder = responseBuilder.WithBody(responseModel.Body, ToEncoding(responseModel.BodyEncoding));
|
responseBuilder = responseBuilder.WithBody(responseModel.BodyAsBytes, responseModel.BodyDestination, ToEncoding(responseModel.BodyEncoding));
|
||||||
|
}
|
||||||
|
else if (responseModel.Body != null)
|
||||||
|
{
|
||||||
|
responseBuilder = responseBuilder.WithBody(responseModel.Body, responseModel.BodyDestination, ToEncoding(responseModel.BodyEncoding));
|
||||||
}
|
}
|
||||||
else if (responseModel.BodyAsJson != null)
|
else if (responseModel.BodyAsJson != null)
|
||||||
{
|
{
|
||||||
responseBuilder = responseBuilder.WithBodyAsJson(responseModel.BodyAsJson, ToEncoding(responseModel.BodyEncoding));
|
responseBuilder = responseBuilder.WithBodyAsJson(responseModel.BodyAsJson, ToEncoding(responseModel.BodyEncoding));
|
||||||
}
|
}
|
||||||
else if (responseModel.BodyAsBase64 != null)
|
else if (responseModel.BodyFromBase64 != null)
|
||||||
{
|
{
|
||||||
responseBuilder = responseBuilder.WithBodyAsBase64(responseModel.BodyAsBase64, ToEncoding(responseModel.BodyEncoding));
|
responseBuilder = responseBuilder.WithBodyFromBase64(responseModel.BodyFromBase64, ToEncoding(responseModel.BodyEncoding));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseModel.UseTransformer)
|
if (responseModel.UseTransformer)
|
||||||
@@ -639,7 +758,7 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
Body = JsonConvert.SerializeObject(result, _settings),
|
Body = JsonConvert.SerializeObject(result, _settings),
|
||||||
StatusCode = 200,
|
StatusCode = 200,
|
||||||
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } }
|
Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMockList<string>("application/json") } }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace WireMock.Server
|
|||||||
public partial class FluentMockServer
|
public partial class FluentMockServer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Log entries notification handler
|
/// Occurs when [log entries changed].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public event NotifyCollectionChangedEventHandler LogEntriesChanged
|
public event NotifyCollectionChangedEventHandler LogEntriesChanged
|
||||||
@@ -66,7 +66,7 @@ namespace WireMock.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the mapping.
|
/// Deletes a LogEntry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="guid">The unique identifier.</param>
|
/// <param name="guid">The unique identifier.</param>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using log4net;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using WireMock.Http;
|
using WireMock.Http;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
using WireMock.Matchers.Request;
|
using WireMock.Matchers.Request;
|
||||||
@@ -21,16 +23,20 @@ namespace WireMock.Server
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class FluentMockServer : IDisposable
|
public partial class FluentMockServer : IDisposable
|
||||||
{
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(FluentMockServer));
|
||||||
private const int ServerStartDelay = 100;
|
private const int ServerStartDelay = 100;
|
||||||
private readonly IOwinSelfHost _httpServer;
|
private readonly IOwinSelfHost _httpServer;
|
||||||
private readonly WireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
|
private readonly WireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this server is started.
|
||||||
|
/// </summary>
|
||||||
|
[PublicAPI]
|
||||||
|
public bool IsStarted { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ports.
|
/// Gets the ports.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The ports.
|
|
||||||
/// </value>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public List<int> Ports { get; }
|
public List<int> Ports { get; }
|
||||||
|
|
||||||
@@ -44,7 +50,7 @@ namespace WireMock.Server
|
|||||||
/// Gets the mappings.
|
/// Gets the mappings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IEnumerable<Mapping> Mappings => new ReadOnlyCollection<Mapping>(_options.Mappings);
|
public IEnumerable<Mapping> Mappings => _options.Mappings.Values.ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the scenarios.
|
/// Gets the scenarios.
|
||||||
@@ -59,7 +65,7 @@ namespace WireMock.Server
|
|||||||
/// <param name="settings">The FluentMockServerSettings.</param>
|
/// <param name="settings">The FluentMockServerSettings.</param>
|
||||||
/// <returns>The <see cref="FluentMockServer"/>.</returns>
|
/// <returns>The <see cref="FluentMockServer"/>.</returns>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static FluentMockServer Start(FluentMockServerSettings settings)
|
public static FluentMockServer Start(IFluentMockServerSettings settings)
|
||||||
{
|
{
|
||||||
Check.NotNull(settings, nameof(settings));
|
Check.NotNull(settings, nameof(settings));
|
||||||
|
|
||||||
@@ -90,7 +96,7 @@ namespace WireMock.Server
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static FluentMockServer Start(params string[] urls)
|
public static FluentMockServer Start(params string[] urls)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(urls, nameof(urls));
|
Check.NotNullOrEmpty(urls, nameof(urls));
|
||||||
|
|
||||||
return new FluentMockServer(new FluentMockServerSettings
|
return new FluentMockServer(new FluentMockServerSettings
|
||||||
{
|
{
|
||||||
@@ -123,7 +129,7 @@ namespace WireMock.Server
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static FluentMockServer StartWithAdminInterface(params string[] urls)
|
public static FluentMockServer StartWithAdminInterface(params string[] urls)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(urls, nameof(urls));
|
Check.NotNullOrEmpty(urls, nameof(urls));
|
||||||
|
|
||||||
return new FluentMockServer(new FluentMockServerSettings
|
return new FluentMockServer(new FluentMockServerSettings
|
||||||
{
|
{
|
||||||
@@ -140,7 +146,7 @@ namespace WireMock.Server
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static FluentMockServer StartWithAdminInterfaceAndReadStaticMappings(params string[] urls)
|
public static FluentMockServer StartWithAdminInterfaceAndReadStaticMappings(params string[] urls)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(urls, nameof(urls));
|
Check.NotNullOrEmpty(urls, nameof(urls));
|
||||||
|
|
||||||
return new FluentMockServer(new FluentMockServerSettings
|
return new FluentMockServer(new FluentMockServerSettings
|
||||||
{
|
{
|
||||||
@@ -150,11 +156,13 @@ namespace WireMock.Server
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private FluentMockServer(FluentMockServerSettings settings)
|
private FluentMockServer(IFluentMockServerSettings settings)
|
||||||
{
|
{
|
||||||
|
Log.DebugFormat("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
|
||||||
|
|
||||||
if (settings.Urls != null)
|
if (settings.Urls != null)
|
||||||
{
|
{
|
||||||
Urls = settings.Urls;
|
Urls = settings.Urls.Select(u => u.EndsWith("/") ? u : $"{u}/").ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -162,11 +170,16 @@ namespace WireMock.Server
|
|||||||
Urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" };
|
Urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
|
||||||
|
_options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
|
||||||
|
|
||||||
#if NETSTANDARD
|
#if NETSTANDARD
|
||||||
_httpServer = new AspNetCoreSelfHost(_options, Urls);
|
_httpServer = new AspNetCoreSelfHost(_options, Urls);
|
||||||
#else
|
#else
|
||||||
_httpServer = new OwinSelfHost(_options, Urls);
|
_httpServer = new OwinSelfHost(_options, Urls);
|
||||||
#endif
|
#endif
|
||||||
|
IsStarted = _httpServer.IsStarted;
|
||||||
|
|
||||||
Ports = _httpServer.Ports;
|
Ports = _httpServer.Ports;
|
||||||
|
|
||||||
_httpServer.StartAsync();
|
_httpServer.StartAsync();
|
||||||
@@ -194,6 +207,11 @@ namespace WireMock.Server
|
|||||||
ReadStaticMappings();
|
ReadStaticMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.WatchStaticMappings == true)
|
||||||
|
{
|
||||||
|
WatchStaticMappings();
|
||||||
|
}
|
||||||
|
|
||||||
if (settings.ProxyAndRecordSettings != null)
|
if (settings.ProxyAndRecordSettings != null)
|
||||||
{
|
{
|
||||||
InitProxyAndRecord(settings.ProxyAndRecordSettings);
|
InitProxyAndRecord(settings.ProxyAndRecordSettings);
|
||||||
@@ -255,7 +273,10 @@ namespace WireMock.Server
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public void ResetMappings()
|
public void ResetMappings()
|
||||||
{
|
{
|
||||||
_options.Mappings = _options.Mappings.Where(m => m.IsAdminInterface).ToList();
|
foreach (var nonAdmin in _options.Mappings.Where(m => !m.Value.IsAdminInterface))
|
||||||
|
{
|
||||||
|
_options.Mappings.Remove(nonAdmin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -266,16 +287,21 @@ namespace WireMock.Server
|
|||||||
public bool DeleteMapping(Guid guid)
|
public bool DeleteMapping(Guid guid)
|
||||||
{
|
{
|
||||||
// Check a mapping exists with the same GUID, if so, remove it.
|
// Check a mapping exists with the same GUID, if so, remove it.
|
||||||
var existingMapping = _options.Mappings.FirstOrDefault(m => m.Guid == guid);
|
if (_options.Mappings.ContainsKey(guid))
|
||||||
if (existingMapping != null)
|
|
||||||
{
|
{
|
||||||
_options.Mappings.Remove(existingMapping);
|
return _options.Mappings.Remove(guid);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool DeleteMapping(string path)
|
||||||
|
{
|
||||||
|
// Check a mapping exists with the same path, if so, remove it.
|
||||||
|
var mapping = _options.Mappings.FirstOrDefault(entry => string.Equals(entry.Value.Path, path, StringComparison.OrdinalIgnoreCase));
|
||||||
|
return DeleteMapping(mapping.Key);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The add request processing delay.
|
/// The add request processing delay.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -290,9 +316,10 @@ namespace WireMock.Server
|
|||||||
/// Allows the partial mapping.
|
/// Allows the partial mapping.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public void AllowPartialMapping()
|
public void AllowPartialMapping(bool allow = true)
|
||||||
{
|
{
|
||||||
_options.AllowPartialMapping = true;
|
Log.InfoFormat("AllowPartialMapping is set to {0}", allow);
|
||||||
|
_options.AllowPartialMapping = allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -360,18 +387,17 @@ namespace WireMock.Server
|
|||||||
return new RespondWithAProvider(RegisterMapping, requestMatcher);
|
return new RespondWithAProvider(RegisterMapping, requestMatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The register mapping.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="mapping">
|
|
||||||
/// The mapping.
|
|
||||||
/// </param>
|
|
||||||
private void RegisterMapping(Mapping mapping)
|
private void RegisterMapping(Mapping mapping)
|
||||||
{
|
{
|
||||||
// Check a mapping exists with the same GUID, if so, remove it first.
|
// Check a mapping exists with the same Guid, if so, replace it.
|
||||||
DeleteMapping(mapping.Guid);
|
if (_options.Mappings.ContainsKey(mapping.Guid))
|
||||||
|
{
|
||||||
_options.Mappings.Add(mapping);
|
_options.Mappings[mapping.Guid] = mapping;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_options.Mappings.Add(mapping.Guid, mapping);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user