From 044255cc83610b8785e93321649b2029c30be48c Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Wed, 26 Jun 2024 17:03:31 -0500 Subject: [PATCH] http2 upstream settings Signed-off-by: Guy Daich --- api/v1alpha1/backendtrafficpolicy_types.go | 5 + api/v1alpha1/clienttrafficpolicy_types.go | 25 -- api/v1alpha1/shared_types.go | 31 ++ api/v1alpha1/zz_generated.deepcopy.go | 10 + ....envoyproxy.io_backendtrafficpolicies.yaml | 44 +++ ...y.envoyproxy.io_clienttrafficpolicies.yaml | 6 + .../translate/out/default-resources.all.yaml | 4 +- .../out/from-gateway-api-to-xds.all.json | 5 +- .../out/from-gateway-api-to-xds.all.yaml | 4 +- .../out/from-gateway-api-to-xds.cluster.yaml | 4 +- internal/gatewayapi/backendtrafficpolicy.go | 17 + internal/gatewayapi/clienttrafficpolicy.go | 43 +-- internal/gatewayapi/http.go | 66 ++++ .../backendtrafficpolicy-with-http2.in.yaml | 94 ++++++ .../backendtrafficpolicy-with-http2.out.yaml | 316 ++++++++++++++++++ .../clienttrafficpolicy-http2.in.yaml | 1 + .../clienttrafficpolicy-http2.out.yaml | 2 + internal/ir/xds.go | 5 + internal/ir/zz_generated.deepcopy.go | 10 + internal/xds/translator/cluster.go | 37 +- internal/xds/translator/listener.go | 10 +- .../testdata/in/xds-ir/http2-route.yaml | 56 ++++ .../accesslog-endpoint-stats.clusters.yaml | 4 +- .../xds-ir/accesslog-formatters.clusters.yaml | 4 +- .../out/xds-ir/accesslog.clusters.yaml | 4 +- .../out/xds-ir/ext-auth.clusters.yaml | 4 +- .../out/xds-ir/ext-proc.clusters.yaml | 16 +- ...ttp-preserve-client-protocol.clusters.yaml | 4 +- .../out/xds-ir/http2-route.clusters.yaml | 74 +++- .../out/xds-ir/http2-route.endpoints.yaml | 36 ++ .../out/xds-ir/http2-route.routes.yaml | 21 ++ .../out/xds-ir/jwt-ratelimit.clusters.yaml | 4 +- .../ratelimit-custom-domain.clusters.yaml | 4 +- .../ratelimit-disable-headers.clusters.yaml | 4 +- .../ratelimit-endpoint-stats.clusters.yaml | 4 +- .../xds-ir/ratelimit-sourceip.clusters.yaml | 4 +- .../out/xds-ir/ratelimit.clusters.yaml | 4 +- .../tracing-endpoint-stats.clusters.yaml | 4 +- .../out/xds-ir/tracing-zipkin.clusters.yaml | 4 +- .../testdata/out/xds-ir/tracing.clusters.yaml | 4 +- internal/xds/translator/translator.go | 1 + site/content/en/latest/api/extension_types.md | 3 + site/content/zh/latest/api/extension_types.md | 3 + 43 files changed, 913 insertions(+), 92 deletions(-) create mode 100644 internal/gatewayapi/http.go create mode 100644 internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml create mode 100644 internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index 8c23b1332312..1d2087ee5a40 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -110,6 +110,11 @@ type BackendTrafficPolicySpec struct { // // +optional Connection *BackendConnection `json:"connection,omitempty"` + + // HTTP2 provides HTTP/2 configuration for backend connections. + // + // +optional + HTTP2 *HTTP2Settings `json:"http2,omitempty"` } // +kubebuilder:object:root=true diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go index 20953b1960b0..db56ac6e0488 100644 --- a/api/v1alpha1/clienttrafficpolicy_types.go +++ b/api/v1alpha1/clienttrafficpolicy_types.go @@ -6,7 +6,6 @@ package v1alpha1 import ( - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) @@ -289,30 +288,6 @@ type HTTP10Settings struct { UseDefaultHost *bool `json:"useDefaultHost,omitempty"` } -// HTTP2Settings provides HTTP/2 configuration on the listener. -type HTTP2Settings struct { - // InitialStreamWindowSize sets the initial window size for HTTP/2 streams. - // If not set, the default value is 64 KiB(64*1024). - // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" - // +optional - InitialStreamWindowSize *resource.Quantity `json:"initialStreamWindowSize,omitempty"` - - // InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. - // If not set, the default value is 1 MiB. - // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" - // +optional - InitialConnectionWindowSize *resource.Quantity `json:"initialConnectionWindowSize,omitempty"` - - // MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. - // If not set, the default value is 100. - // +kubebuilder:validation:Minimum=1 - // +kubebuilder:validation:Maximum=2147483647 - // +optional - MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty"` -} - // HealthCheckSettings provides HealthCheck configuration on the HTTP/HTTPS listener. type HealthCheckSettings struct { // Path specifies the HTTP path to match on for health check requests. diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go index 6ad310859bc8..3bf36d817369 100644 --- a/api/v1alpha1/shared_types.go +++ b/api/v1alpha1/shared_types.go @@ -10,6 +10,7 @@ import ( autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/resource" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) @@ -478,3 +479,33 @@ type BackendRef struct { // A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64". // +kubebuilder:validation:Pattern=`((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]+))|((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/([0-9]+))` type CIDR string + +// HTTP2Settings provides HTTP/2 configuration on the listener. +type HTTP2Settings struct { + // InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + // If not set, the default value is 64 KiB(64*1024). + // + // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +optional + InitialStreamWindowSize *resource.Quantity `json:"initialStreamWindowSize,omitempty"` + + // InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + // If not set, the default value is 1 MiB. + // + // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +optional + InitialConnectionWindowSize *resource.Quantity `json:"initialConnectionWindowSize,omitempty"` + + // MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + // If not set, the default value is 100. + // +kubebuilder:validation:Minimum=1 + // +kubebuilder:validation:Maximum=2147483647 + // +optional + MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty"` + + // ResetStreamOnError determines if Envoy will t erminate the stream or the connection in the event of HTTP messaging error + // It's recommended for L2 Envoy deployments to set this value to true. + // https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + // +optional + ResetStreamOnError *bool `json:"resetStreamOnError,omitempty"` +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index ac4a36025287..81db5e24853a 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -569,6 +569,11 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) *out = new(BackendConnection) (*in).DeepCopyInto(*out) } + if in.HTTP2 != nil { + in, out := &in.HTTP2, &out.HTTP2 + *out = new(HTTP2Settings) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTrafficPolicySpec. @@ -2418,6 +2423,11 @@ func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { *out = new(uint32) **out = **in } + if in.ResetStreamOnError != nil { + in, out := &in.ResetStreamOnError, &out.ResetStreamOnError + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 7d7e7c9680b0..6407fe96954d 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -421,6 +421,50 @@ spec: type: boolean type: object type: object + http2: + description: HTTP2 provides HTTP/2 configuration for backend connections. + properties: + initialConnectionWindowSize: + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + x-kubernetes-validations: + - message: initialConnectionWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" + rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") + : type(self) == int' + initialStreamWindowSize: + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + x-kubernetes-validations: + - message: initialStreamWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" + rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") + : type(self) == int' + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + resetStreamOnError: + description: |- + ResetStreamOnError determines if Envoy will t erminate the stream or the connection in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to true. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + type: boolean + type: object loadBalancer: description: |- LoadBalancer policy to apply when routing traffic from the gateway to diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index 218c1cf2e546..784a9c5e5777 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -300,6 +300,12 @@ spec: maximum: 2147483647 minimum: 1 type: integer + resetStreamOnError: + description: |- + ResetStreamOnError determines if Envoy will t erminate the stream or the connection in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to true. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + type: boolean type: object http3: description: HTTP3 provides HTTP/3 configuration on the listener. diff --git a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml index 1ef7ecd91634..4844857638e9 100644 --- a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml @@ -751,7 +751,9 @@ xds: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - cluster: '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster circuitBreakers: diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json index 34264fa61509..6552d54d3a90 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json @@ -439,7 +439,10 @@ "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", "explicitHttpConfig": { - "http2ProtocolOptions": {} + "http2ProtocolOptions": { + "initialConnectionWindowSize": 1048576, + "initialStreamWindowSize": 65536 + } } } } diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml index 5ac91ed8e452..0d4af047359b 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml @@ -247,7 +247,9 @@ xds: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - cluster: '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster circuitBreakers: diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml index 3d9bce8ad213..c9f782804a46 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml @@ -44,7 +44,9 @@ xds: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - cluster: '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster circuitBreakers: diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index bcc6a5507c2b..00a23e2a9007 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -319,6 +319,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen ka *ir.TCPKeepalive rt *ir.Retry bc *ir.BackendConnection + h2 *ir.HTTP2Settings err, errs error ) @@ -373,6 +374,13 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen } } + if policy.Spec.HTTP2 != nil { + if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil { + err = perr.WithMessage(err, "HTTP2") + errs = errors.Join(errs, err) + } + } + // Early return if got any errors if errs != nil { return errs @@ -422,6 +430,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen TCPKeepalive: ka, Retry: rt, BackendConnection: bc, + HTTP2: h2, } // Update the Host field in HealthCheck, now that we have access to the Route Hostname. @@ -456,6 +465,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back ct *ir.Timeout ka *ir.TCPKeepalive rt *ir.Retry + h2 *ir.HTTP2Settings err, errs error ) @@ -502,6 +512,12 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back errs = errors.Join(errs, err) } } + if policy.Spec.HTTP2 != nil { + if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil { + err = perr.WithMessage(err, "HTTP2") + errs = errors.Join(errs, err) + } + } // Early return if got any errors if errs != nil { @@ -590,6 +606,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back FaultInjection: fi, TCPKeepalive: ka, Retry: rt, + HTTP2: h2, } // Update the Host field in HealthCheck, now that we have access to the Route Hostname. diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index cde236dbc968..f1f6e335c5fb 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -28,11 +28,7 @@ import ( const ( // Use an invalid string to represent all sections (listeners) within a Gateway - AllSections = "/" - MinHTTP2InitialStreamWindowSize = 65535 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size - MaxHTTP2InitialStreamWindowSize = 2147483647 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size - MinHTTP2InitialConnectionWindowSize = MinHTTP2InitialStreamWindowSize - MaxHTTP2InitialConnectionWindowSize = MaxHTTP2InitialStreamWindowSize + AllSections = "/" ) func hasSectionName(target *gwapiv1a2.LocalPolicyTargetReferenceWithSectionName) bool { @@ -693,42 +689,7 @@ func translateHTTP2Settings(http2Settings *egv1a1.HTTP2Settings, httpIR *ir.HTTP return nil } - var ( - http2 = &ir.HTTP2Settings{} - errs error - ) - - if http2Settings.InitialStreamWindowSize != nil { - initialStreamWindowSize, ok := http2Settings.InitialStreamWindowSize.AsInt64() - switch { - case !ok: - errs = errors.Join(errs, fmt.Errorf("invalid InitialStreamWindowSize value %s", http2Settings.InitialStreamWindowSize.String())) - case initialStreamWindowSize < MinHTTP2InitialStreamWindowSize || initialStreamWindowSize > MaxHTTP2InitialStreamWindowSize: - errs = errors.Join(errs, fmt.Errorf("InitialStreamWindowSize value %s is out of range, must be between %d and %d", - http2Settings.InitialStreamWindowSize.String(), - MinHTTP2InitialStreamWindowSize, - MaxHTTP2InitialStreamWindowSize)) - default: - http2.InitialStreamWindowSize = ptr.To(uint32(initialStreamWindowSize)) - } - } - - if http2Settings.InitialConnectionWindowSize != nil { - initialConnectionWindowSize, ok := http2Settings.InitialConnectionWindowSize.AsInt64() - switch { - case !ok: - errs = errors.Join(errs, fmt.Errorf("invalid InitialConnectionWindowSize value %s", http2Settings.InitialConnectionWindowSize.String())) - case initialConnectionWindowSize < MinHTTP2InitialConnectionWindowSize || initialConnectionWindowSize > MaxHTTP2InitialConnectionWindowSize: - errs = errors.Join(errs, fmt.Errorf("InitialConnectionWindowSize value %s is out of range, must be between %d and %d", - http2Settings.InitialConnectionWindowSize.String(), - MinHTTP2InitialConnectionWindowSize, - MaxHTTP2InitialConnectionWindowSize)) - default: - http2.InitialConnectionWindowSize = ptr.To(uint32(initialConnectionWindowSize)) - } - } - - http2.MaxConcurrentStreams = http2Settings.MaxConcurrentStreams + http2, errs := buildIRHTTP2Settings(http2Settings) httpIR.HTTP2 = http2 return errs diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go new file mode 100644 index 000000000000..206ec930ad8e --- /dev/null +++ b/internal/gatewayapi/http.go @@ -0,0 +1,66 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package gatewayapi + +import ( + "errors" + "fmt" + + "k8s.io/utils/ptr" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/ir" +) + +const ( + MinHTTP2InitialStreamWindowSize = 65535 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size + MaxHTTP2InitialStreamWindowSize = 2147483647 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size + MinHTTP2InitialConnectionWindowSize = MinHTTP2InitialStreamWindowSize + MaxHTTP2InitialConnectionWindowSize = MaxHTTP2InitialStreamWindowSize +) + +func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Settings, error) { + var ( + http2 = &ir.HTTP2Settings{} + errs error + ) + + if http2Settings.InitialStreamWindowSize != nil { + initialStreamWindowSize, ok := http2Settings.InitialStreamWindowSize.AsInt64() + switch { + case !ok: + errs = errors.Join(errs, fmt.Errorf("invalid InitialStreamWindowSize value %s", http2Settings.InitialStreamWindowSize.String())) + case initialStreamWindowSize < MinHTTP2InitialStreamWindowSize || initialStreamWindowSize > MaxHTTP2InitialStreamWindowSize: + errs = errors.Join(errs, fmt.Errorf("InitialStreamWindowSize value %s is out of range, must be between %d and %d", + http2Settings.InitialStreamWindowSize.String(), + MinHTTP2InitialStreamWindowSize, + MaxHTTP2InitialStreamWindowSize)) + default: + http2.InitialStreamWindowSize = ptr.To(uint32(initialStreamWindowSize)) + } + } + + if http2Settings.InitialConnectionWindowSize != nil { + initialConnectionWindowSize, ok := http2Settings.InitialConnectionWindowSize.AsInt64() + switch { + case !ok: + errs = errors.Join(errs, fmt.Errorf("invalid InitialConnectionWindowSize value %s", http2Settings.InitialConnectionWindowSize.String())) + case initialConnectionWindowSize < MinHTTP2InitialConnectionWindowSize || initialConnectionWindowSize > MaxHTTP2InitialConnectionWindowSize: + errs = errors.Join(errs, fmt.Errorf("InitialConnectionWindowSize value %s is out of range, must be between %d and %d", + http2Settings.InitialConnectionWindowSize.String(), + MinHTTP2InitialConnectionWindowSize, + MaxHTTP2InitialConnectionWindowSize)) + default: + http2.InitialConnectionWindowSize = ptr.To(uint32(initialConnectionWindowSize)) + } + } + + http2.MaxConcurrentStreams = http2Settings.MaxConcurrentStreams + + http2.ResetStreamOnError = http2Settings.ResetStreamOnError + + return http2, errs +} diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml new file mode 100644 index 000000000000..1a7a11a8e333 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml @@ -0,0 +1,94 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-2 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +grpcRoutes: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: GRPCRoute + metadata: + namespace: default + name: grpcroute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-2 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + http2: + initialStreamWindowSize: 2Mi + initialConnectionWindowSize: 1Gi + maxConcurrentStreams: 500 +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + http2: + initialStreamWindowSize: 1Mi + initialConnectionWindowSize: 500Mi + maxConcurrentStreams: 200 + resetStreamOnError: true diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml new file mode 100644 index 000000000000..045d39359e5d --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml @@ -0,0 +1,316 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + creationTimestamp: null + name: policy-for-route + namespace: default + spec: + http2: + initialConnectionWindowSize: 500Mi + initialStreamWindowSize: 1Mi + maxConcurrentStreams: 200 + resetStreamOnError: true + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway + namespace: envoy-gateway + spec: + http2: + initialConnectionWindowSize: 1Gi + initialStreamWindowSize: 2Mi + maxConcurrentStreams: 500 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-2 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +grpcRoutes: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: GRPCRoute + metadata: + creationTimestamp: null + name: grpcroute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - name: gateway-2 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-2 + namespace: envoy-gateway + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 + envoy-gateway/gateway-2: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-2/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-2 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-2 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: true + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + name: grpcroute/default/grpcroute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: GRPC + weight: 1 + hostname: '*' + isHTTP2: true + name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + traffic: + http2: + initialConnectionWindowSize: 2097152 + initialStreamWindowSize: 1073741824 + maxConcurrentStreams: 500 + envoy-gateway/gateway-2: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-2/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: gateway.envoyproxy.io + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: / + traffic: + http2: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 524288000 + maxConcurrentStreams: 200 + resetStreamOnError: true diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml index fd435bbb51eb..08a0cef1ee11 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml @@ -9,6 +9,7 @@ clientTrafficPolicies: initialStreamWindowSize: 64Ki initialConnectionWindowSize: 32Mi maxConcurrentStreams: 200 + resetStreamOnError: false targetRef: group: gateway.networking.k8s.io kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml index cf410dffe52f..e05012e3e6f3 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml @@ -10,6 +10,7 @@ clientTrafficPolicies: initialConnectionWindowSize: 32Mi initialStreamWindowSize: 64Ki maxConcurrentStreams: 200 + resetStreamOnError: false targetRef: group: gateway.networking.k8s.io kind: Gateway @@ -170,6 +171,7 @@ xdsIR: initialConnectionWindowSize: 65536 initialStreamWindowSize: 33554432 maxConcurrentStreams: 200 + resetStreamOnError: false isHTTP2: false name: envoy-gateway/gateway-1/http-1 path: diff --git a/internal/ir/xds.go b/internal/ir/xds.go index d3eb48d853d1..cf57394f3961 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -454,6 +454,8 @@ type HTTP2Settings struct { InitialConnectionWindowSize *uint32 `json:"initialStreamWindowSize,omitempty" yaml:"initialStreamWindowSize,omitempty"` // MaxConcurrentStreams is the maximum number of concurrent streams that can be opened on a connection. MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty" yaml:"maxConcurrentStreams,omitempty"` + // MaxConcurrentStreams is the maximum number of concurrent streams that can be opened on a connection. + ResetStreamOnError *bool `json:"resetStreamOnError,omitempty" yaml:"resetStreamOnError,omitempty"` } // HealthCheckSettings provides HealthCheck configuration on the HTTP/HTTPS listener. @@ -588,6 +590,9 @@ type TrafficFeatures struct { Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"` // settings of upstream connection BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"` + // HTTP2 provides HTTP/2 configuration for clusters + // +optional + HTTP2 *HTTP2Settings `json:"http2,omitempty" yaml:"http2,omitempty"` } func (b *TrafficFeatures) Validate() error { diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index f4882032c032..5f25960741b0 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -892,6 +892,11 @@ func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { *out = new(uint32) **out = **in } + if in.ResetStreamOnError != nil { + in, out := &in.ResetStreamOnError, &out.ResetStreamOnError + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings. @@ -2697,6 +2702,11 @@ func (in *TrafficFeatures) DeepCopyInto(out *TrafficFeatures) { *out = new(BackendConnection) (*in).DeepCopyInto(*out) } + if in.HTTP2 != nil { + in, out := &in.HTTP2, &out.HTTP2 + *out = new(HTTP2Settings) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficFeatures. diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go index e646f4109448..31057268b2e5 100644 --- a/internal/xds/translator/cluster.go +++ b/internal/xds/translator/cluster.go @@ -48,6 +48,7 @@ type xdsClusterArgs struct { circuitBreaker *ir.CircuitBreaker healthCheck *ir.HealthCheck http1Settings *ir.HTTP1Settings + http2Settings *ir.HTTP2Settings timeout *ir.Timeout tcpkeepalive *ir.TCPKeepalive metrics *ir.Metrics @@ -504,13 +505,15 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_UseDownstreamProtocolConfig{ UseDownstreamProtocolConfig: &httpv3.HttpProtocolOptions_UseDownstreamHttpConfig{ HttpProtocolOptions: http1opts, - Http2ProtocolOptions: &corev3.Http2ProtocolOptions{}, + Http2ProtocolOptions: buildHTTP2Settings(args.http2Settings), }, } case requiresHTTP2Options: protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_ExplicitHttpConfig_{ ExplicitHttpConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig{ - ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{}, + ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{ + Http2ProtocolOptions: buildHTTP2Settings(args.http2Settings), + }, }, } case requiresHTTP1Options: @@ -649,3 +652,33 @@ func buildBackandConnectionBufferLimitBytes(bc *ir.BackendConnection) *wrappers. return wrapperspb.UInt32(tcpClusterPerConnectionBufferLimitBytes) } + +func buildHTTP2Settings(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { + if opts == nil { + opts = &ir.HTTP2Settings{} + } + + // defaults based on https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge + out := &corev3.Http2ProtocolOptions{ + InitialStreamWindowSize: &wrapperspb.UInt32Value{ + Value: ptr.Deref(opts.InitialStreamWindowSize, http2InitialStreamWindowSize), + }, + InitialConnectionWindowSize: &wrapperspb.UInt32Value{ + Value: ptr.Deref(opts.InitialConnectionWindowSize, http2InitialConnectionWindowSize), + }, + } + + if opts.MaxConcurrentStreams != nil { + out.MaxConcurrentStreams = &wrapperspb.UInt32Value{ + Value: *opts.MaxConcurrentStreams, + } + } + + if opts.ResetStreamOnError != nil { + out.OverrideStreamErrorOnInvalidHttpMessage = &wrapperspb.BoolValue{ + Value: *opts.ResetStreamOnError, + } + } + + return out +} diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index ee1f5c7d1336..9d445423e741 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -84,7 +84,7 @@ func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { opts = &ir.HTTP2Settings{} } - return &corev3.Http2ProtocolOptions{ + out := &corev3.Http2ProtocolOptions{ MaxConcurrentStreams: &wrapperspb.UInt32Value{ Value: ptr.Deref(opts.MaxConcurrentStreams, http2MaxConcurrentStreamsLimit), }, @@ -95,6 +95,14 @@ func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { Value: ptr.Deref(opts.InitialConnectionWindowSize, http2InitialConnectionWindowSize), }, } + + if opts.ResetStreamOnError != nil { + out.OverrideStreamErrorOnInvalidHttpMessage = &wrapperspb.BoolValue{ + Value: *opts.ResetStreamOnError, + } + } + + return out } func xffNumTrustedHops(clientIPDetection *ir.ClientIPDetectionSettings) uint32 { diff --git a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml index f3dc12c5aae0..e3104d1bd364 100644 --- a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml @@ -28,3 +28,59 @@ http: - host: "1.2.3.4" port: 50000 protocol: GRPC + traffic: + http2: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 524288000 + maxConcurrentStreams: 200 + resetStreamOnError: true + - name: "second-route" + hostname: "*" + pathMatch: + name: "test" + exact: "bar/foo" + destination: + name: "second-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + protocol: GRPC + traffic: + http2: {} + - name: "third-route-use-client" + hostname: "*" + pathMatch: + name: "test" + exact: "bar/bar" + destination: + name: "third-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + protocol: HTTP + useClientProtocol: true + traffic: + http2: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 524288000 + maxConcurrentStreams: 200 + resetStreamOnError: true + - name: "fourth-route-not-http2" + hostname: "*" + pathMatch: + name: "test" + exact: "foo/foo" + destination: + name: "fourth-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + traffic: + http2: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 524288000 + maxConcurrentStreams: 200 + resetStreamOnError: true diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml index cbf453a1f17b..ea9ef9405ee2 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml @@ -50,4 +50,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml index b8874bf24f91..6d040000dbbe 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml @@ -46,4 +46,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml index b8874bf24f91..6d040000dbbe 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml @@ -46,4 +46,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml index cf4fbc9b2740..e478c2054cdc 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml @@ -70,7 +70,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml index 08b38495e691..6ea0615cb319 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml @@ -53,7 +53,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 @@ -75,7 +77,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 @@ -97,7 +101,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 @@ -119,4 +125,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml index 5de1d1cce34d..f8cfa834cdde 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml @@ -19,5 +19,7 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions useDownstreamProtocolConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 httpProtocolOptions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml index 6086cfbb86f8..85eb367562d7 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml @@ -19,4 +19,76 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 524288000 + initialStreamWindowSize: 1048576 + maxConcurrentStreams: 200 + overrideStreamErrorOnInvalidHttpMessage: true +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: second-route-dest + lbPolicy: LEAST_REQUEST + name: second-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: third-route-dest + lbPolicy: LEAST_REQUEST + name: third-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + useDownstreamProtocolConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 524288000 + initialStreamWindowSize: 1048576 + maxConcurrentStreams: 200 + overrideStreamErrorOnInvalidHttpMessage: true + httpProtocolOptions: {} +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: fourth-route-dest + lbPolicy: LEAST_REQUEST + name: fourth-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml index 3b3f2d09076e..f185af17da75 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml @@ -10,3 +10,39 @@ loadBalancingWeight: 1 locality: region: first-route-dest/backend/0 +- clusterName: second-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: second-route-dest/backend/0 +- clusterName: third-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: third-route-dest/backend/0 +- clusterName: fourth-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: fourth-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml index a32852fcd881..4fdedfabf672 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml @@ -20,3 +20,24 @@ cluster: first-route-dest upgradeConfigs: - upgradeType: websocket + - match: + path: bar/foo + name: second-route + route: + cluster: second-route-dest + upgradeConfigs: + - upgradeType: websocket + - match: + path: bar/bar + name: third-route-use-client + route: + cluster: third-route-dest + upgradeConfigs: + - upgradeType: websocket + - match: + path: foo/foo + name: fourth-route-not-http2 + route: + cluster: fourth-route-dest + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml index d4e9db34e33a..e75a68919d1f 100644 --- a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml @@ -119,4 +119,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml index bd23f61ee21e..45e8e0898cec 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml @@ -93,4 +93,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml index 9f9bc9f1dffe..0ba1749076af 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml @@ -93,4 +93,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml index 21ea06816118..a3c9b6623c91 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml @@ -101,4 +101,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml index 33fc01336b88..427f6d15340b 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml @@ -110,4 +110,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml index 9f9bc9f1dffe..0ba1749076af 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml @@ -93,4 +93,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml index 0936f4b459a4..9e7469dd2785 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml @@ -50,4 +50,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.clusters.yaml index b8a1ac3df39f..7dbb8cf301f1 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.clusters.yaml @@ -46,4 +46,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml index 35bc81158da0..dce48b2c083c 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml @@ -46,4 +46,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 2f6876df0993..f270ae90447a 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -768,6 +768,7 @@ func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute clusterArgs.timeout = bt.Timeout clusterArgs.tcpkeepalive = bt.TCPKeepalive clusterArgs.backendConnection = bt.BackendConnection + clusterArgs.http2Settings = bt.HTTP2 } if err := addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) { diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 953a5d297834..fd50846e623b 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -459,6 +459,7 @@ _Appears in:_ | `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using
the same HTTP protocol that the incoming request used. Defaults to false, which means
that Envoy will use the protocol indicated by the attached BackendRef. | | `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | | `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. | +| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. | #### BasicAuth @@ -1769,6 +1770,7 @@ _Appears in:_ HTTP2Settings provides HTTP/2 configuration on the listener. _Appears in:_ +- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - [ClientTrafficPolicySpec](#clienttrafficpolicyspec) | Field | Type | Required | Description | @@ -1776,6 +1778,7 @@ _Appears in:_ | `initialStreamWindowSize` | _[Quantity](#quantity)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024). | | `initialConnectionWindowSize` | _[Quantity](#quantity)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB. | | `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
If not set, the default value is 100. | +| `resetStreamOnError` | _boolean_ | false | ResetStreamOnError determines if Envoy will t erminate the stream or the connection in the event of HTTP messaging error
It's recommended for L2 Envoy deployments to set this value to true.
https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two | #### HTTP3Settings diff --git a/site/content/zh/latest/api/extension_types.md b/site/content/zh/latest/api/extension_types.md index 953a5d297834..fd50846e623b 100644 --- a/site/content/zh/latest/api/extension_types.md +++ b/site/content/zh/latest/api/extension_types.md @@ -459,6 +459,7 @@ _Appears in:_ | `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using
the same HTTP protocol that the incoming request used. Defaults to false, which means
that Envoy will use the protocol indicated by the attached BackendRef. | | `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | | `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. | +| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. | #### BasicAuth @@ -1769,6 +1770,7 @@ _Appears in:_ HTTP2Settings provides HTTP/2 configuration on the listener. _Appears in:_ +- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - [ClientTrafficPolicySpec](#clienttrafficpolicyspec) | Field | Type | Required | Description | @@ -1776,6 +1778,7 @@ _Appears in:_ | `initialStreamWindowSize` | _[Quantity](#quantity)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024). | | `initialConnectionWindowSize` | _[Quantity](#quantity)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB. | | `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
If not set, the default value is 100. | +| `resetStreamOnError` | _boolean_ | false | ResetStreamOnError determines if Envoy will t erminate the stream or the connection in the event of HTTP messaging error
It's recommended for L2 Envoy deployments to set this value to true.
https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two | #### HTTP3Settings