Подтвердить что ты не робот

.NET 4.5 HttpClient PUT или POST через SSL всегда терпят неудачу

У меня ужасное время, чтобы устранить эту проблему. У меня также ужасное время, последовательно воспроизводя его из одного приложения в другое.

При определенных обстоятельствах, которые я, похоже, не могу идентифицировать, вызывая вызовы PUT и POST с использованием результатов HttpClient в следующем исключении.

При отправке запроса произошла ошибка.

Внутреннее исключение:
Подключенное соединение было закрыто: при отправке произошла непредвиденная ошибка.

Внутреннее исключение:
Эта операция не может быть выполнена на завершенном асинхронном объекте результата.

Кажется, что все работает с HTTP, это происходит только на HTTPS.

Сертификаты действительны, но я попытался установить ServicePointManager.ServerCertificateValidationCallback += (s, c, ch, es) => true;

Я попытался установить client.DefaultRequestHeaders.ExpectContinue = false;

Я попытался, что-то вроде миллиона, другие вещи, начиная от заголовков, аутентификации и т.д.

Кто-нибудь знает, что еще я могу проверить, попробовать и т.д.

Фрагмент кода:

// 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:

Если я сниму ConfigureAwait(false), он отлично работает.

Примечание. Это приложение WPF, в частности, это расширение Visual Studio. Тем не менее, у меня есть приложение ASP.NET MVC 4 с той же проблемой, и это приложение вообще не вызывает ConfigureAwait(false)...

ОБНОВЛЕНИЕ 2:

Я обновил фрагмент кода, чтобы включить экземпляр класса HttpClient. Единственное, что не включено в фрагмент кода, это тип модели и декларация. Это должно быть неуместно, поскольку это сериализуемый класс со всеми авто свойствами без сложных типов.

ОБНОВЛЕНИЕ 3:

Я не знаю, действительно ли это актуально, но я нашел несколько вещей, которые выглядят странно для меня.

При выполнении вышеуказанного кода в Fiddler я получаю 401 в POST, за которым следуют 2 CONNECT, которые приводят к следующим HTTP-ответам:

Соединение HTTP/1.1 200 Установлено
Соединение: закрыть

ОБНОВЛЕНИЕ 4:

Я изменил свой регистрационный код IoC следующим образом:

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");

и теперь он терпит неудачу, но когда я открываю Fiddler и позволяю ему расшифровывать трафик... он работает!

ОБНОВЛЕНИЕ 5:

Я считаю, что это должна быть проблема с сервером или проблема с сертификатом. Любые советы о том, что можно проверить здесь, будут очень признательны. Сертификаты действительны и выдаются из доверенного ЦС.

ОБНОВЛЕНИЕ 6:

Больше отладки и устранения неполадок. Исключение возникает до вызова ServicePointManager CertificateValidationCallback.

4b9b3361

Ответ 1

Мне только что удалось решить проблему с HttpClient. Оказывается, я получал предупреждение SNI во время рукопожатия SSL, что заставило HttpClient заблокироваться на неопределенный срок. Попробуйте запустить WireShark/tcpdump и посмотреть, получаете ли вы предупреждение TLSv1 Unrecognized Name или какое-либо другое предупреждение о подтверждении рукопожатия. HttpClient, похоже, не обрабатывает их должным образом на основе моих тестов.

Ответ 2

У меня была та же проблема, и я решил установить последнюю обновленную версию .NET framework (4.5).