Open carl-di-ortus opened 1 year ago
Tagging subscribers to this area: @dotnet/ncl See info in area-owners.md if you want to be subscribed.
Author: | carl-di-ortus |
---|---|
Assignees: | - |
Labels: | `area-System.Net.Http` |
Milestone: | - |
Do you have packet capture? From the exception it seems like the server is also shutting down the connection. This may be good to enable Expect100Continue.
I'm sorry, I'm not that skilled to understand packet capturing.
Yes server is closing the connection when returning redirect.
By "enable Expect100Continue" do you mean this ServicePointManager.Expect100Continue? It looks like the default value is already true. I tried setting this true/false - no effect, still throwing same exception.
Then I tried ServicePointManager.FindServicePoint()
method to return ServicePoint
instance, even though it says it's deprecated, and setting Expect100Continue
there - no effect.
Then I tried increasing SocketsHttpHandler.Expect100ContinueTimeout
value and passing this handler to client - no effect.
Then while debugging, I noticed HttpClient.DefaultRequestHeaders.ExpectContinue
property - which by default is null. I manually set this to true:
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.ExpectContinue = true;
var response = await client.PostAsync(url, new StringContent(json, Encoding.UTF8, "application/json"));
And suddenly it all worked! I'm not really happy with this approach, I would call it a workaround at best, since documentation for ServicePointManager.Expect100Continue
says it already defaulting to true, but inside HttpClient.DefaultRequestHeaders
this header is nullable boolean defaulting to null.
Our clients (and probably a lot of other people around the world) wouldn't know when they are receiving normal response, when they are being redirected to receive response there. Documentation on HttpClient.DefaultRequestHeaders.ExpectContinue
is very scarce, not comparing to what ServicePointManager
has.
ServicePointManager
is obsolete and does nothing for HttpClient
in .NET Core. The documentation discrepancy comes with age - .NET Framework is around for decades and many articles were written before .NET Core even existed so they can be misleading.
Behavior of the 100Continue is described in HTTP RFC and there are just different ways how to set it on the request.
The problem is server closing connection in middle of the request. HttpClient sees that as IO error and aborts the processing. Perhaps something we can improve in the future to improve compatibility with .NET Framework.
Description
We have a HAProxy setup that handles various domains and subpaths. For some paths we do a redirect with HTTP 307 status code, because we need the client to repeat POST request to a different endpoint. HttpClient throws exception when trying to send request without even getting the redirect location. Same behavior observed if redirect response returns with 308 status code.
Request always passes successfully when compiled to target 4.8 framework. Request passes with small payloads on .NET7, fails on large payloads (tried a valid JSON 202759 chars long). Didn't try to find the exact threshold.
Might be related to #47706
Reproduction Steps
Expected behavior
Request should correctly redirect to final location and send POST request there.
Actual behavior
Large payloads throws exception
Regression?
Haven't tested a lot of build targets, but I suspect it's a regression since reimplementing HttpClientHandler back in .NET Core 2.1.
Known Workarounds
No response
Configuration
No response
Other information
Attaching WSL
curl
command outputs here for reference. Curl never fails with small or large payloads.The only thing that differs with large requests are these lines
But it works correctly even with it.