Почему HttpClientHandler неправильно подбирает и использует настройки прокси-сервера по умолчанию?C#

Место общения программистов C#
Ответить
Anonymous
 Почему HttpClientHandler неправильно подбирает и использует настройки прокси-сервера по умолчанию?

Сообщение Anonymous »

У нас есть ряд служб .NET Core 2.1 и несколько приложений .NET Framework 4.7.1, работающих на компьютере Windows Server (я думаю, 2016 года). У клиента настроен прокси-сервер (через Панель управления > Настройки прокси-сервера > Настройки локальной сети), который должен использовать весь трафик. Все эти службы отправляют вызовы в облако.

Мы видим, что некоторые вызовы от служб .NET Core достигают облака (например, регистрация , который мы можем просмотреть), но время ожидания большинства других вызовов истекает. У нас нет подобных проблем с приложениями .NET Framework.

Все службы/приложения используют HttpClient (один экземпляр в каждом приложении) с запросами HttpRequestMessage. , а не объекты HttpWebRequest. Я читал, что если вы инициализируете HttpClient с помощью HttpClientHandler и установите для свойства UseProxy значение true, а для свойства Proxy — значение null, он должен использовать настройки прокси-сервера по умолчанию, установленные в Windows, и я считаю, что если вы не инициализируете HttpClient с HttpClientHandler, он в любом случае будет использовать стандартный обработчик, который должен иметь тот же эффект.

Мы справились чтобы отследить проблему, связанную с тем, как HttpClient использует настройки прокси-сервера по умолчанию, создав тестовое консольное приложение .Net Core и выполнив вызовы ряда облачных служб. Интересно, что, похоже, используются настройки прокси по умолчанию, поскольку первый вызов работает как положено. Однако каждый последующий вызов (к разным облачным сервисам) завершается с ошибкой точно так же, как если бы он вообще не использовал настройки прокси.

Нам удалось это сделать чтобы решить эту проблему, фактически предоставив объект HttpClientHandler, переданный в HttpClient, с объектом WebProxy, настроенным на использование правильного прокси-сервера. Как только это будет установлено, все вызовы будут успешными. Однако это не самое предпочтительное решение, поскольку оно потребует от клиента предоставления дополнительной конфигурации для каждой службы. Они также не обязательно знают, на каком компьютере будут работать эти службы, и могут не знать настройки прокси-сервера при настройке служб.

Мы также решили проблему другим способом. , удаляя HttpClient после каждого отдельного вызова и создавая новый экземпляр. Очевидно, что это не может быть решением, поскольку это плохая практика и может вызвать другие проблемы (и повлечет за собой множество изменений кода в нескольких зависимостях).

Когда мы преобразовать консольное приложение .NET Core 2.1 в приложение .NET Framework 4.7.1, мы также не видим проблемы.

Мы также не видим никаких проблем, если мы используем объекты HttpWebRequest, чтобы сделать запросы.

Это текущий ошибочный код консольного приложения. Мы правильно используем async в наших сервисах, а не вызываем Result. Кажется, это не имеет значения.

Код: Выделить всё

var httpClient = new HttpClient();

Console.WriteLine("Hitting service 1 API");

var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}/service1/serviceinfo");

var result = httpClient.SendAsync(request).Result;

Console.WriteLine($"Response code: {result.StatusCode}");

var responseMessage = result.Content.ReadAsStringAsync().Result;
Console.WriteLine(responseMessage);

Thread.Sleep(2000);

Console.WriteLine("Hitting service 2 API");

request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}/service2/serviceinfo");

result = httpClient.SendAsync(request).Result;

Console.WriteLine($"Response code: {result.StatusCode}");

responseMessage = result.Content.ReadAsStringAsync().Result;
Console.WriteLine(responseMessage);

Thread.Sleep(2000);

Console.WriteLine("Hitting service 3 API");

request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}/service3/serviceinfo");

result = httpClient.SendAsync(request).Result;

Console.WriteLine($"Response code: {result.StatusCode}");

responseMessage = result.Content.ReadAsStringAsync().Result;
Console.WriteLine(responseMessage);
Ожидаемый результат: все три вызова должны пройти и получить ответ 200, независимо от того, настроен ли у вас прокси-сервер или нет.

Фактический результат: если не использовать прокси-сервер, мы получаем ожидаемый результат, хотя при использовании прокси-сервера первые вызовы выполняются, как и ожидалось, но следующий завершается сбоем с SocketException на нашей локальной тестовой машине или GatewayTimeout на нашей локальной тестовой машине или GatewayTimeout на клиентская машина (я считаю, что это именно так мы блокируем весь трафик, который не проходит через прокси).

Ожидаемый результат достигается, если для каждого вызова используется новый HttpClient.< /p>

Ожидаемый результат возникает, если вместо использования HttpClient используется HttpWebRequest.

Ожидаемый результат возникает, если HttpClient инициализируется с помощью а HttpClientHandler, для которого явно заданы настройки прокси-сервера.

Подробнее здесь: https://stackoverflow.com/questions/572 ... s-correctl
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»