dotnet / dotnet/aspnetcore

HttpResponse implementations should throw if writes are not awaited

Open
#9,876 14 comments 1 reaction 0 assignees View on GitHub
affected-very-few area-networking breaking-change enhancement severity-nice-to-have
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 5h
Merged PRs (30d)
276

Description

Today, Kestrel (I haven't tried this yet on InProc or HttpSysServer) will not throw if you call HttpContext.Response.Body.WriteAsync() multiple times in a row without awaiting for the response. Ex:

```c#
app.Run(context =>
{
context.Response.Body.WriteAsync(buffer1);
context.Response.Body.WriteAsync(buffer2);
return Task.CompletedTask;
});
```

It's possible that the first call to WriteAsync returns a completed Task, but even if it doesn't, Kestrel will allow the app to write again immediately.

To make this work on top of a PipeWriter, we've had to use a [special pipe flushing](https://github.com/aspnet/AspNetCore/blob/0b7458cc984c0c0f9c702f9831c1815a365c07ac/src/Servers/Kestrel/Core/src/Internal/Infrastructure/TimingPipeFlusher.cs#L66) logic, and even that seems like it [might have issues](https://github.com/aspnet/AspNetCore/issues/8843).

Instead, we should throw an InvalidOperationException if the app attempts to write to the response body prior to the previous write's completion. This of course would be a breaking change, and would need to be done ASAP to make it into 3.0.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.