dotnet/aspnetcore

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

開放

#17,840 建立於 2019年12月12日

 (23 則留言) (9 個反應) (1 位負責人)C# (10,653 個分叉)batch import
affected-very-fewarea-networkingenhancementfeature-kestrelhelp wantedseverity-nice-to-have

倉庫指標

星標
 (37,933 顆星)
PR 合併指標
 (PR 指標待抓取)

描述

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

貢獻者指南