.NET 4.5 HttpClient PUT or POST over SSL always fa

2020-06-03 04:16发布

I am having a terrible time troubleshooting this issue. I'm also having a terrible time reproducing it consistently from one application to another.

Under certain circumstances, which I cannot seem to identify, making PUT and POST calls using the HttpClient results in the following exception.

An error occurred while sending the request.

Inner Exception:
The underlying connection was closed: An unexpected error occurred on a send.

Inner Exception:
This operation cannot be performed on a completed asynchronous result object.

Everything seems to work with HTTP, this only happens on HTTPS.

Certificates are valid, but I have tried setting the ServicePointManager.ServerCertificateValidationCallback += (s, c, ch, es) => true;

I have tried setting client.DefaultRequestHeaders.ExpectContinue = false;

I have tried, what seems like a million, other things ranging from headers, authentication, etc.

Does anyone have any idea what else I can check, try, etc?

Code snippet:

// this is my registration in my IoC container...
var handler = new HttpClientHandler
{
    UseDefaultCredentials = true,
    Credentials = CredentialCache.DefaultNetworkCredentials,
};

var client = HttpClientFactory.Create(handler);
client.BaseAddress = new Uri(Properties.Settings.Default.BaseUrl);
client.DefaultRequestHeaders.Add("X-CustomHeader", "value");

// _client is constructor injected into my class...
var response = await _client.PutAsJsonAsync("api/resource/" + id, model).ConfigureAwait(false);
response.EnsureSuccessStatusCode(); // <-- never executes...

UPDATE:

If I take off the ConfigureAwait(false) it works fine.

Note, this is a WPF app, specifically, this is a Visual Studio extension. However, I do have an ASP.NET MVC 4 application with the exact same problem, and that application does not call ConfigureAwait(false) at all...

UPDATE 2:

I updated the code snippet to include the instantiation of the HttpClient class. The only thing that is not included in the code snippet is the model type and declaration. It should be irrelevant, as it is a serializable class with all auto properties with no complex types.

UPDATE 3:

I don't know if this is relevant, but I have found a few things which look weird to me.

When executing the above code, in Fiddler, I get a 401 on the POST, followed by 2 CONNECT's which result in the following HTTP responses:

HTTP/1.1 200 Connection Established
Connection: close

UPDATE 4:

I changed my IoC registration code to be this:

var handler = new HttpClientHandler
{
    UseDefaultCredentials = true,
    Credentials = CredentialCache.DefaultCredentials,
};

var client = HttpClientFactory.Create(handler);
client.BaseAddress = new Uri(Properties.Settings.Default.BaseUrl);
client.DefaultRequestHeaders.Add("X-CustomHeader", "value");

and now it fails, but when I open Fiddler and let it decrypt traffic ... it works!

UPDATE 5:

I believe this must be a server issue, or a cert issue. Any tips on what to check from here would be greatly appreciated. Certs are valid and issued from a trusted CA.

UPDATE 6:

More debugging and troubleshooting. The exception occurs before the ServicePointManager CertificateValidationCallback is invoked.

2条回答
smile是对你的礼貌
2楼-- · 2020-06-03 04:40

I just got done troubleshooting a similar issue with HttpClient. It turns out I was receiving an SNI warning during the SSL handshake, which caused HttpClient to lock up indefinitely. Try running WireShark/tcpdump and see if you are getting a TLSv1 Unrecognized Name warning, or any other kind of handshake warning. HttpClient does not appear to handle these properly based on my tests.

查看更多
不美不萌又怎样
3楼-- · 2020-06-03 04:56

I had the same problem and I resolved it installing the last updated of the .NET framework (4.5).

查看更多
登录 后发表回答