Microsoft.AspNetCore.TestHost.TestServer - Client hangs when writing large data synchronously
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Describe the bug
The client produced by `TestServer.CreateClient()` hangs while writing requests, if the written is sufficiently larger than the buffersize to the underwlying writer, and it is written synchronously.
Following minimal example with a custom content class:
```
public class CustomContent : HttpContent
{
private readonly string _content;
public MessageContent(string content)
{
_content = content;
}
protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
var streamWriter = new StreamWriter(stream);
streamWriter.Write(_content); // never return from here
await streamWriter.FlushAsync();
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
}
```
And the following testcode using the default WebApi-template, but the subject being tested doesn't matter here:
```
var server = new Microsoft.AspNetCore.TestHost.TestServer(
new WebHostBuilder()
.UseTestServer()
.UseStartup(typeof(WeatherForecastController).Assembly.FullName)
);
await server.Host.StartAsync();
var client = server.CreateClient();
var content = string.Join("", Enumerable.Repeat("a", 100000));
var res = await client.PostAsync("http://localhost/AnythingGoesWontBeHit", new CustomContent(content));
```
This will never complete. This is an issue specifically because this is how [Newtonsoft.Json.JsonTextWriter](https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs#L161) writes to a TextWriter, causing a custom HttpContent using newtonsoft to lock up the test suite if too large test data is used.
The issue goes away if the buffer size for the StreamWriter is increased. How much is uknown. It does not need to be larger than the message, but too small will cause it to lock up.
### Expected Behavior
The request data should be written even if it is significantly larger than the StreamWriter's buffer.
### Steps To Reproduce
1. Create a TestHost for a minimal server.
2. Run the code above.
### Exceptions (if any)
_No response_
### .NET Version
6.0.100
### Anything else?
Tested with the current `dotnet new webapi`-template and Microsoft.AspNetCore.TestHost 6.0.2.
Seems to apply to 3.1.x versions as well.
Contributor guide
Research direction
Start with the supplied minimal TestServer/CreateClient reproduction and the custom HttpContent implementation, then trace how TestServer handles synchronously written request bodies larger than the underlying writer buffer. Verify the behavior with the 100,000-character POST and confirm that the request completes without increasing the StreamWriter buffer.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100