From fc7e758d3f60ebb8ffb9f4339d5d42d80d4e6cf4 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Thu, 23 Apr 2020 12:09:33 +0200 Subject: [PATCH] [Backport 6x] Fix check for agressive connectionlimit In dotnet/runtime#22366 we found that if `HttpClient` is using the curl handler it will lead to TCP connections bleeding. Our DefaultConnectionLimit is very restrictive if this is true. Our check however is too lenient and will default to true always on .NET core since netcoreapp still ships with CurlHandler as recent as `3.1.x` --- .../Configuration/ConnectionConfiguration.cs | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/Elasticsearch.Net/Configuration/ConnectionConfiguration.cs b/src/Elasticsearch.Net/Configuration/ConnectionConfiguration.cs index ddda8a1e479..469a451fc78 100644 --- a/src/Elasticsearch.Net/Configuration/ConnectionConfiguration.cs +++ b/src/Elasticsearch.Net/Configuration/ConnectionConfiguration.cs @@ -22,6 +22,43 @@ namespace Elasticsearch.Net /// public class ConnectionConfiguration : ConnectionConfiguration { + /// + /// Detects whether we are running on .NET Core with CurlHandler. + /// If this is true, we will set a very restrictive + /// As the old curl based handler is known to bleed TCP connections: + /// https://github.com/dotnet/runtime/issues/22366 + /// + private static bool UsingCurlHandler + { + get + { +#if !DOTNETCORE + return false; +#else + var curlHandlerExists = typeof(HttpClientHandler).Assembly.GetType("System.Net.Http.CurlHandler") != null; + if (!curlHandlerExists) return false; + + var socketsHandlerExists = typeof(HttpClientHandler).Assembly.GetType("System.Net.Http.SocketsHttpHandler") != null; + // running on a .NET core version with CurlHandler, before the existence of SocketsHttpHandler. + // Must be using CurlHandler. + if (!socketsHandlerExists) return true; + + if (AppContext.TryGetSwitch("System.Net.Http.UseSocketsHttpHandler", out var isEnabled)) + return !isEnabled; + + var environmentVariable = + Environment.GetEnvironmentVariable("DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER"); + + // SocketsHandler exists and no environment variable exists to disable it. + // Must be using SocketsHandler and not CurlHandler + if (environmentVariable == null) return false; + + return environmentVariable.Equals("false", StringComparison.OrdinalIgnoreCase) || + environmentVariable.Equals("0"); +#endif + } + } + /// /// The default ping timeout. Defaults to 2 seconds /// @@ -40,12 +77,12 @@ public class ConnectionConfiguration : ConnectionConfiguration - /// The default connection limit for both Elasticsearch.Net and Nest. Defaults to 80 except for - /// HttpClientHandler implementations based on curl, which defaults to - /// + /// The default connection limit for both Elasticsearch.Net and Nest. Defaults to 80 +#if DOTNETCORE + /// Except for implementations based on curl, which defaults to +#endif /// - public static readonly int DefaultConnectionLimit = IsCurlHandler ? Environment.ProcessorCount : 80; - + public static readonly int DefaultConnectionLimit = UsingCurlHandler ? Environment.ProcessorCount : 80; /// /// The default user agent for Elasticsearch.Net