From 51a4a9f7f6f5c26638988e57ad569fc2f89d5c5a Mon Sep 17 00:00:00 2001 From: "Ahmet Ibrahim Aksoy (from Dev Box)" Date: Thu, 5 Oct 2023 08:53:06 +0200 Subject: [PATCH 1/3] Racing between protocol close and abort fix --- .../tests/FunctionalTests/HttpClientHandlerTest.Http3.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs index 0af7c66ac8ffc..ed8313a39d808 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs @@ -319,12 +319,15 @@ public async Task ServerClosesConnection_ThrowsHttpProtocolException() using Http3LoopbackServer server = CreateHttp3LoopbackServer(); + TaskCompletionSource taskCompletionSource = new TaskCompletionSource(TaskContinuationOptions.RunContinuationsAsynchronously); + Task serverTask = Task.Run(async () => { await using Http3LoopbackConnection connection = (Http3LoopbackConnection)await server.EstablishGenericConnectionAsync(); await using Http3LoopbackStream stream = await connection.AcceptRequestStreamAsync(); await connection.CloseAsync(GeneralProtocolError); + await taskCompletionSource.Task; }); Task clientTask = Task.Run(async () => @@ -339,6 +342,7 @@ public async Task ServerClosesConnection_ThrowsHttpProtocolException() }; await AssertProtocolErrorAsync(GeneralProtocolError, () => client.SendAsync(request)); + taskCompletionSource.SetResult(true); }); await new[] { clientTask, serverTask }.WhenAllOrAnyFailed(20_000); From 84d66f412ab8ec70d76c3db14628c78f37c58415 Mon Sep 17 00:00:00 2001 From: "Ahmet Ibrahim Aksoy (from Dev Box)" Date: Fri, 6 Oct 2023 12:32:35 +0200 Subject: [PATCH 2/3] Add catching for ConnectionAbort in two places --- .../Net/Http/SocketsHttpHandler/Http3Connection.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs index caf39a7ac7bd0..58e9594691b91 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs @@ -388,6 +388,13 @@ private async Task SendSettingsAsync() await _clientControl.WriteAsync(_pool.Settings.Http3SettingsFrame, CancellationToken.None).ConfigureAwait(false); } + catch (QuicException ex) when (ex.QuicError == QuicError.ConnectionAborted) + { + Debug.Assert(ex.ApplicationErrorCode.HasValue); + Http3ErrorCode code = (Http3ErrorCode)ex.ApplicationErrorCode.Value; + + Abort(HttpProtocolException.CreateHttp3ConnectionException(code, SR.net_http_http3_connection_close)); + } catch (Exception ex) { Abort(ex); @@ -577,6 +584,13 @@ private async Task ProcessServerStreamAsync(QuicStream stream) { // ignore the exception, we have already closed the connection } + catch (QuicException ex) when (ex.QuicError == QuicError.ConnectionAborted) + { + Debug.Assert(ex.ApplicationErrorCode.HasValue); + Http3ErrorCode code = (Http3ErrorCode)ex.ApplicationErrorCode.Value; + + Abort(HttpProtocolException.CreateHttp3ConnectionException(code, SR.net_http_http3_connection_close)); + } catch (Exception ex) { Abort(ex); From 1700206390e46a3189691e254a189357417e3d1f Mon Sep 17 00:00:00 2001 From: "Ahmet Ibrahim Aksoy (from Dev Box)" Date: Fri, 6 Oct 2023 12:33:03 +0200 Subject: [PATCH 3/3] Revert change on test --- .../tests/FunctionalTests/HttpClientHandlerTest.Http3.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs index ed8313a39d808..0af7c66ac8ffc 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs @@ -319,15 +319,12 @@ public async Task ServerClosesConnection_ThrowsHttpProtocolException() using Http3LoopbackServer server = CreateHttp3LoopbackServer(); - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(TaskContinuationOptions.RunContinuationsAsynchronously); - Task serverTask = Task.Run(async () => { await using Http3LoopbackConnection connection = (Http3LoopbackConnection)await server.EstablishGenericConnectionAsync(); await using Http3LoopbackStream stream = await connection.AcceptRequestStreamAsync(); await connection.CloseAsync(GeneralProtocolError); - await taskCompletionSource.Task; }); Task clientTask = Task.Run(async () => @@ -342,7 +339,6 @@ public async Task ServerClosesConnection_ThrowsHttpProtocolException() }; await AssertProtocolErrorAsync(GeneralProtocolError, () => client.SendAsync(request)); - taskCompletionSource.SetResult(true); }); await new[] { clientTask, serverTask }.WhenAllOrAnyFailed(20_000);