diff --git a/Directory.Build.props b/Directory.Build.props
index 988d7385..32a01573 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -4,7 +4,7 @@
- 1.0.29
+ 1.0.30
diff --git a/GitHubReleaseNotes.txt b/GitHubReleaseNotes.txt
index a39fdfc4..17ebdce2 100644
--- a/GitHubReleaseNotes.txt
+++ b/GitHubReleaseNotes.txt
@@ -1,3 +1,3 @@
https://github.com/StefH/GitHubReleaseNotes
-GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question, invalid --version 1.0.29.0
\ No newline at end of file
+GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question, invalid --version 1.0.30.0
\ No newline at end of file
diff --git a/src/WireMock.Net/Http/HttpClientHelper.cs b/src/WireMock.Net/Http/HttpClientHelper.cs
index 883cb897..4b5b05e3 100644
--- a/src/WireMock.Net/Http/HttpClientHelper.cs
+++ b/src/WireMock.Net/Http/HttpClientHelper.cs
@@ -72,7 +72,7 @@ namespace WireMock.Http
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
// Create ResponseMessage
- return await HttpResponseMessageHelper.Create(httpResponseMessage, requiredUri, originalUri);
+ return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri);
}
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Http/HttpRequestMessageHelper.cs b/src/WireMock.Net/Http/HttpRequestMessageHelper.cs
index 7f892b00..456a3bd2 100644
--- a/src/WireMock.Net/Http/HttpRequestMessageHelper.cs
+++ b/src/WireMock.Net/Http/HttpRequestMessageHelper.cs
@@ -2,8 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
+using System.Net.Http.Headers;
using JetBrains.Annotations;
-using MimeKit;
using Newtonsoft.Json;
using WireMock.Util;
using WireMock.Validation;
@@ -19,11 +19,11 @@ namespace WireMock.Http
var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);
- ContentType contentType = null;
+ MediaTypeHeaderValue contentType = null;
if (requestMessage.Headers != null && requestMessage.Headers.ContainsKey(HttpKnownHeaderNames.ContentType))
{
var value = requestMessage.Headers[HttpKnownHeaderNames.ContentType].FirstOrDefault();
- ContentType.TryParse(value, out contentType);
+ MediaTypeHeaderValue.TryParse(value, out contentType);
}
switch (requestMessage.BodyData?.DetectedBodyType)
diff --git a/src/WireMock.Net/Http/HttpResponseMessageHelper.cs b/src/WireMock.Net/Http/HttpResponseMessageHelper.cs
index fa134e17..f23c5acb 100644
--- a/src/WireMock.Net/Http/HttpResponseMessageHelper.cs
+++ b/src/WireMock.Net/Http/HttpResponseMessageHelper.cs
@@ -9,7 +9,7 @@ namespace WireMock.Http
{
internal static class HttpResponseMessageHelper
{
- public static async Task Create(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri)
+ public static async Task CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri)
{
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
diff --git a/src/WireMock.Net/Http/StringContentHelper.cs b/src/WireMock.Net/Http/StringContentHelper.cs
index 2d9446f8..f71b55e4 100644
--- a/src/WireMock.Net/Http/StringContentHelper.cs
+++ b/src/WireMock.Net/Http/StringContentHelper.cs
@@ -1,8 +1,6 @@
using System.Net.Http;
using System.Net.Http.Headers;
-using System.Text;
using JetBrains.Annotations;
-using MimeKit;
using WireMock.Validation;
namespace WireMock.Http
@@ -10,29 +8,18 @@ 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.
+ /// Creates a StringContent object.
///
/// The string content (cannot be null)
/// The ContentType (can be null)
/// StringContent
- internal static StringContent Create([NotNull] string content, [CanBeNull] ContentType contentType)
+ internal static StringContent Create([NotNull] string content, [CanBeNull] MediaTypeHeaderValue 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);
+ var stringContent = new StringContent(content);
+ stringContent.Headers.ContentType = contentType;
+ return stringContent;
}
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Util/BodyParser.cs b/src/WireMock.Net/Util/BodyParser.cs
index f31901be..fea3110d 100644
--- a/src/WireMock.Net/Util/BodyParser.cs
+++ b/src/WireMock.Net/Util/BodyParser.cs
@@ -1,33 +1,32 @@
-using JetBrains.Annotations;
-using MimeKit;
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using WireMock.Matchers;
-using WireMock.Validation;
-
-namespace WireMock.Util
-{
- internal static class BodyParser
- {
- private static readonly Encoding DefaultEncoding = Encoding.UTF8;
- private static readonly Encoding[] SupportedBodyAsStringEncodingForMultipart = { Encoding.UTF8, Encoding.ASCII };
-
- /*
- 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.
- */
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+using Newtonsoft.Json;
+using WireMock.Matchers;
+using WireMock.Validation;
+
+namespace WireMock.Util
+{
+ internal static class BodyParser
+ {
+ private static readonly Encoding DefaultEncoding = Encoding.UTF8;
+ private static readonly Encoding[] SupportedBodyAsStringEncodingForMultipart = { Encoding.UTF8, Encoding.ASCII };
+
+ /*
+ 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 IDictionary BodyAllowedForMethods = new Dictionary
{
{ "HEAD", false },
@@ -39,134 +38,131 @@ namespace WireMock.Util
{ "OPTIONS", true },
{ "CONNECT", false },
{ "PATCH", true }
- };
-
- private static readonly IStringMatcher[] MultipartContentTypesMatchers = {
- new WildcardMatcher("multipart/*", true)
- };
-
- private static readonly IStringMatcher[] JsonContentTypesMatchers = {
- new WildcardMatcher("application/json", true),
- new WildcardMatcher("application/vnd.*+json", true)
- };
-
- private static readonly IStringMatcher[] TextContentTypeMatchers =
- {
- new WildcardMatcher("text/*", true),
- new RegexMatcher("^application\\/(java|type)script$", true),
- new WildcardMatcher("application/*xml", true),
- new WildcardMatcher("application/x-www-form-urlencoded", true)
- };
-
- public static bool ParseBodyAsIsValid([CanBeNull] string parseBodyAs)
- {
- return Enum.TryParse(parseBodyAs, out BodyType _);
- }
-
- public static bool ShouldParseBody([CanBeNull] string method)
- {
- if (String.IsNullOrEmpty(method))
+ };
+
+ private static readonly IStringMatcher[] MultipartContentTypesMatchers = {
+ new WildcardMatcher("multipart/*", true)
+ };
+
+ private static readonly IStringMatcher[] JsonContentTypesMatchers = {
+ new WildcardMatcher("application/json", true),
+ new WildcardMatcher("application/vnd.*+json", true)
+ };
+
+ private static readonly IStringMatcher[] TextContentTypeMatchers =
+ {
+ new WildcardMatcher("text/*", true),
+ new RegexMatcher("^application\\/(java|type)script$", true),
+ new WildcardMatcher("application/*xml", true),
+ new WildcardMatcher("application/x-www-form-urlencoded", true)
+ };
+
+ public static bool ShouldParseBody([CanBeNull] string method)
+ {
+ if (string.IsNullOrEmpty(method))
{
return false;
- }
- if (BodyAllowedForMethods.TryGetValue(method.ToUpper(), out var allowed))
+ }
+
+ if (BodyAllowedForMethods.TryGetValue(method.ToUpper(), out bool allowed))
{
return allowed;
- }
- // If we don't have any knowledge of this method, we should assume that a body *may*
- // be present, so we should parse it if it is. Therefore, if a new method is added to
- // the HTTP Method Registry, we only really need to add it to BodyAllowedForMethods if
- // we want to make it clear that a body is *not* allowed.
- return true;
- }
-
- 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;
- }
-
- if (MultipartContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MimeType))))
- {
- return BodyType.MultiPart;
- }
-
- 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)
- };
-
- // In case of MultiPart: check if the BodyAsBytes is a valid UTF8 or ASCII string, in that case read as String else keep as-is
- if (data.DetectedBodyTypeFromContentType == BodyType.MultiPart)
- {
- if (BytesEncodingUtils.TryGetEncoding(data.BodyAsBytes, out Encoding encoding) &&
- SupportedBodyAsStringEncodingForMultipart.Select(x => x.Equals(encoding)).Any())
- {
- data.BodyAsString = encoding.GetString(data.BodyAsBytes);
- data.Encoding = encoding;
- data.DetectedBodyType = BodyType.String;
-
- return data;
- }
-
- return data;
- }
-
- // 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())
- {
- await stream.CopyToAsync(memoryStream);
- return memoryStream.ToArray();
- }
- }
- }
+ }
+
+ // If we don't have any knowledge of this method, we should assume that a body *may*
+ // be present, so we should parse it if it is. Therefore, if a new method is added to
+ // the HTTP Method Registry, we only really need to add it to BodyAllowedForMethods if
+ // we want to make it clear that a body is *not* allowed.
+ return true;
+ }
+
+ public static BodyType DetectBodyTypeFromContentType([CanBeNull] string contentTypeValue)
+ {
+ if (string.IsNullOrEmpty(contentTypeValue) || !MediaTypeHeaderValue.TryParse(contentTypeValue, out MediaTypeHeaderValue contentType))
+ {
+ return BodyType.Bytes;
+ }
+
+ if (TextContentTypeMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
+ {
+ return BodyType.String;
+ }
+
+ if (JsonContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
+ {
+ return BodyType.Json;
+ }
+
+ if (MultipartContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
+ {
+ return BodyType.MultiPart;
+ }
+
+ 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)
+ };
+
+ // In case of MultiPart: check if the BodyAsBytes is a valid UTF8 or ASCII string, in that case read as String else keep as-is
+ if (data.DetectedBodyTypeFromContentType == BodyType.MultiPart)
+ {
+ if (BytesEncodingUtils.TryGetEncoding(data.BodyAsBytes, out Encoding encoding) &&
+ SupportedBodyAsStringEncodingForMultipart.Select(x => x.Equals(encoding)).Any())
+ {
+ data.BodyAsString = encoding.GetString(data.BodyAsBytes);
+ data.Encoding = encoding;
+ data.DetectedBodyType = BodyType.String;
+
+ return data;
+ }
+
+ return data;
+ }
+
+ // 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())
+ {
+ await stream.CopyToAsync(memoryStream);
+ return memoryStream.ToArray();
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/WireMock.Net/WireMock.Net.csproj b/src/WireMock.Net/WireMock.Net.csproj
index 815e5f4c..bfe61902 100644
--- a/src/WireMock.Net/WireMock.Net.csproj
+++ b/src/WireMock.Net/WireMock.Net.csproj
@@ -57,7 +57,6 @@
-
all
runtime; build; native; contentfiles; analyzers
diff --git a/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs b/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs
index ff28b539..dd645b5f 100644
--- a/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs
+++ b/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs
@@ -137,7 +137,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; charset=UTF-8");
}
[Fact]
@@ -156,7 +156,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=us-ascii");
+ Check.That(message.Content.Headers.GetValues("Content-Type")).ContainsExactly("application/xml; charset=Ascii");
}
}
}
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/Http/StringContentHelperTests.cs b/test/WireMock.Net.Tests/Http/StringContentHelperTests.cs
new file mode 100644
index 00000000..5d3e08f5
--- /dev/null
+++ b/test/WireMock.Net.Tests/Http/StringContentHelperTests.cs
@@ -0,0 +1,39 @@
+using System.Net.Http.Headers;
+using FluentAssertions;
+using WireMock.Http;
+using Xunit;
+
+namespace WireMock.Net.Tests.Http
+{
+ public class StringContentHelperTests
+ {
+ [Fact]
+ public void StringContentHelper_Create_WithNullContentType()
+ {
+ // Act
+ var result = StringContentHelper.Create("test", null);
+
+ // Assert
+ result.Headers.ContentType.Should().BeNull();
+ result.ReadAsStringAsync().Result.Should().Be("test");
+ }
+
+ [Theory]
+ [InlineData("application/json", "application/json")]
+ [InlineData("application/soap+xml", "application/soap+xml")]
+ [InlineData("application/soap+xml;charset=UTF-8", "application/soap+xml; charset=UTF-8")]
+ [InlineData("application/soap+xml;charset=UTF-8;action=\"http://myCompany.Customer.Contract/ICustomerService/GetSomeConfiguration\"", "application/soap+xml; charset=UTF-8; action=\"http://myCompany.Customer.Contract/ICustomerService/GetSomeConfiguration\"")]
+ public void StringContentHelper_Create(string test, string expected)
+ {
+ // Arrange
+ var contentType = MediaTypeHeaderValue.Parse(test);
+
+ // Act
+ var result = StringContentHelper.Create("test", contentType);
+
+ // Assert
+ result.Headers.ContentType.ToString().Should().Be(expected);
+ result.ReadAsStringAsync().Result.Should().Be("test");
+ }
+ }
+}
diff --git a/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj b/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj
index 26b90ea4..dbd2c7e8 100644
--- a/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj
+++ b/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj
@@ -39,7 +39,6 @@
-