@@ -56,7 +56,7 @@ internal abstract partial class HttpProtocol : IHttpResponseControl
5656 protected volatile bool _keepAlive = true ;
5757 // _responseBodyMode is set in CreateResponseHeaders.
5858 // If we are writing with GetMemory/Advance before calling StartAsync, assume we can write and throw away contents if we can't.
59- private ResponseBodyMode _responseBodyMode = ResponseBodyMode . ContentLength ;
59+ private ResponseBodyMode _responseBodyMode = ResponseBodyMode . Uninitialized ;
6060 private bool _hasAdvanced ;
6161 private bool _isLeasedMemoryInvalid = true ;
6262 protected Exception ? _applicationException ;
@@ -346,7 +346,7 @@ public void Reset()
346346 _routeValues ? . Clear ( ) ;
347347
348348 _requestProcessingStatus = RequestProcessingStatus . RequestPending ;
349- _responseBodyMode = ResponseBodyMode . ContentLength ;
349+ _responseBodyMode = ResponseBodyMode . Uninitialized ;
350350 _applicationException = null ;
351351 _requestRejectedException = null ;
352352
@@ -1592,28 +1592,28 @@ public ValueTask<FlushResult> WritePipeAsync(ReadOnlyMemory<byte> data, Cancella
15921592 VerifyAndUpdateWrite ( data . Length ) ;
15931593 }
15941594
1595- if ( _responseBodyMode != ResponseBodyMode . Disabled )
1595+ switch ( _responseBodyMode )
15961596 {
1597- if ( _responseBodyMode == ResponseBodyMode . Chunked )
1598- {
1597+ case ResponseBodyMode . Disabled :
1598+ HandleNonBodyResponseWrite ( ) ;
1599+ return default ;
1600+ case ResponseBodyMode . Chunked :
15991601 if ( data . Length == 0 )
16001602 {
16011603 return default ;
16021604 }
16031605
16041606 return Output . WriteChunkAsync ( data . Span , cancellationToken ) ;
1605- }
1606- else
1607- {
1607+ case ResponseBodyMode . ContentLength :
16081608 CheckLastWrite ( ) ;
16091609 return Output . WriteDataToPipeAsync ( data . Span , cancellationToken : cancellationToken ) ;
1610- }
1611- }
1612- else
1613- {
1614- HandleNonBodyResponseWrite ( ) ;
1615- return default ;
1610+ case ResponseBodyMode . Uninitialized :
1611+ ThrowInvalidOperation ( ) ;
1612+ break ;
16161613 }
1614+
1615+ Debug . Assert ( false , "Should not reach here, all cases in above switch statement should return" ) ;
1616+ return default ;
16171617 }
16181618
16191619 private ValueTask < FlushResult > FirstWriteAsync ( ReadOnlyMemory < byte > data , CancellationToken cancellationToken )
@@ -1640,30 +1640,30 @@ private ValueTask<FlushResult> FirstWriteAsyncInternal(ReadOnlyMemory<byte> data
16401640 {
16411641 var responseHeaders = InitializeResponseFirstWrite ( data . Length ) ;
16421642
1643- if ( _responseBodyMode != ResponseBodyMode . Disabled )
1643+ switch ( _responseBodyMode )
16441644 {
1645- if ( _responseBodyMode == ResponseBodyMode . Chunked )
1646- {
1645+ case ResponseBodyMode . Disabled :
1646+ Output . WriteResponseHeaders ( StatusCode , ReasonPhrase , responseHeaders , _responseBodyMode , appCompleted : false ) ;
1647+ HandleNonBodyResponseWrite ( ) ;
1648+ return Output . FlushAsync ( cancellationToken ) ;
1649+ case ResponseBodyMode . Chunked :
16471650 if ( data . Length == 0 )
16481651 {
16491652 Output . WriteResponseHeaders ( StatusCode , ReasonPhrase , responseHeaders , _responseBodyMode , appCompleted : false ) ;
16501653 return Output . FlushAsync ( cancellationToken ) ;
16511654 }
16521655
16531656 return Output . FirstWriteChunkedAsync ( StatusCode , ReasonPhrase , responseHeaders , _responseBodyMode , data . Span , cancellationToken ) ;
1654- }
1655- else
1656- {
1657+ case ResponseBodyMode . ContentLength :
16571658 CheckLastWrite ( ) ;
16581659 return Output . FirstWriteAsync ( StatusCode , ReasonPhrase , responseHeaders , _responseBodyMode , data . Span , cancellationToken ) ;
1659- }
1660- }
1661- else
1662- {
1663- Output . WriteResponseHeaders ( StatusCode , ReasonPhrase , responseHeaders , _responseBodyMode , appCompleted : false ) ;
1664- HandleNonBodyResponseWrite ( ) ;
1665- return Output . FlushAsync ( cancellationToken ) ;
1660+ case ResponseBodyMode . Uninitialized :
1661+ ThrowInvalidOperation ( ) ;
1662+ break ;
16661663 }
1664+
1665+ Debug . Assert ( false , "Should not reach here, all cases in above switch statement should return" ) ;
1666+ return default ;
16671667 }
16681668
16691669 public Task FlushAsync ( CancellationToken cancellationToken = default )
@@ -1689,27 +1689,34 @@ public async ValueTask<FlushResult> WriteAsyncAwaited(Task initializeTask, ReadO
16891689
16901690 // WriteAsyncAwaited is only called for the first write to the body.
16911691 // Ensure headers are flushed if Write(Chunked)Async isn't called.
1692- if ( _responseBodyMode != ResponseBodyMode . Disabled )
1692+ switch ( _responseBodyMode )
16931693 {
1694- if ( _responseBodyMode == ResponseBodyMode . Chunked )
1695- {
1694+ case ResponseBodyMode . Disabled :
1695+ HandleNonBodyResponseWrite ( ) ;
1696+ return await Output . FlushAsync ( cancellationToken ) ;
1697+ case ResponseBodyMode . Chunked :
16961698 if ( data . Length == 0 )
16971699 {
16981700 return await Output . FlushAsync ( cancellationToken ) ;
16991701 }
17001702
17011703 return await Output . WriteChunkAsync ( data . Span , cancellationToken ) ;
1702- }
1703- else
1704- {
1704+ case ResponseBodyMode . ContentLength :
17051705 CheckLastWrite ( ) ;
17061706 return await Output . WriteDataToPipeAsync ( data . Span , cancellationToken : cancellationToken ) ;
1707- }
1708- }
1709- else
1710- {
1711- HandleNonBodyResponseWrite ( ) ;
1712- return await Output . FlushAsync ( cancellationToken ) ;
1707+ case ResponseBodyMode . Uninitialized :
1708+ ThrowInvalidOperation ( ) ;
1709+ break ;
17131710 }
1711+
1712+ Debug . Assert ( false , "Should not reach here, all cases in above switch statement should return" ) ;
1713+ return default ;
1714+ }
1715+
1716+ [ DoesNotReturn ]
1717+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
1718+ static void ThrowInvalidOperation ( )
1719+ {
1720+ throw new InvalidOperationException ( ) ;
17141721 }
17151722}
0 commit comments