diff --git a/Directory.Build.props b/Directory.Build.props index d080a9e0fb8e..a295d60cf0a5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -234,6 +234,11 @@ $(MSBuildThisFileDirectory)Directory.Build.BeforeCommonTargets.targets + + + false + + diff --git a/NuGet.config b/NuGet.config index 1c2f27eb90ce..4fdd9795b401 100644 --- a/NuGet.config +++ b/NuGet.config @@ -6,8 +6,10 @@ + + @@ -28,8 +30,10 @@ + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3d651ff75efa..01f1bf8b8929 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -9,37 +9,37 @@ --> - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - bd381fa6af1f80b3b6a52739729596cd68b6f5c8 + 489d66cd0a20b7ed776a904051729e3b4d3cba13 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - bd381fa6af1f80b3b6a52739729596cd68b6f5c8 + 489d66cd0a20b7ed776a904051729e3b4d3cba13 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - bd381fa6af1f80b3b6a52739729596cd68b6f5c8 + 489d66cd0a20b7ed776a904051729e3b4d3cba13 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - bd381fa6af1f80b3b6a52739729596cd68b6f5c8 + 489d66cd0a20b7ed776a904051729e3b4d3cba13 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - bd381fa6af1f80b3b6a52739729596cd68b6f5c8 + 489d66cd0a20b7ed776a904051729e3b4d3cba13 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - bd381fa6af1f80b3b6a52739729596cd68b6f5c8 + 489d66cd0a20b7ed776a904051729e3b4d3cba13 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - bd381fa6af1f80b3b6a52739729596cd68b6f5c8 + 489d66cd0a20b7ed776a904051729e3b4d3cba13 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - bd381fa6af1f80b3b6a52739729596cd68b6f5c8 + 489d66cd0a20b7ed776a904051729e3b4d3cba13 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -121,9 +121,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -185,9 +185,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be https://github.com/dotnet/source-build-externals @@ -275,17 +275,17 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -316,22 +316,22 @@ Win-x64 is used here because we have picked an arbitrary runtime identifier to flow the version of the latest NETCore.App runtime. All Runtime.$rid packages should have the same version. --> - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be https://github.com/dotnet/xdt @@ -368,9 +368,9 @@ - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 362ab6669d55a75d51166f01b596c967c734ef4c + a2266c728f63a494ccb6786d794da2df135030be https://github.com/dotnet/winforms diff --git a/eng/Versions.props b/eng/Versions.props index 8e165b458f42..ac279dda77c7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -67,12 +67,12 @@ 8.0.2 - 8.0.21 - 8.0.21 - 8.0.21 - 8.0.21 - 8.0.21 - 8.0.21-servicing.25475.13 + 8.0.22 + 8.0.22 + 8.0.22 + 8.0.22 + 8.0.22 + 8.0.22-servicing.25527.7 8.0.0 8.0.1 8.0.0 @@ -93,7 +93,7 @@ 8.0.0 8.0.0 8.0.0 - 8.0.21-servicing.25475.13 + 8.0.22-servicing.25527.7 8.0.1 8.0.1 8.0.1 @@ -109,7 +109,7 @@ 8.0.0 8.0.2 8.0.0 - 8.0.21-servicing.25475.13 + 8.0.22-servicing.25527.7 8.0.1 8.0.1 8.0.2 @@ -129,9 +129,9 @@ 8.0.0 8.0.0 8.0.0 - 8.0.21-servicing.25475.13 + 8.0.22-servicing.25527.7 - 8.0.21-servicing.25475.13 + 8.0.22-servicing.25527.7 8.0.0 8.0.1 @@ -143,14 +143,14 @@ 9.0.0-preview.9.24518.1 9.0.0-preview.9.24518.1 - 8.0.21 - 8.0.21 - 8.0.21 - 8.0.21 - 8.0.21 - 8.0.21 - 8.0.21 - 8.0.21 + 8.0.22 + 8.0.22 + 8.0.22 + 8.0.22 + 8.0.22 + 8.0.22 + 8.0.22 + 8.0.22 4.8.0-7.24574.2 4.8.0-7.24574.2 diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStream.cs index 5bb9452a5da1..1b071ce7c40d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStream.cs @@ -65,6 +65,12 @@ public Http3ControlStream(Http3StreamContext context, long? headerType) context.ClientPeerSettings, this); _frameWriter.Reset(context.Transport.Output, context.ConnectionId); + + _streamClosedFeature.OnClosed(static state => + { + var stream = (Http3ControlStream)state!; + stream.OnStreamClosed(); + }, this); } private void OnStreamClosed() @@ -135,12 +141,6 @@ private bool TryClose() internal async ValueTask ProcessOutboundSendsAsync(long id) { - _streamClosedFeature.OnClosed(static state => - { - var stream = (Http3ControlStream)state!; - stream.OnStreamClosed(); - }, this); - await _frameWriter.WriteStreamIdAsync(id); await _frameWriter.WriteSettingsAsync(_serverPeerSettings.GetNonProtocolDefaults()); } @@ -311,18 +311,13 @@ private async Task HandleControlStream() } } - private async ValueTask HandleEncodingDecodingTask() + private Task HandleEncodingDecodingTask() { // Noop encoding and decoding task. Settings make it so we don't need to read content of encoder and decoder. // An endpoint MUST allow its peer to create an encoder stream and a // decoder stream even if the connection's settings prevent their use. - while (_isClosed == 0) - { - var result = await Input.ReadAsync(); - var readableBuffer = result.Buffer; - Input.AdvanceTo(readableBuffer.End); - } + return Input.CopyToAsync(Stream.Null); } private ValueTask ProcessHttp3ControlStream(Http3RawFrame incomingFrame, bool isContinuedFrame, in ReadOnlySequence payload, out SequencePosition consumed) @@ -372,11 +367,6 @@ private ValueTask ProcessSettingsFrameAsync(bool isContinuedFrame, ReadOnlySeque } _haveReceivedSettingsFrame = true; - _streamClosedFeature.OnClosed(static state => - { - var stream = (Http3ControlStream)state!; - stream.OnStreamClosed(); - }, this); } while (true) diff --git a/src/Servers/Kestrel/shared/test/Http3/Http3InMemory.cs b/src/Servers/Kestrel/shared/test/Http3/Http3InMemory.cs index 544b338ee38f..7a3ac2e05efe 100644 --- a/src/Servers/Kestrel/shared/test/Http3/Http3InMemory.cs +++ b/src/Servers/Kestrel/shared/test/Http3/Http3InMemory.cs @@ -294,12 +294,22 @@ public void OnInboundControlStreamSetting(Http3SettingType type, long value) public bool OnInboundDecoderStream(Server.Kestrel.Core.Internal.Http3.Http3ControlStream stream) { - return _inner.OnInboundDecoderStream(stream); + var res = _inner.OnInboundDecoderStream(stream); + if (_http3TestBase._runningStreams.TryGetValue(stream.StreamId, out var testStream)) + { + testStream.OnDecoderStreamCreatedTcs.TrySetResult(); + } + return res; } public bool OnInboundEncoderStream(Server.Kestrel.Core.Internal.Http3.Http3ControlStream stream) { - return _inner.OnInboundEncoderStream(stream); + var res = _inner.OnInboundEncoderStream(stream); + if (_http3TestBase._runningStreams.TryGetValue(stream.StreamId, out var testStream)) + { + testStream.OnEncoderStreamCreatedTcs.TrySetResult(); + } + return res; } public void OnStreamCompleted(IHttp3Stream stream) @@ -473,6 +483,8 @@ internal class Http3StreamBase internal TaskCompletionSource OnStreamCreatedTcs { get; } = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); internal TaskCompletionSource OnStreamCompletedTcs { get; } = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); internal TaskCompletionSource OnHeaderReceivedTcs { get; } = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + internal TaskCompletionSource OnDecoderStreamCreatedTcs { get; } = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + internal TaskCompletionSource OnEncoderStreamCreatedTcs { get; } = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); internal TestStreamContext StreamContext { get; } internal DuplexPipe.DuplexPipePair Pair { get; } @@ -489,6 +501,8 @@ public long Error public Task OnStreamCreatedTask => OnStreamCreatedTcs.Task; public Task OnStreamCompletedTask => OnStreamCompletedTcs.Task; public Task OnHeaderReceivedTask => OnHeaderReceivedTcs.Task; + public Task OnDecoderStreamCreatedTask => OnDecoderStreamCreatedTcs.Task; + public Task OnEncoderStreamCreatedTask => OnEncoderStreamCreatedTcs.Task; public ConnectionAbortedException AbortReadException => StreamContext.AbortReadException; public ConnectionAbortedException AbortWriteException => StreamContext.AbortWriteException; diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3ConnectionTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3ConnectionTests.cs index 054577365d7d..858e964b6ce1 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3ConnectionTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3ConnectionTests.cs @@ -617,6 +617,57 @@ await Http3Api.InitializeConnectionAsync(context => Assert.NotSame(trailersFirst, trailersLast); } + [Theory] + [InlineData(2)] // encoder + [InlineData(3)] // decoder + public async Task IgnoredControlStreams_CloseConnectionOnEndStream(int streamType) + { + await Http3Api.InitializeConnectionAsync(_noopApplication); + + var stream = await Http3Api.CreateControlStream(streamType); + + // PipeWriter will be completed when end of stream is received. Should exit read loop and close stream + // which will cause the connection to close with an error. + await stream.SendFrameAsync(Http3FrameType.Data, Memory.Empty, endStream: true); + + await stream.OnStreamCompletedTask.DefaultTimeout(); + + Http3Api.TriggerTick(); + Http3Api.TriggerTick(TimeSpan.FromSeconds(1)); + + await Http3Api.WaitForConnectionErrorAsync( + ignoreNonGoAwayFrames: true, + expectedLastStreamId: 0, + expectedErrorCode: Http3ErrorCode.ClosedCriticalStream, + matchExpectedErrorMessage: AssertExpectedErrorMessages, + expectedErrorMessage: CoreStrings.Http3ErrorControlStreamClosed); + } + + [Theory] + [InlineData(2)] // encoder + [InlineData(3)] // decoder + public async Task IgnoredControlStreams_CloseConnectionOnStreamClose(int streamType) + { + await Http3Api.InitializeConnectionAsync(_noopApplication); + + var stream = await Http3Api.CreateControlStream(streamType); + + await (streamType == 2 ? stream.OnEncoderStreamCreatedTask : stream.OnDecoderStreamCreatedTask).DefaultTimeout(); + + // Simulate quic layer closing the stream + stream.StreamContext.Close(); + + Http3Api.TriggerTick(); + Http3Api.TriggerTick(TimeSpan.FromSeconds(1)); + + await Http3Api.WaitForConnectionErrorAsync( + ignoreNonGoAwayFrames: true, + expectedLastStreamId: 0, + expectedErrorCode: Http3ErrorCode.ClosedCriticalStream, + matchExpectedErrorMessage: AssertExpectedErrorMessages, + expectedErrorMessage: CoreStrings.Http3ErrorControlStreamClosed); + } + private async Task MakeRequestAsync(int index, KeyValuePair[] headers, bool sendData, bool waitForServerDispose) { var requestStream = await Http3Api.CreateRequestStream(headers, endStream: !sendData);