66using System . Threading ;
77using System . Threading . Tasks ;
88using Microsoft . AspNetCore . Connections ;
9+ using Microsoft . AspNetCore . Http ;
910using Microsoft . AspNetCore . Server . Kestrel . Core . Features ;
1011using Microsoft . AspNetCore . Server . Kestrel . Core . Internal . Http2 ;
1112using Microsoft . AspNetCore . Server . Kestrel . Core . Internal . Infrastructure ;
@@ -332,6 +333,29 @@ await WaitForConnectionErrorAsyncDoNotCloseTransport<Http2ConnectionErrorExcepti
332333 _pair . Application . Output . Complete ( ) ;
333334 }
334335
336+ private class EchoAppWithNotification
337+ {
338+ private readonly TaskCompletionSource _writeStartedTcs = new TaskCompletionSource ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
339+
340+ public Task WriteStartedTask => _writeStartedTcs . Task ;
341+
342+ public async Task RunApp ( HttpContext context )
343+ {
344+ await context . Response . Body . FlushAsync ( ) ;
345+
346+ var buffer = new byte [ Http2PeerSettings . MinAllowedMaxFrameSize ] ;
347+ int received ;
348+
349+ while ( ( received = await context . Request . Body . ReadAsync ( buffer , 0 , buffer . Length ) ) > 0 )
350+ {
351+ var writeTask = context . Response . Body . WriteAsync ( buffer , 0 , received ) ;
352+ _writeStartedTcs . TrySetResult ( ) ;
353+
354+ await writeTask ;
355+ }
356+ }
357+ }
358+
335359 [ Fact ]
336360 [ QuarantinedTest ( "https://github.com/dotnet/aspnetcore/issues/21520" ) ]
337361 public async Task DATA_Sent_TooSlowlyDueToSocketBackPressureOnSmallWrite_AbortsConnectionAfterGracePeriod ( )
@@ -347,7 +371,8 @@ public async Task DATA_Sent_TooSlowlyDueToSocketBackPressureOnSmallWrite_AbortsC
347371
348372 _timeoutControl . Initialize ( mockSystemClock . UtcNow . Ticks ) ;
349373
350- await InitializeConnectionAsync ( _echoApplication ) ;
374+ var app = new EchoAppWithNotification ( ) ;
375+ await InitializeConnectionAsync ( app . RunApp ) ;
351376
352377 await StartStreamAsync ( 1 , _browserRequestHeaders , endStream : false ) ;
353378 await SendDataAsync ( 1 , _helloWorldBytes , endStream : true ) ;
@@ -357,6 +382,8 @@ await ExpectAsync(Http2FrameType.HEADERS,
357382 withFlags : ( byte ) Http2HeadersFrameFlags . END_HEADERS ,
358383 withStreamId : 1 ) ;
359384
385+ await app . WriteStartedTask . DefaultTimeout ( ) ;
386+
360387 // Complete timing of the request body so we don't induce any unexpected request body rate timeouts.
361388 _timeoutControl . Tick ( mockSystemClock . UtcNow ) ;
362389
@@ -400,7 +427,8 @@ public async Task DATA_Sent_TooSlowlyDueToSocketBackPressureOnLargeWrite_AbortsC
400427
401428 _timeoutControl . Initialize ( mockSystemClock . UtcNow . Ticks ) ;
402429
403- await InitializeConnectionAsync ( _echoApplication ) ;
430+ var app = new EchoAppWithNotification ( ) ;
431+ await InitializeConnectionAsync ( app . RunApp ) ;
404432
405433 await StartStreamAsync ( 1 , _browserRequestHeaders , endStream : false ) ;
406434 await SendDataAsync ( 1 , _maxData , endStream : true ) ;
@@ -410,6 +438,8 @@ await ExpectAsync(Http2FrameType.HEADERS,
410438 withFlags : ( byte ) Http2HeadersFrameFlags . END_HEADERS ,
411439 withStreamId : 1 ) ;
412440
441+ await app . WriteStartedTask . DefaultTimeout ( ) ;
442+
413443 // Complete timing of the request body so we don't induce any unexpected request body rate timeouts.
414444 _timeoutControl . Tick ( mockSystemClock . UtcNow ) ;
415445
0 commit comments