New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HttpClient throws an exception or deadlocks when server closes the connection #71549
Comments
Tagging subscribers to this area: @dotnet/ncl Issue DetailsDescriptionHi there, Just noticed a surprising behaviour in HttpClient when a server rejects a large request by closing the connection early. This happens for example with an ASP.NET Core server when the request body is greater than 30MB: it seems the server side sends a 400 response early and immediately closes the connection before the whole request body is transmitted. Reproduction StepsClone https://github.com/MageFroh/HttpClientTimeout Or, in words: Expected behaviorThe Web app console shows that 400 was returned to a client. The console app shows:
Actual behaviorThe Web app side always shows the expected behaviour. The console app behaviour is not deterministic. When the WebApp is started on Windows natively, it reports an exception from
When the WebApp is started in Docker on Windows:
Regression?Not entirely sure - I've noticed some closed issues in this area but they might not be exactly the same. Known WorkaroundsSet ConfigurationNo response Other informationI don't mind much seeing an HttpRequestException instead of a 400 response on the client side: we loose some good info in the response body but that's not a big deal. The reproducer repo I've sent seems to hang only for the first request. But I've seen other Web app that cause the hangs much more often - maybe this is timing related? Our system uses HTTPS, so the reproducer uses HTTPS.
|
I think this will depend on underlying TCP. When server their side TCP will stain in half-open state for a while. Eventually it may be closed and peer will send RST and pending write will fail. To get more predictable results, I would suggest to set 100Continue header. |
Thanks for the tip: I've added the following and properly observe the server response in all cases:
Is it an actual fix, or just a workaround until investigations in the lock are complete? |
There is no easy answer. The |
triage: we should look if we can surface some better error - like the error response even if we failed to write the body. |
Description
Hi there,
Just noticed a surprising behaviour in HttpClient when a server rejects a large request by closing the connection early.
This happens for example with an ASP.NET Core server when the request body is greater than 30MB: it seems the server side sends a 400 response early and immediately closes the connection before the whole request body is transmitted.
Reproduction Steps
Clone https://github.com/MageFroh/HttpClientTimeout
Start the WebApplication
Execute the console app
Or, in words:
Use HttpClient to POST a request body of more than 30MB to an ASP.NET Core Web application.
Expected behavior
The Web app console shows that 400 was returned to a client.
The console app shows:
Actual behavior
The Web app side always shows the expected behaviour.
The console app behaviour is not deterministic.
When the WebApp is started on Windows natively, it reports an exception from
PostAsync
all the time:When the WebApp is started in Docker on Windows:
Regression?
Not entirely sure - I've noticed some closed issues in this area but they might not be exactly the same.
Known Workarounds
Set
client.Timeout
to aTimeSpan
smaller than 100 seconds.This might not be acceptable for some apps that need to deal with poor network conditions though.
Configuration
No response
Other information
I don't mind much seeing an HttpRequestException instead of a 400 response on the client side: we loose some good info in the response body but that's not a big deal.
But sometimes the client blocks for 100 seconds by default! This is much more annoying...
The reproducer repo I've sent seems to hang only for the first request. But I've seen other Web app that cause the hangs much more often - maybe this is timing related?
Our system uses HTTPS, so the reproducer uses HTTPS.
After further checks, it looks like there is no difference of behaviour between HTTP and HTTPS.
Edit: Forgot to mention that Swagger UI in a browser such as Firefox reports the 400 and its body properly.
The text was updated successfully, but these errors were encountered: