@@ -364,7 +364,7 @@ public async Task ProcessRequestAsync<TContext>(IHttpApplication<TContext> appli
364
364
Log . Http3FrameReceived ( ConnectionId , _streamIdFeature . StreamId , _incomingFrame ) ;
365
365
366
366
consumed = examined = framePayload . End ;
367
- await ProcessHttp3Stream ( application , framePayload ) ;
367
+ await ProcessHttp3Stream ( application , framePayload , result . IsCompleted && readableBuffer . IsEmpty ) ;
368
368
}
369
369
}
370
370
@@ -448,14 +448,14 @@ private ValueTask OnEndStreamReceived()
448
448
return RequestBodyPipe . Writer . CompleteAsync ( ) ;
449
449
}
450
450
451
- private Task ProcessHttp3Stream < TContext > ( IHttpApplication < TContext > application , in ReadOnlySequence < byte > payload ) where TContext : notnull
451
+ private Task ProcessHttp3Stream < TContext > ( IHttpApplication < TContext > application , in ReadOnlySequence < byte > payload , bool isCompleted ) where TContext : notnull
452
452
{
453
453
switch ( _incomingFrame . Type )
454
454
{
455
455
case Http3FrameType . Data :
456
456
return ProcessDataFrameAsync ( payload ) ;
457
457
case Http3FrameType . Headers :
458
- return ProcessHeadersFrameAsync ( application , payload ) ;
458
+ return ProcessHeadersFrameAsync ( application , payload , isCompleted ) ;
459
459
case Http3FrameType . Settings :
460
460
case Http3FrameType . CancelPush :
461
461
case Http3FrameType . GoAway :
@@ -478,7 +478,7 @@ private Task ProcessUnknownFrameAsync()
478
478
return Task . CompletedTask ;
479
479
}
480
480
481
- private Task ProcessHeadersFrameAsync < TContext > ( IHttpApplication < TContext > application , ReadOnlySequence < byte > payload ) where TContext : notnull
481
+ private async Task ProcessHeadersFrameAsync < TContext > ( IHttpApplication < TContext > application , ReadOnlySequence < byte > payload , bool isCompleted ) where TContext : notnull
482
482
{
483
483
// HEADERS frame after trailing headers is invalid.
484
484
// https://quicwg.org/base-drafts/draft-ietf-quic-http.html#section-4.1
@@ -506,19 +506,24 @@ private Task ProcessHeadersFrameAsync<TContext>(IHttpApplication<TContext> appli
506
506
case RequestHeaderParsingState . Trailers :
507
507
// trailers
508
508
// TODO figure out if there is anything else to do here.
509
- return Task . CompletedTask ;
509
+ return ;
510
510
default :
511
511
Debug . Fail ( "Unexpected header parsing state." ) ;
512
512
break ;
513
513
}
514
514
515
515
InputRemaining = HttpRequestHeaders . ContentLength ;
516
516
517
+ // If the stream is complete after receiving the headers then run OnEndStreamReceived.
518
+ // If there is a bad content length then this will throw before the request delegate is called.
519
+ if ( isCompleted )
520
+ {
521
+ await OnEndStreamReceived ( ) ;
522
+ }
523
+
517
524
_appCompleted = new TaskCompletionSource ( ) ;
518
525
519
526
ThreadPool . UnsafeQueueUserWorkItem ( this , preferLocal : false ) ;
520
-
521
- return Task . CompletedTask ;
522
527
}
523
528
524
529
private Task ProcessDataFrameAsync ( in ReadOnlySequence < byte > payload )
0 commit comments