diff --git a/Directory.Build.props b/Directory.Build.props
index b6c806f2..059e75a5 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -4,7 +4,7 @@
- 1.0.6
+ 1.0.6.1
diff --git a/GitHubReleaseNotes.txt b/GitHubReleaseNotes.txt
index a39f929e..f4b7a6d2 100644
--- a/GitHubReleaseNotes.txt
+++ b/GitHubReleaseNotes.txt
@@ -1,3 +1,3 @@
https://github.com/StefH/GitHubReleaseNotes
-GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --version 1.0.6
\ No newline at end of file
+GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --version 1.0.6.1
\ No newline at end of file
diff --git a/src/WireMock.Net/Util/BodyParser.cs b/src/WireMock.Net/Util/BodyParser.cs
index 66b80127..7bd98f74 100644
--- a/src/WireMock.Net/Util/BodyParser.cs
+++ b/src/WireMock.Net/Util/BodyParser.cs
@@ -1,11 +1,11 @@
-using System;
+using JetBrains.Annotations;
+using MimeKit;
+using Newtonsoft.Json;
+using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using JetBrains.Annotations;
-using MimeKit;
-using Newtonsoft.Json;
using WireMock.Matchers;
using WireMock.Validation;
@@ -28,6 +28,10 @@ namespace WireMock.Util
*/
private static readonly string[] AllowedBodyParseMethods = { "PUT", "POST", "OPTIONS", "PATCH" };
+ 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)
@@ -68,6 +72,11 @@ namespace WireMock.Util
return BodyType.Json;
}
+ if (MultipartContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MimeType))))
+ {
+ return BodyType.MultiPart;
+ }
+
return BodyType.Bytes;
}
@@ -82,6 +91,12 @@ namespace WireMock.Util
DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(contentType)
};
+ // In case of MultiPart: never try to read as String but keep as-is
+ if (data.DetectedBodyTypeFromContentType == BodyType.MultiPart)
+ {
+ return data;
+ }
+
// Try to get the body as String
try
{
diff --git a/src/WireMock.Net/Util/BodyType.cs b/src/WireMock.Net/Util/BodyType.cs
index 9bc53019..6c8d2e05 100644
--- a/src/WireMock.Net/Util/BodyType.cs
+++ b/src/WireMock.Net/Util/BodyType.cs
@@ -28,6 +28,11 @@
///
/// Body is a File
///
- File
+ File,
+
+ ///
+ /// Body is a MultiPart
+ ///
+ MultiPart
}
}
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/Util/BodyParserTests.cs b/test/WireMock.Net.Tests/Util/BodyParserTests.cs
index a6e2da14..a5425b2a 100644
--- a/test/WireMock.Net.Tests/Util/BodyParserTests.cs
+++ b/test/WireMock.Net.Tests/Util/BodyParserTests.cs
@@ -1,7 +1,7 @@
-using System.IO;
+using NFluent;
+using System.IO;
using System.Text;
using System.Threading.Tasks;
-using NFluent;
using WireMock.Util;
using Xunit;
@@ -17,7 +17,7 @@ namespace WireMock.Net.Tests.Util
[InlineData("application/vnd.test+json", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
public async Task BodyParser_Parse_ContentTypeJson(string contentType, string bodyAsJson, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
{
- // Assign
+ // Arrange
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson));
// Act
@@ -36,7 +36,7 @@ namespace WireMock.Net.Tests.Util
[InlineData("something", "hello", BodyType.String, BodyType.Bytes)]
public async Task BodyParser_Parse_ContentTypeString(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
{
- // Assign
+ // Arrange
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
// Act
@@ -50,11 +50,49 @@ namespace WireMock.Net.Tests.Util
Check.That(body.DetectedBodyTypeFromContentType).IsEqualTo(detectedBodyTypeFromContentType);
}
+ [Fact]
+ public async Task BodyParser_Parse_ContentTypeMultipart()
+ {
+ // Arrange
+ string contentType = "multipart/form-data";
+ string body = @"
+
+-----------------------------9051914041544843365972754266
+Content-Disposition: form-data; name=""text""
+
+text default
+-----------------------------9051914041544843365972754266
+Content-Disposition: form-data; name=""file1""; filename=""a.txt""
+Content-Type: text/plain
+
+Content of a txt
+
+-----------------------------9051914041544843365972754266
+Content-Disposition: form-data; name=""file2""; filename=""a.html""
+Content-Type: text/html
+
+Content of a.html.
+
+-----------------------------9051914041544843365972754266--";
+
+ var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
+
+ // Act
+ var result = await BodyParser.Parse(memoryStream, contentType);
+
+ // Assert
+ Check.That(result.DetectedBodyType).IsEqualTo(BodyType.Bytes);
+ Check.That(result.DetectedBodyTypeFromContentType).IsEqualTo(BodyType.MultiPart);
+ Check.That(result.BodyAsBytes).IsNotNull();
+ Check.That(result.BodyAsJson).IsNull();
+ Check.That(result.BodyAsString).IsNull();
+ }
+
[Theory]
[InlineData(null, "hello", BodyType.String, BodyType.Bytes)]
public async Task BodyParser_Parse_ContentTypeIsNull(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
{
- // Assign
+ // Arrange
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
// Act