-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
When HttpLoggingMiddleware is enabled and HttpContext.Request.Body is consumed by copying to another stream (calling CopyToAsync) instead of reading, an empty RequestBody is logged after an endpoint is executed.
Expected Behavior
Not empty request body is logged when calling CopyToAsync, e.g. when sending json body
{
"Response": "Test Response"
}it should be logged as is.
Steps To Reproduce
- Simple Program.cs of ASP.NET Core project that copies request into memory stream and writes it back to response:
using System.Text;
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(options => { options.LoggingFields = HttpLoggingFields.RequestBody; });
var app = builder.Build();
app.MapGet("/", async context =>
{
// context.Request.EnableBuffering(); // Enabling buffering "fixes" the issue
using var tempStream = new MemoryStream();
await context.Request.Body.CopyToAsync(tempStream);
var responseContent = Encoding.Default.GetString(tempStream.ToArray());
await context.Response.WriteAsync(responseContent);
});
app.UseHttpLogging();
await app.RunAsync();- Send a request to
/endpoint with some json body, e.g.{ "Response": "Test Response" } - Observe logs.
Logs:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET https://localhost:7255/ application/json 37
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
Request:
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'HTTP: GET /'
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'HTTP: GET /'
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[3]
RequestBody:
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET https://localhost:7255/ application/json 37 - 200 - - 38.6330ms
Exceptions (if any)
Enabling buffering by uncommenting context.Request.EnableBuffering(); line.
Logs in this case:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET https://localhost:7255/ application/json 37
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
Request:
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'HTTP: GET /'
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[3]
RequestBody: {
"Response": "Test Response"
}
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'HTTP: GET /'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET https://localhost:7255/ application/json 37 - 200 - - 25.6788ms
Probably it happens because FileBufferingReadStream calls ReadAsync methods on the inner stream (in this case inner is RequestBufferingStream) in its CopyToAsync implementation. And RequestBufferingStream, when not wrapped, does not write anything in its buffer when CopyToAsync is called.
.NET Version
7.0.203
Anything else?
ASP.NET Core: 7.0.5
IDE: Visual Studio 2022, Rider
Also reproducible for .NET 6