From f760b11c842aff0438a7629e1d556af706b6bf02 Mon Sep 17 00:00:00 2001 From: "Mo.Rajabi" Date: Sun, 21 Jul 2024 10:52:56 +0330 Subject: [PATCH 1/4] feat: add EnableMultipleHttp2Connections --- .../Creator/HttpHandlerOptionsCreator.cs | 3 +- .../File/FileHttpHandlerOptions.cs | 3 ++ .../Configuration/HttpHandlerOptions.cs | 9 ++++- .../HttpHandlerOptionsBuilder.cs | 9 ++++- src/Ocelot/Requester/MessageInvokerPool.cs | 1 + .../DownstreamRouteExtensionsTests.cs | 2 +- .../HttpHandlerOptionsCreatorTests.cs | 38 ++++++++++++++----- ...atingHandlerHandlerProviderFactoryTests.cs | 24 ++++++------ .../Requester/MessageInvokerPoolTests.cs | 8 ++-- 9 files changed, 68 insertions(+), 29 deletions(-) diff --git a/src/Ocelot/Configuration/Creator/HttpHandlerOptionsCreator.cs b/src/Ocelot/Configuration/Creator/HttpHandlerOptionsCreator.cs index e7e963c34..45135ce7f 100644 --- a/src/Ocelot/Configuration/Creator/HttpHandlerOptionsCreator.cs +++ b/src/Ocelot/Configuration/Creator/HttpHandlerOptionsCreator.cs @@ -25,7 +25,8 @@ public HttpHandlerOptions Create(FileHttpHandlerOptions options) var pooledConnectionLifetime = TimeSpan.FromSeconds(options.PooledConnectionLifetimeSeconds ?? DefaultPooledConnectionLifetimeSeconds); return new HttpHandlerOptions(options.AllowAutoRedirect, - options.UseCookieContainer, useTracing, options.UseProxy, maxConnectionPerServer, pooledConnectionLifetime); + options.UseCookieContainer, useTracing, options.UseProxy, maxConnectionPerServer, pooledConnectionLifetime, + options.EnableMultipleHttp2Connections); } } } diff --git a/src/Ocelot/Configuration/File/FileHttpHandlerOptions.cs b/src/Ocelot/Configuration/File/FileHttpHandlerOptions.cs index 4f7f14408..42fadfe93 100644 --- a/src/Ocelot/Configuration/File/FileHttpHandlerOptions.cs +++ b/src/Ocelot/Configuration/File/FileHttpHandlerOptions.cs @@ -9,6 +9,7 @@ public FileHttpHandlerOptions() UseCookieContainer = false; UseProxy = true; PooledConnectionLifetimeSeconds = null; + EnableMultipleHttp2Connections = false; } public FileHttpHandlerOptions(FileHttpHandlerOptions from) @@ -18,6 +19,7 @@ public FileHttpHandlerOptions(FileHttpHandlerOptions from) UseCookieContainer = from.UseCookieContainer; UseProxy = from.UseProxy; PooledConnectionLifetimeSeconds = from.PooledConnectionLifetimeSeconds; + EnableMultipleHttp2Connections = from.EnableMultipleHttp2Connections; } public bool AllowAutoRedirect { get; set; } @@ -26,5 +28,6 @@ public FileHttpHandlerOptions(FileHttpHandlerOptions from) public bool UseProxy { get; set; } public bool UseTracing { get; set; } public int? PooledConnectionLifetimeSeconds { get; set; } + public bool EnableMultipleHttp2Connections { get; set; } } } diff --git a/src/Ocelot/Configuration/HttpHandlerOptions.cs b/src/Ocelot/Configuration/HttpHandlerOptions.cs index c70cca9b7..bdb085e9e 100644 --- a/src/Ocelot/Configuration/HttpHandlerOptions.cs +++ b/src/Ocelot/Configuration/HttpHandlerOptions.cs @@ -6,7 +6,7 @@ public class HttpHandlerOptions { public HttpHandlerOptions(bool allowAutoRedirect, bool useCookieContainer, bool useTracing, bool useProxy, - int maxConnectionsPerServer, TimeSpan pooledConnectionLifeTime) + int maxConnectionsPerServer, TimeSpan pooledConnectionLifeTime, bool enableMultipleHttp2Connections) { AllowAutoRedirect = allowAutoRedirect; UseCookieContainer = useCookieContainer; @@ -14,6 +14,7 @@ public HttpHandlerOptions(bool allowAutoRedirect, bool useCookieContainer, bool UseProxy = useProxy; MaxConnectionsPerServer = maxConnectionsPerServer; PooledConnectionLifeTime = pooledConnectionLifeTime; + EnableMultipleHttp2Connections = enableMultipleHttp2Connections; } /// @@ -51,5 +52,11 @@ public HttpHandlerOptions(bool allowAutoRedirect, bool useCookieContainer, bool /// /// PooledConnectionLifeTime. public TimeSpan PooledConnectionLifeTime { get; } + + /// + /// Gets or sets a value that indicates whether additional HTTP/2 connections can be established to the same server. + /// + /// EnableMultipleHttp2Connections. + public bool EnableMultipleHttp2Connections { get; set; } } } diff --git a/src/Ocelot/Configuration/HttpHandlerOptionsBuilder.cs b/src/Ocelot/Configuration/HttpHandlerOptionsBuilder.cs index ff0f87fe1..a88fbc6e0 100644 --- a/src/Ocelot/Configuration/HttpHandlerOptionsBuilder.cs +++ b/src/Ocelot/Configuration/HttpHandlerOptionsBuilder.cs @@ -10,6 +10,7 @@ public class HttpHandlerOptionsBuilder private bool _useProxy; private int _maxConnectionPerServer; private TimeSpan _pooledConnectionLifetime = TimeSpan.FromSeconds(HttpHandlerOptionsCreator.DefaultPooledConnectionLifetimeSeconds); + private bool _enableMultipleHttp2Connections; public HttpHandlerOptionsBuilder WithAllowAutoRedirect(bool input) { @@ -47,9 +48,15 @@ public HttpHandlerOptionsBuilder WithPooledConnectionLifetimeSeconds(TimeSpan po return this; } + public HttpHandlerOptionsBuilder WithEnableMultipleHttp2Connections(bool enableMultipleHttp2Connections) + { + _enableMultipleHttp2Connections = enableMultipleHttp2Connections; + return this; + } + public HttpHandlerOptions Build() { - return new HttpHandlerOptions(_allowAutoRedirect, _useCookieContainer, _useTracing, _useProxy, _maxConnectionPerServer, _pooledConnectionLifetime); + return new HttpHandlerOptions(_allowAutoRedirect, _useCookieContainer, _useTracing, _useProxy, _maxConnectionPerServer, _pooledConnectionLifetime, _enableMultipleHttp2Connections); } } } diff --git a/src/Ocelot/Requester/MessageInvokerPool.cs b/src/Ocelot/Requester/MessageInvokerPool.cs index 130b4bccb..be8b26a83 100644 --- a/src/Ocelot/Requester/MessageInvokerPool.cs +++ b/src/Ocelot/Requester/MessageInvokerPool.cs @@ -77,6 +77,7 @@ private HttpMessageHandler CreateHandler(DownstreamRoute downstreamRoute) UseProxy = downstreamRoute.HttpHandlerOptions.UseProxy, MaxConnectionsPerServer = downstreamRoute.HttpHandlerOptions.MaxConnectionsPerServer, PooledConnectionLifetime = downstreamRoute.HttpHandlerOptions.PooledConnectionLifeTime, + EnableMultipleHttp2Connections = downstreamRoute.HttpHandlerOptions.EnableMultipleHttp2Connections, }; if (downstreamRoute.HttpHandlerOptions.UseCookieContainer) diff --git a/test/Ocelot.UnitTests/Configuration/DownstreamRouteExtensionsTests.cs b/test/Ocelot.UnitTests/Configuration/DownstreamRouteExtensionsTests.cs index 0c3b3bcc3..ed6791425 100644 --- a/test/Ocelot.UnitTests/Configuration/DownstreamRouteExtensionsTests.cs +++ b/test/Ocelot.UnitTests/Configuration/DownstreamRouteExtensionsTests.cs @@ -22,7 +22,7 @@ public DownstreamRouteExtensionsTests() new List(), null, null, - new HttpHandlerOptions(false, false, false, false, 0, TimeSpan.Zero), + new HttpHandlerOptions(false, false, false, false, 0, TimeSpan.Zero, false), default, default, new QoSOptions(0, 0, 0, null), diff --git a/test/Ocelot.UnitTests/Configuration/HttpHandlerOptionsCreatorTests.cs b/test/Ocelot.UnitTests/Configuration/HttpHandlerOptionsCreatorTests.cs index 924dc919d..df5ac6a1d 100644 --- a/test/Ocelot.UnitTests/Configuration/HttpHandlerOptionsCreatorTests.cs +++ b/test/Ocelot.UnitTests/Configuration/HttpHandlerOptionsCreatorTests.cs @@ -33,7 +33,7 @@ public void should_not_use_tracing_if_fake_tracer_registered() }, }; - var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime); + var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false); this.Given(x => GivenTheFollowing(fileRoute)) .When(x => WhenICreateHttpHandlerOptions()) @@ -52,7 +52,7 @@ public void should_use_tracing_if_real_tracer_registered() }, }; - var expectedOptions = new HttpHandlerOptions(false, false, true, true, int.MaxValue, DefaultPooledConnectionLifeTime); + var expectedOptions = new HttpHandlerOptions(false, false, true, true, int.MaxValue, DefaultPooledConnectionLifeTime, false); this.Given(x => GivenTheFollowing(fileRoute)) .And(x => GivenARealTracer()) @@ -65,7 +65,7 @@ public void should_use_tracing_if_real_tracer_registered() public void should_create_options_with_useCookie_false_and_allowAutoRedirect_true_as_default() { var fileRoute = new FileRoute(); - var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime); + var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false); this.Given(x => GivenTheFollowing(fileRoute)) .When(x => WhenICreateHttpHandlerOptions()) @@ -86,7 +86,7 @@ public void should_create_options_with_specified_useCookie_and_allowAutoRedirect }, }; - var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime); + var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false); this.Given(x => GivenTheFollowing(fileRoute)) .When(x => WhenICreateHttpHandlerOptions()) @@ -102,7 +102,7 @@ public void should_create_options_with_useproxy_true_as_default() HttpHandlerOptions = new FileHttpHandlerOptions(), }; - var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime); + var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false); this.Given(x => GivenTheFollowing(fileRoute)) .When(x => WhenICreateHttpHandlerOptions()) @@ -121,7 +121,7 @@ public void should_create_options_with_specified_useproxy() }, }; - var expectedOptions = new HttpHandlerOptions(false, false, false, false, int.MaxValue, DefaultPooledConnectionLifeTime); + var expectedOptions = new HttpHandlerOptions(false, false, false, false, int.MaxValue, DefaultPooledConnectionLifeTime, false); this.Given(x => GivenTheFollowing(fileRoute)) .When(x => WhenICreateHttpHandlerOptions()) @@ -140,7 +140,7 @@ public void should_create_options_with_specified_MaxConnectionsPerServer() }, }; - var expectedOptions = new HttpHandlerOptions(false, false, false, true, 10, DefaultPooledConnectionLifeTime); + var expectedOptions = new HttpHandlerOptions(false, false, false, true, 10, DefaultPooledConnectionLifeTime, false); this.Given(x => GivenTheFollowing(fileRoute)) .When(x => WhenICreateHttpHandlerOptions()) @@ -159,7 +159,7 @@ public void should_create_options_fixing_specified_MaxConnectionsPerServer_range }, }; - var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime); + var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false); this.Given(x => GivenTheFollowing(fileRoute)) .When(x => WhenICreateHttpHandlerOptions()) @@ -178,7 +178,26 @@ public void should_create_options_fixing_specified_MaxConnectionsPerServer_range }, }; - var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime); + var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false); + + this.Given(x => GivenTheFollowing(fileRoute)) + .When(x => WhenICreateHttpHandlerOptions()) + .Then(x => ThenTheFollowingOptionsReturned(expectedOptions)) + .BDDfy(); + } + + [Fact] + public void should_create_options_with_enableMultipleHttp2Connections() + { + var fileRoute = new FileRoute + { + HttpHandlerOptions = new FileHttpHandlerOptions + { + EnableMultipleHttp2Connections = true, + }, + }; + + var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, true); this.Given(x => GivenTheFollowing(fileRoute)) .When(x => WhenICreateHttpHandlerOptions()) @@ -204,6 +223,7 @@ private void ThenTheFollowingOptionsReturned(HttpHandlerOptions expected) _httpHandlerOptions.UseTracing.ShouldBe(expected.UseTracing); _httpHandlerOptions.UseProxy.ShouldBe(expected.UseProxy); _httpHandlerOptions.MaxConnectionsPerServer.ShouldBe(expected.MaxConnectionsPerServer); + _httpHandlerOptions.EnableMultipleHttp2Connections.ShouldBe(expected.EnableMultipleHttp2Connections); } private void GivenARealTracer() diff --git a/test/Ocelot.UnitTests/Requester/DelegatingHandlerHandlerProviderFactoryTests.cs b/test/Ocelot.UnitTests/Requester/DelegatingHandlerHandlerProviderFactoryTests.cs index d4a75b183..85f769936 100644 --- a/test/Ocelot.UnitTests/Requester/DelegatingHandlerHandlerProviderFactoryTests.cs +++ b/test/Ocelot.UnitTests/Requester/DelegatingHandlerHandlerProviderFactoryTests.cs @@ -46,7 +46,7 @@ public void should_follow_ordering_add_specifics() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithDelegatingHandlers(new List { "FakeDelegatingHandler", @@ -82,7 +82,7 @@ public void should_follow_ordering_order_specifics_and_globals() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithDelegatingHandlers(new List { "FakeDelegatingHandlerTwo", @@ -119,7 +119,7 @@ public void should_follow_ordering_order_specifics() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithDelegatingHandlers(new List { "FakeDelegatingHandlerTwo", @@ -155,7 +155,7 @@ public void should_follow_ordering_order_and_only_add_specifics_in_config() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithDelegatingHandlers(new List { "FakeDelegatingHandler", @@ -189,7 +189,7 @@ public void should_follow_ordering_dont_add_specifics() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithLoadBalancerKey(string.Empty) .Build(); @@ -215,7 +215,7 @@ public void should_apply_re_route_specific() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithDelegatingHandlers(new List { "FakeDelegatingHandler", @@ -243,7 +243,7 @@ public void should_all_from_all_routes_provider_and_qos() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithLoadBalancerKey(string.Empty) .Build(); @@ -265,7 +265,7 @@ public void should_return_provider_with_no_delegates() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithLoadBalancerKey(string.Empty) .Build(); @@ -287,7 +287,7 @@ public void should_return_provider_with_qos_delegate() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithLoadBalancerKey(string.Empty) .Build(); @@ -309,7 +309,7 @@ public void should_return_provider_with_qos_delegate_when_timeout_value_set() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithLoadBalancerKey(string.Empty) .Build(); @@ -333,7 +333,7 @@ public void should_log_error_and_return_no_qos_provider_delegate_when_qos_factor var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithLoadBalancerKey(string.Empty) .Build(); @@ -363,7 +363,7 @@ public void should_log_error_and_return_no_qos_provider_delegate_when_qos_factor var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime)) + .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue, DefaultPooledConnectionLifeTime, false)) .WithLoadBalancerKey(string.Empty) .Build(); diff --git a/test/Ocelot.UnitTests/Requester/MessageInvokerPoolTests.cs b/test/Ocelot.UnitTests/Requester/MessageInvokerPoolTests.cs index 81d7005c4..d7452874e 100644 --- a/test/Ocelot.UnitTests/Requester/MessageInvokerPoolTests.cs +++ b/test/Ocelot.UnitTests/Requester/MessageInvokerPoolTests.cs @@ -87,7 +87,7 @@ public void Should_log_if_ignoring_ssl_errors() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue, TimeSpan.FromSeconds(90))) + .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue, TimeSpan.FromSeconds(90), false)) .WithLoadBalancerKey(string.Empty) .WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue(string.Empty).Build()) .WithQosOptions(new QoSOptionsBuilder().Build()) @@ -110,7 +110,7 @@ public void Should_re_use_cookies_from_container() var route = new DownstreamRouteBuilder() .WithQosOptions(qosOptions) - .WithHttpHandlerOptions(new HttpHandlerOptions(false, true, false, true, int.MaxValue, TimeSpan.FromSeconds(90))) + .WithHttpHandlerOptions(new HttpHandlerOptions(false, true, false, true, int.MaxValue, TimeSpan.FromSeconds(90), false)) .WithLoadBalancerKey(string.Empty) .WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue(string.Empty).Build()) .WithQosOptions(new QoSOptionsBuilder().Build()) @@ -259,7 +259,7 @@ private void GivenARequestWithAUrlAndMethod(DownstreamRoute downstream, string u _context = new DefaultHttpContext(); _context.Items.UpsertDownstreamRoute(downstream); _context.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage - { RequestUri = new Uri(url), Method = method })); + { RequestUri = new Uri(url), Method = method })); } private void ThenSomethingIsReturned() => _response.ShouldNotBeNull(); @@ -330,7 +330,7 @@ private DownstreamRoute DownstreamRouteFactory(string path) .WithQosOptions(new QoSOptions(new FileQoSOptions())) .WithLoadBalancerKey(string.Empty) .WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue(string.Empty).Build()) - .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, false, 10, TimeSpan.FromSeconds(120))) + .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, false, 10, TimeSpan.FromSeconds(120), false)) .WithUpstreamHttpMethod(new() { "Get" }) .Build(); From 8b92cd0104ae2070ee75799cb8ed879effef9953 Mon Sep 17 00:00:00 2001 From: "Mo.Rajabi" Date: Sun, 21 Jul 2024 12:50:03 +0330 Subject: [PATCH 2/4] feat: update doc --- docs/features/configuration.rst | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/features/configuration.rst b/docs/features/configuration.rst index 1be532e08..da595ad41 100644 --- a/docs/features/configuration.rst +++ b/docs/features/configuration.rst @@ -238,7 +238,8 @@ Use ``HttpHandlerOptions`` in a Route configuration to set up ``HttpHandler`` be "AllowAutoRedirect": false, "UseCookieContainer": false, "UseTracing": true, - "MaxConnectionsPerServer": 100 + "MaxConnectionsPerServer": 100, + "EnableMultipleHttp2Connections": false }, * **AllowAutoRedirect** is a value that indicates whether the request should follow redirection responses. @@ -260,6 +261,9 @@ Use ``HttpHandlerOptions`` in a Route configuration to set up ``HttpHandler`` be * **MaxConnectionsPerServer** This controls how many connections the internal ``HttpClient`` will open. This can be set at Route or global level. +* **EnableMultipleHttp2Connections** Gets or sets a value that indicates whether additional HTTP/2 connections can be established to the same server. + true if additional HTTP/2 connections are allowed to be created; otherwise, false. + .. _ssl-errors: SSL Errors @@ -394,7 +398,10 @@ HTTP/2 version policy "DownstreamScheme": "https", "DownstreamHttpVersion": "2.0", "DownstreamHttpVersionPolicy": "", // empty - "DangerousAcceptAnyServerCertificateValidator": true + "DangerousAcceptAnyServerCertificateValidator": true, + "HttpHandlerOptions":{ + "EnableMultipleHttp2Connections": true + } } **And** you configure global settings to use Kestrel with this snippet: @@ -425,7 +432,10 @@ Therefore, the ``DownstreamHttpVersionPolicy`` should be defined as follows: { "DownstreamHttpVersion": "2.0", - "DownstreamHttpVersionPolicy": "RequestVersionOrHigher" // ! + "DownstreamHttpVersionPolicy": "RequestVersionOrHigher", // ! + "HttpHandlerOptions":{ + "EnableMultipleHttp2Connections": true + } } Dependency Injection From 5921a9cddddacb78e913be6f5b272433e9e746a2 Mon Sep 17 00:00:00 2001 From: Raman Maksimchuk Date: Tue, 23 Jul 2024 14:12:01 +0300 Subject: [PATCH 3/4] Sort properties --- src/Ocelot/Requester/MessageInvokerPool.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Ocelot/Requester/MessageInvokerPool.cs b/src/Ocelot/Requester/MessageInvokerPool.cs index be8b26a83..db2908672 100644 --- a/src/Ocelot/Requester/MessageInvokerPool.cs +++ b/src/Ocelot/Requester/MessageInvokerPool.cs @@ -73,11 +73,11 @@ private HttpMessageHandler CreateHandler(DownstreamRoute downstreamRoute) var handler = new SocketsHttpHandler { AllowAutoRedirect = downstreamRoute.HttpHandlerOptions.AllowAutoRedirect, - UseCookies = downstreamRoute.HttpHandlerOptions.UseCookieContainer, - UseProxy = downstreamRoute.HttpHandlerOptions.UseProxy, + EnableMultipleHttp2Connections = downstreamRoute.HttpHandlerOptions.EnableMultipleHttp2Connections, MaxConnectionsPerServer = downstreamRoute.HttpHandlerOptions.MaxConnectionsPerServer, PooledConnectionLifetime = downstreamRoute.HttpHandlerOptions.PooledConnectionLifeTime, - EnableMultipleHttp2Connections = downstreamRoute.HttpHandlerOptions.EnableMultipleHttp2Connections, + UseCookies = downstreamRoute.HttpHandlerOptions.UseCookieContainer, + UseProxy = downstreamRoute.HttpHandlerOptions.UseProxy, }; if (downstreamRoute.HttpHandlerOptions.UseCookieContainer) From 3efc97c11f6fcbbee428ee6d9835e00c50d7e48e Mon Sep 17 00:00:00 2001 From: Mohsen Rajabi Date: Wed, 21 Aug 2024 10:53:19 +0330 Subject: [PATCH 4/4] fix: apply comment --- src/Ocelot/Configuration/HttpHandlerOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ocelot/Configuration/HttpHandlerOptions.cs b/src/Ocelot/Configuration/HttpHandlerOptions.cs index bdb085e9e..976f63160 100644 --- a/src/Ocelot/Configuration/HttpHandlerOptions.cs +++ b/src/Ocelot/Configuration/HttpHandlerOptions.cs @@ -57,6 +57,6 @@ public HttpHandlerOptions(bool allowAutoRedirect, bool useCookieContainer, bool /// Gets or sets a value that indicates whether additional HTTP/2 connections can be established to the same server. /// /// EnableMultipleHttp2Connections. - public bool EnableMultipleHttp2Connections { get; set; } + public bool EnableMultipleHttp2Connections { get; } } }