Skip to content

Commit 0efd9ef

Browse files
committed
Merge in 'release/7.0-rc1' changes
2 parents dffe4b0 + aad9c23 commit 0efd9ef

File tree

2 files changed

+75
-7
lines changed

2 files changed

+75
-7
lines changed

src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,17 @@ private HttpResponseHeaders CreateResponseHeaders(bool appCompleted)
11531153
{
11541154
if (!CanIncludeResponseContentLengthHeader())
11551155
{
1156-
RejectInvalidHeaderForNonBodyResponse(appCompleted, HeaderNames.ContentLength);
1156+
if (responseHeaders.ContentLength.Value == 0)
1157+
{
1158+
// If the response shouldn't include a Content-Length but it's 0
1159+
// we'll just get rid of it without throwing an error, since it
1160+
// is semantically equivalent to not having a Content-Length.
1161+
responseHeaders.ContentLength = null;
1162+
}
1163+
else
1164+
{
1165+
RejectInvalidHeaderForNonBodyResponse(appCompleted, HeaderNames.ContentLength);
1166+
}
11571167
}
11581168
else if (StatusCode == StatusCodes.Status205ResetContent && responseHeaders.ContentLength.Value != 0)
11591169
{

src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,27 @@ public static IEnumerable<object[]> Get1xxAnd204MethodCombinations()
625625

626626
[Theory]
627627
[MemberData(nameof(Get1xxAnd204MethodCombinations))]
628-
public async Task AttemptingToWriteContentLengthFailsFor1xxAnd204Responses(int statusCode, HttpMethod method)
629-
=> await AttemptingToWriteContentLengthFails(statusCode, method).ConfigureAwait(true);
628+
public async Task AttemptingToWriteNonzeroContentLengthFailsFor1xxAnd204Responses(int statusCode, HttpMethod method)
629+
=> await AttemptingToWriteNonzeroContentLengthFails(statusCode, method).ConfigureAwait(true);
630+
631+
[Theory]
632+
[MemberData(nameof(Get1xxAnd204MethodCombinations))]
633+
public async Task AttemptingToWriteZeroContentLengthFor1xxAnd204Responses_ContentLengthRemoved(int statusCode, HttpMethod method)
634+
=> await AttemptingToWriteZeroContentLength_ContentLengthRemoved(statusCode, method).ConfigureAwait(true);
635+
636+
[Theory]
637+
[InlineData(StatusCodes.Status200OK)]
638+
[InlineData(StatusCodes.Status201Created)]
639+
[InlineData(StatusCodes.Status202Accepted)]
640+
[InlineData(StatusCodes.Status203NonAuthoritative)]
641+
[InlineData(StatusCodes.Status204NoContent)]
642+
[InlineData(StatusCodes.Status205ResetContent)]
643+
[InlineData(StatusCodes.Status206PartialContent)]
644+
[InlineData(StatusCodes.Status207MultiStatus)]
645+
[InlineData(StatusCodes.Status208AlreadyReported)]
646+
[InlineData(StatusCodes.Status226IMUsed)]
647+
public async Task AttemptingToWriteNonzeroContentLengthFailsFor2xxResponsesOnConnect(int statusCode)
648+
=> await AttemptingToWriteNonzeroContentLengthFails(statusCode, HttpMethod.Connect).ConfigureAwait(true);
630649

631650
[Theory]
632651
[InlineData(StatusCodes.Status200OK)]
@@ -639,17 +658,17 @@ public async Task AttemptingToWriteContentLengthFailsFor1xxAnd204Responses(int s
639658
[InlineData(StatusCodes.Status207MultiStatus)]
640659
[InlineData(StatusCodes.Status208AlreadyReported)]
641660
[InlineData(StatusCodes.Status226IMUsed)]
642-
public async Task AttemptingToWriteContentLengthFailsFor2xxResponsesOnConnect(int statusCode)
643-
=> await AttemptingToWriteContentLengthFails(statusCode, HttpMethod.Connect).ConfigureAwait(true);
661+
public async Task AttemptingToWriteZeroContentLengthFor2xxResponsesOnConnect_ContentLengthRemoved(int statusCode)
662+
=> await AttemptingToWriteZeroContentLength_ContentLengthRemoved(statusCode, HttpMethod.Connect).ConfigureAwait(true);
644663

645-
private async Task AttemptingToWriteContentLengthFails(int statusCode, HttpMethod method)
664+
private async Task AttemptingToWriteNonzeroContentLengthFails(int statusCode, HttpMethod method)
646665
{
647666
var responseWriteTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
648667

649668
await using (var server = new TestServer(async httpContext =>
650669
{
651670
httpContext.Response.StatusCode = statusCode;
652-
httpContext.Response.Headers.ContentLength = 0;
671+
httpContext.Response.Headers.ContentLength = 1;
653672

654673
try
655674
{
@@ -678,6 +697,45 @@ await connection.Send(
678697
}
679698
}
680699

700+
private async Task AttemptingToWriteZeroContentLength_ContentLengthRemoved(int statusCode, HttpMethod method)
701+
{
702+
var responseWriteTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
703+
704+
await using (var server = new TestServer(async httpContext =>
705+
{
706+
httpContext.Response.StatusCode = statusCode;
707+
httpContext.Response.Headers.ContentLength = 0;
708+
709+
try
710+
{
711+
await httpContext.Response.StartAsync();
712+
}
713+
catch (Exception ex)
714+
{
715+
responseWriteTcs.TrySetException(ex);
716+
throw;
717+
}
718+
719+
responseWriteTcs.TrySetResult();
720+
}, new TestServiceContext(LoggerFactory)))
721+
{
722+
using (var connection = server.CreateConnection())
723+
{
724+
await connection.Send(
725+
$"{HttpUtilities.MethodToString(method)} / HTTP/1.1",
726+
"Host:",
727+
"",
728+
"");
729+
730+
await connection.Receive(
731+
$"HTTP/1.1 {Encoding.ASCII.GetString(ReasonPhrases.ToStatusBytes(statusCode))}",
732+
$"Date: {server.Context.DateHeaderValue}",
733+
"",
734+
"");
735+
}
736+
}
737+
}
738+
681739
[Fact]
682740
public async Task AttemptingToWriteNonzeroContentLengthFailsFor205Response()
683741
{

0 commit comments

Comments
 (0)