From 47b536739793827edbc643f83a7a2c6b1ca7c9ea Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Fri, 5 Jun 2020 23:57:24 +0800 Subject: [PATCH 01/42] Update To Async --- .../Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs index aff3004fb059..9bb8d47977a4 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs @@ -182,7 +182,7 @@ private async Task PumpAsync() } finally { - _requestBodyPipe.Writer.Complete(error); + await _requestBodyPipe.Writer.CompleteAsync(error); } } From db5612ffc2c322dd31e4acdfb85fc99ec12ae4b5 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Sat, 6 Jun 2020 00:00:46 +0800 Subject: [PATCH 02/42] Update To Async --- .../Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs index ede4621cce68..596d8288c603 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs @@ -468,7 +468,7 @@ private async ValueTask ProcessDataWrites() _log.LogCritical(ex, nameof(Http2OutputProducer) + "." + nameof(ProcessDataWrites) + " observed an unexpected exception."); } - _pipeReader.Complete(); + await _pipeReader.CompleteAsync(); // Signal via WriteStreamSuffixAsync to the stream that output has finished. // Stream state will move to RequestProcessingStatus.ResponseCompleted From 98f705783c4eea288295ee26c1cce8c9e37bc554 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Sat, 6 Jun 2020 00:02:56 +0800 Subject: [PATCH 03/42] Update To Async --- src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index d8530a577af5..f92edd48bee1 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -373,7 +373,7 @@ public async Task ProcessRequestAsync(IHttpApplication appli var streamError = error as ConnectionAbortedException ?? new ConnectionAbortedException("The stream has completed.", error); - Input.Complete(); + await Input.CompleteAsync(); await RequestBodyPipe.Writer.CompleteAsync(); From c0564439ce4dd59c98041eafca26dd5b75af4c61 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:43:47 +0800 Subject: [PATCH 04/42] Update Http1ChunkedEncodingMessageBody.cs --- .../src/Internal/Http/Http1ChunkedEncodingMessageBody.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs index 9bb8d47977a4..0194f9bc1603 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs @@ -109,6 +109,13 @@ public override void Complete(Exception exception) _context.ReportApplicationError(exception); } + public override Task CompleteAsync(Exception exception) + { + _completed = true; + _context.ReportApplicationError(exception); + return Task.CompletedTask; + } + public override void CancelPendingRead() { _requestBodyPipe.Reader.CancelPendingRead(); From 8009bed22873e2ae9b04151009ae3b3f213a3fb5 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:44:53 +0800 Subject: [PATCH 05/42] Update Http1ContentLengthMessageBody.cs --- .../src/Internal/Http/Http1ContentLengthMessageBody.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs index 04cfe0214d1e..bf4915acd26d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs @@ -267,6 +267,13 @@ public override void Complete(Exception exception) _completed = true; } + public override Task CompleteAsync(Exception exception) + { + _context.ReportApplicationError(exception); + _completed = true; + return Task.CompletedTask; + } + public override void CancelPendingRead() { Interlocked.Exchange(ref _userCanceled, 1); @@ -275,8 +282,7 @@ public override void CancelPendingRead() protected override Task OnStopAsync() { - Complete(null); - return Task.CompletedTask; + return CompleteAsync(null); } [StackTraceHidden] From 0cc8e43fcfb3116f5107ed501c5277c9a4506b37 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:45:29 +0800 Subject: [PATCH 06/42] Update Http1UpgradeMessageBody.cs --- .../Core/src/Internal/Http/Http1UpgradeMessageBody.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs index 8d67b56462c5..9b5e50597df4 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs @@ -52,6 +52,13 @@ public override void Complete(Exception exception) _completed = true; } + public override Task CompleteAsync(Exception exception) + { + _context.ReportApplicationError(exception); + _completed = true; + return Task.CompletedTask; + } + public override void CancelPendingRead() { _context.Input.CancelPendingRead(); From 64497aa91d2f95df6e604e33e2782a1df7160cb1 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:46:05 +0800 Subject: [PATCH 07/42] Update Http2Connection.cs --- .../Core/src/Internal/Http2/Http2Connection.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index b63f4a4e7cb2..071388e28668 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -22,7 +22,6 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.Extensions.Logging; -using Microsoft.AspNetCore.Internal; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 { @@ -353,7 +352,7 @@ public async Task ProcessRequestsAsync(IHttpApplication appl TimeoutControl.CancelTimeout(); TimeoutControl.StartDrainTimeout(Limits.MinResponseDataRate, Limits.MaxResponseBufferSize); - _frameWriter.Complete(); + await _frameWriter.CompleteAsync(); } catch { @@ -795,7 +794,7 @@ private Task ProcessSettingsFrameAsync(in ReadOnlySequence payload) // the new size. _frameWriter.UpdateMaxHeaderTableSize(Math.Min(_clientSettings.HeaderTableSize, (uint)Limits.Http2.HeaderTableSize)); - return ackTask.GetAsTask(); + return ackTask.AsTask(); } catch (Http2SettingsParameterOutOfRangeException ex) { @@ -834,7 +833,7 @@ private Task ProcessPingFrameAsync(in ReadOnlySequence payload) return Task.CompletedTask; } - return _frameWriter.WritePingAsync(Http2PingFrameFlags.ACK, payload).GetAsTask(); + return _frameWriter.WritePingAsync(Http2PingFrameFlags.ACK, payload).AsTask(); } private Task ProcessGoAwayFrameAsync() @@ -1020,13 +1019,7 @@ private void StartStream() throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMissingMandatoryPseudoHeaderFields, Http2ErrorCode.PROTOCOL_ERROR); } - if (_clientActiveStreamCount == _serverSettings.MaxConcurrentStreams) - { - // Provide feedback in server logs that the client hit the number of maximum concurrent streams, - // and that the client is likely waiting for existing streams to be completed before it can continue. - Log.Http2MaxConcurrentStreamsReached(_context.ConnectionId); - } - else if (_clientActiveStreamCount > _serverSettings.MaxConcurrentStreams) + if (_clientActiveStreamCount > _serverSettings.MaxConcurrentStreams) { // The protocol default stream limit is infinite so the client can exceed our limit at the start of the connection. // Refused streams can be retried, by which time the client must have received our settings frame with our limit information. From 1787f77b13ad369ba2a04430d9e9b7e3a9e439d6 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:46:44 +0800 Subject: [PATCH 08/42] Update Http2FrameWriter.cs --- .../src/Internal/Http2/Http2FrameWriter.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs index 9f9cd89aae16..eeb4448e4d6b 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs @@ -109,6 +109,23 @@ public void Complete() } } + public Task CompleteAsync() + { + lock (_writeLock) + { + if (_completed) + { + return Task.CompletedTask; + } + + _completed = true; + _connectionOutputFlowControl.Abort(); + _outputWriter.Abort(); + } + + return Task.CompletedTask; + } + public void Abort(ConnectionAbortedException error) { lock (_writeLock) @@ -133,7 +150,7 @@ public ValueTask FlushAsync(IHttpOutputAborter outputAborter, Cance { return default; } - + var bytesWritten = _unflushedBytes; _unflushedBytes = 0; From d89c5858a4e2e88634a954b442131d89dbe0fd58 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:47:21 +0800 Subject: [PATCH 09/42] Update Http2MessageBody.cs --- .../Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs index 53d88f4ff959..734bfede7c56 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs @@ -114,6 +114,12 @@ public override void Complete(Exception exception) _context.ReportApplicationError(exception); } + public override async Task CompleteAsync(Exception exception) + { + await _context.RequestBodyPipe.Reader.CompleteAsync(); + _context.ReportApplicationError(exception); + } + public override void CancelPendingRead() { _context.RequestBodyPipe.Reader.CancelPendingRead(); From 7e759653a7b704b22f2cac7d0e75f59aa514d251 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:49:41 +0800 Subject: [PATCH 10/42] Update Http3FrameWriter.cs --- .../Core/src/Internal/Http3/Http3FrameWriter.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs index bb2e33a4cbbb..7742d12705f3 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs @@ -313,6 +313,20 @@ public void Complete() } } + public async Task CompleteAsync() + { + lock (_writeLock) + { + if (_completed) + { + return; + } + + _completed = true; + } + await _outputWriter.CompleteAsync(); + } + public void Abort(ConnectionAbortedException error) { lock (_writeLock) From 23a98258d252ed816f9b541d6b075071a5a32ba6 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:50:09 +0800 Subject: [PATCH 11/42] Update Http3MessageBody.cs --- .../Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs index 96c6bc8aee04..44856a771fc8 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs @@ -104,6 +104,12 @@ public override void Complete(Exception exception) _context.ReportApplicationError(exception); } + public override async Task CompleteAsync(Exception exception) + { + await _context.RequestBodyPipe.Reader.CompleteAsync(); + _context.ReportApplicationError(exception); + } + public override void CancelPendingRead() { _context.RequestBodyPipe.Reader.CancelPendingRead(); From 83e9e3ad93ec6e39d654c801a83219f2d46a6469 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:50:33 +0800 Subject: [PATCH 12/42] Update Http3OutputProducer.cs --- .../Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs index a9244975ebb7..da0d0733b22c 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs @@ -365,7 +365,7 @@ private async ValueTask ProcessDataWrites() // Headers have already been written and there is no other content to write // TODO complete something here. flushResult = await _frameWriter.FlushAsync(outputAborter: null, cancellationToken: default); - _frameWriter.Complete(); + await _frameWriter.CompleteAsync(); } else { @@ -384,7 +384,7 @@ private async ValueTask ProcessDataWrites() _log.LogCritical(ex, nameof(Http3OutputProducer) + "." + nameof(ProcessDataWrites) + " observed an unexpected exception."); } - _pipeReader.Complete(); + await _pipeReader.CompleteAsync(); return flushResult; From 1df35f16a01f055b3955a42befa2a4c2fffc552e Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:51:10 +0800 Subject: [PATCH 13/42] Update Http3Stream.cs --- .../Kestrel/Core/src/Internal/Http3/Http3Stream.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index f92edd48bee1..2e5d21f4d1fc 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -347,7 +347,7 @@ public async Task ProcessRequestAsync(IHttpApplication appli if (result.IsCompleted) { - OnEndStreamReceived(); + await OnEndStreamReceived(); return; } } @@ -385,7 +385,7 @@ public async Task ProcessRequestAsync(IHttpApplication appli try { - _frameWriter.Complete(); + await _frameWriter.CompleteAsync(); } catch { @@ -399,7 +399,7 @@ public async Task ProcessRequestAsync(IHttpApplication appli } } - private void OnEndStreamReceived() + private async Task OnEndStreamReceived() { if (InputRemaining.HasValue) { @@ -411,7 +411,7 @@ private void OnEndStreamReceived() } OnTrailersComplete(); - RequestBodyPipe.Writer.Complete(); + await RequestBodyPipe.Writer.CompleteAsync(); } private Task ProcessHttp3Stream(IHttpApplication application, in ReadOnlySequence payload) From a627b1c874a0b060bf4f5208975c3f8881a97478 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:52:04 +0800 Subject: [PATCH 14/42] Update HttpRequestPipeReader.cs --- .../Core/src/Internal/Http/HttpRequestPipeReader.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs index f2af61b327c5..ea5e606384a5 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs @@ -52,6 +52,13 @@ public override void Complete(Exception exception = null) _body.Complete(exception); } + public override async ValueTask CompleteAsync(Exception exception = null) + { + ValidateState(); + + await _body.CompleteAsync(exception); + } + public override ValueTask ReadAsync(CancellationToken cancellationToken = default) { ValidateState(cancellationToken); From 258f10297e424e35dae90b0f55e3231b1bdbc9c4 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:52:54 +0800 Subject: [PATCH 15/42] Update MessageBody.cs --- src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs index 08f13a59592b..9c71582f54ec 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs @@ -51,6 +51,8 @@ protected MessageBody(HttpProtocol context) public abstract void Complete(Exception exception); + public abstract Task CompleteAsync(Exception exception); + public abstract void CancelPendingRead(); public abstract ValueTask ReadAsync(CancellationToken cancellationToken = default); From 99d845434b28b0422a925e479561f74ffbc26d58 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:59:38 +0800 Subject: [PATCH 16/42] Update ZeroContentLengthMessageBody.cs --- .../Core/src/Internal/Http/ZeroContentLengthMessageBody.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs index 109083285809..a9da86d41c0d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs @@ -35,6 +35,8 @@ public override bool TryRead(out ReadResult result) } public override void Complete(Exception ex) { } + + public override Task CompleteAsync(Exception exception)=>Task.CompletedTask; public override void CancelPendingRead() { } } From 3abfcb7bdf84d273313529ec818484f161c19c4a Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 09:25:30 +0800 Subject: [PATCH 17/42] Update Http2Connection.cs --- .../Core/src/Internal/Http2/Http2Connection.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index 071388e28668..0918830852d7 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -833,7 +833,7 @@ private Task ProcessPingFrameAsync(in ReadOnlySequence payload) return Task.CompletedTask; } - return _frameWriter.WritePingAsync(Http2PingFrameFlags.ACK, payload).AsTask(); + return _frameWriter.WritePingAsync(Http2PingFrameFlags.ACK, payload).GetAsTask(); } private Task ProcessGoAwayFrameAsync() @@ -1018,14 +1018,20 @@ private void StartStream() // fields is malformed (Section 8.1.2.6). throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMissingMandatoryPseudoHeaderFields, Http2ErrorCode.PROTOCOL_ERROR); } - - if (_clientActiveStreamCount > _serverSettings.MaxConcurrentStreams) + + if (_clientActiveStreamCount == _serverSettings.MaxConcurrentStreams) + { + // Provide feedback in server logs that the client hit the number of maximum concurrent streams, + // and that the client is likely waiting for existing streams to be completed before it can continue. + Log.Http2MaxConcurrentStreamsReached(_context.ConnectionId); + } + else if (_clientActiveStreamCount > _serverSettings.MaxConcurrentStreams) { // The protocol default stream limit is infinite so the client can exceed our limit at the start of the connection. // Refused streams can be retried, by which time the client must have received our settings frame with our limit information. throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMaxStreams, Http2ErrorCode.REFUSED_STREAM); } - + // We don't use the _serverActiveRequestCount here as during shutdown, it and the dictionary counts get out of sync. // The streams still exist in the dictionary until the client responds with a RST or END_STREAM. // Also, we care about the dictionary size for too much memory consumption. From 1040e9c2bac3e83c0647b4d28ad82b4f788c96e0 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 09:44:15 +0800 Subject: [PATCH 18/42] Update MessageBody.cs --- src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs index 9c71582f54ec..c9d27deda986 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs @@ -51,7 +51,11 @@ protected MessageBody(HttpProtocol context) public abstract void Complete(Exception exception); - public abstract Task CompleteAsync(Exception exception); + public virtual ValueTask CompleteAsync(Exception exception) + { + Complete(exception); + return new ValueTask(); + }; public abstract void CancelPendingRead(); From 67958b9bded606bad51994b548bb87e665d7a0e3 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 09:47:10 +0800 Subject: [PATCH 19/42] Update Http3Stream.cs --- src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index 2e5d21f4d1fc..8fcb367d0433 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -399,7 +399,7 @@ public async Task ProcessRequestAsync(IHttpApplication appli } } - private async Task OnEndStreamReceived() + private ValueTask OnEndStreamReceived() { if (InputRemaining.HasValue) { @@ -411,7 +411,7 @@ private async Task OnEndStreamReceived() } OnTrailersComplete(); - await RequestBodyPipe.Writer.CompleteAsync(); + retrun RequestBodyPipe.Writer.CompleteAsync(); } private Task ProcessHttp3Stream(IHttpApplication application, in ReadOnlySequence payload) From 64e65880fd36c736b6e445f9c28e5aed15eee9e2 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 09:55:00 +0800 Subject: [PATCH 20/42] Update Http3MessageBody.cs --- src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs index 44856a771fc8..0e4c8cdeb447 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs @@ -104,7 +104,7 @@ public override void Complete(Exception exception) _context.ReportApplicationError(exception); } - public override async Task CompleteAsync(Exception exception) + public override async ValueTask CompleteAsync(Exception exception) { await _context.RequestBodyPipe.Reader.CompleteAsync(); _context.ReportApplicationError(exception); From 6fa3bc220a0e0699e00c55e0b4b2619dd03f201e Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 09:55:56 +0800 Subject: [PATCH 21/42] Update Http2MessageBody.cs --- src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs index 734bfede7c56..ffe41ec59235 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs @@ -114,7 +114,7 @@ public override void Complete(Exception exception) _context.ReportApplicationError(exception); } - public override async Task CompleteAsync(Exception exception) + public override async ValueTask CompleteAsync(Exception exception) { await _context.RequestBodyPipe.Reader.CompleteAsync(); _context.ReportApplicationError(exception); From 08a083eeaeb075aaa5078bdea56ee37692aa14d8 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 09:57:30 +0800 Subject: [PATCH 22/42] Update Http1ChunkedEncodingMessageBody.cs --- .../Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs index 0194f9bc1603..024799e27a8e 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs @@ -109,11 +109,11 @@ public override void Complete(Exception exception) _context.ReportApplicationError(exception); } - public override Task CompleteAsync(Exception exception) + public override ValueTask CompleteAsync(Exception exception) { _completed = true; _context.ReportApplicationError(exception); - return Task.CompletedTask; + return new ValueTask(); } public override void CancelPendingRead() From dbe405f9302c968d78c6f752d0c001b38a23051f Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:00:32 +0800 Subject: [PATCH 23/42] Update Http1ContentLengthMessageBody.cs --- .../Core/src/Internal/Http/Http1ContentLengthMessageBody.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs index bf4915acd26d..6163eb2639c8 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs @@ -267,11 +267,11 @@ public override void Complete(Exception exception) _completed = true; } - public override Task CompleteAsync(Exception exception) + public override ValueTask CompleteAsync(Exception exception) { _context.ReportApplicationError(exception); _completed = true; - return Task.CompletedTask; + return new ValueTask(); } public override void CancelPendingRead() @@ -280,7 +280,7 @@ public override void CancelPendingRead() _context.Input.CancelPendingRead(); } - protected override Task OnStopAsync() + protected override ValueTask OnStopAsync() { return CompleteAsync(null); } From 92262e58d854e16bfc15679e5ae016454815fab0 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:01:33 +0800 Subject: [PATCH 24/42] Update MessageBody.cs --- src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs index c9d27deda986..125fb4a949e7 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs @@ -68,7 +68,7 @@ public virtual Task ConsumeAsync() return OnConsumeAsync(); } - public virtual Task StopAsync() + public virtual ValueTask StopAsync() { TryStop(); @@ -77,7 +77,7 @@ public virtual Task StopAsync() protected virtual Task OnConsumeAsync() => Task.CompletedTask; - protected virtual Task OnStopAsync() => Task.CompletedTask; + protected virtual ValueTask OnStopAsync() => new ValueTask(); public virtual void Reset() { From cc1f72ea2bfe213669e9db37af90b0de36f8ce38 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:02:58 +0800 Subject: [PATCH 25/42] Update Http1ChunkedEncodingMessageBody.cs --- .../src/Internal/Http/Http1ChunkedEncodingMessageBody.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs index 024799e27a8e..752598d3c339 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs @@ -193,11 +193,11 @@ private async Task PumpAsync() } } - protected override Task OnStopAsync() + protected override ValueTask OnStopAsync() { if (!_context.HasStartedConsumingRequestBody) { - return Task.CompletedTask; + return new ValueTask(); } // call complete here on the reader @@ -208,14 +208,14 @@ protected override Task OnStopAsync() { // At this point both the request body pipe reader and writer should be completed. _requestBodyPipe.Reset(); - return Task.CompletedTask; + return new ValueTask(); } // Should I call complete here? return StopAsyncAwaited(); } - private async Task StopAsyncAwaited() + private async ValueTask StopAsyncAwaited() { _canceled = true; _context.Input.CancelPendingRead(); From 68d2f05ccb4499cbc675ac0c1af8bbfe6663ba21 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:04:26 +0800 Subject: [PATCH 26/42] Update Http1UpgradeMessageBody.cs --- .../Core/src/Internal/Http/Http1UpgradeMessageBody.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs index 9b5e50597df4..2186e6cbb0c9 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs @@ -52,7 +52,7 @@ public override void Complete(Exception exception) _completed = true; } - public override Task CompleteAsync(Exception exception) + public override ValueTask CompleteAsync(Exception exception) { _context.ReportApplicationError(exception); _completed = true; @@ -69,9 +69,9 @@ public override Task ConsumeAsync() return Task.CompletedTask; } - public override Task StopAsync() + public override ValueTask StopAsync() { - return Task.CompletedTask; + return new ValueTask(); } public override bool TryReadInternal(out ReadResult readResult) From 119cc933ac6cb8a3cd589a83d8c3bbfc077bc7dd Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:05:17 +0800 Subject: [PATCH 27/42] Update Http2MessageBody.cs --- .../Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs index ffe41ec59235..a194200ac9ce 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs @@ -125,16 +125,16 @@ public override void CancelPendingRead() _context.RequestBodyPipe.Reader.CancelPendingRead(); } - protected override Task OnStopAsync() + protected override ValueTask OnStopAsync() { if (!_context.HasStartedConsumingRequestBody) { - return Task.CompletedTask; + return new ValueTask(); } _context.RequestBodyPipe.Reader.Complete(); - return Task.CompletedTask; + return new ValueTask(); } } } From fd090e12c5594e9dee13d2b492bd84ec9d940ac1 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:06:02 +0800 Subject: [PATCH 28/42] Update Http3MessageBody.cs --- .../Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs index 0e4c8cdeb447..a287b43f5039 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs @@ -115,16 +115,16 @@ public override void CancelPendingRead() _context.RequestBodyPipe.Reader.CancelPendingRead(); } - protected override Task OnStopAsync() + protected override ValueTask OnStopAsync() { if (!_context.HasStartedConsumingRequestBody) { - return Task.CompletedTask; + return new ValueTask(); } _context.RequestBodyPipe.Reader.Complete(); - return Task.CompletedTask; + return new ValueTask(); } } } From 068005175f38e76bfc40a4cdb22043dddc0ca28f Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:07:21 +0800 Subject: [PATCH 29/42] Update ZeroContentLengthMessageBody.cs --- .../Core/src/Internal/Http/ZeroContentLengthMessageBody.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs index a9da86d41c0d..ef5919aca482 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs @@ -22,7 +22,7 @@ public ZeroContentLengthMessageBody(bool keepAlive) public override Task ConsumeAsync() => Task.CompletedTask; - public override Task StopAsync() => Task.CompletedTask; + public override ValueTask StopAsync() => new ValueTask(); public override void AdvanceTo(SequencePosition consumed) { } From 580d3449e1f487723489d7d2e62130f659277eb0 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:13:55 +0800 Subject: [PATCH 30/42] Update MessageBody.cs --- src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs index 125fb4a949e7..162534677d73 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs @@ -55,7 +55,7 @@ public virtual ValueTask CompleteAsync(Exception exception) { Complete(exception); return new ValueTask(); - }; + } public abstract void CancelPendingRead(); From 96a3cbba387ac544ccc265b251dc0fb38a153503 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:15:33 +0800 Subject: [PATCH 31/42] Update Http3Stream.cs --- src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index 8fcb367d0433..73cdbfb95d06 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -411,7 +411,7 @@ private ValueTask OnEndStreamReceived() } OnTrailersComplete(); - retrun RequestBodyPipe.Writer.CompleteAsync(); + return RequestBodyPipe.Writer.CompleteAsync(); } private Task ProcessHttp3Stream(IHttpApplication application, in ReadOnlySequence payload) From 37b08e0546cfdd7cb104453514d64942d1f78897 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:23:08 +0800 Subject: [PATCH 32/42] Update ZeroContentLengthMessageBody.cs --- .../Core/src/Internal/Http/ZeroContentLengthMessageBody.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs index ef5919aca482..de9f17c76ef2 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs @@ -35,8 +35,6 @@ public override bool TryRead(out ReadResult result) } public override void Complete(Exception ex) { } - - public override Task CompleteAsync(Exception exception)=>Task.CompletedTask; public override void CancelPendingRead() { } } From b493c0e8427716221374837b0e4f53c6c5a8ed59 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:30:25 +0800 Subject: [PATCH 33/42] Update Http1UpgradeMessageBody.cs --- .../Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs index 2186e6cbb0c9..93b8d424de00 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs @@ -56,7 +56,7 @@ public override ValueTask CompleteAsync(Exception exception) { _context.ReportApplicationError(exception); _completed = true; - return Task.CompletedTask; + return new ValueTask(); } public override void CancelPendingRead() From 715a845206238abc1662e0ba69a7447c4faff373 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:36:34 +0800 Subject: [PATCH 34/42] Update Http2Connection.cs --- src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index 0918830852d7..01fbbe019e95 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -22,6 +22,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.Extensions.Logging; +using Microsoft.AspNetCore.Internal; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 { From eb61fc1b8ec9e613887b7eb57de7c1d81ff1c2fc Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Fri, 12 Jun 2020 05:35:47 +0800 Subject: [PATCH 35/42] Update src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs Co-authored-by: Stephen Halter --- .../Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs index 752598d3c339..0255f8b80cfe 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs @@ -197,7 +197,7 @@ protected override ValueTask OnStopAsync() { if (!_context.HasStartedConsumingRequestBody) { - return new ValueTask(); + return default; } // call complete here on the reader From 934c054458523ad2aa86b625b03d40048299d68c Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Fri, 12 Jun 2020 05:36:18 +0800 Subject: [PATCH 36/42] Update src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs Co-authored-by: Stephen Halter --- src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index 01fbbe019e95..4e9efe5403c8 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -795,7 +795,7 @@ private Task ProcessSettingsFrameAsync(in ReadOnlySequence payload) // the new size. _frameWriter.UpdateMaxHeaderTableSize(Math.Min(_clientSettings.HeaderTableSize, (uint)Limits.Http2.HeaderTableSize)); - return ackTask.AsTask(); + return ackTask.GetAsTask(); } catch (Http2SettingsParameterOutOfRangeException ex) { From 6806e320479b81728686fd101f0c51dbdc620c98 Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Fri, 12 Jun 2020 05:36:39 +0800 Subject: [PATCH 37/42] Update src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs Co-authored-by: Stephen Halter --- src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index 4e9efe5403c8..d49b388702d6 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -1019,7 +1019,6 @@ private void StartStream() // fields is malformed (Section 8.1.2.6). throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMissingMandatoryPseudoHeaderFields, Http2ErrorCode.PROTOCOL_ERROR); } - if (_clientActiveStreamCount == _serverSettings.MaxConcurrentStreams) { // Provide feedback in server logs that the client hit the number of maximum concurrent streams, From 30cb66c5383e27c97101a13b30c645e46d7610cc Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Fri, 12 Jun 2020 05:49:40 +0800 Subject: [PATCH 38/42] Update Http1ChunkedEncodingMessageBody.cs --- .../src/Internal/Http/Http1ChunkedEncodingMessageBody.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs index 0255f8b80cfe..78cb16ed4447 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs @@ -108,14 +108,7 @@ public override void Complete(Exception exception) _completed = true; _context.ReportApplicationError(exception); } - - public override ValueTask CompleteAsync(Exception exception) - { - _completed = true; - _context.ReportApplicationError(exception); - return new ValueTask(); - } - + public override void CancelPendingRead() { _requestBodyPipe.Reader.CancelPendingRead(); From d80891bc8f722542fd9fbbaf4089bb5a4717e87e Mon Sep 17 00:00:00 2001 From: Huei Feng <34702552+hueifeng@users.noreply.github.com> Date: Fri, 12 Jun 2020 05:53:06 +0800 Subject: [PATCH 39/42] Update Http3FrameWriter.cs --- .../Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs index 7742d12705f3..a5bea3679322 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs @@ -313,18 +313,18 @@ public void Complete() } } - public async Task CompleteAsync() + public ValueTask CompleteAsync() { lock (_writeLock) { if (_completed) { - return; + return default; } _completed = true; } - await _outputWriter.CompleteAsync(); + return _outputWriter.CompleteAsync(); } public void Abort(ConnectionAbortedException error) From eef9dd9aa9e5584c2a052df490ba8f9908a80f22 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Thu, 10 Sep 2020 15:14:10 -0700 Subject: [PATCH 40/42] Cleanup --- .../Http/Http1ChunkedEncodingMessageBody.cs | 4 ++-- .../Http/Http1ContentLengthMessageBody.cs | 9 +-------- .../Internal/Http/Http1UpgradeMessageBody.cs | 9 +-------- .../src/Internal/Http/HttpRequestPipeReader.cs | 4 ++-- .../Core/src/Internal/Http/MessageBody.cs | 4 ++-- .../Http/ZeroContentLengthMessageBody.cs | 2 +- .../Core/src/Internal/Http2/Http2Connection.cs | 5 +++-- .../Core/src/Internal/Http2/Http2FrameWriter.cs | 17 ----------------- .../Core/src/Internal/Http2/Http2MessageBody.cs | 10 +++++----- .../Core/src/Internal/Http3/Http3FrameWriter.cs | 15 --------------- .../Core/src/Internal/Http3/Http3MessageBody.cs | 10 +++++----- .../src/Internal/Http3/Http3OutputProducer.cs | 3 +-- .../Core/src/Internal/Http3/Http3Stream.cs | 2 +- 13 files changed, 24 insertions(+), 70 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs index 78cb16ed4447..4eea5a0a6101 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs @@ -108,7 +108,7 @@ public override void Complete(Exception exception) _completed = true; _context.ReportApplicationError(exception); } - + public override void CancelPendingRead() { _requestBodyPipe.Reader.CancelPendingRead(); @@ -201,7 +201,7 @@ protected override ValueTask OnStopAsync() { // At this point both the request body pipe reader and writer should be completed. _requestBodyPipe.Reset(); - return new ValueTask(); + return default; } // Should I call complete here? diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs index 6163eb2639c8..d9bcd3ede766 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs @@ -267,13 +267,6 @@ public override void Complete(Exception exception) _completed = true; } - public override ValueTask CompleteAsync(Exception exception) - { - _context.ReportApplicationError(exception); - _completed = true; - return new ValueTask(); - } - public override void CancelPendingRead() { Interlocked.Exchange(ref _userCanceled, 1); @@ -282,7 +275,7 @@ public override void CancelPendingRead() protected override ValueTask OnStopAsync() { - return CompleteAsync(null); + return CompleteAsync(exception: null); } [StackTraceHidden] diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs index 93b8d424de00..c46ed75c8c91 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs @@ -52,13 +52,6 @@ public override void Complete(Exception exception) _completed = true; } - public override ValueTask CompleteAsync(Exception exception) - { - _context.ReportApplicationError(exception); - _completed = true; - return new ValueTask(); - } - public override void CancelPendingRead() { _context.Input.CancelPendingRead(); @@ -71,7 +64,7 @@ public override Task ConsumeAsync() public override ValueTask StopAsync() { - return new ValueTask(); + return default; } public override bool TryReadInternal(out ReadResult readResult) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs index ea5e606384a5..047d5bf96a4c 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs @@ -52,11 +52,11 @@ public override void Complete(Exception exception = null) _body.Complete(exception); } - public override async ValueTask CompleteAsync(Exception exception = null) + public override ValueTask CompleteAsync(Exception exception = null) { ValidateState(); - await _body.CompleteAsync(exception); + return _body.CompleteAsync(exception); } public override ValueTask ReadAsync(CancellationToken cancellationToken = default) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs index 162534677d73..2ca2af12028d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs @@ -54,7 +54,7 @@ protected MessageBody(HttpProtocol context) public virtual ValueTask CompleteAsync(Exception exception) { Complete(exception); - return new ValueTask(); + return default; } public abstract void CancelPendingRead(); @@ -77,7 +77,7 @@ public virtual ValueTask StopAsync() protected virtual Task OnConsumeAsync() => Task.CompletedTask; - protected virtual ValueTask OnStopAsync() => new ValueTask(); + protected virtual ValueTask OnStopAsync() => default; public virtual void Reset() { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs index de9f17c76ef2..0ae4d768d42c 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs @@ -22,7 +22,7 @@ public ZeroContentLengthMessageBody(bool keepAlive) public override Task ConsumeAsync() => Task.CompletedTask; - public override ValueTask StopAsync() => new ValueTask(); + public override ValueTask StopAsync() => default; public override void AdvanceTo(SequencePosition consumed) { } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index d49b388702d6..b63f4a4e7cb2 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -353,7 +353,7 @@ public async Task ProcessRequestsAsync(IHttpApplication appl TimeoutControl.CancelTimeout(); TimeoutControl.StartDrainTimeout(Limits.MinResponseDataRate, Limits.MaxResponseBufferSize); - await _frameWriter.CompleteAsync(); + _frameWriter.Complete(); } catch { @@ -1019,6 +1019,7 @@ private void StartStream() // fields is malformed (Section 8.1.2.6). throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMissingMandatoryPseudoHeaderFields, Http2ErrorCode.PROTOCOL_ERROR); } + if (_clientActiveStreamCount == _serverSettings.MaxConcurrentStreams) { // Provide feedback in server logs that the client hit the number of maximum concurrent streams, @@ -1031,7 +1032,7 @@ private void StartStream() // Refused streams can be retried, by which time the client must have received our settings frame with our limit information. throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMaxStreams, Http2ErrorCode.REFUSED_STREAM); } - + // We don't use the _serverActiveRequestCount here as during shutdown, it and the dictionary counts get out of sync. // The streams still exist in the dictionary until the client responds with a RST or END_STREAM. // Also, we care about the dictionary size for too much memory consumption. diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs index eeb4448e4d6b..e568fb426a93 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs @@ -109,23 +109,6 @@ public void Complete() } } - public Task CompleteAsync() - { - lock (_writeLock) - { - if (_completed) - { - return Task.CompletedTask; - } - - _completed = true; - _connectionOutputFlowControl.Abort(); - _outputWriter.Abort(); - } - - return Task.CompletedTask; - } - public void Abort(ConnectionAbortedException error) { lock (_writeLock) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs index a194200ac9ce..e121a8b680c7 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs @@ -110,14 +110,14 @@ public override async ValueTask ReadAsync(CancellationToken cancella public override void Complete(Exception exception) { - _context.RequestBodyPipe.Reader.Complete(); _context.ReportApplicationError(exception); + _context.RequestBodyPipe.Reader.Complete(); } - public override async ValueTask CompleteAsync(Exception exception) + public override ValueTask CompleteAsync(Exception exception) { - await _context.RequestBodyPipe.Reader.CompleteAsync(); _context.ReportApplicationError(exception); + return _context.RequestBodyPipe.Reader.CompleteAsync(); } public override void CancelPendingRead() @@ -129,12 +129,12 @@ protected override ValueTask OnStopAsync() { if (!_context.HasStartedConsumingRequestBody) { - return new ValueTask(); + return default; } _context.RequestBodyPipe.Reader.Complete(); - return new ValueTask(); + return default; } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs index a5bea3679322..d0c513503b6d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs @@ -309,24 +309,9 @@ public void Complete() } _completed = true; - _outputWriter.Complete(); } } - public ValueTask CompleteAsync() - { - lock (_writeLock) - { - if (_completed) - { - return default; - } - - _completed = true; - } - return _outputWriter.CompleteAsync(); - } - public void Abort(ConnectionAbortedException error) { lock (_writeLock) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs index a287b43f5039..f3f34202e2a6 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs @@ -100,14 +100,14 @@ public override async ValueTask ReadAsync(CancellationToken cancella public override void Complete(Exception exception) { - _context.RequestBodyPipe.Reader.Complete(); _context.ReportApplicationError(exception); + _context.RequestBodyPipe.Reader.Complete(); } - public override async ValueTask CompleteAsync(Exception exception) + public override ValueTask CompleteAsync(Exception exception) { - await _context.RequestBodyPipe.Reader.CompleteAsync(); _context.ReportApplicationError(exception); + return _context.RequestBodyPipe.Reader.CompleteAsync(); } public override void CancelPendingRead() @@ -119,12 +119,12 @@ protected override ValueTask OnStopAsync() { if (!_context.HasStartedConsumingRequestBody) { - return new ValueTask(); + return default; } _context.RequestBodyPipe.Reader.Complete(); - return new ValueTask(); + return default; } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs index da0d0733b22c..bd986bba5688 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs @@ -233,7 +233,6 @@ public void Stop() _completed = true; _pipeWriter.Complete(new OperationCanceledException()); - } } @@ -365,7 +364,7 @@ private async ValueTask ProcessDataWrites() // Headers have already been written and there is no other content to write // TODO complete something here. flushResult = await _frameWriter.FlushAsync(outputAborter: null, cancellationToken: default); - await _frameWriter.CompleteAsync(); + _frameWriter.Complete(); } else { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index 73cdbfb95d06..72deb4879198 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -385,7 +385,7 @@ public async Task ProcessRequestAsync(IHttpApplication appli try { - await _frameWriter.CompleteAsync(); + _frameWriter.Complete(); } catch { From 43b7f9541b123c6cb3769b3a973be63c0c181d15 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Thu, 10 Sep 2020 15:23:01 -0700 Subject: [PATCH 41/42] Add HttpResponsePipeWriter.CompleteAsync() --- .../Core/src/Internal/Http/HttpResponsePipeWriter.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponsePipeWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponsePipeWriter.cs index 6ccb84b66c6e..e7c411005ebc 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponsePipeWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponsePipeWriter.cs @@ -40,6 +40,12 @@ public override void Complete(Exception exception = null) _completeTask = _pipeControl.CompleteAsync(exception); } + public override ValueTask CompleteAsync(Exception exception = null) + { + Complete(); + return new ValueTask(_completeTask); + } + public override ValueTask FlushAsync(CancellationToken cancellationToken = default) { ValidateState(cancellationToken); From 25a0c12be1b69d7e457d1668159641a91a4931dd Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Tue, 15 Sep 2020 15:23:32 -0700 Subject: [PATCH 42/42] More cleanup --- .../Http/Http1ChunkedEncodingMessageBody.cs | 24 ---------- .../Http/Http1ContentLengthMessageBody.cs | 28 ------------ .../src/Internal/Http/Http1MessageBody.cs | 45 +++++++++++++------ .../Internal/Http/Http1UpgradeMessageBody.cs | 24 ---------- .../Core/src/Internal/Http/MessageBody.cs | 15 ++++--- .../Http/ZeroContentLengthMessageBody.cs | 2 - .../src/Internal/Http2/Http2MessageBody.cs | 5 --- .../src/Internal/Http3/Http3FrameWriter.cs | 14 ++++-- .../src/Internal/Http3/Http3MessageBody.cs | 10 +---- .../src/Internal/Http3/Http3OutputProducer.cs | 2 +- .../Core/src/Internal/Http3/Http3Stream.cs | 2 +- .../Kestrel/Core/test/BodyControlTests.cs | 5 --- 12 files changed, 54 insertions(+), 122 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs index 4eea5a0a6101..03856ceaf97f 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs @@ -37,24 +37,12 @@ public Http1ChunkedEncodingMessageBody(bool keepAlive, Http1Connection context) _requestBodyPipe = CreateRequestBodyPipe(context); } - public override void AdvanceTo(SequencePosition consumed) - { - AdvanceTo(consumed, consumed); - } - public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { TrackConsumedAndExaminedBytes(_readResult, consumed, examined); _requestBodyPipe.Reader.AdvanceTo(consumed, examined); } - public override bool TryRead(out ReadResult readResult) - { - ThrowIfCompleted(); - - return TryReadInternal(out readResult); - } - public override bool TryReadInternal(out ReadResult readResult) { TryStart(); @@ -72,12 +60,6 @@ public override bool TryReadInternal(out ReadResult readResult) return boolResult; } - public override ValueTask ReadAsync(CancellationToken cancellationToken = default) - { - ThrowIfCompleted(); - return ReadAsyncInternal(cancellationToken); - } - public override async ValueTask ReadAsyncInternal(CancellationToken cancellationToken = default) { TryStart(); @@ -103,12 +85,6 @@ public override async ValueTask ReadAsyncInternal(CancellationToken return _readResult; } - public override void Complete(Exception exception) - { - _completed = true; - _context.ReportApplicationError(exception); - } - public override void CancelPendingRead() { _requestBodyPipe.Reader.CancelPendingRead(); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs index d9bcd3ede766..9d04881cb130 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs @@ -31,12 +31,6 @@ public Http1ContentLengthMessageBody(bool keepAlive, long contentLength, Http1Co _unexaminedInputLength = _contentLength; } - public override ValueTask ReadAsync(CancellationToken cancellationToken = default) - { - ThrowIfCompleted(); - return ReadAsyncInternal(cancellationToken); - } - public override async ValueTask ReadAsyncInternal(CancellationToken cancellationToken = default) { VerifyIsNotReading(); @@ -125,12 +119,6 @@ void ResetReadingState() return _readResult; } - public override bool TryRead(out ReadResult readResult) - { - ThrowIfCompleted(); - return TryReadInternal(out readResult); - } - public override bool TryReadInternal(out ReadResult readResult) { VerifyIsNotReading(); @@ -216,11 +204,6 @@ private long CreateReadResultFromConnectionReadResult() return maxLength; } - public override void AdvanceTo(SequencePosition consumed) - { - AdvanceTo(consumed, consumed); - } - public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { if (!_isReading) @@ -261,23 +244,12 @@ protected override void OnReadStarting() } } - public override void Complete(Exception exception) - { - _context.ReportApplicationError(exception); - _completed = true; - } - public override void CancelPendingRead() { Interlocked.Exchange(ref _userCanceled, 1); _context.Input.CancelPendingRead(); } - protected override ValueTask OnStopAsync() - { - return CompleteAsync(exception: null); - } - [StackTraceHidden] private void VerifyIsNotReading() { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1MessageBody.cs index 34427d3f561e..7936768bc88b 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1MessageBody.cs @@ -16,29 +16,34 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http internal abstract class Http1MessageBody : MessageBody { protected readonly Http1Connection _context; - protected bool _completed; + private bool _readerCompleted; protected Http1MessageBody(Http1Connection context) : base(context) { _context = context; } - [StackTraceHidden] - protected void ThrowUnexpectedEndOfRequestContent() + public override ValueTask ReadAsync(CancellationToken cancellationToken = default) { - // OnInputOrOutputCompleted() is an idempotent method that closes the connection. Sometimes - // input completion is observed here before the Input.OnWriterCompleted() callback is fired, - // so we call OnInputOrOutputCompleted() now to prevent a race in our tests where a 400 - // response is written after observing the unexpected end of request content instead of just - // closing the connection without a response as expected. - _context.OnInputOrOutputCompleted(); + ThrowIfReaderCompleted(); + return ReadAsyncInternal(cancellationToken); + } - KestrelBadHttpRequestException.Throw(RequestRejectionReason.UnexpectedEndOfRequestContent); + public abstract ValueTask ReadAsyncInternal(CancellationToken cancellationToken = default); + + public override bool TryRead(out ReadResult readResult) + { + ThrowIfReaderCompleted(); + return TryReadInternal(out readResult); } public abstract bool TryReadInternal(out ReadResult readResult); - public abstract ValueTask ReadAsyncInternal(CancellationToken cancellationToken = default); + public override void Complete(Exception exception) + { + _readerCompleted = true; + _context.ReportApplicationError(exception); + } protected override Task OnConsumeAsync() { @@ -184,12 +189,26 @@ public static MessageBody For( return keepAlive ? MessageBody.ZeroContentLengthKeepAlive : MessageBody.ZeroContentLengthClose; } - protected void ThrowIfCompleted() + [StackTraceHidden] + private void ThrowIfReaderCompleted() { - if (_completed) + if (_readerCompleted) { throw new InvalidOperationException("Reading is not allowed after the reader was completed."); } } + + [StackTraceHidden] + protected void ThrowUnexpectedEndOfRequestContent() + { + // OnInputOrOutputCompleted() is an idempotent method that closes the connection. Sometimes + // input completion is observed here before the Input.OnWriterCompleted() callback is fired, + // so we call OnInputOrOutputCompleted() now to prevent a race in our tests where a 400 + // response is written after observing the unexpected end of request content instead of just + // closing the connection without a response as expected. + _context.OnInputOrOutputCompleted(); + + KestrelBadHttpRequestException.Throw(RequestRejectionReason.UnexpectedEndOfRequestContent); + } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs index c46ed75c8c91..6dd17a1d17bb 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1UpgradeMessageBody.cs @@ -23,35 +23,11 @@ public Http1UpgradeMessageBody(Http1Connection context) // This returns IsEmpty so we can avoid draining the body (since it's basically an endless stream) public override bool IsEmpty => true; - public override ValueTask ReadAsync(CancellationToken cancellationToken = default) - { - ThrowIfCompleted(); - return _context.Input.ReadAsync(cancellationToken); - } - - public override bool TryRead(out ReadResult result) - { - ThrowIfCompleted(); - return _context.Input.TryRead(out result); - } - - public override void AdvanceTo(SequencePosition consumed) - { - _context.Input.AdvanceTo(consumed); - } - public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { _context.Input.AdvanceTo(consumed, examined); } - public override void Complete(Exception exception) - { - // Don't call Connection.Complete. - _context.ReportApplicationError(exception); - _completed = true; - } - public override void CancelPendingRead() { _context.Input.CancelPendingRead(); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs index 2ca2af12028d..da8e0888d307 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs @@ -43,11 +43,18 @@ protected MessageBody(HttpProtocol context) protected IKestrelTrace Log => _context.ServiceContext.Log; - public abstract void AdvanceTo(SequencePosition consumed); + public abstract ValueTask ReadAsync(CancellationToken cancellationToken = default); + + public abstract bool TryRead(out ReadResult readResult); + + public void AdvanceTo(SequencePosition consumed) + { + AdvanceTo(consumed, consumed); + } public abstract void AdvanceTo(SequencePosition consumed, SequencePosition examined); - public abstract bool TryRead(out ReadResult readResult); + public abstract void CancelPendingRead(); public abstract void Complete(Exception exception); @@ -57,10 +64,6 @@ public virtual ValueTask CompleteAsync(Exception exception) return default; } - public abstract void CancelPendingRead(); - - public abstract ValueTask ReadAsync(CancellationToken cancellationToken = default); - public virtual Task ConsumeAsync() { TryStart(); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs index 0ae4d768d42c..5b3df005d26b 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs @@ -24,8 +24,6 @@ public ZeroContentLengthMessageBody(bool keepAlive) public override ValueTask StopAsync() => default; - public override void AdvanceTo(SequencePosition consumed) { } - public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { } public override bool TryRead(out ReadResult result) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs index e121a8b680c7..40d4c5191ebb 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs @@ -45,11 +45,6 @@ public override void Reset() _readResult = default; } - public override void AdvanceTo(SequencePosition consumed) - { - AdvanceTo(consumed, consumed); - } - public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { var newlyExaminedBytes = TrackConsumedAndExaminedBytes(_readResult, consumed, examined); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs index d0c513503b6d..c097d30d317f 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs @@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeWriterHelpers; @@ -299,16 +298,17 @@ private void FinishWritingHeaders(int payloadLength, bool done) } } - public void Complete() + public ValueTask CompleteAsync() { lock (_writeLock) { if (_completed) { - return; + return default; } _completed = true; + return _outputWriter.CompleteAsync(); } } @@ -324,7 +324,13 @@ public void Abort(ConnectionAbortedException error) _aborted = true; _connectionContext.Abort(error); - Complete(); + if (_completed) + { + return; + } + + _completed = true; + _outputWriter.Complete(); } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs index f3f34202e2a6..041cf2e616b5 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs @@ -20,6 +20,7 @@ private Http3MessageBody(Http3Stream context) { _context = context; } + protected override void OnReadStarting() { // Note ContentLength or MaxRequestBodySize may be null @@ -29,20 +30,11 @@ protected override void OnReadStarting() } } - protected override void OnReadStarted() - { - } - public static MessageBody For(Http3Stream context) { return new Http3MessageBody(context); } - public override void AdvanceTo(SequencePosition consumed) - { - AdvanceTo(consumed, consumed); - } - public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { var newlyExaminedBytes = TrackConsumedAndExaminedBytes(_readResult, consumed, examined); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs index bd986bba5688..e00050856b9a 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs @@ -364,7 +364,7 @@ private async ValueTask ProcessDataWrites() // Headers have already been written and there is no other content to write // TODO complete something here. flushResult = await _frameWriter.FlushAsync(outputAborter: null, cancellationToken: default); - _frameWriter.Complete(); + await _frameWriter.CompleteAsync(); } else { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index 72deb4879198..73cdbfb95d06 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -385,7 +385,7 @@ public async Task ProcessRequestAsync(IHttpApplication appli try { - _frameWriter.Complete(); + await _frameWriter.CompleteAsync(); } catch { diff --git a/src/Servers/Kestrel/Core/test/BodyControlTests.cs b/src/Servers/Kestrel/Core/test/BodyControlTests.cs index 9ecf67792b24..9f5cf40bdcc0 100644 --- a/src/Servers/Kestrel/Core/test/BodyControlTests.cs +++ b/src/Servers/Kestrel/Core/test/BodyControlTests.cs @@ -146,11 +146,6 @@ public MockMessageBody(bool upgradeable = false) RequestUpgrade = upgradeable; } - public override void AdvanceTo(SequencePosition consumed) - { - throw new NotImplementedException(); - } - public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { throw new NotImplementedException();