@@ -58,6 +58,7 @@ public abstract partial class Frame : ConnectionContext, IFrameControl
58
58
59
59
protected RequestProcessingStatus _requestProcessingStatus ;
60
60
protected bool _keepAlive ;
61
+ private bool _canHaveBody ;
61
62
private bool _autoChunk ;
62
63
protected Exception _applicationException ;
63
64
@@ -465,6 +466,9 @@ public void Write(ArraySegment<byte> data)
465
466
{
466
467
ProduceStartAndFireOnStarting ( ) . GetAwaiter ( ) . GetResult ( ) ;
467
468
469
+ // Don't write to body for HEAD requests or 101, 204, 205, 304 responses.
470
+ if ( ! _canHaveBody ) return ;
471
+
468
472
if ( _autoChunk )
469
473
{
470
474
if ( data . Count == 0 )
@@ -486,6 +490,9 @@ public Task WriteAsync(ArraySegment<byte> data, CancellationToken cancellationTo
486
490
return WriteAsyncAwaited ( data , cancellationToken ) ;
487
491
}
488
492
493
+ // Don't write to body for HEAD requests or 101, 204, 205, 304 responses.
494
+ if ( ! _canHaveBody ) return TaskUtilities . CompletedTask ;
495
+
489
496
if ( _autoChunk )
490
497
{
491
498
if ( data . Count == 0 )
@@ -710,10 +717,12 @@ private void CreateResponseHeader(
710
717
bool appCompleted )
711
718
{
712
719
var responseHeaders = FrameResponseHeaders ;
713
- responseHeaders . SetReadOnly ( ) ;
714
720
715
721
var hasConnection = responseHeaders . HasConnection ;
716
722
723
+ // Set whether response can have body
724
+ _canHaveBody = StatusCanHaveBody ( StatusCode ) && Method != "HEAD" ;
725
+
717
726
var end = SocketOutput . ProducingStart ( ) ;
718
727
if ( _keepAlive && hasConnection )
719
728
{
@@ -727,11 +736,9 @@ private void CreateResponseHeader(
727
736
}
728
737
}
729
738
730
- if ( _keepAlive && ! responseHeaders . HasTransferEncoding && ! responseHeaders . HasContentLength )
739
+ if ( _canHaveBody )
731
740
{
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 )
735
742
{
736
743
if ( appCompleted )
737
744
{
@@ -753,15 +760,26 @@ private void CreateResponseHeader(
753
760
_autoChunk = true ;
754
761
responseHeaders . SetRawTransferEncoding ( "chunked" , _bytesTransferEncodingChunked ) ;
755
762
}
763
+ else
764
+ {
765
+ _keepAlive = false ;
766
+ }
756
767
}
757
768
}
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 )
760
775
{
761
- _keepAlive = false ;
776
+ // Remove Transfer-Encoding encoding header if it exists
777
+ responseHeaders . Remove ( "Transfer-Encoding" ) ;
762
778
}
763
779
}
764
780
781
+ responseHeaders . SetReadOnly ( ) ;
782
+
765
783
if ( ! _keepAlive && ! hasConnection && _httpVersion != HttpVersionType . Http10 )
766
784
{
767
785
responseHeaders . SetRawConnection ( "close" , _bytesConnectionClose ) ;
0 commit comments