Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit f9656ef

Browse files
committed
Don't write body for non-body responses
1 parent 10aef1b commit f9656ef

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Frame.cs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public abstract partial class Frame : ConnectionContext, IFrameControl
5858

5959
protected RequestProcessingStatus _requestProcessingStatus;
6060
protected bool _keepAlive;
61+
private bool _canHaveBody;
6162
private bool _autoChunk;
6263
protected Exception _applicationException;
6364

@@ -465,6 +466,9 @@ public void Write(ArraySegment<byte> data)
465466
{
466467
ProduceStartAndFireOnStarting().GetAwaiter().GetResult();
467468

469+
// Don't write to body for HEAD requests or 101, 204, 205, 304 responses.
470+
if (!_canHaveBody) return;
471+
468472
if (_autoChunk)
469473
{
470474
if (data.Count == 0)
@@ -486,6 +490,9 @@ public Task WriteAsync(ArraySegment<byte> data, CancellationToken cancellationTo
486490
return WriteAsyncAwaited(data, cancellationToken);
487491
}
488492

493+
// Don't write to body for HEAD requests or 101, 204, 205, 304 responses.
494+
if (!_canHaveBody) return TaskUtilities.CompletedTask;
495+
489496
if (_autoChunk)
490497
{
491498
if (data.Count == 0)
@@ -710,10 +717,12 @@ private void CreateResponseHeader(
710717
bool appCompleted)
711718
{
712719
var responseHeaders = FrameResponseHeaders;
713-
responseHeaders.SetReadOnly();
714720

715721
var hasConnection = responseHeaders.HasConnection;
716722

723+
// Set whether response can have body
724+
_canHaveBody = StatusCanHaveBody(StatusCode) && Method != "HEAD";
725+
717726
var end = SocketOutput.ProducingStart();
718727
if (_keepAlive && hasConnection)
719728
{
@@ -727,11 +736,9 @@ private void CreateResponseHeader(
727736
}
728737
}
729738

730-
if (_keepAlive && !responseHeaders.HasTransferEncoding && !responseHeaders.HasContentLength)
739+
if (_canHaveBody)
731740
{
732-
// Don't set the Content-Length or Transfer-Encoding headers
733-
// automatically for HEAD requests or 101, 204, 205, 304 responses.
734-
if (Method != "HEAD" && StatusCanHaveBody(StatusCode))
741+
if (_keepAlive && !responseHeaders.HasTransferEncoding && !responseHeaders.HasContentLength)
735742
{
736743
if (appCompleted)
737744
{
@@ -753,15 +760,26 @@ private void CreateResponseHeader(
753760
_autoChunk = true;
754761
responseHeaders.SetRawTransferEncoding("chunked", _bytesTransferEncodingChunked);
755762
}
763+
else
764+
{
765+
_keepAlive = false;
766+
}
756767
}
757768
}
758-
759-
if (!appCompleted && _httpVersion != HttpVersionType.Http11)
769+
}
770+
else
771+
{
772+
// Don't set the Content-Length or Transfer-Encoding headers
773+
// automatically for HEAD requests or 101, 204, 205, 304 responses.
774+
if (responseHeaders.HasTransferEncoding)
760775
{
761-
_keepAlive = false;
776+
// Remove Transfer-Encoding encoding header if it exists
777+
responseHeaders.Remove("Transfer-Encoding");
762778
}
763779
}
764780

781+
responseHeaders.SetReadOnly();
782+
765783
if (!_keepAlive && !hasConnection && _httpVersion != HttpVersionType.Http10)
766784
{
767785
responseHeaders.SetRawConnection("close", _bytesConnectionClose);

src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/FrameHeaders.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ bool ICollection<KeyValuePair<string, StringValues>>.Remove(KeyValuePair<string,
196196
RemoveFast(item.Key);
197197
}
198198

199-
bool IDictionary<string, StringValues>.Remove(string key)
199+
public bool Remove(string key)
200200
{
201201
if (_isReadOnly)
202202
{

0 commit comments

Comments
 (0)