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);