diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 00000000..6a3dcd7a
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,19 @@
+
+
+ $(MsBuildAllProjects);$(MsBuildThisFileFullPath)
+
+
+
+ 1.0.4.18
+
+
+
+
+
+
+
+ $(Prerelease)-1$(BUILD_BUILDID)
+
+
+
+
\ No newline at end of file
diff --git a/WireMock.Net Solution.sln b/WireMock.Net Solution.sln
index 3eb92425..3bccf3d9 100644
--- a/WireMock.Net Solution.sln
+++ b/WireMock.Net Solution.sln
@@ -13,6 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
azure-pipelines.yml = azure-pipelines.yml
build-info.md = build-info.md
CHANGELOG.md = CHANGELOG.md
+ Directory.Build.props = Directory.Build.props
GitReleaseNotes.txt = GitReleaseNotes.txt
README.md = README.md
ReSharper_WireMock.DotSettings = ReSharper_WireMock.DotSettings
diff --git a/WireMock.Net Solution.sln.DotSettings b/WireMock.Net Solution.sln.DotSettings
index 10779af8..f147855d 100644
--- a/WireMock.Net Solution.sln.DotSettings
+++ b/WireMock.Net Solution.sln.DotSettings
@@ -8,4 +8,7 @@
WWW
XMS
XUA
+ True
+ True
+ True
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 07f4e069..29544e3f 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -2,17 +2,20 @@ pool:
vmImage: 'vs2017-win2016'
variables:
- buildConfiguration: 'Debug'
+ Prerelease: 'ci'
buildId: "1$(Build.BuildId)"
+ buildProjects: '**/src/**/*.csproj'
steps:
# Print buildId
- script: |
echo "BuildId = $(buildId)"
+ displayName: 'Print buildId'
# Install SonarScanner
- script: |
dotnet tool install --global dotnet-sonarscanner
+ displayName: Install SonarScanner
# Begin SonarScanner
# See also
@@ -22,17 +25,53 @@ steps:
#
- script: |
%USERPROFILE%\.dotnet\tools\dotnet-sonarscanner begin /k:"wiremock" /d:sonar.organization="stefh-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$(SONAR_TOKEN)" /v:"$(buildId)" /d:sonar.cs.opencover.reportsPaths="**\coverage.opencover.xml"
+ displayName: Begin SonarScanner
# Build source, tests and run tests for net452 and netcoreapp2.1 (with coverage)
- script: |
- dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework net452
- dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework netcoreapp2.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
+ dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework net452
+ dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework netcoreapp2.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
+ displayName: 'Build source, tests and run tests for net452 and netcoreapp2.1 (with coverage)'
# End SonarScanner
- script: |
%USERPROFILE%\.dotnet\tools\dotnet-sonarscanner end /d:sonar.login="$(SONAR_TOKEN)"
+ displayName: End SonarScanner
- task: PublishTestResults@2
inputs:
testRunner: VSTest
- testResultsFiles: '**/*.trx'
\ No newline at end of file
+ testResultsFiles: '**/*.trx'
+
+# Based on https://whereslou.com/2018/09/versioning-and-publishing-nuget-packages-automatically-using-azure-devops-pipelines/
+- task: DotNetCoreCLI@2
+ displayName: Build Release
+ inputs:
+ command: 'build'
+ arguments: /p:Configuration=Release # https://github.com/MicrosoftDocs/vsts-docs/issues/1976
+ projects: $(buildProjects)
+
+- task: DotNetCoreCLI@2
+ displayName: Pack
+ condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
+ inputs:
+ command: pack
+ configuration: 'Release'
+ packagesToPack: $(buildProjects)
+ nobuild: true
+ packDirectory: '$(Build.ArtifactStagingDirectory)/packages'
+ verbosityPack: 'normal'
+
+- task: PublishBuildArtifacts@1
+ displayName: Publish Artifacts
+ condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
+ inputs:
+ PathtoPublish: '$(Build.ArtifactStagingDirectory)'
+
+- task: DotNetCoreCLI@2
+ displayName: Push to MyGet
+ condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
+ inputs:
+ command: custom
+ custom: nuget
+ arguments: push $(Build.ArtifactStagingDirectory)\packages\*.nupkg --source https://www.myget.org/F/wiremock-net/api/v3/index.json --no-service-endpoint --api-key $(MyGetKey)
\ No newline at end of file
diff --git a/examples/WireMock.Net.Console.Proxy.NETCoreApp2/Program.cs b/examples/WireMock.Net.Console.Proxy.NETCoreApp2/Program.cs
index 461f66a4..dbbfee78 100644
--- a/examples/WireMock.Net.Console.Proxy.NETCoreApp2/Program.cs
+++ b/examples/WireMock.Net.Console.Proxy.NETCoreApp2/Program.cs
@@ -24,7 +24,7 @@ namespace WireMock.Net.Console.Proxy.NETCoreApp2
ReadStaticMappings = false,
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
- Url = "https://www.google.com",
+ Url = "http://postman-echo.com/post",
//ClientX509Certificate2ThumbprintOrSubjectName = "www.yourclientcertname.com OR yourcertificatethumbprint (only if the service you're proxying to requires it)",
SaveMapping = true,
SaveMappingToFile = false,
diff --git a/src/WireMock.Net.StandAlone/WireMock.Net.StandAlone.csproj b/src/WireMock.Net.StandAlone/WireMock.Net.StandAlone.csproj
index 07228e02..522621ae 100644
--- a/src/WireMock.Net.StandAlone/WireMock.Net.StandAlone.csproj
+++ b/src/WireMock.Net.StandAlone/WireMock.Net.StandAlone.csproj
@@ -2,7 +2,6 @@
Lightweight StandAlone Http Mocking Server for .Net.
WireMock.Net.StandAlone
- 1.0.4.18
Stef Heyenrath
net451;net452;net46;netstandard1.3;netstandard2.0
true
@@ -21,6 +20,8 @@
True
True
{B6269AAC-170A-43D5-8B9A-579DED3D9A95}
+ true
+ true
diff --git a/src/WireMock.Net/Admin/Requests/LogRequestModel.cs b/src/WireMock.Net/Admin/Requests/LogRequestModel.cs
index fa9bdcb7..0a926377 100644
--- a/src/WireMock.Net/Admin/Requests/LogRequestModel.cs
+++ b/src/WireMock.Net/Admin/Requests/LogRequestModel.cs
@@ -36,7 +36,7 @@ namespace WireMock.Admin.Requests
public string Url { get; set; }
///
- /// The absolete URL.
+ /// The absolute URL.
///
public string AbsoluteUrl { get; set; }
@@ -56,7 +56,7 @@ namespace WireMock.Admin.Requests
public IDictionary> Headers { get; set; }
///
- /// Tthe Cookies.
+ /// The Cookies.
///
public IDictionary Cookies { get; set; }
@@ -79,5 +79,25 @@ namespace WireMock.Admin.Requests
/// The body encoding.
///
public EncodingModel BodyEncoding { get; set; }
+
+ ///
+ /// The DetectedBodyType, valid values are:
+ ///
+ /// - None
+ /// - String
+ /// - Json
+ /// - Bytes
+ ///
+ public string DetectedBodyType { get; set; }
+
+ ///
+ /// The DetectedBodyTypeFromContentType, valid values are:
+ ///
+ /// - None
+ /// - String
+ /// - Json
+ /// - Bytes
+ ///
+ public string DetectedBodyTypeFromContentType { get; set; }
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Admin/Requests/LogResponseModel.cs b/src/WireMock.Net/Admin/Requests/LogResponseModel.cs
index 60190c63..b7b51a76 100644
--- a/src/WireMock.Net/Admin/Requests/LogResponseModel.cs
+++ b/src/WireMock.Net/Admin/Requests/LogResponseModel.cs
@@ -58,5 +58,15 @@ namespace WireMock.Admin.Requests
/// Gets or sets the body.
///
public EncodingModel BodyEncoding { get; set; }
+
+ ///
+ /// The detected body type (detection based on body content).
+ ///
+ public BodyType DetectedBodyType { get; set; }
+
+ ///
+ /// The detected body type (detection based on Content-Type).
+ ///
+ public BodyType DetectedBodyTypeFromContentType { get; set; }
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Http/HttpRequestMessageHelper.cs b/src/WireMock.Net/Http/HttpRequestMessageHelper.cs
index c4da3b93..7f892b00 100644
--- a/src/WireMock.Net/Http/HttpRequestMessageHelper.cs
+++ b/src/WireMock.Net/Http/HttpRequestMessageHelper.cs
@@ -2,16 +2,21 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
-using System.Text;
+using JetBrains.Annotations;
using MimeKit;
using Newtonsoft.Json;
+using WireMock.Util;
+using WireMock.Validation;
namespace WireMock.Http
{
internal static class HttpRequestMessageHelper
{
- public static HttpRequestMessage Create(RequestMessage requestMessage, string url)
+ internal static HttpRequestMessage Create([NotNull] RequestMessage requestMessage, [NotNull] string url)
{
+ Check.NotNull(requestMessage, nameof(requestMessage));
+ Check.NotNullOrEmpty(url, nameof(url));
+
var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);
ContentType contentType = null;
@@ -21,40 +26,25 @@ namespace WireMock.Http
ContentType.TryParse(value, out contentType);
}
- // Set Body if present
- if (requestMessage.BodyAsBytes != null)
+ switch (requestMessage.BodyData?.DetectedBodyType)
{
- httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);
- }
- else if (requestMessage.BodyAsJson != null)
- {
- if (contentType != null)
- {
- var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");
- httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson), encoding, contentType.MimeType);
- }
- else
- {
- httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson), requestMessage.BodyEncoding);
- }
- }
- else if (requestMessage.Body != null)
- {
- if (contentType != null)
- {
- var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");
- httpRequestMessage.Content = new StringContent(requestMessage.Body, encoding, contentType.MimeType);
- }
- else
- {
- httpRequestMessage.Content = new StringContent(requestMessage.Body, requestMessage.BodyEncoding);
- }
+ case BodyType.Bytes:
+ httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyData.BodyAsBytes);
+ break;
+
+ case BodyType.Json:
+ httpRequestMessage.Content = StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType);
+ break;
+
+ case BodyType.String:
+ httpRequestMessage.Content = StringContentHelper.Create(requestMessage.BodyData.BodyAsString, contentType);
+ break;
}
// Overwrite the host header
httpRequestMessage.Headers.Host = new Uri(url).Authority;
- // Set other headers if present and if not excluded
+ // Set other headers if present
if (requestMessage.Headers == null || requestMessage.Headers.Count == 0)
{
return httpRequestMessage;
@@ -63,6 +53,7 @@ namespace WireMock.Http
var excludeHeaders = new List { HttpKnownHeaderNames.Host, HttpKnownHeaderNames.ContentLength };
if (contentType != null)
{
+ // Content-Type should be set on the content
excludeHeaders.Add(HttpKnownHeaderNames.ContentType);
}
diff --git a/src/WireMock.Net/Http/HttpResponseMessageHelper.cs b/src/WireMock.Net/Http/HttpResponseMessageHelper.cs
index 1be9dfd5..fa134e17 100644
--- a/src/WireMock.Net/Http/HttpResponseMessageHelper.cs
+++ b/src/WireMock.Net/Http/HttpResponseMessageHelper.cs
@@ -24,10 +24,7 @@ namespace WireMock.Http
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
}
- var body = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
- responseMessage.Body = body.BodyAsString;
- responseMessage.BodyAsJson = body.BodyAsJson;
- responseMessage.BodyAsBytes = body.BodyAsBytes;
+ responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
}
foreach (var header in headers)
diff --git a/src/WireMock.Net/Http/StringContentHelper.cs b/src/WireMock.Net/Http/StringContentHelper.cs
new file mode 100644
index 00000000..2d9446f8
--- /dev/null
+++ b/src/WireMock.Net/Http/StringContentHelper.cs
@@ -0,0 +1,38 @@
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using JetBrains.Annotations;
+using MimeKit;
+using WireMock.Validation;
+
+namespace WireMock.Http
+{
+ internal static class StringContentHelper
+ {
+ ///
+ /// Creates a StringContent object. Note that the Encoding is only set when it's also set on the original header.
+ ///
+ /// The string content (cannot be null)
+ /// The ContentType (can be null)
+ /// StringContent
+ internal static StringContent Create([NotNull] string content, [CanBeNull] ContentType contentType)
+ {
+ Check.NotNull(content, nameof(content));
+
+ if (contentType == null)
+ {
+ return new StringContent(content);
+ }
+
+ if (contentType.Charset == null)
+ {
+ var stringContent = new StringContent(content);
+ stringContent.Headers.ContentType = new MediaTypeHeaderValue(contentType.MimeType);
+ return stringContent;
+ }
+
+ var encoding = Encoding.GetEncoding(contentType.Charset);
+ return new StringContent(content, encoding, contentType.MimeType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net/Mapping.cs b/src/WireMock.Net/Mapping.cs
index b35a47c3..cbf24ec5 100644
--- a/src/WireMock.Net/Mapping.cs
+++ b/src/WireMock.Net/Mapping.cs
@@ -24,15 +24,12 @@ namespace WireMock
public int Priority { get; }
///
- [CanBeNull]
public string Scenario { get; }
///
- [CanBeNull]
public string ExecutionConditionState { get; }
///
- [CanBeNull]
public string NextState { get; }
///
@@ -79,7 +76,7 @@ namespace WireMock
}
///
- public RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, [CanBeNull] string nextState)
+ public RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, string nextState)
{
var result = new RequestMatchResult();
diff --git a/src/WireMock.Net/Matchers/IValueMatcher.cs b/src/WireMock.Net/Matchers/IValueMatcher.cs
index 36426f4f..503068a7 100644
--- a/src/WireMock.Net/Matchers/IValueMatcher.cs
+++ b/src/WireMock.Net/Matchers/IValueMatcher.cs
@@ -7,7 +7,7 @@
public interface IValueMatcher: IObjectMatcher
{
///
- /// Gets the value (can be a string or an obejct).
+ /// Gets the value (can be a string or an object).
///
/// Value
object Value { get; }
diff --git a/src/WireMock.Net/Matchers/MatchScores.cs b/src/WireMock.Net/Matchers/MatchScores.cs
index c4679578..fd03d2d3 100644
--- a/src/WireMock.Net/Matchers/MatchScores.cs
+++ b/src/WireMock.Net/Matchers/MatchScores.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
namespace WireMock.Matchers
@@ -11,7 +12,7 @@ namespace WireMock.Matchers
///
/// The tolerance
///
- public const double Tolerance = 0.0001;
+ public const double Tolerance = 0.000001;
///
/// The default mismatch score
@@ -28,6 +29,16 @@ namespace WireMock.Matchers
///
public const double AlmostPerfect = 0.99;
+ ///
+ /// Is the value a perfect match?
+ ///
+ /// The value.
+ /// true/false
+ public static bool IsPerfect(double value)
+ {
+ return Math.Abs(value - Perfect) < Tolerance;
+ }
+
///
/// Convert a bool to the score.
///
@@ -39,7 +50,7 @@ namespace WireMock.Matchers
}
///
- /// Calculates the score from multiple funcs.
+ /// Calculates the score from multiple values.
///
/// The values.
/// average score
@@ -49,7 +60,7 @@ namespace WireMock.Matchers
}
///
- /// Calculates the score from multiple funcs.
+ /// Calculates the score from multiple values.
///
/// The values.
/// average score
diff --git a/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs b/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs
index e0a08f1f..18a81443 100644
--- a/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs
+++ b/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs
@@ -1,5 +1,6 @@
using System;
using JetBrains.Annotations;
+using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Matchers.Request
@@ -93,6 +94,7 @@ namespace WireMock.Matchers.Request
public RequestMessageBodyMatcher([NotNull] IMatcher matcher)
{
Check.NotNull(matcher, nameof(matcher));
+
Matcher = matcher;
}
@@ -109,47 +111,41 @@ namespace WireMock.Matchers.Request
if (Matcher is IObjectMatcher objectMatcher)
{
// If the body is a JSON object, try to match.
- if (requestMessage.BodyAsJson != null)
+ if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
{
- return objectMatcher.IsMatch(requestMessage.BodyAsJson);
+ return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsJson);
}
// If the body is a byte array, try to match.
- if (requestMessage.BodyAsBytes != null)
+ if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Bytes)
{
- return objectMatcher.IsMatch(requestMessage.BodyAsBytes);
+ return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
}
}
// Check if the matcher is a IStringMatcher
if (Matcher is IStringMatcher stringMatcher)
{
- // If the body is a JSON object, try to use Body (string) to match.
- if (requestMessage.BodyAsJson != null && requestMessage.Body != null)
+ // If the body is a Json or a String, use the BodyAsString to match on.
+ if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json || requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
{
- return stringMatcher.IsMatch(requestMessage.Body);
- }
-
- // If the string body is defined, try to match.
- if (requestMessage.Body != null)
- {
- return stringMatcher.IsMatch(requestMessage.Body);
+ return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
}
}
if (Func != null)
{
- return MatchScores.ToScore(requestMessage.Body != null && Func(requestMessage.Body));
- }
-
- if (DataFunc != null)
- {
- return MatchScores.ToScore(requestMessage.BodyAsBytes != null && DataFunc(requestMessage.BodyAsBytes));
+ return MatchScores.ToScore(requestMessage?.BodyData?.DetectedBodyType == BodyType.String && Func(requestMessage.BodyData.BodyAsString));
}
if (JsonFunc != null)
{
- return MatchScores.ToScore(requestMessage.BodyAsJson != null && JsonFunc(requestMessage.BodyAsJson));
+ return MatchScores.ToScore(requestMessage?.BodyData?.DetectedBodyType == BodyType.Json && JsonFunc(requestMessage.BodyData.BodyAsJson));
+ }
+
+ if (DataFunc != null)
+ {
+ return MatchScores.ToScore(requestMessage?.BodyData?.DetectedBodyType == BodyType.Bytes && DataFunc(requestMessage.BodyData.BodyAsBytes));
}
return MatchScores.Mismatch;
diff --git a/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs b/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs
index b76ce625..6c0e1342 100644
--- a/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs
+++ b/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs
@@ -47,7 +47,7 @@ namespace WireMock.Owin.Mappers
}
BodyData body = null;
- if (request.Body != null && ShouldParseBody(method))
+ if (request.Body != null && BodyParser.ShouldParseBody(method))
{
body = await BodyParser.Parse(request.Body, request.ContentType);
}
@@ -69,21 +69,5 @@ namespace WireMock.Owin.Mappers
#endif
return (urldetails, clientIP);
}
-
- private bool ShouldParseBody(string method)
- {
- /*
- HEAD - No defined body semantics.
- GET - No defined body semantics.
- PUT - Body supported.
- POST - Body supported.
- DELETE - No defined body semantics.
- TRACE - Body not supported.
- OPTIONS - Body supported but no semantics on usage (maybe in the future).
- CONNECT - No defined body semantics
- PATCH - Body supported.
- */
- return new[] { "PUT", "POST", "OPTIONS", "PATCH" }.Contains(method.ToUpper());
- }
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs b/src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs
index fc1e1e8a..aefdcafa 100644
--- a/src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs
+++ b/src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs
@@ -45,23 +45,25 @@ namespace WireMock.Owin.Mappers
response.StatusCode = responseMessage.StatusCode;
byte[] bytes = null;
- if (responseMessage.BodyAsBytes != null)
+ switch (responseMessage.BodyData?.DetectedBodyType)
{
- bytes = responseMessage.BodyAsBytes;
- }
- else if (responseMessage.BodyAsFile != null)
- {
- bytes = File.ReadAllBytes(responseMessage.BodyAsFile);
- }
- else if (responseMessage.BodyAsJson != null)
- {
- Formatting formatting = responseMessage.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
- string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
- bytes = (responseMessage.BodyEncoding ?? _utf8NoBom).GetBytes(jsonBody);
- }
- else if (responseMessage.Body != null)
- {
- bytes = (responseMessage.BodyEncoding ?? _utf8NoBom).GetBytes(responseMessage.Body);
+ case BodyType.String:
+ bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(responseMessage.BodyData.BodyAsString);
+ break;
+
+ case BodyType.Json:
+ Formatting formatting = responseMessage.BodyData.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
+ string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
+ bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
+ break;
+
+ case BodyType.Bytes:
+ bytes = responseMessage.BodyData.BodyAsBytes;
+ break;
+
+ case BodyType.File:
+ bytes = File.ReadAllBytes(responseMessage.BodyData.BodyAsFile);
+ break;
}
SetResponseHeaders(responseMessage, response);
diff --git a/src/WireMock.Net/Owin/OwinSelfHost.cs b/src/WireMock.Net/Owin/OwinSelfHost.cs
index f6c3c027..eb4e0d14 100644
--- a/src/WireMock.Net/Owin/OwinSelfHost.cs
+++ b/src/WireMock.Net/Owin/OwinSelfHost.cs
@@ -94,7 +94,7 @@ namespace WireMock.Owin
IsStarted = true;
// WaitHandle is signaled when the token is cancelled,
- // which will be more efficent than Thread.Sleep in while loop
+ // which will be more efficient than Thread.Sleep in while loop
_cts.Token.WaitHandle.WaitOne();
}
catch (Exception e)
diff --git a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
index aa7a2f89..cc8741cf 100644
--- a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
+++ b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
@@ -26,7 +26,7 @@ namespace WireMock.Owin
public ConcurrentDictionary Scenarios { get; } = new ConcurrentDictionary();
- public ObservableCollection LogEntries { get; } = new ConcurentObservableCollection();
+ public ObservableCollection LogEntries { get; } = new ConcurrentObservableCollection();
public int? RequestLogExpirationDuration { get; set; }
diff --git a/src/WireMock.Net/RequestMessage.cs b/src/WireMock.Net/RequestMessage.cs
index 8b36290d..5a7262fe 100644
--- a/src/WireMock.Net/RequestMessage.cs
+++ b/src/WireMock.Net/RequestMessage.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using System.Net;
using JetBrains.Annotations;
using WireMock.Models;
@@ -81,19 +80,34 @@ namespace WireMock
public string RawQuery { get; }
///
- /// The original body as string, this is defined when Body or BodyAsJson are not null.
+ /// The body.
+ ///
+ public BodyData BodyData { get; }
+
+ ///
+ /// The original body as string. Convenience getter for Handlebars.
///
public string Body { get; }
///
- /// The body (as JSON object).
+ /// The body (as JSON object). Convenience getter for Handlebars.
///
- public object BodyAsJson { get; set; }
+ public object BodyAsJson { get; }
///
- /// The body (as bytearray).
+ /// The body (as bytearray). Convenience getter for Handlebars.
///
- public byte[] BodyAsBytes { get; set; }
+ public byte[] BodyAsBytes { get; }
+
+ ///
+ /// The detected body type. Convenience getter for Handlebars.
+ ///
+ public string DetectedBodyType { get; }
+
+ ///
+ /// The detected body type from the Content-Type header. Convenience getter for Handlebars.
+ ///
+ public string DetectedBodyTypeFromContentType { get; }
///
/// Gets the Host
@@ -115,21 +129,16 @@ namespace WireMock
///
public string Origin { get; }
- ///
- /// The body encoding.
- ///
- public Encoding BodyEncoding { get; }
-
///
/// Initializes a new instance of the class.
///
/// The original url details.
/// The HTTP method.
/// The client IP Address.
- /// The body.
+ /// The BodyData.
/// The headers.
/// The cookies.
- public RequestMessage([NotNull] UrlDetails urlDetails, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyData body = null, [CanBeNull] IDictionary headers = null, [CanBeNull] IDictionary cookies = null)
+ public RequestMessage([NotNull] UrlDetails urlDetails, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyData bodyData = null, [CanBeNull] IDictionary headers = null, [CanBeNull] IDictionary cookies = null)
{
Check.NotNull(urlDetails, nameof(urlDetails));
Check.NotNull(method, nameof(method));
@@ -150,10 +159,14 @@ namespace WireMock
Method = method;
ClientIP = clientIP;
- Body = body?.BodyAsString;
- BodyEncoding = body?.Encoding;
- BodyAsJson = body?.BodyAsJson;
- BodyAsBytes = body?.BodyAsBytes;
+ BodyData = bodyData;
+
+ // Convenience getters for e.g. Handlebars
+ Body = BodyData?.BodyAsString;
+ BodyAsJson = BodyData?.BodyAsJson;
+ BodyAsBytes = BodyData?.BodyAsBytes;
+ DetectedBodyType = BodyData?.DetectedBodyType.ToString();
+ DetectedBodyTypeFromContentType = BodyData?.DetectedBodyTypeFromContentType.ToString();
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList(header.Value));
Cookies = cookies;
diff --git a/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs b/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs
index 2ab12e77..0ebd1c25 100644
--- a/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs
+++ b/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs
@@ -56,17 +56,17 @@ namespace WireMock.ResponseBuilders
///
/// WithBody : Create a string response based on a Base64 string (which will be decoded to a normal string).
///
- /// The body.
+ /// The body.
/// The Encoding.
/// A .
[Obsolete("Should not be used, will be removed in future.")]
- IResponseBuilder WithBodyFromBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
+ IResponseBuilder WithBodyFromBase64([NotNull] string bodyAsBase64, [CanBeNull] Encoding encoding = null);
///
/// WithBodyFromFile : Create a ... response based on a File.
///
/// The filename.
- /// Defines if this file is cached in memory or retrieved from disk everytime the response is created.
+ /// Defines if this file is cached in memory or retrieved from disk every time the response is created.
/// A .
IResponseBuilder WithBodyFromFile([NotNull] string filename, bool cache = true);
}
diff --git a/src/WireMock.Net/ResponseBuilders/Response.cs b/src/WireMock.Net/ResponseBuilders/Response.cs
index 58980af6..fd8da1db 100644
--- a/src/WireMock.Net/ResponseBuilders/Response.cs
+++ b/src/WireMock.Net/ResponseBuilders/Response.cs
@@ -178,9 +178,12 @@ namespace WireMock.ResponseBuilders
return WithCallbackInternal(false, req => new ResponseMessage
{
- Body = bodyFactory(req),
- BodyDestination = destination,
- BodyEncoding = encoding ?? Encoding.UTF8
+ BodyData = new BodyData
+ {
+ DetectedBodyType = BodyType.String,
+ BodyAsString = bodyFactory(req),
+ Encoding = encoding ?? Encoding.UTF8
+ }
});
}
@@ -190,19 +193,20 @@ namespace WireMock.ResponseBuilders
Check.NotNull(body, nameof(body));
ResponseMessage.BodyDestination = destination;
+ ResponseMessage.BodyData = new BodyData();
switch (destination)
{
case BodyDestinationFormat.String:
var enc = encoding ?? Encoding.UTF8;
- ResponseMessage.BodyAsBytes = null;
- ResponseMessage.Body = enc.GetString(body);
- ResponseMessage.BodyEncoding = enc;
+ ResponseMessage.BodyData.DetectedBodyType = BodyType.String;
+ ResponseMessage.BodyData.BodyAsString = enc.GetString(body);
+ ResponseMessage.BodyData.Encoding = enc;
break;
default:
- ResponseMessage.BodyAsBytes = body;
- ResponseMessage.BodyEncoding = null;
+ ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
+ ResponseMessage.BodyData.BodyAsBytes = body;
break;
}
@@ -214,20 +218,20 @@ namespace WireMock.ResponseBuilders
{
Check.NotNull(filename, nameof(filename));
- ResponseMessage.BodyEncoding = null;
- ResponseMessage.BodyAsFileIsCached = cache;
+ ResponseMessage.BodyData = new BodyData
+ {
+ BodyAsFileIsCached = cache
+ };
if (cache)
{
- ResponseMessage.Body = null;
- ResponseMessage.BodyAsBytes = File.ReadAllBytes(filename);
- ResponseMessage.BodyAsFile = null;
+ ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
+ ResponseMessage.BodyData.BodyAsBytes = File.ReadAllBytes(filename);
}
else
{
- ResponseMessage.Body = null;
- ResponseMessage.BodyAsBytes = null;
- ResponseMessage.BodyAsFile = filename;
+ ResponseMessage.BodyData.DetectedBodyType = BodyType.File;
+ ResponseMessage.BodyData.BodyAsFile = filename;
}
return this;
@@ -241,26 +245,27 @@ namespace WireMock.ResponseBuilders
encoding = encoding ?? Encoding.UTF8;
ResponseMessage.BodyDestination = destination;
- ResponseMessage.BodyEncoding = encoding;
+
+ ResponseMessage.BodyData = new BodyData
+ {
+ Encoding = encoding
+ };
switch (destination)
{
case BodyDestinationFormat.Bytes:
- ResponseMessage.Body = null;
- ResponseMessage.BodyAsJson = null;
- ResponseMessage.BodyAsBytes = encoding.GetBytes(body);
+ ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
+ ResponseMessage.BodyData.BodyAsBytes= encoding.GetBytes(body);
break;
case BodyDestinationFormat.Json:
- ResponseMessage.Body = null;
- ResponseMessage.BodyAsJson = JsonConvert.DeserializeObject(body);
- ResponseMessage.BodyAsBytes = null;
+ ResponseMessage.BodyData.DetectedBodyType = BodyType.Json;
+ ResponseMessage.BodyData.BodyAsJson = JsonConvert.DeserializeObject(body);
break;
default:
- ResponseMessage.Body = body;
- ResponseMessage.BodyAsJson = null;
- ResponseMessage.BodyAsBytes = null;
+ ResponseMessage.BodyData.DetectedBodyType = BodyType.String;
+ ResponseMessage.BodyData.BodyAsString = body;
break;
}
@@ -273,10 +278,14 @@ namespace WireMock.ResponseBuilders
Check.NotNull(body, nameof(body));
ResponseMessage.BodyDestination = null;
- ResponseMessage.BodyAsJson = body;
- ResponseMessage.BodyEncoding = encoding;
- ResponseMessage.BodyAsJsonIndented = indented;
-
+ ResponseMessage.BodyData = new BodyData
+ {
+ Encoding = encoding,
+ DetectedBodyType = BodyType.Json,
+ BodyAsJson = body,
+ BodyAsJsonIndented = indented
+ };
+
return this;
}
@@ -287,15 +296,18 @@ namespace WireMock.ResponseBuilders
}
///
- public IResponseBuilder WithBodyFromBase64(string bodyAsbase64, Encoding encoding = null)
+ public IResponseBuilder WithBodyFromBase64(string bodyAsBase64, Encoding encoding = null)
{
- Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));
+ Check.NotNull(bodyAsBase64, nameof(bodyAsBase64));
encoding = encoding ?? Encoding.UTF8;
- ResponseMessage.BodyDestination = null;
- ResponseMessage.Body = encoding.GetString(Convert.FromBase64String(bodyAsbase64));
- ResponseMessage.BodyEncoding = encoding;
+ ResponseMessage.BodyData = new BodyData
+ {
+ Encoding = encoding,
+ DetectedBodyType = BodyType.String,
+ BodyAsString = encoding.GetString(Convert.FromBase64String(bodyAsBase64))
+ };
return this;
}
diff --git a/src/WireMock.Net/ResponseMessage.cs b/src/WireMock.Net/ResponseMessage.cs
index 79551b67..1d5c49c3 100644
--- a/src/WireMock.Net/ResponseMessage.cs
+++ b/src/WireMock.Net/ResponseMessage.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using WireMock.Util;
using WireMock.Validation;
@@ -32,39 +31,9 @@ namespace WireMock
public string BodyDestination { get; set; }
///
- /// Gets or sets the body as a string.
+ /// The Body.
///
- public string Body { get; set; }
-
- ///
- /// Gets or sets the body as a json object.
- ///
- public object BodyAsJson { get; set; }
-
- ///
- /// Gets or sets a value indicating whether child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.
- ///
- public bool? BodyAsJsonIndented { get; set; }
-
- ///
- /// Gets or sets the body as bytes.
- ///
- public byte[] BodyAsBytes { get; set; }
-
- ///
- /// Gets or sets the body as a file.
- ///
- public string BodyAsFile { get; set; }
-
- ///
- /// Is the body as file cached?
- ///
- public bool? BodyAsFileIsCached { get; set; }
-
- ///
- /// Gets or sets the body encoding.
- ///
- public Encoding BodyEncoding { get; set; } = new UTF8Encoding(false);
+ public BodyData BodyData { get; set; }
///
/// Adds the header.
diff --git a/src/WireMock.Net/ResponseMessageBuilder.cs b/src/WireMock.Net/ResponseMessageBuilder.cs
index cefe5d36..b4903e89 100644
--- a/src/WireMock.Net/ResponseMessageBuilder.cs
+++ b/src/WireMock.Net/ResponseMessageBuilder.cs
@@ -16,10 +16,18 @@ namespace WireMock
var response = new ResponseMessage
{
StatusCode = statusCode,
- Headers = ContentTypeJsonHeaders,
- BodyAsJson = message != null ? new StatusModel { Status = message, Guid = guid } : null
+ Headers = ContentTypeJsonHeaders
};
+ if (message != null)
+ {
+ response.BodyData = new BodyData
+ {
+ DetectedBodyType = BodyType.Json,
+ BodyAsJson = new StatusModel { Status = message, Guid = guid }
+ };
+ }
+
return response;
}
}
diff --git a/src/WireMock.Net/Serialization/LogEntryMapper.cs b/src/WireMock.Net/Serialization/LogEntryMapper.cs
index ee4a539b..0cd9adf2 100644
--- a/src/WireMock.Net/Serialization/LogEntryMapper.cs
+++ b/src/WireMock.Net/Serialization/LogEntryMapper.cs
@@ -2,6 +2,7 @@
using WireMock.Admin.Mappings;
using WireMock.Admin.Requests;
using WireMock.Logging;
+using WireMock.Util;
namespace WireMock.Serialization
{
@@ -9,51 +10,102 @@ namespace WireMock.Serialization
{
public static LogEntryModel Map(LogEntry logEntry)
{
+ var logRequestModel = new LogRequestModel
+ {
+ DateTime = logEntry.RequestMessage.DateTime,
+ ClientIP = logEntry.RequestMessage.ClientIP,
+ Path = logEntry.RequestMessage.Path,
+ AbsolutePath = logEntry.RequestMessage.AbsolutePath,
+ Url = logEntry.RequestMessage.Url,
+ AbsoluteUrl = logEntry.RequestMessage.AbsoluteUrl,
+ Query = logEntry.RequestMessage.Query,
+ Method = logEntry.RequestMessage.Method,
+ Headers = logEntry.RequestMessage.Headers,
+ Cookies = logEntry.RequestMessage.Cookies
+ };
+
+ if (logEntry.RequestMessage.BodyData != null)
+ {
+ logRequestModel.DetectedBodyType = logEntry.RequestMessage.BodyData.DetectedBodyType.ToString();
+ logRequestModel.DetectedBodyTypeFromContentType = logEntry.RequestMessage.BodyData.DetectedBodyTypeFromContentType.ToString();
+
+ switch (logEntry.RequestMessage.BodyData.DetectedBodyType)
+ {
+ case BodyType.String:
+ logRequestModel.Body = logEntry.RequestMessage.BodyData.BodyAsString;
+ break;
+
+ case BodyType.Json:
+ logRequestModel.Body = logEntry.RequestMessage.BodyData.BodyAsString; // In case of Json, do also save the Body as string (backwards compatible)
+ logRequestModel.BodyAsJson = logEntry.RequestMessage.BodyData.BodyAsJson;
+ break;
+
+ case BodyType.Bytes:
+ logRequestModel.BodyAsBytes = logEntry.RequestMessage.BodyData.BodyAsBytes;
+ break;
+ }
+
+ logRequestModel.BodyEncoding = logEntry.RequestMessage.BodyData.Encoding != null
+ ? new EncodingModel
+ {
+ EncodingName = logEntry.RequestMessage.BodyData.Encoding.EncodingName,
+ CodePage = logEntry.RequestMessage.BodyData.Encoding.CodePage,
+ WebName = logEntry.RequestMessage.BodyData.Encoding.WebName
+ }
+ : null;
+ }
+
+ var logResponseModel = new LogResponseModel
+ {
+ StatusCode = logEntry.ResponseMessage.StatusCode,
+ Headers = logEntry.ResponseMessage.Headers
+ };
+
+ if (logEntry.ResponseMessage.BodyData != null)
+ {
+ logResponseModel.BodyOriginal = logEntry.ResponseMessage.BodyOriginal;
+ logResponseModel.BodyDestination = logEntry.ResponseMessage.BodyDestination;
+
+ logResponseModel.DetectedBodyType = logEntry.ResponseMessage.BodyData.DetectedBodyType;
+ logResponseModel.DetectedBodyTypeFromContentType = logEntry.ResponseMessage.BodyData.DetectedBodyTypeFromContentType;
+
+ switch (logEntry.ResponseMessage.BodyData.DetectedBodyType)
+ {
+ case BodyType.String:
+ logResponseModel.Body = logEntry.ResponseMessage.BodyData.BodyAsString;
+ break;
+
+ case BodyType.Json:
+ logResponseModel.BodyAsJson = logEntry.ResponseMessage.BodyData.BodyAsJson;
+ break;
+
+ case BodyType.Bytes:
+ logResponseModel.BodyAsBytes = logEntry.ResponseMessage.BodyData.BodyAsBytes;
+ break;
+
+ case BodyType.File:
+ logResponseModel.BodyAsFile = logEntry.ResponseMessage.BodyData.BodyAsFile;
+ logResponseModel.BodyAsFileIsCached = logEntry.ResponseMessage.BodyData.BodyAsFileIsCached;
+ break;
+ }
+
+ logResponseModel.BodyEncoding = logEntry.ResponseMessage.BodyData.Encoding != null
+ ? new EncodingModel
+ {
+ EncodingName = logEntry.ResponseMessage.BodyData.Encoding.EncodingName,
+ CodePage = logEntry.ResponseMessage.BodyData.Encoding.CodePage,
+ WebName = logEntry.ResponseMessage.BodyData.Encoding.WebName
+ }
+ : null;
+ }
+
return new LogEntryModel
{
Guid = logEntry.Guid,
- Request = new LogRequestModel
- {
- DateTime = logEntry.RequestMessage.DateTime,
- ClientIP = logEntry.RequestMessage.ClientIP,
- Path = logEntry.RequestMessage.Path,
- AbsolutePath = logEntry.RequestMessage.AbsolutePath,
- Url = logEntry.RequestMessage.Url,
- AbsoluteUrl = logEntry.RequestMessage.AbsoluteUrl,
- Query = logEntry.RequestMessage.Query,
- Method = logEntry.RequestMessage.Method,
- Body = logEntry.RequestMessage.Body,
- BodyAsJson = logEntry.RequestMessage.BodyAsJson,
- BodyAsBytes = logEntry.RequestMessage.BodyAsBytes,
- Headers = logEntry.RequestMessage.Headers,
- Cookies = logEntry.RequestMessage.Cookies,
- BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel
- {
- EncodingName = logEntry.RequestMessage.BodyEncoding.EncodingName,
- CodePage = logEntry.RequestMessage.BodyEncoding.CodePage,
- WebName = logEntry.RequestMessage.BodyEncoding.WebName
- } : null
- },
- Response = new LogResponseModel
- {
- StatusCode = logEntry.ResponseMessage.StatusCode,
- BodyDestination = logEntry.ResponseMessage.BodyDestination,
- Body = logEntry.ResponseMessage.Body,
- BodyAsJson = logEntry.ResponseMessage.BodyAsJson,
- BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
- BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
- BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
- BodyAsFileIsCached = logEntry.ResponseMessage.BodyAsFileIsCached,
- Headers = logEntry.ResponseMessage.Headers,
- BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
- {
- EncodingName = logEntry.ResponseMessage.BodyEncoding.EncodingName,
- CodePage = logEntry.ResponseMessage.BodyEncoding.CodePage,
- WebName = logEntry.ResponseMessage.BodyEncoding.WebName
- } : null
- },
MappingGuid = logEntry.MappingGuid,
MappingTitle = logEntry.MappingTitle,
+ Request = logRequestModel,
+ Response = logResponseModel,
RequestMatchResult = logEntry.RequestMatchResult != null ? new LogRequestMatchModel
{
TotalScore = logEntry.RequestMatchResult.TotalScore,
diff --git a/src/WireMock.Net/Serialization/MappingConverter.cs b/src/WireMock.Net/Serialization/MappingConverter.cs
index a53b66ab..46b5af01 100644
--- a/src/WireMock.Net/Serialization/MappingConverter.cs
+++ b/src/WireMock.Net/Serialization/MappingConverter.cs
@@ -100,22 +100,40 @@ namespace WireMock.Serialization
mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
mappingModel.Response.Headers = Map(response.ResponseMessage.Headers);
- mappingModel.Response.BodyAsJson = response.ResponseMessage.BodyAsJson;
- mappingModel.Response.BodyAsJsonIndented = response.ResponseMessage.BodyAsJsonIndented;
- mappingModel.Response.Body = response.ResponseMessage.Body;
- mappingModel.Response.BodyAsBytes = response.ResponseMessage.BodyAsBytes;
- mappingModel.Response.BodyAsFile = response.ResponseMessage.BodyAsFile;
- mappingModel.Response.BodyAsFileIsCached = response.ResponseMessage.BodyAsFileIsCached;
mappingModel.Response.UseTransformer = response.UseTransformer;
- if (response.ResponseMessage.BodyEncoding != null && response.ResponseMessage.BodyEncoding.WebName != "utf-8")
+ if (response.ResponseMessage.BodyData != null)
{
- mappingModel.Response.BodyEncoding = new EncodingModel
+ switch (response.ResponseMessage.BodyData?.DetectedBodyType)
{
- EncodingName = response.ResponseMessage.BodyEncoding.EncodingName,
- CodePage = response.ResponseMessage.BodyEncoding.CodePage,
- WebName = response.ResponseMessage.BodyEncoding.WebName
- };
+ case BodyType.String:
+ mappingModel.Response.Body = response.ResponseMessage.BodyData.BodyAsString;
+ break;
+
+ case BodyType.Json:
+ mappingModel.Response.BodyAsJson = response.ResponseMessage.BodyData.BodyAsJson;
+ mappingModel.Response.BodyAsJsonIndented = response.ResponseMessage.BodyData.BodyAsJsonIndented;
+ break;
+
+ case BodyType.Bytes:
+ mappingModel.Response.BodyAsBytes = response.ResponseMessage.BodyData.BodyAsBytes;
+ break;
+
+ case BodyType.File:
+ mappingModel.Response.BodyAsFile = response.ResponseMessage.BodyData.BodyAsFile;
+ mappingModel.Response.BodyAsFileIsCached = response.ResponseMessage.BodyData.BodyAsFileIsCached;
+ break;
+ }
+
+ if (response.ResponseMessage.BodyData.Encoding != null && response.ResponseMessage.BodyData.Encoding.WebName != "utf-8")
+ {
+ mappingModel.Response.BodyEncoding = new EncodingModel
+ {
+ EncodingName = response.ResponseMessage.BodyData.Encoding.EncodingName,
+ CodePage = response.ResponseMessage.BodyData.Encoding.CodePage,
+ WebName = response.ResponseMessage.BodyData.Encoding.WebName
+ };
+ }
}
}
diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
index 02fb8ae3..47f45175 100644
--- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
@@ -274,13 +274,13 @@ namespace WireMock.Server
}
});
- if (requestMessage.BodyAsJson != null)
+ if (requestMessage.BodyData?.DetectedBodyType == BodyType.Json)
{
- request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyAsJson));
+ request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson));
}
- else if (requestMessage.Body != null)
+ else if (requestMessage.BodyData?.DetectedBodyType == BodyType.String)
{
- request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.Body));
+ request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsString));
}
var response = Response.Create(responseMessage);
@@ -764,9 +764,13 @@ namespace WireMock.Server
{
return new ResponseMessage
{
- Body = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _settings),
+ BodyData = new BodyData
+ {
+ DetectedBodyType = BodyType.String,
+ BodyAsString = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _settings)
+ },
StatusCode = 200,
- Headers = new Dictionary> { { HttpKnownHeaderNames.ContentType, new WireMockList("application/json") } }
+ Headers = new Dictionary> { { HttpKnownHeaderNames.ContentType, new WireMockList(ContentTypeJson) } }
};
}
@@ -777,9 +781,17 @@ namespace WireMock.Server
private T DeserializeObject(RequestMessage requestMessage)
{
- return requestMessage.Body != null ?
- JsonConvert.DeserializeObject(requestMessage.Body) :
- ((JObject)requestMessage.BodyAsJson).ToObject();
+ if (requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
+ {
+ return JsonConvert.DeserializeObject(requestMessage.BodyData.BodyAsString);
+ }
+
+ if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
+ {
+ return ((JObject)requestMessage.BodyData.BodyAsJson).ToObject();
+ }
+
+ return default(T);
}
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Server/FluentMockServer.cs b/src/WireMock.Net/Server/FluentMockServer.cs
index c077d0d8..6ef7421a 100644
--- a/src/WireMock.Net/Server/FluentMockServer.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.cs
@@ -5,7 +5,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
-using System.Threading.Tasks;
using Newtonsoft.Json;
using WireMock.Handlers;
using WireMock.Logging;
diff --git a/src/WireMock.Net/Transformers/HandleBarsRegex.cs b/src/WireMock.Net/Transformers/HandleBarsRegex.cs
index 05f9300d..7a0ca278 100644
--- a/src/WireMock.Net/Transformers/HandleBarsRegex.cs
+++ b/src/WireMock.Net/Transformers/HandleBarsRegex.cs
@@ -50,14 +50,12 @@ namespace WireMock.Transformers
string ParseAsString(object arg)
{
- if (arg is string)
+ if (arg is string argAsString)
{
- return (string) arg;
- }
- else
- {
- throw new NotSupportedException($"The value '{arg}' with type '{arg?.GetType()}' cannot be used in Handlebars Regex.");
+ return argAsString;
}
+
+ throw new NotSupportedException($"The value '{arg}' with type '{arg?.GetType()}' cannot be used in Handlebars Regex.");
}
return (ParseAsString(arguments[0]), ParseAsString(arguments[1]), arguments.Length == 3 ? arguments[2] : null);
diff --git a/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs b/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs
index 586219dd..2a8842a5 100644
--- a/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs
+++ b/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs
@@ -17,12 +17,12 @@ namespace WireMock.Transformers
public static ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original)
{
- bool bodyIsJson = original.BodyAsJson != null;
+ bool bodyIsJson = original.BodyData.DetectedBodyType == BodyType.Json;
var responseMessage = new ResponseMessage { StatusCode = original.StatusCode };
if (!bodyIsJson)
{
- responseMessage.BodyOriginal = original.Body;
+ responseMessage.BodyOriginal = original.BodyData.BodyAsString;
}
var template = new { request = requestMessage };
@@ -57,7 +57,7 @@ namespace WireMock.Transformers
private static void TransformBodyAsJson(object template, ResponseMessage original, ResponseMessage responseMessage)
{
JToken jToken;
- switch (original.BodyAsJson)
+ switch (original.BodyData.BodyAsJson)
{
case JObject bodyAsJObject:
jToken = bodyAsJObject;
@@ -68,13 +68,18 @@ namespace WireMock.Transformers
break;
default:
- jToken = JObject.FromObject(original.BodyAsJson);
+ jToken = JObject.FromObject(original.BodyData.BodyAsJson);
break;
}
WalkNode(jToken, template);
- responseMessage.BodyAsJson = jToken;
+ responseMessage.BodyData = new BodyData
+ {
+ DetectedBodyType = original.BodyData.DetectedBodyType,
+ DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
+ BodyAsJson = jToken
+ };
}
private static void WalkNode(JToken node, object template)
@@ -127,9 +132,14 @@ namespace WireMock.Transformers
private static void TransformBodyAsString(object template, ResponseMessage original, ResponseMessage responseMessage)
{
- var templateBody = Handlebars.Compile(original.Body);
+ var templateBody = Handlebars.Compile(original.BodyData.BodyAsString);
- responseMessage.Body = templateBody(template);
+ responseMessage.BodyData = new BodyData
+ {
+ DetectedBodyType = original.BodyData.DetectedBodyType,
+ DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
+ BodyAsString = templateBody(template)
+ };
}
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Util/BodyData.cs b/src/WireMock.Net/Util/BodyData.cs
index 2444b0f1..965dd9b2 100644
--- a/src/WireMock.Net/Util/BodyData.cs
+++ b/src/WireMock.Net/Util/BodyData.cs
@@ -26,5 +26,30 @@ namespace WireMock.Util
/// The body (as bytearray).
///
public byte[] BodyAsBytes { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.
+ ///
+ public bool? BodyAsJsonIndented { get; set; }
+
+ ///
+ /// Gets or sets the body as a file.
+ ///
+ public string BodyAsFile { get; set; }
+
+ ///
+ /// Is the body as file cached?
+ ///
+ public bool? BodyAsFileIsCached { get; set; }
+
+ ///
+ /// The detected body type (detection based on body content).
+ ///
+ public BodyType DetectedBodyType { get; set; }
+
+ ///
+ /// The detected body type (detection based on Content-Type).
+ ///
+ public BodyType DetectedBodyTypeFromContentType { get; set; }
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Util/BodyParser.cs b/src/WireMock.Net/Util/BodyParser.cs
index 58362917..66b80127 100644
--- a/src/WireMock.Net/Util/BodyParser.cs
+++ b/src/WireMock.Net/Util/BodyParser.cs
@@ -4,36 +4,112 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
+using MimeKit;
using Newtonsoft.Json;
+using WireMock.Matchers;
+using WireMock.Validation;
namespace WireMock.Util
{
internal static class BodyParser
{
- private static readonly string[] JsonContentTypes =
- {
- "application/json",
- "application/vnd.api+json"
+ private static readonly Encoding DefaultEncoding = Encoding.UTF8;
+
+ /*
+ HEAD - No defined body semantics.
+ GET - No defined body semantics.
+ PUT - Body supported.
+ POST - Body supported.
+ DELETE - No defined body semantics.
+ TRACE - Body not supported.
+ OPTIONS - Body supported but no semantics on usage (maybe in the future).
+ CONNECT - No defined body semantics
+ PATCH - Body supported.
+ */
+ private static readonly string[] AllowedBodyParseMethods = { "PUT", "POST", "OPTIONS", "PATCH" };
+
+ private static readonly IStringMatcher[] JsonContentTypesMatchers = {
+ new WildcardMatcher("application/json", true),
+ new WildcardMatcher("application/vnd.*+json", true)
};
- private static readonly string[] TextContentTypes =
+ private static readonly IStringMatcher[] TextContentTypeMatchers =
{
- "text/",
- "application/javascript", "application/typescript",
- "application/xml", "application/xhtml+xml",
- "application/x-www-form-urlencoded"
+ new WildcardMatcher("text/*", true),
+ new RegexMatcher("^application\\/(java|type)script$", true),
+ new WildcardMatcher("application/*xml", true),
+ new WildcardMatcher("application/x-www-form-urlencoded", true)
};
- private static async Task> ReadStringAsync(Stream stream)
+ public static bool ParseBodyAsIsValid([CanBeNull] string parseBodyAs)
{
- using (var streamReader = new StreamReader(stream))
- {
- string content = await streamReader.ReadToEndAsync();
-
- return new Tuple(content, streamReader.CurrentEncoding);
- }
+ return Enum.TryParse(parseBodyAs, out BodyType _);
}
+ public static bool ShouldParseBody([CanBeNull] string method)
+ {
+ return AllowedBodyParseMethods.Contains(method, StringComparer.OrdinalIgnoreCase);
+ }
+
+ public static BodyType DetectBodyTypeFromContentType([CanBeNull] string contentTypeValue)
+ {
+ if (string.IsNullOrEmpty(contentTypeValue) || !ContentType.TryParse(contentTypeValue, out ContentType contentType))
+ {
+ return BodyType.Bytes;
+ }
+
+ if (TextContentTypeMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MimeType))))
+ {
+ return BodyType.String;
+ }
+
+ if (JsonContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MimeType))))
+ {
+ return BodyType.Json;
+ }
+
+ return BodyType.Bytes;
+ }
+
+ public static async Task Parse([NotNull] Stream stream, [CanBeNull] string contentType)
+ {
+ Check.NotNull(stream, nameof(stream));
+
+ var data = new BodyData
+ {
+ BodyAsBytes = await ReadBytesAsync(stream),
+ DetectedBodyType = BodyType.Bytes,
+ DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(contentType)
+ };
+
+ // Try to get the body as String
+ try
+ {
+ data.BodyAsString = DefaultEncoding.GetString(data.BodyAsBytes);
+ data.Encoding = DefaultEncoding;
+ data.DetectedBodyType = BodyType.String;
+
+ // If string is not null or empty, try to get as Json
+ if (!string.IsNullOrEmpty(data.BodyAsString))
+ {
+ try
+ {
+ data.BodyAsJson = JsonConvert.DeserializeObject(data.BodyAsString, new JsonSerializerSettings { Formatting = Formatting.Indented });
+ data.DetectedBodyType = BodyType.Json;
+ }
+ catch
+ {
+ // JsonConvert failed, just ignore.
+ }
+ }
+ }
+ catch
+ {
+ // Reading as string failed, just ignore
+ }
+
+ return data;
+ }
private static async Task ReadBytesAsync(Stream stream)
{
using (var memoryStream = new MemoryStream())
@@ -42,47 +118,5 @@ namespace WireMock.Util
return memoryStream.ToArray();
}
}
-
- public static async Task Parse([NotNull] Stream stream, [CanBeNull] string contentTypeHeaderValue)
- {
- var data = new BodyData();
-
- if (contentTypeHeaderValue != null && TextContentTypes.Any(text => contentTypeHeaderValue.StartsWith(text, 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 && JsonContentTypes.Any(json => contentTypeHeaderValue.StartsWith(json, StringComparison.OrdinalIgnoreCase)))
- {
- var stringData = await ReadStringAsync(stream);
- data.BodyAsString = stringData.Item1;
- 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;
- }
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Util/BodyType.cs b/src/WireMock.Net/Util/BodyType.cs
new file mode 100644
index 00000000..9bc53019
--- /dev/null
+++ b/src/WireMock.Net/Util/BodyType.cs
@@ -0,0 +1,33 @@
+namespace WireMock.Util
+{
+ ///
+ /// The BodyType
+ ///
+ public enum BodyType
+ {
+ ///
+ /// No body present
+ ///
+ None,
+
+ ///
+ /// Body is a String
+ ///
+ String,
+
+ ///
+ /// Body is a Json object
+ ///
+ Json,
+
+ ///
+ /// Body is a Byte array
+ ///
+ Bytes,
+
+ ///
+ /// Body is a File
+ ///
+ File
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net/Util/ConcurentObservableCollection.cs b/src/WireMock.Net/Util/ConcurrentObservableCollection.cs
similarity index 75%
rename from src/WireMock.Net/Util/ConcurentObservableCollection.cs
rename to src/WireMock.Net/Util/ConcurrentObservableCollection.cs
index 60d2c90d..f85381ca 100644
--- a/src/WireMock.Net/Util/ConcurentObservableCollection.cs
+++ b/src/WireMock.Net/Util/ConcurrentObservableCollection.cs
@@ -8,26 +8,26 @@ namespace WireMock.Util
///
/// The type of elements in the collection.
///
- public class ConcurentObservableCollection : ObservableCollection
+ public class ConcurrentObservableCollection : ObservableCollection
{
private readonly object _lockObject = new object();
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
- public ConcurentObservableCollection() { }
+ public ConcurrentObservableCollection() { }
///
- /// Initializes a new instance of the class that contains elements copied from the specified list.
+ /// Initializes a new instance of the class that contains elements copied from the specified list.
///
/// The list from which the elements are copied.
- public ConcurentObservableCollection(List list) : base(list) { }
+ public ConcurrentObservableCollection(List list) : base(list) { }
///
- /// Initializes a new instance of the class that contains elements copied from the specified collection.
+ /// Initializes a new instance of the class that contains elements copied from the specified collection.
///
/// The collection from which the elements are copied.
- public ConcurentObservableCollection(IEnumerable collection) : base(collection) { }
+ public ConcurrentObservableCollection(IEnumerable collection) : base(collection) { }
///
protected override void ClearItems()
diff --git a/src/WireMock.Net/Util/FileHelper.cs b/src/WireMock.Net/Util/FileHelper.cs
index 5af19661..b391f060 100644
--- a/src/WireMock.Net/Util/FileHelper.cs
+++ b/src/WireMock.Net/Util/FileHelper.cs
@@ -11,16 +11,16 @@ namespace WireMock.Util
private const int NumberOfRetries = 3;
private const int DelayOnRetry = 500;
- public static string ReadAllTextWithRetryAndDelay([NotNull] IFileSystemHandler filehandler, [NotNull] string path)
+ public static string ReadAllTextWithRetryAndDelay([NotNull] IFileSystemHandler handler, [NotNull] string path)
{
- Check.NotNull(filehandler, nameof(filehandler));
+ Check.NotNull(handler, nameof(handler));
Check.NotNullOrEmpty(path, nameof(path));
for (int i = 1; i <= NumberOfRetries; ++i)
{
try
{
- return filehandler.ReadMappingFile(path);
+ return handler.ReadMappingFile(path);
}
catch
{
diff --git a/src/WireMock.Net/Util/JsonUtils.cs b/src/WireMock.Net/Util/JsonUtils.cs
index a8a8715f..79ccba9e 100644
--- a/src/WireMock.Net/Util/JsonUtils.cs
+++ b/src/WireMock.Net/Util/JsonUtils.cs
@@ -92,7 +92,7 @@ namespace WireMock.Util
private static void ProcessItem(JToken node, string path, string propertyName, List lines)
{
- string castText = string.Empty;
+ string castText;
switch (node.Type)
{
case JTokenType.Boolean:
@@ -132,8 +132,7 @@ namespace WireMock.Util
break;
default:
- throw new NotSupportedException(
- $"JTokenType '{node.Type}' cannot be converted to a Dynamic Linq cast operator.");
+ throw new NotSupportedException($"JTokenType '{node.Type}' cannot be converted to a Dynamic Linq cast operator.");
}
if (!string.IsNullOrEmpty(propertyName))
diff --git a/src/WireMock.Net/Util/UrlUtils.cs b/src/WireMock.Net/Util/UrlUtils.cs
index 78b070a8..7ed37d65 100644
--- a/src/WireMock.Net/Util/UrlUtils.cs
+++ b/src/WireMock.Net/Util/UrlUtils.cs
@@ -1,6 +1,7 @@
using System;
using JetBrains.Annotations;
using WireMock.Models;
+using WireMock.Validation;
#if !USE_ASPNETCORE
using Microsoft.Owin;
#else
@@ -13,6 +14,8 @@ namespace WireMock.Util
{
public static UrlDetails Parse([NotNull] Uri uri, PathString pathBase)
{
+ Check.NotNull(uri, nameof(uri));
+
if (!pathBase.HasValue)
{
return new UrlDetails(uri, uri);
@@ -26,7 +29,7 @@ namespace WireMock.Util
private static string RemoveFirst(string text, string search)
{
- int pos = text.IndexOf(search);
+ int pos = text.IndexOf(search, StringComparison.Ordinal);
if (pos < 0)
{
return text;
diff --git a/src/WireMock.Net/WireMock.Net.csproj b/src/WireMock.Net/WireMock.Net.csproj
index 46aff3d7..9a5f95c8 100644
--- a/src/WireMock.Net/WireMock.Net.csproj
+++ b/src/WireMock.Net/WireMock.Net.csproj
@@ -2,7 +2,6 @@
Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.
WireMock.Net
- 1.0.4.18
Stef Heyenrath
net451;net452;net46;net461;netstandard1.3;netstandard2.0
true
@@ -21,6 +20,8 @@
True
True
{D3804228-91F4-4502-9595-39584E5A01AD}
+ true
+ true
@@ -47,57 +48,66 @@
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
-
-
+
+
+
-
+
+
-
+
+
-
+
+
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/FluentMockServerTests.Admin.cs b/test/WireMock.Net.Tests/FluentMockServerTests.Admin.cs
index 2667ef88..97e164a4 100644
--- a/test/WireMock.Net.Tests/FluentMockServerTests.Admin.cs
+++ b/test/WireMock.Net.Tests/FluentMockServerTests.Admin.cs
@@ -319,7 +319,7 @@ namespace WireMock.Net.Tests
Check.That(server.LogEntries).HasSize(1);
var requestLogged = server.LogEntries.First();
Check.That(requestLogged.RequestMessage.Method).IsEqualTo("GET");
- Check.That(requestLogged.RequestMessage.BodyAsBytes).IsNull();
+ Check.That(requestLogged.RequestMessage.BodyData).IsNull();
}
[Fact]
diff --git a/test/WireMock.Net.Tests/FluentMockServerTests.Proxy.cs b/test/WireMock.Net.Tests/FluentMockServerTests.Proxy.cs
index d487ef98..cd696900 100644
--- a/test/WireMock.Net.Tests/FluentMockServerTests.Proxy.cs
+++ b/test/WireMock.Net.Tests/FluentMockServerTests.Proxy.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
+using System.Text;
using System.Threading.Tasks;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
@@ -67,7 +68,7 @@ namespace WireMock.Net.Tests
{
Method = HttpMethod.Post,
RequestUri = new Uri($"{server.Urls[0]}{path}"),
- Content = new StringContent("stringContent")
+ Content = new StringContent("stringContent", Encoding.ASCII)
};
requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
requestMessage.Content.Headers.Add("bbb", "test");
@@ -75,7 +76,7 @@ namespace WireMock.Net.Tests
// then
var receivedRequest = serverForProxyForwarding.LogEntries.First().RequestMessage;
- Check.That(receivedRequest.Body).IsEqualTo("stringContent");
+ Check.That(receivedRequest.BodyData.BodyAsString).IsEqualTo("stringContent");
Check.That(receivedRequest.Headers).ContainsKey("Content-Type");
Check.That(receivedRequest.Headers["Content-Type"].First()).Contains("text/plain");
Check.That(receivedRequest.Headers).ContainsKey("bbb");
@@ -158,7 +159,7 @@ namespace WireMock.Net.Tests
// Assert
var receivedRequest = serverForProxyForwarding.LogEntries.First().RequestMessage;
- Check.That(receivedRequest.Body).IsEqualTo("");
+ Check.That(receivedRequest.BodyData.BodyAsString).IsEqualTo("");
Check.That(receivedRequest.Headers).ContainsKey("Content-Type");
Check.That(receivedRequest.Headers["Content-Type"].First()).Contains("text/plain");
}
diff --git a/test/WireMock.Net.Tests/FluentMockServerTests.Proxy2.cs b/test/WireMock.Net.Tests/FluentMockServerTests.Proxy2.cs
index 2cdc58e0..2066ce97 100644
--- a/test/WireMock.Net.Tests/FluentMockServerTests.Proxy2.cs
+++ b/test/WireMock.Net.Tests/FluentMockServerTests.Proxy2.cs
@@ -1,115 +1,46 @@
using NFluent;
using System;
-using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
-using System.Text;
-using System.Threading;
using System.Threading.Tasks;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
-using WireMock.Settings;
using Xunit;
-using Xunit.Abstractions;
namespace WireMock.Net.Tests
{
- public class FluentMockServerProxy2Tests : IDisposable
+ public class FluentMockServerProxy2Tests
{
- private readonly ITestOutputHelper _output;
- private readonly CancellationTokenSource _cts;
- private Guid _guid;
- private string _url;
-
- public FluentMockServerProxy2Tests(ITestOutputHelper output)
- {
- _output = output;
-
- _cts = new CancellationTokenSource();
- }
-
- //private Task Run()
- //{
-
- // return Task.Run(() =>
- // {
- // _guid = Guid.NewGuid();
-
- // var targetServer = FluentMockServer.Start();
- // targetServer.Given(Request.Create().UsingPost().WithPath($"/{_guid}"))
- // .RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 42 }).WithHeader("Content-Type", "application/json"));
-
- // _url = targetServer.Urls[0];
-
- // //while (!_cts.IsCancellationRequested)
- // //{
- // // Thread.Sleep(100);
- // //}
- // }, _cts.Token);
- //}
-
- private void X()
- {
- _guid = Guid.NewGuid();
-
- var targetServer = FluentMockServer.Start();
- targetServer.Given(Request.Create().UsingPost().WithPath($"/{_guid}"))
- .RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 42 }).WithHeader("Content-Type", "application/json"));
-
- _url = targetServer.Urls[0];
-
- // Thread.Sleep(TimeSpan.FromSeconds(3));
-
- _output.WriteLine(targetServer.Urls[0]);
-
- //while (!_cts.IsCancellationRequested)
- //{
- // Thread.Sleep(100);
- //}
- }
-
[Fact]
- public void FluentMockServer_ProxyAndRecordSettings_ShouldProxyContentTypeHeader()
+ public async Task FluentMockServer_ProxyAndRecordSettings_ShouldProxy()
{
// Assign
- _output.WriteLine("This is output fr");
- //var t = new Thread(X);
- //t.Start();
- X();
- _output.WriteLine("started");
+ var server = FluentMockServer.Start();
- Thread.Sleep(TimeSpan.FromSeconds(4));
+ server.Given(Request.Create().UsingPost().WithHeader("prx", "1"))
+ .RespondWith(Response.Create().WithProxy(server.Urls[0]));
- _output.WriteLine("sleep 4 done");
-
- var server = FluentMockServer.Start(
- new FluentMockServerSettings
- {
- ProxyAndRecordSettings = new ProxyAndRecordSettings
- {
- Url = _url
- }
- }
- );
-
- _output.WriteLine("started 2");
- _output.WriteLine(server.Urls[0]);
+ server.Given(Request.Create().UsingPost())
+ .RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 42 }).WithHeader("Content-Type", "application/json"));
// Act
- var response = new HttpClient().PostAsync(new Uri($"{server.Urls[0]}/{_guid}"), new StringContent("{ \"x\": 1 }", Encoding.UTF8, "application/json")).Result;
- //string content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
+ var request = new HttpRequestMessage
+ {
+ Method = HttpMethod.Post,
+ RequestUri = new Uri($"{server.Urls[0]}/TST"),
+ Content = new StringContent("test")
+ };
+ request.Headers.Add("prx", "1");
- //// Assert
- //Check.That(content).IsEqualTo("{\"p\":42}");
- //Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.Created);
- //Check.That(response.Content.Headers.GetValues("Content-Type").First()).IsEqualTo("application/json");
- }
+ // Assert
+ var response = await new HttpClient().SendAsync(request);
+ string content = await response.Content.ReadAsStringAsync();
- public void Dispose()
- {
- _cts.Cancel();
+ Check.That(content).IsEqualTo("{\"p\":42}");
+ Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.Created);
+ Check.That(response.Content.Headers.GetValues("Content-Type").First()).IsEqualTo("application/json");
}
}
}
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs b/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs
index 50af98c8..ff28b539 100644
--- a/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs
+++ b/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs
@@ -17,11 +17,7 @@ namespace WireMock.Net.Tests.Http
{
// Assign
var headers = new Dictionary { { "x", new[] { "value-1" } } };
- var body = new BodyData
- {
- BodyAsString = "hello"
- };
- var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body, headers);
+ var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, null, headers);
// Act
var message = HttpRequestMessageHelper.Create(request, "http://url");
@@ -36,7 +32,8 @@ namespace WireMock.Net.Tests.Http
// Assign
var body = new BodyData
{
- BodyAsBytes = Encoding.UTF8.GetBytes("hi")
+ BodyAsBytes = Encoding.UTF8.GetBytes("hi"),
+ DetectedBodyType = BodyType.Bytes
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", ClientIp, body);
@@ -53,7 +50,8 @@ namespace WireMock.Net.Tests.Http
// Assign
var body = new BodyData
{
- BodyAsJson = new { x = 42 }
+ BodyAsJson = new { x = 42 },
+ DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", ClientIp, body);
@@ -71,7 +69,28 @@ namespace WireMock.Net.Tests.Http
var headers = new Dictionary { { "Content-Type", new[] { "application/json" } } };
var body = new BodyData
{
- BodyAsJson = new { x = 42 }
+ BodyAsJson = new { x = 42 },
+ DetectedBodyType = BodyType.Json
+ };
+ var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", ClientIp, body, headers);
+
+ // Act
+ var message = HttpRequestMessageHelper.Create(request, "http://url");
+
+ // Assert
+ Check.That(await message.Content.ReadAsStringAsync()).Equals("{\"x\":42}");
+ Check.That(message.Content.Headers.GetValues("Content-Type")).ContainsExactly("application/json");
+ }
+
+ [Fact]
+ public async void HttpRequestMessageHelper_Create_Json_With_ContentType_ApplicationJson_UTF8()
+ {
+ // Assign
+ var headers = new Dictionary { { "Content-Type", new[] { "application/json; charset=utf-8" } } };
+ var body = new BodyData
+ {
+ BodyAsJson = new { x = 42 },
+ DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", ClientIp, body, headers);
@@ -90,7 +109,8 @@ namespace WireMock.Net.Tests.Http
var headers = new Dictionary { { "Content-Type", new[] { "application/xml" } } };
var body = new BodyData
{
- BodyAsString = "hello"
+ BodyAsString = "hello",
+ DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body, headers);
@@ -98,7 +118,7 @@ namespace WireMock.Net.Tests.Http
var message = HttpRequestMessageHelper.Create(request, "http://url");
// Assert
- Check.That(message.Content.Headers.GetValues("Content-Type")).ContainsExactly("application/xml; charset=utf-8");
+ Check.That(message.Content.Headers.GetValues("Content-Type")).ContainsExactly("application/xml");
}
[Fact]
@@ -108,7 +128,8 @@ namespace WireMock.Net.Tests.Http
var headers = new Dictionary { { "Content-Type", new[] { "application/xml; charset=UTF-8" } } };
var body = new BodyData
{
- BodyAsString = "hello"
+ BodyAsString = "hello",
+ DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body, headers);
@@ -126,7 +147,8 @@ namespace WireMock.Net.Tests.Http
var headers = new Dictionary { { "Content-Type", new[] { "application/xml; charset=Ascii" } } };
var body = new BodyData
{
- BodyAsString = "hello"
+ BodyAsString = "hello",
+ DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body, headers);
diff --git a/test/WireMock.Net.Tests/MatcherMapperTests.cs b/test/WireMock.Net.Tests/MatcherMapperTests.cs
deleted file mode 100644
index d18685d3..00000000
--- a/test/WireMock.Net.Tests/MatcherMapperTests.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using System;
-using NFluent;
-using WireMock.Admin.Mappings;
-using WireMock.Matchers;
-using WireMock.Serialization;
-using Xunit;
-
-namespace WireMock.Net.Tests
-{
- public class MatcherMapperTests
- {
- [Fact]
- public void MatcherMapper_Map_MatcherModel_Null()
- {
- // Act
- var result = MatcherMapper.Map((MatcherModel)null);
-
- // Assert
- Check.That(result).IsNull();
- }
-
- [Fact]
- public void MatcherMapper_Map_MatcherModel_Exception()
- {
- // Assign
- var model = new MatcherModel { Name = "test" };
-
- // Act and Assert
- Check.ThatCode(() => MatcherMapper.Map(model)).Throws();
- }
-
- [Fact]
- public void MatcherMapper_Map_MatcherModel_LinqMatcher_Pattern()
- {
- // Assign
- var model = new MatcherModel
- {
- Name = "LinqMatcher",
- Pattern = "p"
- };
-
- // Act
- var matcher = MatcherMapper.Map(model) as LinqMatcher;
-
- // Assert
- Check.That(matcher).IsNotNull();
- Check.That(matcher.MatchBehaviour).IsEqualTo(MatchBehaviour.AcceptOnMatch);
- Check.That(matcher.GetPatterns()).ContainsExactly("p");
- }
-
- [Fact]
- public void MatcherMapper_Map_MatcherModel_LinqMatcher_Patterns()
- {
- // Assign
- var model = new MatcherModel
- {
- Name = "LinqMatcher",
- Patterns = new[] { "p1", "p2" }
- };
-
- // Act
- var matcher = MatcherMapper.Map(model) as LinqMatcher;
-
- // Assert
- Check.That(matcher).IsNotNull();
- Check.That(matcher.MatchBehaviour).IsEqualTo(MatchBehaviour.AcceptOnMatch);
- Check.That(matcher.GetPatterns()).Contains(new[] { "p1", "p2" });
- }
-
- [Fact]
- public void MatcherMapper_Map_IMatcher_Null()
- {
- // Act
- var result = MatcherMapper.Map((IMatcher)null);
-
- // Assert
- Check.That(result).IsNull();
- }
-
- [Fact]
- public void MatcherMapper_Map_IMatcher_LinqMatcher_Pattern()
- {
- // Assign
- var matcher = new LinqMatcher(MatchBehaviour.AcceptOnMatch, "p");
-
- // Act
- var result = MatcherMapper.Map(matcher);
-
- // Assert
- Check.That(result).IsNotNull();
- Check.That(result.Name).IsEqualTo("LinqMatcher");
- Check.That(result.IgnoreCase).IsNull();
- Check.That(result.Pattern).IsEqualTo("p");
- Check.That(result.Patterns).IsNull();
- }
- }
-}
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/Owin/Mappers/OwinResponseMapperTests.cs b/test/WireMock.Net.Tests/Owin/Mappers/OwinResponseMapperTests.cs
index 3590ad46..10c1b004 100644
--- a/test/WireMock.Net.Tests/Owin/Mappers/OwinResponseMapperTests.cs
+++ b/test/WireMock.Net.Tests/Owin/Mappers/OwinResponseMapperTests.cs
@@ -96,7 +96,7 @@ namespace WireMock.Net.Tests.Owin.Mappers
var responseMessage = new ResponseMessage
{
Headers = new Dictionary>(),
- Body = body
+ BodyData = new BodyData { DetectedBodyType = BodyType.String, BodyAsString = body }
};
// Act
@@ -114,7 +114,7 @@ namespace WireMock.Net.Tests.Owin.Mappers
var responseMessage = new ResponseMessage
{
Headers = new Dictionary>(),
- BodyAsBytes = bytes
+ BodyData = new BodyData { DetectedBodyType = BodyType.Bytes, BodyAsBytes = bytes }
};
// Act
@@ -128,11 +128,11 @@ namespace WireMock.Net.Tests.Owin.Mappers
public async void OwinResponseMapper_MapAsync_BodyAsJson()
{
// Assign
+ var json = new { t = "x", i = (string)null };
var responseMessage = new ResponseMessage
{
Headers = new Dictionary>(),
- BodyAsJson = new { t = "x", i = (string)null },
- BodyAsJsonIndented = false
+ BodyData = new BodyData { DetectedBodyType = BodyType.Json, BodyAsJson = json, BodyAsJsonIndented = false }
};
// Act
diff --git a/test/WireMock.Net.Tests/Owin/MappingMatcherTests.cs b/test/WireMock.Net.Tests/Owin/MappingMatcherTests.cs
index 3eb1d772..d1b04ccf 100644
--- a/test/WireMock.Net.Tests/Owin/MappingMatcherTests.cs
+++ b/test/WireMock.Net.Tests/Owin/MappingMatcherTests.cs
@@ -21,7 +21,7 @@ namespace WireMock.Net.Tests.Owin
_optionsMock = new Mock();
_optionsMock.SetupAllProperties();
_optionsMock.Setup(o => o.Mappings).Returns(new ConcurrentDictionary());
- _optionsMock.Setup(o => o.LogEntries).Returns(new ConcurentObservableCollection());
+ _optionsMock.Setup(o => o.LogEntries).Returns(new ConcurrentObservableCollection());
_optionsMock.Setup(o => o.Scenarios).Returns(new ConcurrentDictionary());
_sut = new MappingMatcher(_optionsMock.Object);
diff --git a/test/WireMock.Net.Tests/Owin/WireMockMiddlewareTests.cs b/test/WireMock.Net.Tests/Owin/WireMockMiddlewareTests.cs
index ccf75d7f..08470fce 100644
--- a/test/WireMock.Net.Tests/Owin/WireMockMiddlewareTests.cs
+++ b/test/WireMock.Net.Tests/Owin/WireMockMiddlewareTests.cs
@@ -44,7 +44,7 @@ namespace WireMock.Net.Tests.Owin
_optionsMock = new Mock();
_optionsMock.SetupAllProperties();
_optionsMock.Setup(o => o.Mappings).Returns(new ConcurrentDictionary());
- _optionsMock.Setup(o => o.LogEntries).Returns(new ConcurentObservableCollection());
+ _optionsMock.Setup(o => o.LogEntries).Returns(new ConcurrentObservableCollection());
_optionsMock.Setup(o => o.Scenarios).Returns(new ConcurrentDictionary());
_optionsMock.Setup(o => o.Logger.Warn(It.IsAny(), It.IsAny
+
@@ -27,17 +28,19 @@
all
runtime; build; native; contentfiles; analyzers
+
+
+
-
+
-