diff --git a/src/Kestrel.Transport.Sockets/Internal/SocketConnection.cs b/src/Kestrel.Transport.Sockets/Internal/SocketConnection.cs index cf128c05f3..2ab964e894 100644 --- a/src/Kestrel.Transport.Sockets/Internal/SocketConnection.cs +++ b/src/Kestrel.Transport.Sockets/Internal/SocketConnection.cs @@ -57,13 +57,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal public async Task StartAsync(IConnectionHandler connectionHandler) { + Exception sendError = null; try { connectionHandler.OnConnection(this); // Spawn send and receive logic Task receiveTask = DoReceive(); - Task sendTask = DoSend(); + Task sendTask = DoSend(); // If the sending task completes then close the receive // We don't need to do this in the other direction because the kestrel @@ -76,7 +77,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal // Now wait for both to complete await receiveTask; - await sendTask; + sendError = await sendTask; // Dispose the socket(should noop if already called) _socket.Dispose(); @@ -85,6 +86,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal { _trace.LogError(0, ex, $"Unexpected exception in {nameof(SocketConnection)}.{nameof(StartAsync)}."); } + finally + { + // Complete the output after disposing the socket + Output.Complete(sendError); + } } private async Task DoReceive() @@ -181,7 +187,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal } } - private async Task DoSend() + private async Task DoSend() { Exception error = null; @@ -233,8 +239,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal } finally { - Output.Complete(error); - // Make sure to close the connection only after the _aborted flag is set. // Without this, the RequestsCanBeAbortedMidRead test will sometimes fail when // a BadHttpRequestException is thrown instead of a TaskCanceledException. @@ -242,6 +246,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal _trace.ConnectionWriteFin(ConnectionId); _socket.Shutdown(SocketShutdown.Both); } + + return error; } } }