Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET 4.5 HttpClient PUT or POST over SSL always fails

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.

like image 852
Adam Avatar asked Jun 14 '13 20:06

Adam


1 Answers

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.

like image 195
user3331229 Avatar answered Oct 16 '22 09:10

user3331229