mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-02-25 10:15:04 +01:00
Compare commits
27 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 |
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
|
||||||
16
README.md
16
README.md
@@ -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.27004.2010
|
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,14 +9,13 @@ 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
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{F0C22C47-DF71-463C-9B04-B4E0F3B8708A}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{F0C22C47-DF71-463C-9B04-B4E0F3B8708A}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
examples\WireMock.Net.Console.Record.NETCoreApp\__admin\mappings\ab38efae-4e4d-4f20-8afe-635533ec2535.json = examples\WireMock.Net.Console.Record.NETCoreApp\__admin\mappings\ab38efae-4e4d-4f20-8afe-635533ec2535.json
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{890A1DED-C229-4FA1-969E-AAC3BBFC05E5}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{890A1DED-C229-4FA1-969E-AAC3BBFC05E5}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -26,7 +25,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Tests", "test\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NETCoreApp", "examples\WireMock.Net.Console.NETCoreApp\WireMock.Net.Console.NETCoreApp.csproj", "{FE281639-B014-4C8A-96FA-141164A74713}"
|
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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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
|
||||||
@@ -41,6 +40,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.StandAlone.Net
|
|||||||
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}"
|
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
|
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
|
||||||
@@ -83,6 +88,18 @@ Global
|
|||||||
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
|
||||||
{668F689E-57B4-422E-8846-C0FF643CA268}.Release|Any CPU.Build.0 = 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
|
||||||
@@ -97,6 +114,9 @@ Global
|
|||||||
{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}
|
{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
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {BF428BCC-C837-433B-87D2-15C7014B73E9}
|
SolutionGuid = {BF428BCC-C837-433B-87D2-15C7014B73E9}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,10 +22,17 @@
|
|||||||
|
|
||||||
<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>
|
||||||
|
|
||||||
<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">
|
<None Update="__admin\mappings\791a3f31-6946-4ce7-8e6f-0237c7443275.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
},
|
},
|
||||||
"UseTransformer": false,
|
"UseTransformer": false,
|
||||||
"Headers": {
|
"Headers": {
|
||||||
"Date": "Wed, 25 Oct 2017 18:57:40 GMT",
|
"Date": "Wed, 27 Oct 2017 18:57:40 GMT",
|
||||||
"Alt-Svc": "quic=\":443\"; ma=2592000; v=\"39,38,37,35\"",
|
"Alt-Svc": "quic=\":443\"; ma=2592000; v=\"39,38,37,35\"",
|
||||||
"Referrer-Policy": "no-referrer",
|
"Referrer-Policy": "no-referrer",
|
||||||
"Connection": "close"
|
"Connection": "close"
|
||||||
|
|||||||
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
|
||||||
{
|
{
|
||||||
@@ -16,9 +16,10 @@ namespace WireMock.Net.Console.Record.NETCoreApp
|
|||||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
{
|
{
|
||||||
Url = "https://www.google.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
|
SaveMappingToFile = false,
|
||||||
|
BlackListedHeaders = new [] { "dnt", "Content-Length" }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,9 @@
|
|||||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="CommandLineArgumentsParser" Version="3.0.10" />
|
|
||||||
</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.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -21,6 +21,7 @@ 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
|
//ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
//{
|
//{
|
||||||
// SaveMapping = true
|
// SaveMapping = true
|
||||||
@@ -28,7 +29,7 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
PreWireMockMiddlewareInit = app => { System.Console.WriteLine($"PreWireMockMiddlewareInit : {app.GetType()}"); },
|
PreWireMockMiddlewareInit = app => { System.Console.WriteLine($"PreWireMockMiddlewareInit : {app.GetType()}"); },
|
||||||
PostWireMockMiddlewareInit = app => { System.Console.WriteLine($"PostWireMockMiddlewareInit : {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");
|
||||||
|
|
||||||
@@ -40,6 +41,15 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
// .RespondWith(Response.Create()
|
// .RespondWith(Response.Create()
|
||||||
// .WithProxy("http://restcountries.eu"));
|
// .WithProxy("http://restcountries.eu"));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request
|
||||||
|
.Create()
|
||||||
|
.WithPath("/jsonthings")
|
||||||
|
.WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]"))
|
||||||
|
.UsingPut())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBody(@"{ ""result"": ""JsonPathMatcher !!!""}"));
|
||||||
|
|
||||||
server
|
server
|
||||||
.Given(Request
|
.Given(Request
|
||||||
.Create()
|
.Create()
|
||||||
@@ -53,8 +63,9 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
.Given(Request.Create().WithPath("/headers", "/headers_test").UsingPost().WithHeader("Content-Type", "application/json*"))
|
.Given(Request.Create().WithPath("/headers", "/headers_test").UsingPost().WithHeader("Content-Type", "application/json*"))
|
||||||
.RespondWith(Response.Create()
|
.RespondWith(Response.Create()
|
||||||
.WithStatusCode(201)
|
.WithStatusCode(201)
|
||||||
.WithHeader("MyHeader", "application/json", "application/json2")
|
//.WithHeader("MyHeader", "application/json", "application/json2")
|
||||||
.WithBody(@"{ ""result"": ""data posted with 201""}"));
|
.WithHeader("Content-Type", "application/json")
|
||||||
|
.WithBodyAsJson(new { result = "data:headers posted with 201" }));
|
||||||
|
|
||||||
server
|
server
|
||||||
.Given(Request.Create().WithPath("/file").UsingGet())
|
.Given(Request.Create().WithPath("/file").UsingGet())
|
||||||
@@ -116,7 +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
|
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,17 +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="System.XML" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="MainApp.cs" />
|
<Compile Include="MainApp.cs" />
|
||||||
@@ -57,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>
|
||||||
|
|||||||
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"),
|
||||||
@@ -67,15 +69,14 @@ namespace WireMock.Net.StandAlone
|
|||||||
Url = proxyURL,
|
Url = proxyURL,
|
||||||
SaveMapping = parser.GetBoolValue("SaveMapping"),
|
SaveMapping = parser.GetBoolValue("SaveMapping"),
|
||||||
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
|
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
|
||||||
X509Certificate2ThumbprintOrSubjectName = parser.GetStringValue("X509Certificate2ThumbprintOrSubjectName")
|
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,26 +1,32 @@
|
|||||||
<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.10</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>
|
||||||
<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>
|
||||||
@@ -30,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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,52 +11,62 @@ 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.
|
/// The Path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the absolete URL.
|
///The absolete URL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
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.
|
/// The method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Method { get; set; }
|
public string Method { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Headers.
|
/// The Headers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, WireMockList<string>> Headers { get; set; }
|
public IDictionary<string, WireMockList<string>> Headers { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Cookies.
|
/// Tthe Cookies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
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>
|
||||||
public string Body { get; set; }
|
public string Body { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets 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>
|
||||||
|
/// The body encoding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EncodingModel BodyEncoding { get; set; }
|
public EncodingModel BodyEncoding { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,12 +25,17 @@ namespace WireMock.Admin.Requests
|
|||||||
public string BodyDestination { get; set; }
|
public string BodyDestination { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body.
|
/// The body (as string).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Body { get; set; }
|
public string Body { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the body as bytes.
|
/// The body (as JSON object).
|
||||||
|
/// </summary>
|
||||||
|
public object BodyAsJson { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body (as bytearray).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte[] BodyAsBytes { get; set; }
|
public byte[] BodyAsBytes { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -137,6 +138,7 @@ 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")]
|
||||||
|
[Header("Content-Type", "application/json")]
|
||||||
Task<IList<LogEntryModel>> FindRequestsAsync([Body] RequestModel model);
|
Task<IList<LogEntryModel>> FindRequestsAsync([Body] RequestModel model);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -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,7 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using WireMock.HttpsCertificate;
|
||||||
|
using WireMock.Util;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
|
|
||||||
namespace WireMock.Http
|
namespace WireMock.Http
|
||||||
@@ -10,37 +16,28 @@ namespace WireMock.Http
|
|||||||
{
|
{
|
||||||
public static HttpClient CreateHttpClient(string clientX509Certificate2ThumbprintOrSubjectName = null)
|
public static HttpClient CreateHttpClient(string clientX509Certificate2ThumbprintOrSubjectName = null)
|
||||||
{
|
{
|
||||||
HttpClientHandler handler;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(clientX509Certificate2ThumbprintOrSubjectName))
|
|
||||||
{
|
|
||||||
handler = new HttpClientHandler();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if NETSTANDARD || NET46
|
#if NETSTANDARD || NET46
|
||||||
handler = new HttpClientHandler
|
var handler = new HttpClientHandler
|
||||||
{
|
{
|
||||||
ClientCertificateOptions = ClientCertificateOption.Manual,
|
CheckCertificateRevocationList = false,
|
||||||
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
|
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
|
||||||
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
|
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
|
||||||
};
|
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||||
|
};
|
||||||
var x509Certificate2 = CertificateUtil.GetCertificate(clientX509Certificate2ThumbprintOrSubjectName);
|
|
||||||
handler.ClientCertificates.Add(x509Certificate2);
|
|
||||||
#else
|
#else
|
||||||
|
var handler = new WebRequestHandler
|
||||||
var webRequestHandler = new WebRequestHandler
|
{
|
||||||
{
|
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
|
||||||
ClientCertificateOptions = ClientCertificateOption.Manual,
|
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||||
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
|
};
|
||||||
AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate
|
|
||||||
};
|
|
||||||
|
|
||||||
var x509Certificate2 = CertificateUtil.GetCertificate(clientX509Certificate2ThumbprintOrSubjectName);
|
|
||||||
webRequestHandler.ClientCertificates.Add(x509Certificate2);
|
|
||||||
handler = webRequestHandler;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(clientX509Certificate2ThumbprintOrSubjectName))
|
||||||
|
{
|
||||||
|
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
|
||||||
|
|
||||||
|
var x509Certificate2 = ClientCertificateHelper.GetCertificate(clientX509Certificate2ThumbprintOrSubjectName);
|
||||||
|
handler.ClientCertificates.Add(x509Certificate2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For proxy we shouldn't follow auto redirects
|
// For proxy we shouldn't follow auto redirects
|
||||||
@@ -49,23 +46,43 @@ namespace WireMock.Http
|
|||||||
// If UseCookies enabled, httpClient ignores Cookie header
|
// If UseCookies enabled, httpClient ignores Cookie header
|
||||||
handler.UseCookies = false;
|
handler.UseCookies = false;
|
||||||
|
|
||||||
return new HttpClient(handler);
|
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(HttpClient client, RequestMessage requestMessage, string url)
|
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url)
|
||||||
{
|
{
|
||||||
Check.NotNull(client, nameof(client));
|
Check.NotNull(client, nameof(client));
|
||||||
|
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||||
|
|
||||||
var originalUri = new Uri(requestMessage.Url);
|
var originalUri = new Uri(requestMessage.Url);
|
||||||
var requiredUri = new Uri(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
|
// Set Body if present
|
||||||
if (requestMessage.BodyAsBytes != null && requestMessage.BodyAsBytes.Length > 0)
|
if (requestMessage.BodyAsBytes != null)
|
||||||
{
|
{
|
||||||
httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);
|
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 = requiredUri.Authority;
|
httpRequestMessage.Headers.Host = requiredUri.Authority;
|
||||||
@@ -86,23 +103,25 @@ namespace WireMock.Http
|
|||||||
// Call the URL
|
// Call the URL
|
||||||
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
|
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
|
||||||
|
|
||||||
// Transform response
|
// Create transform response
|
||||||
var responseMessage = new ResponseMessage
|
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
|
||||||
{
|
|
||||||
StatusCode = (int)httpResponseMessage.StatusCode,
|
|
||||||
|
|
||||||
BodyAsBytes = await httpResponseMessage.Content.ReadAsByteArrayAsync(),
|
|
||||||
Body = await httpResponseMessage.Content.ReadAsStringAsync()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set both content and response headers, replacing URLs in values
|
// Set both content and response headers, replacing URLs in values
|
||||||
var headers = httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers);
|
var headers = (httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers) ?? Enumerable.Empty<KeyValuePair<string, IEnumerable<string>>>()).ToArray();
|
||||||
|
if (httpResponseMessage.Content != null)
|
||||||
|
{
|
||||||
|
var stream = await httpResponseMessage.Content.ReadAsStreamAsync();
|
||||||
|
var body = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
|
||||||
|
responseMessage.Body = body.BodyAsString;
|
||||||
|
responseMessage.BodyAsJson = body.BodyAsJson;
|
||||||
|
responseMessage.BodyAsBytes = body.BodyAsBytes;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var header in headers)
|
foreach (var header in headers)
|
||||||
{
|
{
|
||||||
// if Location header contains absolute redirect URL, and base URL is one that we proxy to,
|
// If Location header contains absolute redirect URL, and base URL is one that we proxy to,
|
||||||
// we need to replace it to original one.
|
// we need to replace it to original one.
|
||||||
if (string.Equals(header.Key, "Location", StringComparison.OrdinalIgnoreCase)
|
if (string.Equals(header.Key, HttpKnownHeaderNames.Location, StringComparison.OrdinalIgnoreCase)
|
||||||
&& Uri.TryCreate(header.Value.First(), UriKind.Absolute, out Uri absoluteLocationUri)
|
&& Uri.TryCreate(header.Value.First(), UriKind.Absolute, out Uri absoluteLocationUri)
|
||||||
&& string.Equals(absoluteLocationUri.Host, requiredUri.Host, StringComparison.OrdinalIgnoreCase))
|
&& string.Equals(absoluteLocationUri.Host, requiredUri.Host, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,11 @@ namespace WireMock
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
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>
|
||||||
@@ -63,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)).Cast<IMatcher>().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;
|
||||||
@@ -59,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));
|
||||||
|
|||||||
@@ -26,7 +26,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="RequestMessageHeaderMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||||
@@ -40,7 +40,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>
|
||||||
@@ -55,7 +55,7 @@ namespace WireMock.Matchers.Request
|
|||||||
Check.NotNull(patterns, nameof(patterns));
|
Check.NotNull(patterns, nameof(patterns));
|
||||||
|
|
||||||
Name = name;
|
Name = name;
|
||||||
Matchers = patterns.Select(pattern => new WildcardMatcher(pattern, ignoreCase)).Cast<IMatcher>().ToArray();
|
Matchers = patterns.Select(pattern => new WildcardMatcher(pattern, ignoreCase)).Cast<IStringMatcher>().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -63,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));
|
||||||
@@ -93,16 +93,24 @@ 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.ToDictionary(entry => entry.Key, entry => entry.Value.ToArray()))));
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
WireMockList<string> list = requestMessage.Headers[Name];
|
WireMockList<string> list = requestMessage.Headers[Name];
|
||||||
return Matchers.Max(m => list.Max(value => m.IsMatch(value))); // TODO : is this correct ?
|
return Matchers.Max(m => list.Max(value => m.IsMatch(value))); // TODO : is this correct ?
|
||||||
|
|||||||
@@ -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)).Cast<IMatcher>().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;
|
||||||
@@ -59,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)).Cast<IMatcher>().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;
|
||||||
@@ -59,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()
|
||||||
@@ -47,16 +51,45 @@ namespace WireMock.Owin
|
|||||||
.Configure(appBuilder =>
|
.Configure(appBuilder =>
|
||||||
{
|
{
|
||||||
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
|
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
|
||||||
|
|
||||||
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
|
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||||
|
|
||||||
appBuilder.UseMiddleware<WireMockMiddleware>(_options);
|
appBuilder.UseMiddleware<WireMockMiddleware>(_options);
|
||||||
|
|
||||||
_options.PostWireMockMiddlewareInit?.Invoke(appBuilder);
|
_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);
|
||||||
@@ -65,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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using log4net;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
#if !NETSTANDARD
|
#if !NETSTANDARD
|
||||||
using Microsoft.Owin;
|
using Microsoft.Owin;
|
||||||
@@ -15,6 +16,7 @@ namespace WireMock.Owin
|
|||||||
internal class GlobalExceptionMiddleware
|
internal class GlobalExceptionMiddleware
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(GlobalExceptionMiddleware));
|
||||||
#if !NETSTANDARD
|
#if !NETSTANDARD
|
||||||
public GlobalExceptionMiddleware(OwinMiddleware next) : base(next) { }
|
public GlobalExceptionMiddleware(OwinMiddleware next) : base(next) { }
|
||||||
#else
|
#else
|
||||||
@@ -42,6 +44,7 @@ namespace WireMock.Owin
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Log.Error("HttpStatusCode set to 500", ex);
|
||||||
await _responseMapper.MapAsync(new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) }, ctx.Response);
|
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,20 +44,6 @@ namespace WireMock.Owin
|
|||||||
#endif
|
#endif
|
||||||
string method = request.Method;
|
string method = request.Method;
|
||||||
|
|
||||||
string bodyAsString = null;
|
|
||||||
byte[] body = null;
|
|
||||||
Encoding bodyEncoding = null;
|
|
||||||
if (ParseBody(method) && request.Body != null)
|
|
||||||
{
|
|
||||||
using (var streamReader = new StreamReader(request.Body))
|
|
||||||
{
|
|
||||||
bodyAsString = await streamReader.ReadToEndAsync();
|
|
||||||
bodyEncoding = streamReader.CurrentEncoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
body = bodyEncoding.GetBytes(bodyAsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary<string, string[]> headers = null;
|
Dictionary<string, string[]> headers = null;
|
||||||
if (request.Headers.Any())
|
if (request.Headers.Any())
|
||||||
{
|
{
|
||||||
@@ -77,10 +64,16 @@ namespace WireMock.Owin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RequestMessage(url, method, clientIP, body, bodyAsString, bodyEncoding, headers, cookies) { DateTime = DateTime.Now };
|
BodyData body = null;
|
||||||
|
if (request.Body != null && ShouldParseBody(method))
|
||||||
|
{
|
||||||
|
body = await BodyParser.Parse(request.Body, request.ContentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RequestMessage(url, method, clientIP, body, headers, cookies) { DateTime = DateTime.Now };
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ParseBody(string method)
|
private bool ShouldParseBody(string method)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
HEAD - No defined body semantics.
|
HEAD - No defined body semantics.
|
||||||
|
|||||||
@@ -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 Newtonsoft.Json;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
#if !NETSTANDARD
|
#if !NETSTANDARD
|
||||||
using Microsoft.Owin;
|
using Microsoft.Owin;
|
||||||
@@ -65,7 +66,7 @@ namespace WireMock.Owin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseMessage.Body == null && responseMessage.BodyAsBytes == null && responseMessage.BodyAsFile == null)
|
if (responseMessage.Body == null && responseMessage.BodyAsBytes == null && responseMessage.BodyAsFile == null && responseMessage.BodyAsJson == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -84,11 +85,20 @@ namespace WireMock.Owin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Encoding encoding = responseMessage.BodyEncoding ?? _utf8NoBom;
|
if (responseMessage.BodyAsJson != null)
|
||||||
using (var writer = new StreamWriter(response.Body, encoding))
|
{
|
||||||
|
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);
|
||||||
// TODO : response.ContentLength = responseMessage.Body.Length;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,9 +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 WireMock.Util;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using WireMock.Http;
|
||||||
#if !NETSTANDARD
|
#if !NETSTANDARD
|
||||||
using Microsoft.Owin;
|
using Microsoft.Owin;
|
||||||
#else
|
#else
|
||||||
@@ -20,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;
|
||||||
|
|
||||||
@@ -52,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)
|
||||||
@@ -61,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,
|
||||||
@@ -95,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;
|
||||||
}
|
}
|
||||||
@@ -103,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 WireMockList<string> authorization);
|
bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList<string> authorization);
|
||||||
if (!present || _options.AuthorizationMatcher.IsMatch(authorization.ToString()) < 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;
|
||||||
}
|
}
|
||||||
@@ -125,6 +130,7 @@ namespace WireMock.Owin
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Log.Error("HttpStatusCode set to 500", ex);
|
||||||
response = new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) };
|
response = new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) };
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ 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 ConcurentObservableCollection<LogEntry>();
|
public ObservableCollection<LogEntry> LogEntries { get; } = new ConcurentObservableCollection<LogEntry>();
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -35,7 +35,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 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.
|
||||||
@@ -59,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.
|
||||||
|
|||||||
@@ -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,7 +165,7 @@ 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;
|
||||||
@@ -228,73 +228,34 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb"/>
|
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb"/>
|
||||||
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));
|
||||||
@@ -303,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));
|
||||||
@@ -321,14 +300,10 @@ 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;
|
||||||
@@ -360,10 +335,10 @@ 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 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;
|
||||||
@@ -376,7 +351,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <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;
|
||||||
@@ -401,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;
|
||||||
@@ -416,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;
|
||||||
|
|||||||
@@ -60,15 +60,20 @@ namespace WireMock
|
|||||||
public string RawQuery { get; }
|
public string RawQuery { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the bodyAsBytes.
|
/// The body as string.
|
||||||
/// </summary>
|
|
||||||
public byte[] BodyAsBytes { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the body.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Body { get; }
|
public string Body { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body (as JSON object).
|
||||||
|
/// </summary>
|
||||||
|
public object BodyAsJson { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body (as bytearray).
|
||||||
|
/// </summary>
|
||||||
|
public byte[] BodyAsBytes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Host
|
/// Gets the Host
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -90,10 +95,45 @@ namespace WireMock
|
|||||||
public string Origin { get; }
|
public string Origin { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the body encoding.
|
/// 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>
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using WireMock.Http;
|
using WireMock.Http;
|
||||||
|
using WireMock.Settings;
|
||||||
using WireMock.Transformers;
|
using WireMock.Transformers;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
@@ -43,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.
|
||||||
@@ -246,16 +247,9 @@ namespace WireMock.ResponseBuilders
|
|||||||
{
|
{
|
||||||
Check.NotNull(body, nameof(body));
|
Check.NotNull(body, nameof(body));
|
||||||
|
|
||||||
string jsonBody = JsonConvert.SerializeObject(body, new JsonSerializerSettings { Formatting = Formatting.None, NullValueHandling = NullValueHandling.Ignore });
|
|
||||||
|
|
||||||
if (encoding != null && !encoding.Equals(Encoding.UTF8))
|
|
||||||
{
|
|
||||||
jsonBody = encoding.GetString(Encoding.UTF8.GetBytes(jsonBody));
|
|
||||||
ResponseMessage.BodyEncoding = encoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResponseMessage.BodyDestination = null;
|
ResponseMessage.BodyDestination = null;
|
||||||
ResponseMessage.Body = jsonBody;
|
ResponseMessage.BodyAsJson = body;
|
||||||
|
ResponseMessage.BodyEncoding = encoding;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -296,22 +290,25 @@ namespace WireMock.ResponseBuilders
|
|||||||
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);
|
_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>
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ namespace WireMock
|
|||||||
/// </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>
|
/// <summary>
|
||||||
/// Gets or sets the body as bytes.
|
/// Gets or sets the body as bytes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -74,7 +79,7 @@ namespace WireMock
|
|||||||
/// <param name="values">The values.</param>
|
/// <param name="values">The values.</param>
|
||||||
public void AddHeader(string name, params string[] values)
|
public void AddHeader(string name, params string[] values)
|
||||||
{
|
{
|
||||||
Check.NotEmpty(values, nameof(values));
|
Check.NotNullOrEmpty(values, nameof(values));
|
||||||
|
|
||||||
var newHeaderValues = Headers.TryGetValue(name, out WireMockList<string> existingValues)
|
var newHeaderValues = Headers.TryGetValue(name, out WireMockList<string> existingValues)
|
||||||
? values.Union(existingValues).ToArray()
|
? values.Union(existingValues).ToArray()
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ 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.BodyDestination = null;
|
||||||
|
mappingModel.Response.BodyAsJson = null;
|
||||||
mappingModel.Response.Body = null;
|
mappingModel.Response.Body = null;
|
||||||
mappingModel.Response.BodyAsBytes = null;
|
mappingModel.Response.BodyAsBytes = null;
|
||||||
mappingModel.Response.BodyAsFile = null;
|
mappingModel.Response.BodyAsFile = null;
|
||||||
@@ -110,6 +111,7 @@ namespace WireMock.Serialization
|
|||||||
mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
|
mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
|
||||||
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
|
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
|
||||||
mappingModel.Response.Headers = Map(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.BodyAsBytes = response.ResponseMessage.BodyAsBytes;
|
||||||
mappingModel.Response.BodyAsFile = response.ResponseMessage.BodyAsFile;
|
mappingModel.Response.BodyAsFile = response.ResponseMessage.BodyAsFile;
|
||||||
@@ -150,7 +152,9 @@ namespace WireMock.Serialization
|
|||||||
private static MatcherModel[] Map([CanBeNull] IEnumerable<IMatcher> matchers)
|
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();
|
||||||
}
|
}
|
||||||
@@ -158,9 +162,12 @@ namespace WireMock.Serialization
|
|||||||
private 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
|
||||||
{
|
{
|
||||||
@@ -186,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];
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
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;
|
||||||
@@ -29,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";
|
||||||
@@ -42,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
|
||||||
@@ -99,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
|
||||||
@@ -128,17 +91,114 @@ 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 HttpClient _httpClientForProxy;
|
private HttpClient _httpClientForProxy;
|
||||||
|
|
||||||
private void InitProxyAndRecord(ProxyAndRecordSettings settings)
|
private void InitProxyAndRecord(IProxyAndRecordSettings settings)
|
||||||
{
|
{
|
||||||
_httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.X509Certificate2ThumbprintOrSubjectName);
|
_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);
|
||||||
@@ -148,8 +208,8 @@ namespace WireMock.Server
|
|||||||
|
|
||||||
if (settings.SaveMapping)
|
if (settings.SaveMapping)
|
||||||
{
|
{
|
||||||
var mapping = ToMapping(requestMessage, responseMessage);
|
var mapping = ToMapping(requestMessage, responseMessage, settings.BlackListedHeaders ?? new string[] { });
|
||||||
_options.Mappings.Add(mapping);
|
_options.Mappings.Add(mapping.Guid, mapping);
|
||||||
|
|
||||||
if (settings.SaveMappingToFile)
|
if (settings.SaveMappingToFile)
|
||||||
{
|
{
|
||||||
@@ -160,16 +220,23 @@ namespace WireMock.Server
|
|||||||
return responseMessage;
|
return responseMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage)
|
private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage, string[] blacklistedHeaders)
|
||||||
{
|
{
|
||||||
var request = Request.Create();
|
var request = Request.Create();
|
||||||
request.WithPath(requestMessage.Path);
|
request.WithPath(requestMessage.Path);
|
||||||
request.UsingVerb(requestMessage.Method);
|
request.UsingVerb(requestMessage.Method);
|
||||||
|
|
||||||
requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray()));
|
requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray()));
|
||||||
requestMessage.Headers.Loop((key, value) => request.WithHeader(key, value.ToArray()));
|
|
||||||
requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, value));
|
requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, value));
|
||||||
|
|
||||||
|
requestMessage.Headers.Loop((key, value) =>
|
||||||
|
{
|
||||||
|
if (!blacklistedHeaders.Any(b => string.Equals(key, b, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
request.WithHeader(key, value.ToArray());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (requestMessage.Body != null)
|
if (requestMessage.Body != null)
|
||||||
{
|
{
|
||||||
request.WithBody(new ExactMatcher(requestMessage.Body));
|
request.WithBody(new ExactMatcher(requestMessage.Body));
|
||||||
@@ -177,7 +244,7 @@ namespace WireMock.Server
|
|||||||
|
|
||||||
var response = Response.Create(responseMessage);
|
var response = Response.Create(responseMessage);
|
||||||
|
|
||||||
return new Mapping(Guid.NewGuid(), string.Empty, request, response, 0, null, null, null);
|
return new Mapping(Guid.NewGuid(), string.Empty, null, request, response, 0, null, null, null);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -197,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;
|
||||||
@@ -220,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);
|
||||||
|
|
||||||
@@ -230,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" };
|
||||||
}
|
}
|
||||||
@@ -256,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" };
|
||||||
}
|
}
|
||||||
@@ -277,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 = '_')
|
||||||
@@ -307,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));
|
||||||
@@ -343,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)
|
||||||
{
|
{
|
||||||
@@ -376,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);
|
||||||
|
|
||||||
@@ -418,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
|
||||||
@@ -432,6 +509,7 @@ namespace WireMock.Server
|
|||||||
StatusCode = logEntry.ResponseMessage.StatusCode,
|
StatusCode = logEntry.ResponseMessage.StatusCode,
|
||||||
BodyDestination = logEntry.ResponseMessage.BodyDestination,
|
BodyDestination = logEntry.ResponseMessage.BodyDestination,
|
||||||
Body = logEntry.ResponseMessage.Body,
|
Body = logEntry.ResponseMessage.Body,
|
||||||
|
BodyAsJson = logEntry.ResponseMessage.BodyAsJson,
|
||||||
BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
|
BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
|
||||||
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
|
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
|
||||||
BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
|
BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
|
||||||
@@ -472,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);
|
||||||
|
|
||||||
@@ -528,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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,7 +623,7 @@ namespace WireMock.Server
|
|||||||
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,7 +640,7 @@ namespace WireMock.Server
|
|||||||
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -576,7 +654,7 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,7 +758,7 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
Body = JsonConvert.SerializeObject(result, _settings),
|
Body = JsonConvert.SerializeObject(result, _settings),
|
||||||
StatusCode = 200,
|
StatusCode = 200,
|
||||||
Headers = new Dictionary<string, WireMockList<string>> { { "Content-Type", new WireMockList<string>("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]
|
||||||
@@ -83,4 +83,4 @@ namespace WireMock.Server
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -170,6 +178,8 @@ namespace WireMock.Server
|
|||||||
#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();
|
||||||
@@ -197,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);
|
||||||
@@ -258,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>
|
||||||
@@ -269,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>
|
||||||
@@ -293,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>
|
||||||
@@ -363,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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,13 @@ namespace WireMock.Server
|
|||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||||
IRespondWithAProvider WithTitle(string title);
|
IRespondWithAProvider WithTitle(string title);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Define the full filepath for this mapping.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The full filepath.</param>
|
||||||
|
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||||
|
IRespondWithAProvider WithPath(string path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Define a unique identifier for this mapping.
|
/// Define a unique identifier for this mapping.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -11,18 +11,11 @@ namespace WireMock.Server
|
|||||||
private int _priority;
|
private int _priority;
|
||||||
private Guid? _guid;
|
private Guid? _guid;
|
||||||
private string _title;
|
private string _title;
|
||||||
|
private string _path;
|
||||||
private object _executionConditionState;
|
private object _executionConditionState;
|
||||||
private object _nextState;
|
private object _nextState;
|
||||||
private string _scenario;
|
private string _scenario;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The _registration callback.
|
|
||||||
/// </summary>
|
|
||||||
private readonly RegistrationCallback _registrationCallback;
|
private readonly RegistrationCallback _registrationCallback;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The _request matcher.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IRequestMatcher _requestMatcher;
|
private readonly IRequestMatcher _requestMatcher;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -39,30 +32,20 @@ namespace WireMock.Server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The respond with.
|
/// The respond with.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="provider">
|
/// <param name="provider">The provider.</param>
|
||||||
/// The provider.
|
|
||||||
/// </param>
|
|
||||||
public void RespondWith(IResponseProvider provider)
|
public void RespondWith(IResponseProvider provider)
|
||||||
{
|
{
|
||||||
var mappingGuid = _guid ?? Guid.NewGuid();
|
var mappingGuid = _guid ?? Guid.NewGuid();
|
||||||
_registrationCallback(new Mapping(mappingGuid, _title, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState));
|
_registrationCallback(new Mapping(mappingGuid, _title, _path, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <see cref="IRespondWithAProvider.WithGuid(string)"/>
|
||||||
/// Define a unique identifier for this mapping.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="guid">The unique identifier.</param>
|
|
||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
|
||||||
public IRespondWithAProvider WithGuid(string guid)
|
public IRespondWithAProvider WithGuid(string guid)
|
||||||
{
|
{
|
||||||
return WithGuid(Guid.Parse(guid));
|
return WithGuid(Guid.Parse(guid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <see cref="IRespondWithAProvider.WithGuid(Guid)"/>
|
||||||
/// Define a unique identifier for this mapping.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="guid">The unique identifier.</param>
|
|
||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
|
||||||
public IRespondWithAProvider WithGuid(Guid guid)
|
public IRespondWithAProvider WithGuid(Guid guid)
|
||||||
{
|
{
|
||||||
_guid = guid;
|
_guid = guid;
|
||||||
@@ -70,11 +53,7 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <see cref="IRespondWithAProvider.WithTitle"/>
|
||||||
/// Define a unique identifier for this mapping.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="title">The unique identifier.</param>
|
|
||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
|
||||||
public IRespondWithAProvider WithTitle(string title)
|
public IRespondWithAProvider WithTitle(string title)
|
||||||
{
|
{
|
||||||
_title = title;
|
_title = title;
|
||||||
@@ -82,11 +61,15 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <see cref="IRespondWithAProvider.WithPath"/>
|
||||||
/// Define the priority for this mapping.
|
public IRespondWithAProvider WithPath(string path)
|
||||||
/// </summary>
|
{
|
||||||
/// <param name="priority">The priority.</param>
|
_path = path;
|
||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <see cref="IRespondWithAProvider.AtPriority"/>
|
||||||
public IRespondWithAProvider AtPriority(int priority)
|
public IRespondWithAProvider AtPriority(int priority)
|
||||||
{
|
{
|
||||||
_priority = priority;
|
_priority = priority;
|
||||||
@@ -94,6 +77,7 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <see cref="IRespondWithAProvider.InScenario(string)"/>
|
||||||
public IRespondWithAProvider InScenario(string scenario)
|
public IRespondWithAProvider InScenario(string scenario)
|
||||||
{
|
{
|
||||||
_scenario = scenario;
|
_scenario = scenario;
|
||||||
@@ -101,6 +85,7 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <see cref="IRespondWithAProvider.WhenStateIs"/>
|
||||||
public IRespondWithAProvider WhenStateIs(object state)
|
public IRespondWithAProvider WhenStateIs(object state)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_scenario))
|
if (string.IsNullOrEmpty(_scenario))
|
||||||
@@ -118,6 +103,7 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <see cref="IRespondWithAProvider.WillSetStateTo"/>
|
||||||
public IRespondWithAProvider WillSetStateTo(object state)
|
public IRespondWithAProvider WillSetStateTo(object state)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_scenario))
|
if (string.IsNullOrEmpty(_scenario))
|
||||||
|
|||||||
@@ -1,97 +1,75 @@
|
|||||||
using System;
|
using System;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace WireMock.Settings
|
namespace WireMock.Settings
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FluentMockServerSettings
|
/// FluentMockServerSettings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FluentMockServerSettings
|
public class FluentMockServerSettings : IFluentMockServerSettings
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.Port"/>
|
||||||
/// Gets or sets the port.
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public int? Port { get; set; }
|
public int? Port { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.UseSSL"/>
|
||||||
/// Gets or sets the use SSL.
|
|
||||||
/// </summary>
|
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
public bool? UseSSL { get; set; }
|
public bool? UseSSL { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.StartAdminInterface"/>
|
||||||
/// Gets or sets wether to start admin interface.
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool? StartAdminInterface { get; set; }
|
public bool? StartAdminInterface { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.ReadStaticMappings"/>
|
||||||
/// Gets or sets if the static mappings should be read at startup.
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool? ReadStaticMappings { get; set; }
|
public bool? ReadStaticMappings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.WatchStaticMappings"/>
|
||||||
/// Gets or sets if the server should record and save requests and responses.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>true/false</value>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public ProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
|
public bool? WatchStaticMappings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.ProxyAndRecordSettings"/>
|
||||||
/// Gets or sets the urls.
|
[PublicAPI]
|
||||||
/// </summary>
|
public IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IFluentMockServerSettings.Urls"/>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public string[] Urls { get; set; }
|
public string[] Urls { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.StartTimeout"/>
|
||||||
/// StartTimeout
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public int StartTimeout { get; set; } = 10000;
|
public int StartTimeout { get; set; } = 10000;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.AllowPartialMapping"/>
|
||||||
/// Allow Partial Mapping (default set to false).
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool? AllowPartialMapping { get; set; }
|
public bool? AllowPartialMapping { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.AdminUsername"/>
|
||||||
/// The username needed for __admin access.
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public string AdminUsername { get; set; }
|
public string AdminUsername { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.AdminPassword"/>
|
||||||
/// The password needed for __admin access.
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public string AdminPassword { get; set; }
|
public string AdminPassword { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.RequestLogExpirationDuration"/>
|
||||||
/// The RequestLog expiration in hours (optional).
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public int? RequestLogExpirationDuration { get; set; }
|
public int? RequestLogExpirationDuration { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.MaxRequestLogCount"/>
|
||||||
/// The MaxRequestLog count (optional).
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public int? MaxRequestLogCount { get; set; }
|
public int? MaxRequestLogCount { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.PreWireMockMiddlewareInit"/>
|
||||||
/// Action which is called (with the IAppBuilder or IApplicationBuilder) before the internal WireMockMiddleware is initialized. [Optional]
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
|
[JsonIgnore]
|
||||||
public Action<object> PreWireMockMiddlewareInit { get; set; }
|
public Action<object> PreWireMockMiddlewareInit { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFluentMockServerSettings.PostWireMockMiddlewareInit"/>
|
||||||
/// Action which is called (with the IAppBuilder or IApplicationBuilder) after the internal WireMockMiddleware is initialized. [Optional]
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
|
[JsonIgnore]
|
||||||
public Action<object> PostWireMockMiddlewareInit { get; set; }
|
public Action<object> PostWireMockMiddlewareInit { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
86
src/WireMock.Net/Settings/IFluentMockServerSettings.cs
Normal file
86
src/WireMock.Net/Settings/IFluentMockServerSettings.cs
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace WireMock.Settings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// IFluentMockServerSettings
|
||||||
|
/// </summary>
|
||||||
|
public interface IFluentMockServerSettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the port.
|
||||||
|
/// </summary>
|
||||||
|
int? Port { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the use SSL.
|
||||||
|
/// </summary>
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
|
bool? UseSSL { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets wether to start admin interface.
|
||||||
|
/// </summary>
|
||||||
|
bool? StartAdminInterface { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets if the static mappings should be read at startup.
|
||||||
|
/// </summary>
|
||||||
|
bool? ReadStaticMappings { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Watch the static mapping files + folder for changes when running.
|
||||||
|
/// </summary>
|
||||||
|
bool? WatchStaticMappings { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets if the proxy and record settings.
|
||||||
|
/// </summary>
|
||||||
|
IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the urls.
|
||||||
|
/// </summary>
|
||||||
|
string[] Urls { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// StartTimeout
|
||||||
|
/// </summary>
|
||||||
|
int StartTimeout { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allow Partial Mapping (default set to false).
|
||||||
|
/// </summary>
|
||||||
|
bool? AllowPartialMapping { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The username needed for __admin access.
|
||||||
|
/// </summary>
|
||||||
|
string AdminUsername { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The password needed for __admin access.
|
||||||
|
/// </summary>
|
||||||
|
string AdminPassword { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The RequestLog expiration in hours (optional).
|
||||||
|
/// </summary>
|
||||||
|
int? RequestLogExpirationDuration { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The MaxRequestLog count (optional).
|
||||||
|
/// </summary>
|
||||||
|
int? MaxRequestLogCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Action which is called (with the IAppBuilder or IApplicationBuilder) before the internal WireMockMiddleware is initialized. [Optional]
|
||||||
|
/// </summary>
|
||||||
|
Action<object> PreWireMockMiddlewareInit { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Action which is called (with the IAppBuilder or IApplicationBuilder) after the internal WireMockMiddleware is initialized. [Optional]
|
||||||
|
/// </summary>
|
||||||
|
Action<object> PostWireMockMiddlewareInit { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/WireMock.Net/Settings/IProxyAndRecordSettings.cs
Normal file
34
src/WireMock.Net/Settings/IProxyAndRecordSettings.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
namespace WireMock.Settings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// IProxyAndRecordSettings
|
||||||
|
/// </summary>
|
||||||
|
public interface IProxyAndRecordSettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The URL to proxy.
|
||||||
|
/// </summary>
|
||||||
|
string Url { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Save the mapping for each request/response to the internal Mappings.
|
||||||
|
/// </summary>
|
||||||
|
bool SaveMapping { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Save the mapping for each request/response to also file. (Note that SaveMapping must also be set to true.)
|
||||||
|
/// </summary>
|
||||||
|
bool SaveMappingToFile { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The clientCertificate thumbprint or subject name fragment to use.
|
||||||
|
/// Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
||||||
|
/// </summary>
|
||||||
|
string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines a list from headers which will excluded from the saved mappings.
|
||||||
|
/// </summary>
|
||||||
|
string[] BlackListedHeaders { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +1,30 @@
|
|||||||
namespace WireMock.Settings
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace WireMock.Settings
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// RecordAndSaveSettings
|
/// ProxyAndRecordSettings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ProxyAndRecordSettings
|
public class ProxyAndRecordSettings : IProxyAndRecordSettings
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc cref="IProxyAndRecordSettings.Url"/>
|
||||||
/// The URL to proxy.
|
[PublicAPI]
|
||||||
/// </summary>
|
|
||||||
public string Url { get; set; }
|
public string Url { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IProxyAndRecordSettings.SaveMapping"/>
|
||||||
/// Save the mapping for each request/response to the internal Mappings.
|
[PublicAPI]
|
||||||
/// </summary>
|
|
||||||
public bool SaveMapping { get; set; } = true;
|
public bool SaveMapping { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IProxyAndRecordSettings.SaveMappingToFile"/>
|
||||||
/// Save the mapping for each request/response to also file. (Note that SaveMapping must also be set to true.)
|
[PublicAPI]
|
||||||
/// </summary>
|
|
||||||
public bool SaveMappingToFile { get; set; } = true;
|
public bool SaveMappingToFile { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="IProxyAndRecordSettings.ClientX509Certificate2ThumbprintOrSubjectName"/>
|
||||||
/// The clientCertificate thumbprint or subject name fragment to use. Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
[PublicAPI]
|
||||||
/// </summary>
|
public string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||||
public string X509Certificate2ThumbprintOrSubjectName { get; set; }
|
|
||||||
|
/// <inheritdoc cref="IProxyAndRecordSettings.BlackListedHeaders"/>
|
||||||
|
[PublicAPI]
|
||||||
|
public string[] BlackListedHeaders { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
30
src/WireMock.Net/Util/BodyData.cs
Normal file
30
src/WireMock.Net/Util/BodyData.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace WireMock.Util
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// BodyData
|
||||||
|
/// </summary>
|
||||||
|
public class BodyData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The body encoding.
|
||||||
|
/// </summary>
|
||||||
|
public Encoding Encoding { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The body as string.
|
||||||
|
/// </summary>
|
||||||
|
public string BodyAsString { 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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
75
src/WireMock.Net/Util/BodyParser.cs
Normal file
75
src/WireMock.Net/Util/BodyParser.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace WireMock.Util
|
||||||
|
{
|
||||||
|
internal static class BodyParser
|
||||||
|
{
|
||||||
|
private static readonly string[] TextContentTypes = { "text/", "application/xml", "application/javascript", "application/typescript", "application/xhtml+xml" };
|
||||||
|
|
||||||
|
private static async Task<Tuple<string, Encoding>> ReadStringAsync(Stream stream)
|
||||||
|
{
|
||||||
|
using (var streamReader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
string content = await streamReader.ReadToEndAsync();
|
||||||
|
|
||||||
|
return new Tuple<string, Encoding>(content, streamReader.CurrentEncoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<byte[]> ReadBytesAsync(Stream stream)
|
||||||
|
{
|
||||||
|
using (var memoryStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
await stream.CopyToAsync(memoryStream);
|
||||||
|
return memoryStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentTypeHeaderValue)
|
||||||
|
{
|
||||||
|
var data = new BodyData();
|
||||||
|
|
||||||
|
if (contentTypeHeaderValue != null && TextContentTypes.Any(t => contentTypeHeaderValue.StartsWith(t, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var stringData = await ReadStringAsync(stream);
|
||||||
|
data.BodyAsString = stringData.Item1;
|
||||||
|
data.Encoding = stringData.Item2;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Reading as string failed, just get the ByteArray.
|
||||||
|
data.BodyAsBytes = await ReadBytesAsync(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (contentTypeHeaderValue != null && contentTypeHeaderValue.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var stringData = await ReadStringAsync(stream);
|
||||||
|
data.Encoding = stringData.Item2;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
data.BodyAsJson = JsonConvert.DeserializeObject(stringData.Item1, new JsonSerializerSettings { Formatting = Formatting.Indented });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// JsonConvert failed, just set the Body as string.
|
||||||
|
data.BodyAsString = stringData.Item1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.BodyAsBytes = await ReadBytesAsync(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
265
src/WireMock.Net/Util/EnhancedFileSystemWatcher.cs
Normal file
265
src/WireMock.Net/Util/EnhancedFileSystemWatcher.cs
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.IO;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using WireMock.Validation;
|
||||||
|
|
||||||
|
namespace WireMock.Util
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An EnhancedFileSystemWatcher, which can be used to suppress duplicate events that fire on a single change to the file.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="System.IO.FileSystemWatcher" />
|
||||||
|
/// <seealso cref="System.IDisposable" />
|
||||||
|
public class EnhancedFileSystemWatcher : FileSystemWatcher, IDisposable
|
||||||
|
{
|
||||||
|
#region Private Members
|
||||||
|
// Default Watch Interval in Milliseconds
|
||||||
|
private const int DefaultWatchInterval = 100;
|
||||||
|
|
||||||
|
// This Dictionary keeps the track of when an event occured last for a particular file
|
||||||
|
private ConcurrentDictionary<string, DateTime> _lastFileEvent;
|
||||||
|
|
||||||
|
// Watch Interval in Milliseconds
|
||||||
|
private int _interval;
|
||||||
|
|
||||||
|
// Timespan created when interval is set
|
||||||
|
private TimeSpan _recentTimeSpan;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Properties
|
||||||
|
/// <summary>
|
||||||
|
/// Interval, in milliseconds, within which events are considered "recent".
|
||||||
|
/// </summary>
|
||||||
|
[PublicAPI]
|
||||||
|
public int Interval
|
||||||
|
{
|
||||||
|
get => _interval;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_interval = value;
|
||||||
|
|
||||||
|
// Set timespan based on the value passed
|
||||||
|
_recentTimeSpan = new TimeSpan(0, 0, 0, 0, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allows user to set whether to filter recent events.
|
||||||
|
/// If this is set a false, this class behaves like System.IO.FileSystemWatcher class.
|
||||||
|
/// </summary>
|
||||||
|
[PublicAPI]
|
||||||
|
public bool FilterRecentEvents { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="interval">The interval.</param>
|
||||||
|
public EnhancedFileSystemWatcher(int interval = DefaultWatchInterval)
|
||||||
|
{
|
||||||
|
Check.Condition(interval, i => i >= 0, nameof(interval));
|
||||||
|
|
||||||
|
InitializeMembers(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The directory to monitor, in standard or Universal Naming Convention (UNC) notation.</param>
|
||||||
|
/// <param name="interval">The interval.</param>
|
||||||
|
public EnhancedFileSystemWatcher([NotNull] string path, int interval = DefaultWatchInterval) : base(path)
|
||||||
|
{
|
||||||
|
Check.NotNullOrEmpty(path, nameof(path));
|
||||||
|
Check.Condition(interval, i => i >= 0, nameof(interval));
|
||||||
|
|
||||||
|
InitializeMembers(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The directory to monitor, in standard or Universal Naming Convention (UNC) notation.</param>
|
||||||
|
/// <param name="filter">The type of files to watch. For example, "*.txt" watches for changes to all text files.</param>
|
||||||
|
/// <param name="interval">The interval.</param>
|
||||||
|
public EnhancedFileSystemWatcher([NotNull] string path, [NotNull] string filter, int interval = DefaultWatchInterval) : base(path, filter)
|
||||||
|
{
|
||||||
|
Check.NotNullOrEmpty(path, nameof(path));
|
||||||
|
Check.NotNullOrEmpty(filter, nameof(filter));
|
||||||
|
Check.Condition(interval, i => i >= 0, nameof(interval));
|
||||||
|
|
||||||
|
InitializeMembers(interval);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
// These events hide the events from the base class.
|
||||||
|
// We want to raise these events appropriately and we do not want the
|
||||||
|
// users of this class subscribing to these events of the base class accidentally
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is changed.
|
||||||
|
/// </summary>
|
||||||
|
public new event FileSystemEventHandler Changed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is created.
|
||||||
|
/// </summary>
|
||||||
|
public new event FileSystemEventHandler Created;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is deleted.
|
||||||
|
/// </summary>
|
||||||
|
public new event FileSystemEventHandler Deleted;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is renamed.
|
||||||
|
/// </summary>
|
||||||
|
public new event RenamedEventHandler Renamed;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Protected Methods to raise the Events for this class
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the <see cref="E:System.IO.FileSystemWatcher.Changed" /> event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>
|
||||||
|
protected new virtual void OnChanged(FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
Changed?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the <see cref="E:System.IO.FileSystemWatcher.Created" /> event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>
|
||||||
|
protected new virtual void OnCreated(FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
Created?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the <see cref="E:System.IO.FileSystemWatcher.Deleted" /> event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>
|
||||||
|
protected new virtual void OnDeleted(FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
Deleted?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the <see cref="E:System.IO.FileSystemWatcher.Renamed" /> event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">A <see cref="T:System.IO.RenamedEventArgs" /> that contains the event data.</param>
|
||||||
|
protected new virtual void OnRenamed(RenamedEventArgs e)
|
||||||
|
{
|
||||||
|
Renamed?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
/// <summary>
|
||||||
|
/// This Method Initializes the private members.
|
||||||
|
/// Interval is set to its default value of 100 millisecond.
|
||||||
|
/// FilterRecentEvents is set to true, _lastFileEvent dictionary is initialized.
|
||||||
|
/// We subscribe to the base class events.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeMembers(int interval = 100)
|
||||||
|
{
|
||||||
|
Interval = interval;
|
||||||
|
FilterRecentEvents = true;
|
||||||
|
_lastFileEvent = new ConcurrentDictionary<string, DateTime>();
|
||||||
|
|
||||||
|
base.Created += OnCreated;
|
||||||
|
base.Changed += OnChanged;
|
||||||
|
base.Deleted += OnDeleted;
|
||||||
|
base.Renamed += OnRenamed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method searches the dictionary to find out when the last event occured
|
||||||
|
/// for a particular file. If that event occured within the specified timespan
|
||||||
|
/// it returns true, else false
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The filename to be checked</param>
|
||||||
|
/// <returns>True if an event has occured within the specified interval, False otherwise</returns>
|
||||||
|
private bool HasAnotherFileEventOccuredRecently(string fileName)
|
||||||
|
{
|
||||||
|
// Check dictionary only if user wants to filter recent events otherwise return value stays false.
|
||||||
|
if (!FilterRecentEvents)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool retVal = false;
|
||||||
|
if (_lastFileEvent.ContainsKey(fileName))
|
||||||
|
{
|
||||||
|
// If dictionary contains the filename, check how much time has elapsed
|
||||||
|
// since the last event occured. If the timespan is less that the
|
||||||
|
// specified interval, set return value to true
|
||||||
|
// and store current datetime in dictionary for this file
|
||||||
|
DateTime lastEventTime = _lastFileEvent[fileName];
|
||||||
|
DateTime currentTime = DateTime.Now;
|
||||||
|
TimeSpan timeSinceLastEvent = currentTime - lastEventTime;
|
||||||
|
retVal = timeSinceLastEvent < _recentTimeSpan;
|
||||||
|
_lastFileEvent[fileName] = currentTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If dictionary does not contain the filename,
|
||||||
|
// no event has occured in past for this file, so set return value to false
|
||||||
|
// and append filename along with current datetime to the dictionary
|
||||||
|
_lastFileEvent.TryAdd(fileName, DateTime.Now);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region FileSystemWatcher EventHandlers
|
||||||
|
// Base class Event Handlers. Check if an event has occured recently and call method
|
||||||
|
// to raise appropriate event only if no recent event is detected
|
||||||
|
private void OnChanged(object sender, FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasAnotherFileEventOccuredRecently(e.FullPath))
|
||||||
|
{
|
||||||
|
OnChanged(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCreated(object sender, FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasAnotherFileEventOccuredRecently(e.FullPath))
|
||||||
|
{
|
||||||
|
OnCreated(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDeleted(object sender, FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasAnotherFileEventOccuredRecently(e.FullPath))
|
||||||
|
{
|
||||||
|
OnDeleted(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRenamed(object sender, RenamedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasAnotherFileEventOccuredRecently(e.OldFullPath))
|
||||||
|
{
|
||||||
|
OnRenamed(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Members
|
||||||
|
/// <summary>
|
||||||
|
/// Releases all resources used by the <see cref="T:System.ComponentModel.Component" />.
|
||||||
|
/// </summary>
|
||||||
|
public new void Dispose()
|
||||||
|
{
|
||||||
|
base.Dispose();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/WireMock.Net/Util/FileHelper.cs
Normal file
29
src/WireMock.Net/Util/FileHelper.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace WireMock.Util
|
||||||
|
{
|
||||||
|
internal static class FileHelper
|
||||||
|
{
|
||||||
|
private const int NumberOfRetries = 3;
|
||||||
|
private const int DelayOnRetry = 500;
|
||||||
|
|
||||||
|
public static string ReadAllText(string path)
|
||||||
|
{
|
||||||
|
for (int i = 1; i <= NumberOfRetries; ++i)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return File.ReadAllText(path);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// You may check error code to filter some exceptions, not every error can be recovered.
|
||||||
|
Thread.Sleep(DelayOnRetry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ namespace WireMock.Validation
|
|||||||
|
|
||||||
if (!condition(value))
|
if (!condition(value))
|
||||||
{
|
{
|
||||||
NotEmpty(parameterName, nameof(parameterName));
|
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||||
|
|
||||||
throw new ArgumentOutOfRangeException(parameterName);
|
throw new ArgumentOutOfRangeException(parameterName);
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ namespace WireMock.Validation
|
|||||||
{
|
{
|
||||||
if (ReferenceEquals(value, null))
|
if (ReferenceEquals(value, null))
|
||||||
{
|
{
|
||||||
NotEmpty(parameterName, nameof(parameterName));
|
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||||
|
|
||||||
throw new ArgumentNullException(parameterName);
|
throw new ArgumentNullException(parameterName);
|
||||||
}
|
}
|
||||||
@@ -45,15 +45,12 @@ namespace WireMock.Validation
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ContractAnnotation("value:null => halt")]
|
[ContractAnnotation("value:null => halt")]
|
||||||
public static T NotNull<T>(
|
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName, [NotNull] string propertyName)
|
||||||
[NoEnumeration] T value,
|
|
||||||
[InvokerParameterName] [NotNull] string parameterName,
|
|
||||||
[NotNull] string propertyName)
|
|
||||||
{
|
{
|
||||||
if (ReferenceEquals(value, null))
|
if (ReferenceEquals(value, null))
|
||||||
{
|
{
|
||||||
NotEmpty(parameterName, nameof(parameterName));
|
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||||
NotEmpty(propertyName, nameof(propertyName));
|
NotNullOrEmpty(propertyName, nameof(propertyName));
|
||||||
|
|
||||||
throw new ArgumentException(CoreStrings.ArgumentPropertyNull(propertyName, parameterName));
|
throw new ArgumentException(CoreStrings.ArgumentPropertyNull(propertyName, parameterName));
|
||||||
}
|
}
|
||||||
@@ -62,13 +59,13 @@ namespace WireMock.Validation
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ContractAnnotation("value:null => halt")]
|
[ContractAnnotation("value:null => halt")]
|
||||||
public static IList<T> NotEmpty<T>(IList<T> value, [InvokerParameterName] [NotNull] string parameterName)
|
public static IList<T> NotNullOrEmpty<T>(IList<T> value, [InvokerParameterName] [NotNull] string parameterName)
|
||||||
{
|
{
|
||||||
NotNull(value, parameterName);
|
NotNull(value, parameterName);
|
||||||
|
|
||||||
if (value.Count == 0)
|
if (value.Count == 0)
|
||||||
{
|
{
|
||||||
NotEmpty(parameterName, nameof(parameterName));
|
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||||
|
|
||||||
throw new ArgumentException(CoreStrings.CollectionArgumentIsEmpty(parameterName));
|
throw new ArgumentException(CoreStrings.CollectionArgumentIsEmpty(parameterName));
|
||||||
}
|
}
|
||||||
@@ -77,7 +74,7 @@ namespace WireMock.Validation
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ContractAnnotation("value:null => halt")]
|
[ContractAnnotation("value:null => halt")]
|
||||||
public static string NotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
|
public static string NotNullOrEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
|
||||||
{
|
{
|
||||||
Exception e = null;
|
Exception e = null;
|
||||||
if (ReferenceEquals(value, null))
|
if (ReferenceEquals(value, null))
|
||||||
@@ -91,7 +88,7 @@ namespace WireMock.Validation
|
|||||||
|
|
||||||
if (e != null)
|
if (e != null)
|
||||||
{
|
{
|
||||||
NotEmpty(parameterName, nameof(parameterName));
|
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@@ -104,7 +101,7 @@ namespace WireMock.Validation
|
|||||||
if (!ReferenceEquals(value, null)
|
if (!ReferenceEquals(value, null)
|
||||||
&& (value.Length == 0))
|
&& (value.Length == 0))
|
||||||
{
|
{
|
||||||
NotEmpty(parameterName, nameof(parameterName));
|
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||||
|
|
||||||
throw new ArgumentException(CoreStrings.ArgumentIsEmpty(parameterName));
|
throw new ArgumentException(CoreStrings.ArgumentIsEmpty(parameterName));
|
||||||
}
|
}
|
||||||
@@ -119,7 +116,7 @@ namespace WireMock.Validation
|
|||||||
|
|
||||||
if (value.Any(e => e == null))
|
if (value.Any(e => e == null))
|
||||||
{
|
{
|
||||||
NotEmpty(parameterName, nameof(parameterName));
|
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||||
|
|
||||||
throw new ArgumentException(parameterName);
|
throw new ArgumentException(parameterName);
|
||||||
}
|
}
|
||||||
@@ -131,7 +128,7 @@ namespace WireMock.Validation
|
|||||||
{
|
{
|
||||||
if (!value.GetTypeInfo().IsClass)
|
if (!value.GetTypeInfo().IsClass)
|
||||||
{
|
{
|
||||||
NotEmpty(parameterName, nameof(parameterName));
|
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||||
|
|
||||||
throw new ArgumentException(CoreStrings.InvalidEntityType(value, parameterName));
|
throw new ArgumentException(CoreStrings.InvalidEntityType(value, parameterName));
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user