mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-07-09 14:25:13 +02:00
Allow setting Content-Length header on the response (#1158)
* Allow setting Content-Length header on the response * fix?
This commit is contained in:
@@ -137,7 +137,6 @@ message HelloReply {
|
|||||||
public static void Run()
|
public static void Run()
|
||||||
{
|
{
|
||||||
RunOnLocal();
|
RunOnLocal();
|
||||||
return;
|
|
||||||
|
|
||||||
var mappingBuilder = new MappingBuilder();
|
var mappingBuilder = new MappingBuilder();
|
||||||
mappingBuilder
|
mappingBuilder
|
||||||
@@ -308,17 +307,6 @@ message HelloReply {
|
|||||||
.RespondWith(Response.Create()
|
.RespondWith(Response.Create()
|
||||||
.WithBody("GraphQL is ok")
|
.WithBody("GraphQL is ok")
|
||||||
);
|
);
|
||||||
|
|
||||||
//server
|
|
||||||
// .AddGraphQLSchema("my-graphql", TestSchema, customScalars)
|
|
||||||
// .Given(Request.Create()
|
|
||||||
// .WithPath("/graphql2")
|
|
||||||
// .UsingPost()
|
|
||||||
// )
|
|
||||||
// .WithGraphQLSchema("my-graphql")
|
|
||||||
// .RespondWith(Response.Create()
|
|
||||||
// .WithBody("GraphQL is ok")
|
|
||||||
// );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MIMEKIT
|
#if MIMEKIT
|
||||||
@@ -377,6 +365,15 @@ message HelloReply {
|
|||||||
.WithHeader("Content-Type", "text/plain")
|
.WithHeader("Content-Type", "text/plain")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create()
|
||||||
|
.UsingHead()
|
||||||
|
.WithPath("/cl")
|
||||||
|
)
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithHeader("Content-Length", "42")
|
||||||
|
);
|
||||||
|
|
||||||
server
|
server
|
||||||
.Given(Request.Create()
|
.Given(Request.Create()
|
||||||
.UsingMethod("GET")
|
.UsingMethod("GET")
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ namespace WireMock.Http;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal static class HttpKnownHeaderNames
|
internal static class HttpKnownHeaderNames
|
||||||
{
|
{
|
||||||
// https://docs.microsoft.com/en-us/dotnet/api/system.net.webheadercollection.isrestricted
|
// - https://docs.microsoft.com/en-us/dotnet/api/system.net.webheadercollection.isrestricted
|
||||||
|
// - ContentLength is allowed per #720
|
||||||
private static readonly string[] RestrictedResponseHeaders =
|
private static readonly string[] RestrictedResponseHeaders =
|
||||||
{
|
{
|
||||||
Accept,
|
Accept,
|
||||||
Connection,
|
Connection,
|
||||||
ContentLength,
|
|
||||||
ContentType,
|
ContentType,
|
||||||
Date, // RFC1123Pattern
|
Date, // RFC1123Pattern
|
||||||
Expect,
|
Expect,
|
||||||
|
|||||||
@@ -37,12 +37,19 @@ namespace WireMock.Owin.Mappers
|
|||||||
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
|
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
|
||||||
|
|
||||||
// https://msdn.microsoft.com/en-us/library/78h415ay(v=vs.110).aspx
|
// https://msdn.microsoft.com/en-us/library/78h415ay(v=vs.110).aspx
|
||||||
#if !USE_ASPNETCORE
|
private static readonly IDictionary<string, Action<IResponse, bool, WireMockList<string>>> ResponseHeadersToFix =
|
||||||
private static readonly IDictionary<string, Action<IResponse, WireMockList<string>>> ResponseHeadersToFix = new Dictionary<string, Action<IResponse, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase) {
|
new Dictionary<string, Action<IResponse, bool, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase)
|
||||||
#else
|
{
|
||||||
private static readonly IDictionary<string, Action<IResponse, WireMockList<string>>> ResponseHeadersToFix = new Dictionary<string, Action<IResponse, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase) {
|
{ HttpKnownHeaderNames.ContentType, (r, _, v) => r.ContentType = v.FirstOrDefault() },
|
||||||
#endif
|
{ HttpKnownHeaderNames.ContentLength, (r, hasBody, v) =>
|
||||||
{ HttpKnownHeaderNames.ContentType, (r, v) => r.ContentType = v.FirstOrDefault() }
|
{
|
||||||
|
// Only set the Content-Length header if the response does not have a body
|
||||||
|
if (!hasBody && long.TryParse(v.FirstOrDefault(), out var contentLength))
|
||||||
|
{
|
||||||
|
r.ContentLength = contentLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -83,23 +90,21 @@ namespace WireMock.Owin.Mappers
|
|||||||
}
|
}
|
||||||
|
|
||||||
var statusCodeType = responseMessage.StatusCode?.GetType();
|
var statusCodeType = responseMessage.StatusCode?.GetType();
|
||||||
switch (statusCodeType)
|
if (statusCodeType != null)
|
||||||
|
{
|
||||||
|
if (statusCodeType == typeof(int) || statusCodeType == typeof(int?) || statusCodeType.GetTypeInfo().IsEnum)
|
||||||
{
|
{
|
||||||
case { } when statusCodeType == typeof(int) || statusCodeType == typeof(int?) || statusCodeType.GetTypeInfo().IsEnum:
|
|
||||||
response.StatusCode = MapStatusCode((int)responseMessage.StatusCode!);
|
response.StatusCode = MapStatusCode((int)responseMessage.StatusCode!);
|
||||||
break;
|
}
|
||||||
|
else if (statusCodeType == typeof(string))
|
||||||
case { } when statusCodeType == typeof(string):
|
{
|
||||||
// Note: this case will also match on null
|
// Note: this case will also match on null
|
||||||
int.TryParse(responseMessage.StatusCode as string, out var result);
|
int.TryParse(responseMessage.StatusCode as string, out var statusCodeTypeAsInt);
|
||||||
response.StatusCode = MapStatusCode(result);
|
response.StatusCode = MapStatusCode(statusCodeTypeAsInt);
|
||||||
break;
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetResponseHeaders(responseMessage, response);
|
SetResponseHeaders(responseMessage, bytes, response);
|
||||||
|
|
||||||
if (bytes != null)
|
if (bytes != null)
|
||||||
{
|
{
|
||||||
@@ -160,7 +165,7 @@ namespace WireMock.Owin.Mappers
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetResponseHeaders(IResponseMessage responseMessage, IResponse response)
|
private static void SetResponseHeaders(IResponseMessage responseMessage, byte[]? bytes, IResponse response)
|
||||||
{
|
{
|
||||||
// Force setting the Date header (#577)
|
// Force setting the Date header (#577)
|
||||||
AppendResponseHeader(
|
AppendResponseHeader(
|
||||||
@@ -179,11 +184,11 @@ namespace WireMock.Owin.Mappers
|
|||||||
var value = item.Value;
|
var value = item.Value;
|
||||||
if (ResponseHeadersToFix.TryGetValue(headerName, out var action))
|
if (ResponseHeadersToFix.TryGetValue(headerName, out var action))
|
||||||
{
|
{
|
||||||
action?.Invoke(response, value);
|
action?.Invoke(response, bytes != null, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check if this response header can be added (#148 and #227)
|
// Check if this response header can be added (#148, #227 and #720)
|
||||||
if (!HttpKnownHeaderNames.IsRestrictedResponseHeader(headerName))
|
if (!HttpKnownHeaderNames.IsRestrictedResponseHeader(headerName))
|
||||||
{
|
{
|
||||||
AppendResponseHeader(response, headerName, value.ToArray());
|
AppendResponseHeader(response, headerName, value.ToArray());
|
||||||
@@ -206,7 +211,7 @@ namespace WireMock.Owin.Mappers
|
|||||||
var value = item.Value;
|
var value = item.Value;
|
||||||
if (ResponseHeadersToFix.TryGetValue(headerName, out var action))
|
if (ResponseHeadersToFix.TryGetValue(headerName, out var action))
|
||||||
{
|
{
|
||||||
action?.Invoke(response, value);
|
action?.Invoke(response, false, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ using Response = Microsoft.AspNetCore.Http.HttpResponse;
|
|||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace WireMock.Net.Tests.Owin.Mappers
|
namespace WireMock.Net.Tests.Owin.Mappers;
|
||||||
{
|
|
||||||
public class OwinResponseMapperTests
|
public class OwinResponseMapperTests
|
||||||
{
|
{
|
||||||
private static readonly Task CompletedTask = Task.FromResult(true);
|
private static readonly Task CompletedTask = Task.FromResult(true);
|
||||||
@@ -299,4 +299,3 @@ namespace WireMock.Net.Tests.Owin.Mappers
|
|||||||
_stream.Verify(s => s.WriteAsync(It.IsAny<byte[]>(), 0, It.Is<int>(count => count >= 0), It.IsAny<CancellationToken>()), Times.Once);
|
_stream.Verify(s => s.WriteAsync(It.IsAny<byte[]>(), 0, It.Is<int>(count => count >= 0), It.IsAny<CancellationToken>()), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -14,6 +14,7 @@ using FluentAssertions;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NFluent;
|
using NFluent;
|
||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
|
using WireMock.Http;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
using WireMock.Net.Tests.Serialization;
|
using WireMock.Net.Tests.Serialization;
|
||||||
using WireMock.Net.Xunit;
|
using WireMock.Net.Xunit;
|
||||||
@@ -351,7 +352,7 @@ public partial class WireMockServerTests
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task WireMockServer_Should_exclude_restrictedResponseHeader()
|
public async Task WireMockServer_Should_Exclude_RestrictedResponseHeader()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
string path = $"/foo_{Guid.NewGuid()}";
|
string path = $"/foo_{Guid.NewGuid()}";
|
||||||
@@ -371,6 +372,26 @@ public partial class WireMockServerTests
|
|||||||
server.Stop();
|
server.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact] // #720
|
||||||
|
public async Task WireMockServer_Should_AllowResponseHeaderContentLength_For_HEAD()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
const string length = "42";
|
||||||
|
var path = $"/cl_{Guid.NewGuid()}";
|
||||||
|
using var server = WireMockServer.Start();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath(path).UsingHead())
|
||||||
|
.RespondWith(Response.Create().WithHeader(HttpKnownHeaderNames.ContentLength, length));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Head, path);
|
||||||
|
var response = await server.CreateClient().SendAsync(httpRequestMessage).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.Content.Headers.GetValues(HttpKnownHeaderNames.ContentLength).Should().Contain(length);
|
||||||
|
}
|
||||||
|
|
||||||
#if !NET452 && !NET461
|
#if !NET452 && !NET461
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("TRACE")]
|
[InlineData("TRACE")]
|
||||||
|
|||||||
Reference in New Issue
Block a user