From d0cfa91fe7408aa864ad034ecf2ac1adb737f914 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Tue, 6 Jun 2023 20:02:05 +0200 Subject: [PATCH 1/2] Allow setting the Content-Length header for a HTTP method HEAD --- .../Http/HttpRequestMessageHelper.cs | 22 ++++++++++++++- .../Http/HttpRequestMessageHelperTests.cs | 27 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/WireMock.Net/Http/HttpRequestMessageHelper.cs b/src/WireMock.Net/Http/HttpRequestMessageHelper.cs index 44fb37457..d6ce304f4 100644 --- a/src/WireMock.Net/Http/HttpRequestMessageHelper.cs +++ b/src/WireMock.Net/Http/HttpRequestMessageHelper.cs @@ -5,12 +5,18 @@ using System.Net.Http.Headers; using Newtonsoft.Json; using Stef.Validation; +using WireMock.Constants; using WireMock.Types; namespace WireMock.Http; internal static class HttpRequestMessageHelper { + private static readonly IDictionary ContentLengthHeaderAllowed = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { HttpRequestMethod.HEAD, true } + }; + internal static HttpRequestMessage Create(IRequestMessage requestMessage, string url) { Guard.NotNull(requestMessage); @@ -25,6 +31,8 @@ internal static HttpRequestMessage Create(IRequestMessage requestMessage, string MediaTypeHeaderValue.TryParse(value, out contentType); } + + switch (requestMessage.BodyData?.DetectedBodyType) { case BodyType.Bytes: @@ -50,7 +58,19 @@ internal static HttpRequestMessage Create(IRequestMessage requestMessage, string return httpRequestMessage; } - var excludeHeaders = new List { HttpKnownHeaderNames.Host, HttpKnownHeaderNames.ContentLength }; + var excludeHeaders = new List { HttpKnownHeaderNames.Host }; + + var contentLengthHeaderAllowed = ContentLengthHeaderAllowed.TryGetValue(requestMessage.Method, out var allowed) && allowed; + if (contentLengthHeaderAllowed) + { + // Set Content to empty ByteArray to be able to set the Content-Length on the content in case of a HEAD method. + httpRequestMessage.Content ??= new ByteArrayContent(EmptyArray.Value); + } + else + { + excludeHeaders.Add(HttpKnownHeaderNames.ContentLength); + } + if (contentType != null) { // Content-Type should be set on the content diff --git a/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs b/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs index 5de28dcc4..84307aafc 100644 --- a/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs +++ b/test/WireMock.Net.Tests/Http/HttpRequestMessageHelperTests.cs @@ -1,7 +1,9 @@ using NFluent; using System.Collections.Generic; +using System.Linq; using System.Text; using System.Threading.Tasks; +using FluentAssertions; using WireMock.Http; using WireMock.Models; using WireMock.Types; @@ -160,4 +162,29 @@ public void HttpRequestMessageHelper_Create_String_With_ContentType_ApplicationX // Assert Check.That(message.Content.Headers.GetValues("Content-Type")).ContainsExactly("application/xml; charset=Ascii"); } + + [Theory] + [InlineData("HEAD", true)] + [InlineData("GET", false)] + [InlineData("PUT", false)] + [InlineData("POST", false)] + [InlineData("DELETE", false)] + [InlineData("TRACE", false)] + [InlineData("OPTIONS", false)] + [InlineData("CONNECT", false)] + [InlineData("PATCH", false)] + public void HttpRequestMessageHelper_Create_ContentLengthAllowedForMethod(string method, bool resultShouldBe) + { + // Arrange + var key = "Content-Length"; + var value = 1234; + var headers = new Dictionary { { key, new[] { "1234" } } }; + var request = new RequestMessage(new UrlDetails("http://localhost/foo"), method, ClientIp, null, headers); + + // Act + var message = HttpRequestMessageHelper.Create(request, "http://url"); + + // Assert + message.Content?.Headers.ContentLength.Should().Be(resultShouldBe ? value : null); + } } \ No newline at end of file From 9759522fb15cf672f2a885099db3adaf816270d9 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Tue, 6 Jun 2023 22:04:50 +0200 Subject: [PATCH 2/2] . --- src/WireMock.Net/Http/HttpRequestMessageHelper.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/WireMock.Net/Http/HttpRequestMessageHelper.cs b/src/WireMock.Net/Http/HttpRequestMessageHelper.cs index d6ce304f4..778fb7a18 100644 --- a/src/WireMock.Net/Http/HttpRequestMessageHelper.cs +++ b/src/WireMock.Net/Http/HttpRequestMessageHelper.cs @@ -31,8 +31,6 @@ internal static HttpRequestMessage Create(IRequestMessage requestMessage, string MediaTypeHeaderValue.TryParse(value, out contentType); } - - switch (requestMessage.BodyData?.DetectedBodyType) { case BodyType.Bytes: