@@ -844,6 +844,7 @@ protected override bool BeginRead(out ValueTask<ReadResult> awaitable)
844844 protected override bool TryParseRequest ( ReadResult result , out bool endConnection )
845845 {
846846 var reader = new SequenceReader < byte > ( result . Buffer ) ;
847+ var isConsumed = false ;
847848
848849 // Use non-throwing parser path for performance.
849850 // Note: The parser itself doesn't throw, but handler callbacks (OnStartLine, OnHeader)
@@ -853,14 +854,28 @@ protected override bool TryParseRequest(ReadResult result, out bool endConnectio
853854 try
854855 {
855856 parseResult = TryParseRequestNoThrow ( ref reader ) ;
857+
858+ // Handle parse errors without exceptions
859+ if ( parseResult . HasError )
860+ {
861+ // Create exception and call OnBadRequest BEFORE finally runs AdvanceTo,
862+ // as that may invalidate the buffer
863+ var ex = CreateBadRequestException ( parseResult , result . Buffer ) ;
864+ OnBadRequest ( result . Buffer , ex ) ;
865+
866+ SetBadRequestState ( ex ) ;
867+ endConnection = true ;
868+ return true ;
869+ }
870+
871+ isConsumed = parseResult . IsComplete ;
856872 }
857873#pragma warning disable CS0618 // Type or member is obsolete
858874 catch ( BadHttpRequestException ex )
859875 {
876+ // OnBadRequest must be called before finally runs AdvanceTo
860877 OnBadRequest ( result . Buffer , ex ) ;
861878
862- Input . AdvanceTo ( reader . Position , result . Buffer . End ) ;
863-
864879 SetBadRequestState ( ex ) ;
865880 endConnection = true ;
866881 return true ;
@@ -870,30 +885,13 @@ protected override bool TryParseRequest(ReadResult result, out bool endConnectio
870885 {
871886 // Record OtherError for unexpected exceptions that escape the parser
872887 KestrelMetrics . AddConnectionEndReason ( MetricsContext , ConnectionEndReason . OtherError ) ;
873-
874- // Must advance buffer before re-throwing (matches original finally block behavior)
875- Input . AdvanceTo ( reader . Position , result . Buffer . End ) ;
876888 throw ;
877889 }
878-
879- var isConsumed = parseResult . IsComplete ;
880-
881- // Handle parse errors without exceptions
882- if ( parseResult . HasError )
890+ finally
883891 {
884- // Create exception and call OnBadRequest BEFORE AdvanceTo, as that may invalidate the buffer
885- var ex = CreateBadRequestException ( parseResult , result . Buffer ) ;
886- OnBadRequest ( result . Buffer , ex ) ;
887-
888- Input . AdvanceTo ( reader . Position , result . Buffer . End ) ;
889-
890- SetBadRequestState ( ex ) ;
891- endConnection = true ;
892- return true ;
892+ Input . AdvanceTo ( reader . Position , isConsumed ? reader . Position : result . Buffer . End ) ;
893893 }
894894
895- Input . AdvanceTo ( reader . Position , isConsumed ? reader . Position : result . Buffer . End ) ;
896-
897895 if ( result . IsCompleted )
898896 {
899897 switch ( _requestProcessingStatus )
0 commit comments