From 1bdd9be75248aac5beb28e50e2f5a9ccb44c90b3 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 25 Jun 2019 23:40:16 -0700 Subject: [PATCH] Don't complete the connection pipe in Http2FrameWriter - This leads to trunated data in some cases. Instead just yield the middleware so we can be sure no more user code is running (Http1OutputProducer does this as well). There are still cases where a misbeaving application that doesn't properly await writes gets cut off but that will be fixed in the SteamPipeWriter itself. - Updated tests --- .../Core/src/Internal/Http2/Http2FrameWriter.cs | 1 - .../Http2/Http2TestBase.cs | 17 ++++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs index 630927bb3ff6..593408337142 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs @@ -89,7 +89,6 @@ public void Complete() _completed = true; _connectionOutputFlowControl.Abort(); - _outputWriter.Complete(); } } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs index 543a9dc2896b..d9fd7fe6f52f 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs @@ -467,7 +467,22 @@ protected async Task InitializeConnectionAsync(RequestDelegate application, int CreateConnection(); } - _connectionTask = _connection.ProcessRequestsAsync(new DummyApplication(application)); + var connectionTask = _connection.ProcessRequestsAsync(new DummyApplication(application)); + + async Task CompletePipeOnTaskCompletion() + { + try + { + await connectionTask; + } + finally + { + _pair.Transport.Input.Complete(); + _pair.Transport.Output.Complete(); + } + } + + _connectionTask = CompletePipeOnTaskCompletion(); await SendPreambleAsync().ConfigureAwait(false); await SendSettingsAsync();