diff --git a/changelogs/unreleased/6846-rajatvig-small.md b/changelogs/unreleased/6846-rajatvig-small.md new file mode 100644 index 00000000000..05bc7628eae --- /dev/null +++ b/changelogs/unreleased/6846-rajatvig-small.md @@ -0,0 +1 @@ +Set `allow_connect` to true on `Http2ProtocolOptions` on the Listener when websockets are enabled. diff --git a/internal/envoy/v3/listener.go b/internal/envoy/v3/listener.go index 51a8a53bebe..245d69c33f9 100644 --- a/internal/envoy/v3/listener.go +++ b/internal/envoy/v3/listener.go @@ -602,10 +602,10 @@ func (b *httpConnectionManagerBuilder) Get() *envoy_config_listener_v3.Filter { cm.CommonHttpProtocolOptions.MaxRequestsPerConnection = wrapperspb.UInt32(*b.maxRequestsPerConnection) } + http2Options := &envoy_config_core_v3.Http2ProtocolOptions{} + if b.http2MaxConcurrentStreams != nil { - cm.Http2ProtocolOptions = &envoy_config_core_v3.Http2ProtocolOptions{ - MaxConcurrentStreams: wrapperspb.UInt32(*b.http2MaxConcurrentStreams), - } + http2Options.MaxConcurrentStreams = wrapperspb.UInt32(*b.http2MaxConcurrentStreams) } if b.enableWebsockets { @@ -614,6 +614,12 @@ func (b *httpConnectionManagerBuilder) Get() *envoy_config_listener_v3.Filter { UpgradeType: "websocket", }, ) + http2Options.AllowConnect = true + } + + // Assign http2Options only when max concurrent streams are set or web sockets are enabled + if b.http2MaxConcurrentStreams != nil || b.enableWebsockets { + cm.Http2ProtocolOptions = http2Options } return &envoy_config_listener_v3.Filter{ diff --git a/internal/envoy/v3/listener_test.go b/internal/envoy/v3/listener_test.go index 2cc564d924d..b516966eb70 100644 --- a/internal/envoy/v3/listener_test.go +++ b/internal/envoy/v3/listener_test.go @@ -676,6 +676,7 @@ func TestHTTPConnectionManager(t *testing.T) { stripTrailingHostDot bool maxRequestsPerConnection *uint32 http2MaxConcurrentStreams *uint32 + enableWebsockets bool want *envoy_config_listener_v3.Filter }{ "default": { @@ -1518,6 +1519,114 @@ func TestHTTPConnectionManager(t *testing.T) { }, }, }, + "websockets enabled without http2MaxConcurrentStreams": { + routename: "default/kuard", + accesslogger: FileAccessLogEnvoy("/dev/stdout", "", nil, contour_v1alpha1.LogLevelInfo), + enableWebsockets: true, + want: &envoy_config_listener_v3.Filter{ + Name: wellknown.HTTPConnectionManager, + ConfigType: &envoy_config_listener_v3.Filter_TypedConfig{ + TypedConfig: protobuf.MustMarshalAny(&envoy_filter_network_http_connection_manager_v3.HttpConnectionManager{ + StatPrefix: "default/kuard", + RouteSpecifier: &envoy_filter_network_http_connection_manager_v3.HttpConnectionManager_Rds{ + Rds: &envoy_filter_network_http_connection_manager_v3.Rds{ + RouteConfigName: "default/kuard", + ConfigSource: &envoy_config_core_v3.ConfigSource{ + ResourceApiVersion: envoy_config_core_v3.ApiVersion_V3, + ConfigSourceSpecifier: &envoy_config_core_v3.ConfigSource_ApiConfigSource{ + ApiConfigSource: &envoy_config_core_v3.ApiConfigSource{ + ApiType: envoy_config_core_v3.ApiConfigSource_GRPC, + TransportApiVersion: envoy_config_core_v3.ApiVersion_V3, + GrpcServices: []*envoy_config_core_v3.GrpcService{{ + TargetSpecifier: &envoy_config_core_v3.GrpcService_EnvoyGrpc_{ + EnvoyGrpc: &envoy_config_core_v3.GrpcService_EnvoyGrpc{ + ClusterName: "contour", + Authority: "contour", + }, + }, + }}, + }, + }, + }, + }, + }, + HttpFilters: defaultHTTPFilters, + HttpProtocolOptions: &envoy_config_core_v3.Http1ProtocolOptions{ + AcceptHttp_10: true, + }, + CommonHttpProtocolOptions: &envoy_config_core_v3.HttpProtocolOptions{}, + Http2ProtocolOptions: &envoy_config_core_v3.Http2ProtocolOptions{ + AllowConnect: true, + }, + UpgradeConfigs: []*envoy_filter_network_http_connection_manager_v3.HttpConnectionManager_UpgradeConfig{ + { + UpgradeType: "websocket", + }, + }, + AccessLog: FileAccessLogEnvoy("/dev/stdout", "", nil, contour_v1alpha1.LogLevelInfo), + UseRemoteAddress: wrapperspb.Bool(true), + NormalizePath: wrapperspb.Bool(true), + PreserveExternalRequestId: true, + MergeSlashes: false, + }), + }, + }, + }, + "websockets enabled with http2MaxConcurrentStreams": { + routename: "default/kuard", + accesslogger: FileAccessLogEnvoy("/dev/stdout", "", nil, contour_v1alpha1.LogLevelInfo), + http2MaxConcurrentStreams: ptr.To(uint32(50)), + enableWebsockets: true, + want: &envoy_config_listener_v3.Filter{ + Name: wellknown.HTTPConnectionManager, + ConfigType: &envoy_config_listener_v3.Filter_TypedConfig{ + TypedConfig: protobuf.MustMarshalAny(&envoy_filter_network_http_connection_manager_v3.HttpConnectionManager{ + StatPrefix: "default/kuard", + RouteSpecifier: &envoy_filter_network_http_connection_manager_v3.HttpConnectionManager_Rds{ + Rds: &envoy_filter_network_http_connection_manager_v3.Rds{ + RouteConfigName: "default/kuard", + ConfigSource: &envoy_config_core_v3.ConfigSource{ + ResourceApiVersion: envoy_config_core_v3.ApiVersion_V3, + ConfigSourceSpecifier: &envoy_config_core_v3.ConfigSource_ApiConfigSource{ + ApiConfigSource: &envoy_config_core_v3.ApiConfigSource{ + ApiType: envoy_config_core_v3.ApiConfigSource_GRPC, + TransportApiVersion: envoy_config_core_v3.ApiVersion_V3, + GrpcServices: []*envoy_config_core_v3.GrpcService{{ + TargetSpecifier: &envoy_config_core_v3.GrpcService_EnvoyGrpc_{ + EnvoyGrpc: &envoy_config_core_v3.GrpcService_EnvoyGrpc{ + ClusterName: "contour", + Authority: "contour", + }, + }, + }}, + }, + }, + }, + }, + }, + HttpFilters: defaultHTTPFilters, + HttpProtocolOptions: &envoy_config_core_v3.Http1ProtocolOptions{ + AcceptHttp_10: true, + }, + CommonHttpProtocolOptions: &envoy_config_core_v3.HttpProtocolOptions{}, + Http2ProtocolOptions: &envoy_config_core_v3.Http2ProtocolOptions{ + MaxConcurrentStreams: wrapperspb.UInt32(50), + AllowConnect: true, + }, + UpgradeConfigs: []*envoy_filter_network_http_connection_manager_v3.HttpConnectionManager_UpgradeConfig{ + { + UpgradeType: "websocket", + }, + }, + AccessLog: FileAccessLogEnvoy("/dev/stdout", "", nil, contour_v1alpha1.LogLevelInfo), + UseRemoteAddress: wrapperspb.Bool(true), + NormalizePath: wrapperspb.Bool(true), + PreserveExternalRequestId: true, + MergeSlashes: false, + }), + }, + }, + }, } for name, tc := range tests { t.Run(name, func(t *testing.T) { @@ -1539,6 +1648,7 @@ func TestHTTPConnectionManager(t *testing.T) { ForwardClientCertificate(tc.forwardClientCertificate). MaxRequestsPerConnection(tc.maxRequestsPerConnection). HTTP2MaxConcurrentStreams(tc.http2MaxConcurrentStreams). + EnableWebsockets(tc.enableWebsockets). DefaultFilters(). Get()