Fix HTTP/2 stream output flow control abort error (#23727)
* Fix stream output flow control abort error * Clean up * Clean up * Add timeouts
This commit is contained in:
parent
cc3c1d0e74
commit
3709eda270
|
|
@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl
|
|||
if (_currentConnectionLevelAwaitable != null &&
|
||||
_currentConnectionLevelAwaitable.Version == _currentConnectionLevelAwaitableVersion)
|
||||
{
|
||||
_currentConnectionLevelAwaitable.SetResult(null);
|
||||
_currentConnectionLevelAwaitable.TrySetResult(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1594,6 +1594,68 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
await WaitForAllStreamsAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OutputFlowControl_ConnectionAndRequestAborted_NoException()
|
||||
{
|
||||
// Ensure the stream window size is bigger than the connection window size
|
||||
_clientSettings.InitialWindowSize = _clientSettings.InitialWindowSize * 2;
|
||||
|
||||
var connectionAbortedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var requestAbortedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
await InitializeConnectionAsync(async context =>
|
||||
{
|
||||
// Exceed connection window size
|
||||
await context.Response.WriteAsync(new string('!', 65536));
|
||||
|
||||
await connectionAbortedTcs.Task;
|
||||
|
||||
try
|
||||
{
|
||||
context.Abort();
|
||||
requestAbortedTcs.SetResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
requestAbortedTcs.SetException(ex);
|
||||
}
|
||||
}).DefaultTimeout();
|
||||
|
||||
await StartStreamAsync(1, _browserRequestHeaders, endStream: true).DefaultTimeout();
|
||||
|
||||
await ExpectAsync(Http2FrameType.HEADERS,
|
||||
withLength: 32,
|
||||
withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS),
|
||||
withStreamId: 1).DefaultTimeout();
|
||||
|
||||
await ExpectAsync(Http2FrameType.DATA,
|
||||
withLength: 16384,
|
||||
withFlags: (byte)(Http2DataFrameFlags.NONE),
|
||||
withStreamId: 1).DefaultTimeout();
|
||||
|
||||
await ExpectAsync(Http2FrameType.DATA,
|
||||
withLength: 16384,
|
||||
withFlags: (byte)(Http2DataFrameFlags.NONE),
|
||||
withStreamId: 1).DefaultTimeout();
|
||||
|
||||
await ExpectAsync(Http2FrameType.DATA,
|
||||
withLength: 16384,
|
||||
withFlags: (byte)(Http2DataFrameFlags.NONE),
|
||||
withStreamId: 1).DefaultTimeout();
|
||||
|
||||
await ExpectAsync(Http2FrameType.DATA,
|
||||
withLength: 16383,
|
||||
withFlags: (byte)(Http2DataFrameFlags.NONE),
|
||||
withStreamId: 1).DefaultTimeout();
|
||||
|
||||
_connection.HandleReadDataRateTimeout();
|
||||
|
||||
connectionAbortedTcs.SetResult();
|
||||
|
||||
// Task completing successfully means HttpContext.Abort didn't throw
|
||||
await requestAbortedTcs.Task.DefaultTimeout();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DATA_Sent_DespiteStreamOutputFlowControl_IfEmptyAndEndsStream()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue