Skip to content

Commit d13b3ee

Browse files
authored
[release/9.0] (http2): Lower WINDOWS_UPDATE received on (half)closed stream to stream abortion (#63934)
* window update fix backport * nit
1 parent 401a128 commit d13b3ee

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,8 +1156,12 @@ private Task ProcessWindowUpdateFrameAsync()
11561156
{
11571157
if (stream.RstStreamReceived)
11581158
{
1159-
// Hard abort, do not allow any more frames on this stream.
1160-
throw CreateReceivedFrameStreamAbortedException(stream);
1159+
// WINDOW_UPDATE received after we have already processed an inbound RST_STREAM for this stream.
1160+
// RFC 7540 (Sections 5.1, 6.9) / RFC 9113 do not explicitly define semantics for WINDOW_UPDATE on a
1161+
// stream in the "closed" state due to a reset by client. We surface it as a stream error (STREAM_CLOSED)
1162+
// rather than aborting the entire connection to keep behavior deterministic and consistent with other servers.
1163+
// https://github.com/dotnet/aspnetcore/issues/63726
1164+
throw new Http2StreamErrorException(_incomingFrame.StreamId, CoreStrings.Http2StreamAborted, Http2ErrorCode.STREAM_CLOSED);
11611165
}
11621166

11631167
if (!stream.TryUpdateOutputWindow(_incomingFrame.WindowUpdateSizeIncrement))

src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3584,7 +3584,6 @@ public async Task RST_STREAM_IncompleteRequest_AdditionalResetFrame_IgnoreAdditi
35843584
AssertConnectionNoError();
35853585
}
35863586

3587-
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/53744")]
35883587
[Fact]
35893588
public async Task RST_STREAM_IncompleteRequest_AdditionalWindowUpdateFrame_ConnectionAborted()
35903589
{
@@ -3602,10 +3601,13 @@ public async Task RST_STREAM_IncompleteRequest_AdditionalWindowUpdateFrame_Conne
36023601
await SendDataAsync(1, new byte[1], endStream: false);
36033602
await SendRstStreamAsync(1);
36043603
await SendWindowUpdateAsync(1, 1024);
3605-
tcs.TrySetResult();
36063604

3607-
await WaitForConnectionErrorAsync<Http2ConnectionErrorException>(ignoreNonGoAwayFrames: false, expectedLastStreamId: 1,
3608-
Http2ErrorCode.STREAM_CLOSED, CoreStrings.FormatHttp2ErrorStreamAborted(Http2FrameType.WINDOW_UPDATE, 1));
3605+
await WaitForStreamErrorAsync(expectedStreamId: 1, Http2ErrorCode.STREAM_CLOSED, CoreStrings.Http2StreamAborted);
3606+
3607+
tcs.TrySetResult(); // Don't let the response start until after the abort
3608+
3609+
await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false);
3610+
AssertConnectionNoError();
36093611
}
36103612

36113613
[Fact]

0 commit comments

Comments
 (0)