dotnet/aspnetcore

Provide better experience when the BodyReader is left in a reading state

Open

#17,840 opened on Dec 12, 2019

View on GitHub
 (23 comments) (9 reactions) (1 assignee)C# (10,653 forks)batch import
affected-very-fewarea-networkingenhancementfeature-kestrelhelp wantedseverity-nice-to-have

Repository metrics

Stars
 (37,933 stars)
PR merge metrics
 (Avg merge 16d 9h) (258 merged PRs in 30d)

Description

When middleware calls HttpContext.Request.BodyReader.ReadAsync() and exits without calling HttpContext.Request.BodyReader.AdvanceTo(), Kestrel will fail to read the following request while logging the following exception as a warning (at least for Content-Length HTTP/1.1 requests, not sure about others):

System.InvalidOperationException
  HResult=0x80131509
  Message=Reading is already in progress.
  Source=Microsoft.AspNetCore.Server.Kestrel.Core
  StackTrace:
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1ContentLengthMessageBody.TryReadInternal(ReadResult& readResult) in /_/src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs:line 126

This is pretty common type of error when something throws in between calls to ReadAsync() and AdvanceTo() and AdvanceTo() isn't in a finally block.

It would be better if Kestrel logged a warning that explicitly tells the developer that there's a missing call to BodyReader.AdvanceTo(). Better yet would be to recover from this situation by draining the rest of the request despite the BodyReader being left in a bad state so that the connection can still be used for future requests.

We should also ensure Kestrel handles the BodyWriter being left in a bad state gracefully.

See #17723 and #14727 (In that case it was Kestrel itself throwing without properly advancing the connection pipe though).

  • ASP.NET Core version 3.1

Contributor guide