From 47976dd3c929c89f881388d3ff8ee6d0918c9602 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Fri, 20 Aug 2021 10:37:46 -0700 Subject: [PATCH 1/2] Don't cache CanReuse value --- .../Kestrel/Core/src/Internal/Http2/Http2Stream.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs index 0cea2d8f1d1a..e4690e7a83c1 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs @@ -41,7 +41,6 @@ public void Initialize(Http2StreamContext context) { base.Initialize(context); - CanReuse = false; _decrementCalled = false; _completionState = StreamCompletionFlags.None; InputRemaining = null; @@ -107,7 +106,9 @@ public bool ReceivedEmptyRequestBody } } - public bool CanReuse { get; private set; } + // We only want to reuse a stream that was not aborted and has completely finished writing. + // This ensures Http2OutputProducer.ProcessDataWrites is in the correct state to be reused. + public bool CanReuse => !_connectionAborted && HasResponseCompleted; protected override void OnReset() { @@ -164,9 +165,6 @@ public void CompleteStream(bool errored) // connection's flow-control window. _inputFlowControl.Abort(); - // We only want to reuse a stream that was not aborted and has completely finished writing. - // This ensures Http2OutputProducer.ProcessDataWrites is in the correct state to be reused. - CanReuse = !_connectionAborted && HasResponseCompleted; } finally { From f01c29c46ab9c5f099002603213f9ec28d0cba6f Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 24 Aug 2021 14:27:49 -0700 Subject: [PATCH 2/2] Comment on when to use CanReuse --- src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs index e4690e7a83c1..178a42b68d79 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs @@ -108,6 +108,13 @@ public bool ReceivedEmptyRequestBody // We only want to reuse a stream that was not aborted and has completely finished writing. // This ensures Http2OutputProducer.ProcessDataWrites is in the correct state to be reused. + + // CanReuse must be evaluated on the main frame-processing looping after the stream is removed + // from the connection's active streams collection. This is required because a RST_STREAM + // frame could arrive after the END_STREAM flag is received. Only once the stream is removed + // from the connection's active stream collection can no longer be reset, and is safe to + // evaluate for pooling. + public bool CanReuse => !_connectionAborted && HasResponseCompleted; protected override void OnReset()