Skip to content

Commit d802a88

Browse files
authored
enable websockets for Gateway listeners (#5524)
Closes #5241. Signed-off-by: Steve Kriss <[email protected]>
1 parent a1f8c9e commit d802a88

File tree

9 files changed

+47
-11
lines changed

9 files changed

+47
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Gateway API: enable websockets upgrade by default.

internal/dag/builder_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -1951,6 +1951,7 @@ func TestDAGInsertGatewayAPI(t *testing.T) {
19511951
virtualhost("test.projectcontour.io",
19521952
prefixrouteHTTPRoute("/", service(kuardService)),
19531953
)),
1954+
EnableWebsockets: true,
19541955
},
19551956
),
19561957
},
@@ -16203,10 +16204,12 @@ func listeners(ls ...*Listener) []*Listener {
1620316204
listener.Protocol = "http"
1620416205
listener.Address = "0.0.0.0"
1620516206
listener.Port = 8080
16207+
listener.EnableWebsockets = true
1620616208
case "https-443":
1620716209
listener.Protocol = "https"
1620816210
listener.Address = "0.0.0.0"
1620916211
listener.Port = 8443
16212+
listener.EnableWebsockets = true
1621016213
}
1621116214
}
1621216215

internal/dag/dag.go

+4
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,10 @@ type Listener struct {
891891
// This cannot be used with VirtualHosts/SecureVirtualHosts
892892
// on a given Listener.
893893
TCPProxy *TCPProxy
894+
895+
// EnableWebsockets defines whether to enable the websocket
896+
// upgrade.
897+
EnableWebsockets bool
894898
}
895899

896900
// TCPProxy represents a cluster of TCP endpoints.

internal/dag/listener_processor.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ func (p *ListenerProcessor) Run(dag *DAG, cache *KubernetesCache) {
4141
address = p.HTTPSAddress
4242
}
4343
dag.Listeners[port.Name] = &Listener{
44-
Name: port.Name,
45-
Protocol: port.Protocol,
46-
Address: address,
47-
Port: int(port.ContainerPort),
48-
vhostsByName: map[string]*VirtualHost{},
49-
svhostsByName: map[string]*SecureVirtualHost{},
44+
Name: port.Name,
45+
Protocol: port.Protocol,
46+
Address: address,
47+
Port: int(port.ContainerPort),
48+
EnableWebsockets: true,
49+
vhostsByName: map[string]*VirtualHost{},
50+
svhostsByName: map[string]*SecureVirtualHost{},
5051
}
5152
}
5253
} else {

internal/envoy/v3/listener.go

+14
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ type httpConnectionManagerBuilder struct {
167167
numTrustedHops uint32
168168
tracingConfig *http.HttpConnectionManager_Tracing
169169
maxRequestsPerConnection *uint32
170+
enableWebsockets bool
171+
}
172+
173+
func (b *httpConnectionManagerBuilder) EnableWebsockets(enable bool) *httpConnectionManagerBuilder {
174+
b.enableWebsockets = enable
175+
return b
170176
}
171177

172178
// RouteConfigName sets the name of the RDS element that contains
@@ -527,6 +533,14 @@ func (b *httpConnectionManagerBuilder) Get() *envoy_listener_v3.Filter {
527533
cm.CommonHttpProtocolOptions.MaxRequestsPerConnection = wrapperspb.UInt32(*b.maxRequestsPerConnection)
528534
}
529535

536+
if b.enableWebsockets {
537+
cm.UpgradeConfigs = append(cm.UpgradeConfigs,
538+
&http.HttpConnectionManager_UpgradeConfig{
539+
UpgradeType: "websocket",
540+
},
541+
)
542+
}
543+
530544
return &envoy_listener_v3.Filter{
531545
Name: wellknown.HTTPConnectionManager,
532546
ConfigType: &envoy_listener_v3.Filter_TypedConfig{

internal/featuretests/v3/envoy.go

+10
Original file line numberDiff line numberDiff line change
@@ -456,13 +456,23 @@ func httpsFilterFor(vhost string) *envoy_listener_v3.Filter {
456456
Get()
457457
}
458458

459+
func httpFilterForGateway() *envoy_listener_v3.Filter {
460+
return envoy_v3.HTTPConnectionManagerBuilder().
461+
DefaultFilters().
462+
RouteConfigName("http-80").
463+
AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo)).
464+
EnableWebsockets(true).
465+
Get()
466+
}
467+
459468
func httpsFilterForGateway(listener, vhost string) *envoy_listener_v3.Filter {
460469
return envoy_v3.HTTPConnectionManagerBuilder().
461470
AddFilter(envoy_v3.FilterMisdirectedRequests(vhost)).
462471
DefaultFilters().
463472
RouteConfigName(path.Join(listener, vhost)).
464473
MetricsPrefix(listener).
465474
AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo)).
475+
EnableWebsockets(true).
466476
Get()
467477
}
468478

internal/featuretests/v3/listeners_test.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -1466,11 +1466,9 @@ func TestGatewayListenersSetAddress(t *testing.T) {
14661466
TypeUrl: listenerType,
14671467
Resources: resources(t,
14681468
&envoy_listener_v3.Listener{
1469-
Name: "http-80",
1470-
Address: envoy_v3.SocketAddress("127.0.0.100", 8080),
1471-
FilterChains: envoy_v3.FilterChains(
1472-
envoy_v3.HTTPConnectionManager("http-80", envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo), 0),
1473-
),
1469+
Name: "http-80",
1470+
Address: envoy_v3.SocketAddress("127.0.0.100", 8080),
1471+
FilterChains: envoy_v3.FilterChains(httpFilterForGateway()),
14741472
SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(),
14751473
},
14761474
),

internal/xdscache/v3/listener.go

+3
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
386386
Tracing(envoy_v3.TracingConfig(envoyTracingConfig(cfg.TracingConfig))).
387387
AddFilter(envoy_v3.GlobalRateLimitFilter(envoyGlobalRateLimitConfig(cfg.RateLimitConfig))).
388388
AddFilter(httpGlobalExternalAuthConfig(cfg.GlobalExternalAuthConfig)).
389+
EnableWebsockets(listener.EnableWebsockets).
389390
Get()
390391

391392
listeners[listener.Name] = envoy_v3.Listener(
@@ -455,6 +456,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
455456
AddFilter(envoy_v3.GlobalRateLimitFilter(envoyGlobalRateLimitConfig(cfg.RateLimitConfig))).
456457
ForwardClientCertificate(forwardClientCertificate).
457458
MaxRequestsPerConnection(cfg.MaxRequestsPerConnection).
459+
EnableWebsockets(listener.EnableWebsockets).
458460
Get()
459461

460462
filters = envoy_v3.Filters(cm)
@@ -520,6 +522,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
520522
AddFilter(envoy_v3.GlobalRateLimitFilter(envoyGlobalRateLimitConfig(cfg.RateLimitConfig))).
521523
ForwardClientCertificate(forwardClientCertificate).
522524
MaxRequestsPerConnection(cfg.MaxRequestsPerConnection).
525+
EnableWebsockets(listener.EnableWebsockets).
523526
Get()
524527

525528
// Default filter chain

site/content/docs/main/config/websockets.md

+2
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ spec:
2323
- name: chat-app
2424
port: 80
2525
```
26+
27+
If you are using Gateway API, websockets are enabled by default at the Listener level.

0 commit comments

Comments
 (0)