From b4d5b67f39835fbff3c730214c84ac76e952e2bb Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 8 Jul 2024 10:57:18 +0300
Subject: [PATCH 01/30] build(deps): bump docker/setup-buildx-action from 3.3.0
to 3.4.0 (#6543)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/d70bba72b1f3fd22344832f00baa16ece964efeb...4fd812986e6c8c2a69e18311145f9371337f27d4)
---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: chaosbox
---
.github/workflows/build_main.yaml | 2 +-
.github/workflows/build_tag.yaml | 2 +-
.github/workflows/prbuild.yaml | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/build_main.yaml b/.github/workflows/build_main.yaml
index 8a5f1fc9186..029d788b887 100644
--- a/.github/workflows/build_main.yaml
+++ b/.github/workflows/build_main.yaml
@@ -21,7 +21,7 @@ jobs:
with:
persist-credentials: false
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
+ uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4 # v3.4.0
with:
version: latest
- name: Log in to GHCR
diff --git a/.github/workflows/build_tag.yaml b/.github/workflows/build_tag.yaml
index b7e7a4990d9..69c2e1e5475 100644
--- a/.github/workflows/build_tag.yaml
+++ b/.github/workflows/build_tag.yaml
@@ -31,7 +31,7 @@ jobs:
with:
persist-credentials: false
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
+ uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4 # v3.4.0
with:
version: latest
- name: Log in to GHCR
diff --git a/.github/workflows/prbuild.yaml b/.github/workflows/prbuild.yaml
index 13dab29ca94..0feae896984 100644
--- a/.github/workflows/prbuild.yaml
+++ b/.github/workflows/prbuild.yaml
@@ -103,7 +103,7 @@ jobs:
with:
persist-credentials: false
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
+ uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4 # v3.4.0
with:
version: latest
- name: Build image
From 081a47c42df23ca45db9aeea7cfd101eee16dd36 Mon Sep 17 00:00:00 2001
From: chaosbox
Date: Tue, 9 Jul 2024 09:37:07 +0100
Subject: [PATCH 02/30] Adds "disableCompression" as a feature to turnon/off
Envoy's GZIP response compression
Signed-off-by: chaosbox
---
apis/projectcontour/v1alpha1/contourconfig.go | 6 +
cmd/contour/serve.go | 1 +
cmd/contour/servecontext.go | 1 +
cmd/contour/servecontext_test.go | 2 +
examples/contour/01-crds.yaml | 12 ++
examples/render/contour-deployment.yaml | 12 ++
.../render/contour-gateway-provisioner.yaml | 12 ++
examples/render/contour-gateway.yaml | 12 ++
examples/render/contour.yaml | 12 ++
internal/envoy/v3/listener.go | 62 +++++----
internal/featuretests/v3/compression_test.go | 121 ++++++++++++++++++
internal/xdscache/v3/listener.go | 8 ++
internal/xdscache/v3/listener_test.go | 42 ++++++
pkg/config/parameters.go | 5 +
.../docs/main/config/api-reference.html | 15 +++
test/e2e/httpproxy/envoy_compression_test.go | 79 ++++++++++++
test/e2e/httpproxy/httpproxy_test.go | 13 ++
17 files changed, 389 insertions(+), 26 deletions(-)
create mode 100644 internal/featuretests/v3/compression_test.go
create mode 100644 test/e2e/httpproxy/envoy_compression_test.go
diff --git a/apis/projectcontour/v1alpha1/contourconfig.go b/apis/projectcontour/v1alpha1/contourconfig.go
index 08fd76a23fc..db8fe9cdf4d 100644
--- a/apis/projectcontour/v1alpha1/contourconfig.go
+++ b/apis/projectcontour/v1alpha1/contourconfig.go
@@ -341,6 +341,12 @@ type EnvoyListenerConfig struct {
// +optional
UseProxyProto *bool `json:"useProxyProtocol,omitempty"`
+ // DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ // Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ // Contour's default is false.
+ // +optional
+ DisableCompression bool `json:"disableCompression,omitempty"`
+
// DisableAllowChunkedLength disables the RFC-compliant Envoy behavior to
// strip the "Content-Length" header if "Transfer-Encoding: chunked" is
// also set. This is an emergency off-switch to revert back to Envoy's
diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go
index e3cdd0adeeb..0af00921b58 100644
--- a/cmd/contour/serve.go
+++ b/cmd/contour/serve.go
@@ -447,6 +447,7 @@ func (s *Server) doServe() error {
}
listenerConfig := xdscache_v3.ListenerConfig{
+ DisableCompression: contourConfiguration.Envoy.Listener.DisableCompression,
UseProxyProto: *contourConfiguration.Envoy.Listener.UseProxyProto,
HTTPAccessLog: contourConfiguration.Envoy.HTTPListener.AccessLog,
HTTPSAccessLog: contourConfiguration.Envoy.HTTPSListener.AccessLog,
diff --git a/cmd/contour/servecontext.go b/cmd/contour/servecontext.go
index 3a1057b6479..67451bc0ad7 100644
--- a/cmd/contour/servecontext.go
+++ b/cmd/contour/servecontext.go
@@ -519,6 +519,7 @@ func (ctx *serveContext) convertToContourConfigurationSpec() contour_v1alpha1.Co
Envoy: &contour_v1alpha1.EnvoyConfig{
Listener: &contour_v1alpha1.EnvoyListenerConfig{
UseProxyProto: &ctx.useProxyProto,
+ DisableCompression: ctx.Config.DisableCompression,
DisableAllowChunkedLength: &ctx.Config.DisableAllowChunkedLength,
DisableMergeSlashes: &ctx.Config.DisableMergeSlashes,
ServerHeaderTransformation: serverHeaderTransformation,
diff --git a/cmd/contour/servecontext_test.go b/cmd/contour/servecontext_test.go
index 766a2f0af83..27335f40913 100644
--- a/cmd/contour/servecontext_test.go
+++ b/cmd/contour/servecontext_test.go
@@ -892,12 +892,14 @@ func TestConvertServeContext(t *testing.T) {
ctx.Config.Listener.MaxRequestsPerIOCycle = ptr.To(uint32(10))
ctx.Config.Listener.HTTP2MaxConcurrentStreams = ptr.To(uint32(30))
ctx.Config.Listener.MaxConnectionsPerListener = ptr.To(uint32(50))
+ ctx.Config.DisableCompression = true
return ctx
},
getContourConfiguration: func(cfg contour_v1alpha1.ContourConfigurationSpec) contour_v1alpha1.ContourConfigurationSpec {
cfg.Envoy.Listener.MaxRequestsPerIOCycle = ptr.To(uint32(10))
cfg.Envoy.Listener.HTTP2MaxConcurrentStreams = ptr.To(uint32(30))
cfg.Envoy.Listener.MaxConnectionsPerListener = ptr.To(uint32(50))
+ cfg.Envoy.Listener.DisableCompression = true
return cfg
},
},
diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml
index 00aebca5e95..83ff28dbfeb 100644
--- a/examples/contour/01-crds.yaml
+++ b/examples/contour/01-crds.yaml
@@ -293,6 +293,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4067,6 +4073,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml
index b7663b38be1..6ebab58bdc5 100644
--- a/examples/render/contour-deployment.yaml
+++ b/examples/render/contour-deployment.yaml
@@ -513,6 +513,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4287,6 +4293,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml
index 91a8ac8a800..8d623f73656 100644
--- a/examples/render/contour-gateway-provisioner.yaml
+++ b/examples/render/contour-gateway-provisioner.yaml
@@ -304,6 +304,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4078,6 +4084,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml
index 0d70b6c4c4f..c9df01c0e82 100644
--- a/examples/render/contour-gateway.yaml
+++ b/examples/render/contour-gateway.yaml
@@ -329,6 +329,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4103,6 +4109,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml
index b44c26538bc..3f80b104e89 100644
--- a/examples/render/contour.yaml
+++ b/examples/render/contour.yaml
@@ -513,6 +513,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4287,6 +4293,12 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
+ disableCompression:
+ description: |-
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+ Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Contour's default is false.
+ type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/internal/envoy/v3/listener.go b/internal/envoy/v3/listener.go
index 5d1f2c233ce..fc57b436645 100644
--- a/internal/envoy/v3/listener.go
+++ b/internal/envoy/v3/listener.go
@@ -188,6 +188,7 @@ type httpConnectionManagerBuilder struct {
maxRequestsPerConnection *uint32
http2MaxConcurrentStreams *uint32
enableWebsockets bool
+ disableCompression bool
}
func (b *httpConnectionManagerBuilder) EnableWebsockets(enable bool) *httpConnectionManagerBuilder {
@@ -271,6 +272,11 @@ func (b *httpConnectionManagerBuilder) MergeSlashes(enabled bool) *httpConnectio
return b
}
+func (b *httpConnectionManagerBuilder) DisableCompression(disabled bool) *httpConnectionManagerBuilder {
+ b.disableCompression = disabled
+ return b
+}
+
func (b *httpConnectionManagerBuilder) ServerHeaderTransformation(value contour_v1alpha1.ServerHeaderTransformationType) *httpConnectionManagerBuilder {
switch value {
case contour_v1alpha1.OverwriteServerHeader:
@@ -308,34 +314,38 @@ func (b *httpConnectionManagerBuilder) DefaultFilters() *httpConnectionManagerBu
// Add a default set of ordered http filters.
// The names are not required to match anything and are
// identified by the TypeURL of each filter.
- b.filters = append(b.filters,
- &envoy_filter_network_http_connection_manager_v3.HttpFilter{
- Name: CompressorFilterName,
- ConfigType: &envoy_filter_network_http_connection_manager_v3.HttpFilter_TypedConfig{
- TypedConfig: protobuf.MustMarshalAny(&envoy_filter_http_compressor_v3.Compressor{
- CompressorLibrary: &envoy_config_core_v3.TypedExtensionConfig{
- Name: "gzip",
- TypedConfig: protobuf.MustMarshalAny(
- &envoy_compression_gzip_compressor_v3.Gzip{},
- ),
- },
- ResponseDirectionConfig: &envoy_filter_http_compressor_v3.Compressor_ResponseDirectionConfig{
- CommonConfig: &envoy_filter_http_compressor_v3.Compressor_CommonDirectionConfig{
- ContentType: []string{
- // Default content-types https://github.com/envoyproxy/envoy/blob/e74999dbdb12aa4d6b7a5d62d51731ea86bf72be/source/extensions/filters/http/compressor/compressor_filter.cc#L35-L38
- "text/html", "text/plain", "text/css", "application/javascript", "application/x-javascript",
- "text/javascript", "text/x-javascript", "text/ecmascript", "text/js", "text/jscript",
- "text/x-js", "application/ecmascript", "application/x-json", "application/xml",
- "application/json", "image/svg+xml", "text/xml", "application/xhtml+xml",
- // Additional content-types for grpc-web https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
- "application/grpc-web", "application/grpc-web+proto", "application/grpc-web+json", "application/grpc-web+thrift",
- "application/grpc-web-text", "application/grpc-web-text+proto", "application/grpc-web-text+thrift",
+ if !b.disableCompression {
+ // If compression is enabled add compressor filter
+ b.filters = append(b.filters,
+ &envoy_filter_network_http_connection_manager_v3.HttpFilter{
+ Name: CompressorFilterName,
+ ConfigType: &envoy_filter_network_http_connection_manager_v3.HttpFilter_TypedConfig{
+ TypedConfig: protobuf.MustMarshalAny(&envoy_filter_http_compressor_v3.Compressor{
+ CompressorLibrary: &envoy_config_core_v3.TypedExtensionConfig{
+ Name: "gzip",
+ TypedConfig: protobuf.MustMarshalAny(
+ &envoy_compression_gzip_compressor_v3.Gzip{},
+ ),
+ },
+ ResponseDirectionConfig: &envoy_filter_http_compressor_v3.Compressor_ResponseDirectionConfig{
+ CommonConfig: &envoy_filter_http_compressor_v3.Compressor_CommonDirectionConfig{
+ ContentType: []string{
+ // Default content-types https://github.com/envoyproxy/envoy/blob/e74999dbdb12aa4d6b7a5d62d51731ea86bf72be/source/extensions/filters/http/compressor/compressor_filter.cc#L35-L38
+ "text/html", "text/plain", "text/css", "application/javascript", "application/x-javascript",
+ "text/javascript", "text/x-javascript", "text/ecmascript", "text/js", "text/jscript",
+ "text/x-js", "application/ecmascript", "application/x-json", "application/xml",
+ "application/json", "image/svg+xml", "text/xml", "application/xhtml+xml",
+ // Additional content-types for grpc-web https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
+ "application/grpc-web", "application/grpc-web+proto", "application/grpc-web+json", "application/grpc-web+thrift",
+ "application/grpc-web-text", "application/grpc-web-text+proto", "application/grpc-web-text+thrift",
+ },
},
},
- },
- }),
- },
- },
+ }),
+ },
+ })
+ }
+ b.filters = append(b.filters,
&envoy_filter_network_http_connection_manager_v3.HttpFilter{
Name: GRPCWebFilterName,
ConfigType: &envoy_filter_network_http_connection_manager_v3.HttpFilter_TypedConfig{
diff --git a/internal/featuretests/v3/compression_test.go b/internal/featuretests/v3/compression_test.go
new file mode 100644
index 00000000000..af5e71f6f6a
--- /dev/null
+++ b/internal/featuretests/v3/compression_test.go
@@ -0,0 +1,121 @@
+// Copyright Project Contour Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package v3
+
+import (
+ envoy_service_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
+ core_v1 "k8s.io/api/core/v1"
+ meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "testing"
+
+ contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1"
+ contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
+ envoy_v3 "github.com/projectcontour/contour/internal/envoy/v3"
+ "github.com/projectcontour/contour/internal/fixture"
+ xdscache_v3 "github.com/projectcontour/contour/internal/xdscache/v3"
+)
+
+func TestDefaultCompression(t *testing.T) {
+ withDefaultListenerConfig := func(conf *xdscache_v3.ListenerConfig) {
+ }
+
+ rh, c, done := setup(t, withDefaultListenerConfig)
+ defer done()
+
+ s1 := fixture.NewService("backend").
+ WithPorts(core_v1.ServicePort{Name: "http", Port: 80})
+ rh.OnAdd(s1)
+
+ hp1 := &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "simple",
+ Namespace: s1.Namespace,
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: "example.com",
+ },
+ Routes: []contour_v1.Route{{
+ Conditions: matchconditions(prefixMatchCondition("/")),
+ Services: []contour_v1.Service{{
+ Name: s1.Name,
+ Port: 80,
+ }},
+ }},
+ },
+ }
+ rh.OnAdd(hp1)
+
+ httpListener := defaultHTTPListener()
+ httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
+ RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
+ MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ )
+
+ c.Request(listenerType, xdscache_v3.ENVOY_HTTP_LISTENER).Equals(&envoy_service_discovery_v3.DiscoveryResponse{
+ TypeUrl: listenerType,
+ Resources: resources(t, httpListener),
+ })
+}
+
+func TestDisableCompression(t *testing.T) {
+ withDisableCompression := func(conf *xdscache_v3.ListenerConfig) {
+ conf.DisableCompression = true
+ }
+
+ rh, c, done := setup(t, withDisableCompression)
+ defer done()
+
+ s1 := fixture.NewService("backend").
+ WithPorts(core_v1.ServicePort{Name: "http", Port: 80})
+ rh.OnAdd(s1)
+
+ hp1 := &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "simple",
+ Namespace: s1.Namespace,
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: "example.com",
+ },
+ Routes: []contour_v1.Route{{
+ Conditions: matchconditions(prefixMatchCondition("/")),
+ Services: []contour_v1.Service{{
+ Name: s1.Name,
+ Port: 80,
+ }},
+ }},
+ },
+ }
+ rh.OnAdd(hp1)
+
+ httpListener := defaultHTTPListener()
+ httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
+ DisableCompression(true).
+ RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
+ MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ )
+
+ c.Request(listenerType, xdscache_v3.ENVOY_HTTP_LISTENER).Equals(&envoy_service_discovery_v3.DiscoveryResponse{
+ TypeUrl: listenerType,
+ Resources: resources(t, httpListener),
+ })
+}
diff --git a/internal/xdscache/v3/listener.go b/internal/xdscache/v3/listener.go
index 975c0654743..23869ea2e81 100644
--- a/internal/xdscache/v3/listener.go
+++ b/internal/xdscache/v3/listener.go
@@ -66,6 +66,11 @@ type ListenerConfig struct {
// If not set, defaults to false.
UseProxyProto bool
+ // DisableCompression configures listener to ignore adding compression filter as part of the defaultFilters
+ // Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ // If not set, defaults to false.
+ DisableCompression bool
+
// MinimumTLSVersion defines the minimum TLS protocol version the proxy should accept.
MinimumTLSVersion string
@@ -393,6 +398,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
// order for the HTTPS virtualhosts.
if len(listener.VirtualHosts) > 0 {
cm := envoy_v3.HTTPConnectionManagerBuilder().
+ DisableCompression(cfg.DisableCompression).
Codec(envoy_v3.CodecForVersions(cfg.DefaultHTTPVersions...)).
DefaultFilters().
RouteConfigName(httpRouteConfigName(listener)).
@@ -465,6 +471,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
// Contour versions since the metrics prefix will be
// coded into monitoring dashboards.
cm := envoy_v3.HTTPConnectionManagerBuilder().
+ DisableCompression(cfg.DisableCompression).
Codec(envoy_v3.CodecForVersions(cfg.DefaultHTTPVersions...)).
AddFilter(envoy_v3.FilterMisdirectedRequests(vh.VirtualHost.Name)).
DefaultFilters().
@@ -544,6 +551,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
)
cm := envoy_v3.HTTPConnectionManagerBuilder().
+ DisableCompression(cfg.DisableCompression).
DefaultFilters().
RouteConfigName(fallbackCertRouteConfigName(listener)).
MetricsPrefix(listener.Name).
diff --git a/internal/xdscache/v3/listener_test.go b/internal/xdscache/v3/listener_test.go
index 095f248210a..1b85ab968b0 100644
--- a/internal/xdscache/v3/listener_test.go
+++ b/internal/xdscache/v3/listener_test.go
@@ -3074,6 +3074,48 @@ func TestListenerVisit(t *testing.T) {
SocketOptions: envoy_v3.NewSocketOptions().TCPKeepalive().Build(),
}),
},
+ "httpproxy with DisableCompression set in listener config": {
+ ListenerConfig: ListenerConfig{
+ DisableCompression: true,
+ },
+ objs: []any{
+ &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "simple",
+ Namespace: "default",
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: "www.example.com",
+ },
+ Routes: []contour_v1.Route{{
+ Conditions: []contour_v1.MatchCondition{{
+ Prefix: "/",
+ }},
+ Services: []contour_v1.Service{{
+ Name: "backend",
+ Port: 80,
+ }},
+ }},
+ },
+ },
+ service,
+ },
+ want: listenermap(&envoy_config_listener_v3.Listener{
+ Name: ENVOY_HTTP_LISTENER,
+ Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
+ FilterChains: envoy_v3.FilterChains(
+ envoy_v3.HTTPConnectionManagerBuilder().
+ DisableCompression(true).
+ RouteConfigName(ENVOY_HTTP_LISTENER).
+ MetricsPrefix(ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ ),
+ SocketOptions: envoy_v3.NewSocketOptions().TCPKeepalive().Build(),
+ }),
+ },
"httpsproxy with PerConnectionBufferLimitBytes set in listener config": {
ListenerConfig: ListenerConfig{
PerConnectionBufferLimitBytes: ptr.To(uint32(32768)),
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
index b4c7aaa3869..21bfb0bf794 100644
--- a/pkg/config/parameters.go
+++ b/pkg/config/parameters.go
@@ -649,6 +649,11 @@ type Parameters struct {
// which strips duplicate slashes from request URL paths.
DisableMergeSlashes bool `yaml:"disableMergeSlashes,omitempty"`
+ // DisableCompression disables GZIP compression HTTP filter
+ // Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ // If not set, defaults to false.
+ DisableCompression bool `yaml:"disableCompression,omitempty"`
+
// Defines the action to be applied to the Server header on the response path.
// When configured as overwrite, overwrites any Server header with "envoy".
// When configured as append_if_absent, if a Server header is present, pass it through, otherwise set it to "envoy".
diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html
index b9ba8f7400d..6c7c52e6cf5 100644
--- a/site/content/docs/main/config/api-reference.html
+++ b/site/content/docs/main/config/api-reference.html
@@ -6800,6 +6800,21 @@ EnvoyListenerConfig
+disableCompression
+
+
+bool
+
+ |
+
+(Optional)
+ DisableCompression disables GZIP compression HTTP filter from the default Listener filters
+Setting this true will enable Envoy skip “Accept-Encoding: gzip,deflate” request header and always return uncompressed response
+Contour’s default is false.
+ |
+
+
+
disableAllowChunkedLength
diff --git a/test/e2e/httpproxy/envoy_compression_test.go b/test/e2e/httpproxy/envoy_compression_test.go
new file mode 100644
index 00000000000..06ae85bbd41
--- /dev/null
+++ b/test/e2e/httpproxy/envoy_compression_test.go
@@ -0,0 +1,79 @@
+// Copyright Project Contour Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build e2e
+
+package httpproxy
+
+import (
+ "fmt"
+ . "github.com/onsi/ginkgo/v2"
+ "github.com/stretchr/testify/require"
+ meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "net/http"
+
+ contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1"
+ "github.com/projectcontour/contour/test/e2e"
+)
+
+func testEnvoyDisableCompression(namespace string, enabled bool) {
+ testSpec := "responses compressed with default settings"
+ if enabled {
+ testSpec = "responses are plaintext when compression disabled"
+ }
+ FSpecify(testSpec, func() {
+ resp := "minimum_text_to_enable_gzipminimum_text_to_enable_gzipminimum_text_to_enable_gzipminimum_text_to_enable_gzipminimum_text_to_enable_gzipminimum_text_to_enable_gzip"
+ p := &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "direct-response",
+ Namespace: namespace,
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: fmt.Sprintf("%s-fqdn.projectcontour.io", namespace),
+ }, Routes: []contour_v1.Route{
+ {
+ Conditions: []contour_v1.MatchCondition{{
+ Prefix: "/directresponse",
+ }},
+ DirectResponsePolicy: &contour_v1.HTTPDirectResponsePolicy{
+ StatusCode: 200,
+ Body: resp,
+ },
+ }},
+ },
+ }
+ require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid))
+
+ // Send HTTP request, we will check backend connection was over HTTPS.
+ res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{
+ Path: "/directresponse",
+ Host: p.Spec.VirtualHost.Fqdn,
+ RequestOpts: []func(*http.Request){
+ e2e.OptSetHeaders(map[string]string{
+ "Accept-Encoding": "gzip, deflate",
+ }),
+ },
+ Condition: e2e.HasStatusCode(200),
+ })
+ require.NotNil(f.T(), res, "request never succeeded")
+ require.Truef(f.T(), ok, "expected 200 response code, got %d", res.StatusCode)
+ fmt.Printf("response: %+v\n", res.Headers)
+ if enabled {
+ require.NotContains(f.T(), res.Headers["Content-Encoding"], "gzip", "expected plain text")
+ return
+ }
+ require.Contains(f.T(), res.Headers["Content-Encoding"], "gzip", "expected plain text")
+
+ })
+}
diff --git a/test/e2e/httpproxy/httpproxy_test.go b/test/e2e/httpproxy/httpproxy_test.go
index ff01a0af897..42edb73bd9c 100644
--- a/test/e2e/httpproxy/httpproxy_test.go
+++ b/test/e2e/httpproxy/httpproxy_test.go
@@ -388,6 +388,19 @@ var _ = Describe("HTTPProxy", func() {
})
})
+ f.NamespacedTest("httpproxy-default-compression", func(namespace string) {
+ testEnvoyDisableCompression(namespace, false)
+ })
+
+ f.NamespacedTest("httpproxy-disable-compression", func(namespace string) {
+ Context("with compression disabled", func() {
+ BeforeEach(func() {
+ contourConfig.DisableCompression = true
+ })
+ testEnvoyDisableCompression(namespace, true)
+ })
+ })
+
f.NamespacedTest("httpproxy-external-auth", testExternalAuth)
f.NamespacedTest("httpproxy-http-health-checks", testHTTPHealthChecks)
From 7ddb6f02363b96044c2445ab5a346b7dae41e84f Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Thu, 22 Aug 2024 17:46:08 +0100
Subject: [PATCH 03/30] This fixes linter nag parameter 'conf' seems to be
unused
Co-authored-by: Tero Saarni
Signed-off-by: Geoff Macartney
---
internal/featuretests/v3/compression_test.go | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/internal/featuretests/v3/compression_test.go b/internal/featuretests/v3/compression_test.go
index af5e71f6f6a..4aea4b7e1cb 100644
--- a/internal/featuretests/v3/compression_test.go
+++ b/internal/featuretests/v3/compression_test.go
@@ -27,10 +27,7 @@ import (
)
func TestDefaultCompression(t *testing.T) {
- withDefaultListenerConfig := func(conf *xdscache_v3.ListenerConfig) {
- }
-
- rh, c, done := setup(t, withDefaultListenerConfig)
+ rh, c, done := setup(t)
defer done()
s1 := fixture.NewService("backend").
From 8df07e29b4563673fb07ba94871c6bef11c1e685 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Thu, 22 Aug 2024 17:47:50 +0100
Subject: [PATCH 04/30] This fixes linter nag File is not gci-ed with ...
Co-authored-by: Tero Saarni
Signed-off-by: Geoff Macartney
---
test/e2e/httpproxy/envoy_compression_test.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/test/e2e/httpproxy/envoy_compression_test.go b/test/e2e/httpproxy/envoy_compression_test.go
index 06ae85bbd41..3224d0469cd 100644
--- a/test/e2e/httpproxy/envoy_compression_test.go
+++ b/test/e2e/httpproxy/envoy_compression_test.go
@@ -17,10 +17,11 @@ package httpproxy
import (
"fmt"
+ "net/http"
+
. "github.com/onsi/ginkgo/v2"
"github.com/stretchr/testify/require"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "net/http"
contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1"
"github.com/projectcontour/contour/test/e2e"
From 100bf40de4dad160b8df57922194625d5db35218 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Thu, 22 Aug 2024 17:48:27 +0100
Subject: [PATCH 05/30] This fixes linter nag File is not gci-ed with ...
Co-authored-by: Tero Saarni
Signed-off-by: Geoff Macartney
---
internal/featuretests/v3/compression_test.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/internal/featuretests/v3/compression_test.go b/internal/featuretests/v3/compression_test.go
index 4aea4b7e1cb..1c16eaaa77b 100644
--- a/internal/featuretests/v3/compression_test.go
+++ b/internal/featuretests/v3/compression_test.go
@@ -14,10 +14,11 @@
package v3
import (
+ "testing"
+
envoy_service_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
core_v1 "k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "testing"
contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1"
contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
From 56e4ee7442436f6c59bd810ac78fcf1125d1e447 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Thu, 22 Aug 2024 17:49:01 +0100
Subject: [PATCH 06/30] This fixes linter nag File is not gofumpt-ed with
-extra
Co-authored-by: Tero Saarni
Signed-off-by: Geoff Macartney
---
test/e2e/httpproxy/envoy_compression_test.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/test/e2e/httpproxy/envoy_compression_test.go b/test/e2e/httpproxy/envoy_compression_test.go
index 3224d0469cd..44ff5d66987 100644
--- a/test/e2e/httpproxy/envoy_compression_test.go
+++ b/test/e2e/httpproxy/envoy_compression_test.go
@@ -51,7 +51,8 @@ func testEnvoyDisableCompression(namespace string, enabled bool) {
StatusCode: 200,
Body: resp,
},
- }},
+ },
+ },
},
}
require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid))
From 548981ee0ee5b3cfc4d4d619f647de3b4bd8588a Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Thu, 22 Aug 2024 17:49:54 +0100
Subject: [PATCH 07/30] This fixes linter nag File is not gofumpt-ed with
-extra
Co-authored-by: Tero Saarni
Signed-off-by: Geoff Macartney
---
test/e2e/httpproxy/envoy_compression_test.go | 1 -
1 file changed, 1 deletion(-)
diff --git a/test/e2e/httpproxy/envoy_compression_test.go b/test/e2e/httpproxy/envoy_compression_test.go
index 44ff5d66987..9fd81366f4c 100644
--- a/test/e2e/httpproxy/envoy_compression_test.go
+++ b/test/e2e/httpproxy/envoy_compression_test.go
@@ -76,6 +76,5 @@ func testEnvoyDisableCompression(namespace string, enabled bool) {
return
}
require.Contains(f.T(), res.Headers["Content-Encoding"], "gzip", "expected plain text")
-
})
}
From 934ca4885b8371d3b541fdfd9b448007315fbf20 Mon Sep 17 00:00:00 2001
From: geomacy
Date: Wed, 21 Aug 2024 17:53:15 +0100
Subject: [PATCH 08/30] Fix table borders
This change is solely a formatting change and does not change any of the text of the table
Signed-off-by: Geoff Macartney
---
site/content/docs/main/configuration.md | 62 ++++++++++++-------------
1 file changed, 31 insertions(+), 31 deletions(-)
diff --git a/site/content/docs/main/configuration.md b/site/content/docs/main/configuration.md
index 5277ab79e38..c13583b3b91 100644
--- a/site/content/docs/main/configuration.md
+++ b/site/content/docs/main/configuration.md
@@ -72,37 +72,37 @@ The Contour configuration file is optional.
In its absence, Contour will operate with reasonable defaults.
Where Contour settings can also be specified with command-line flags, the command-line value takes precedence over the configuration file.
-| Field Name | Type | Default | Description |
-|---------------------------| ---------------------- |------------------------------------------------------------------------------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| accesslog-format | string | `envoy` | This key sets the global [access log format][2] for Envoy. Valid options are `envoy` or `json`. |
-| accesslog-format-string | string | None | If present, this specifies custom access log format for Envoy. See [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage) for more information about the syntax. This field only has effect if `accesslog-format` is `envoy` |
-| accesslog-level | string | `info` | This field specifies the verbosity level of the access log. Valid options are `info` (default, all requests are logged), `error` (all non-success, i.e. 300+ response code, requests are logged), `critical` (all server error, i.e. 500+ response code, requests are logged) and `disabled`. |
-| debug | boolean | `false` | Enables debug logging. |
-| default-http-versions | string array | HTTP/1.1 HTTP/2 | This array specifies the HTTP versions that Contour should program Envoy to serve. HTTP versions are specified as strings of the form "HTTP/x", where "x" represents the version number. |
-| disableAllowChunkedLength | boolean | `false` | If this field is true, Contour will disable the RFC-compliant Envoy behavior to strip the `Content-Length` header if `Transfer-Encoding: chunked` is also set. This is an emergency off-switch to revert back to Envoy's default behavior in case of failures.
-| disableMergeSlashes | boolean | `false` | This field disables Envoy's non-standard merge_slashes path transformation behavior that strips duplicate slashes from request URL paths.
-| serverHeaderTransformation | string | `overwrite` | This field defines the action to be applied to the Server header on the response path. Values: `overwrite` (default), `append_if_absent`, `pass_through`
-| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. |
-| envoy-service-name | string | `envoy` | This sets the service name that will be inspected for address details to be applied to Ingress objects. |
-| envoy-service-namespace | string | `projectcontour` | This sets the namespace of the service that will be inspected for address details to be applied to Ingress objects. If the `CONTOUR_NAMESPACE` environment variable is present, Contour will populate this field with its value. |
-| ingress-status-address | string | None | If present, this specifies the address that will be copied into the Ingress status for each Ingress that Contour manages. It is exclusive with `envoy-service-name` and `envoy-service-namespace`. |
-| incluster | boolean | `false` | This field specifies that Contour is running in a Kubernetes cluster and should use the in-cluster client access configuration. |
-| json-fields | string array | [fields][5] | This is the list the field names to include in the JSON [access log format][2]. This field only has effect if `accesslog-format` is `json`. |
-| kubeconfig | string | `$HOME/.kube/config` | Path to a Kubernetes [kubeconfig file][3] for when Contour is executed outside a cluster. |
-| kubernetesClientQPS | float32 | | QPS allowed for the Kubernetes client. |
-| kubernetesClientBurst | int | | Burst allowed for the Kubernetes client. |
-| policy | PolicyConfig | | The default [policy configuration](#policy-configuration). |
-| tls | TLS | | The default [TLS configuration](#tls-configuration). |
-| timeouts | TimeoutConfig | | The [timeout configuration](#timeout-configuration). |
-| cluster | ClusterConfig | | The [cluster configuration](#cluster-configuration). |
-| network | NetworkConfig | | The [network configuration](#network-configuration). |
-| listener | ListenerConfig | | The [listener configuration](#listener-configuration). |
-| server | ServerConfig | | The [server configuration](#server-configuration) for `contour serve` command. |
-| gateway | GatewayConfig | | The [gateway-api Gateway configuration](#gateway-configuration). |
-| rateLimitService | RateLimitServiceConfig | | The [rate limit service configuration](#rate-limit-service-configuration). |
-| enableExternalNameService | boolean | `false` | Enable ExternalName Service processing. Enabling this has security implications. Please see the [advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for more details. |
-| metrics | MetricsParameters | | The [metrics configuration](#metrics-configuration) |
-| featureFlags | string array | `[]` | Defines the toggle to enable new contour features. Available toggles are: 1. `useEndpointSlices` - configures contour to fetch endpoint data from k8s endpoint slices. |
+| Field Name | Type | Default | Description |
+|----------------------------|------------------------|------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| accesslog-format | string | `envoy` | This key sets the global [access log format][2] for Envoy. Valid options are `envoy` or `json`. |
+| accesslog-format-string | string | None | If present, this specifies custom access log format for Envoy. See [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage) for more information about the syntax. This field only has effect if `accesslog-format` is `envoy` |
+| accesslog-level | string | `info` | This field specifies the verbosity level of the access log. Valid options are `info` (default, all requests are logged), `error` (all non-success, i.e. 300+ response code, requests are logged), `critical` (all server error, i.e. 500+ response code, requests are logged) and `disabled`. |
+| debug | boolean | `false` | Enables debug logging. |
+| default-http-versions | string array | HTTP/1.1 HTTP/2 | This array specifies the HTTP versions that Contour should program Envoy to serve. HTTP versions are specified as strings of the form "HTTP/x", where "x" represents the version number. |
+| disableAllowChunkedLength | boolean | `false` | If this field is true, Contour will disable the RFC-compliant Envoy behavior to strip the `Content-Length` header if `Transfer-Encoding: chunked` is also set. This is an emergency off-switch to revert back to Envoy's default behavior in case of failures. |
+| disableMergeSlashes | boolean | `false` | This field disables Envoy's non-standard merge_slashes path transformation behavior that strips duplicate slashes from request URL paths. |
+| serverHeaderTransformation | string | `overwrite` | This field defines the action to be applied to the Server header on the response path. Values: `overwrite` (default), `append_if_absent`, `pass_through` |
+| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. |
+| envoy-service-name | string | `envoy` | This sets the service name that will be inspected for address details to be applied to Ingress objects. |
+| envoy-service-namespace | string | `projectcontour` | This sets the namespace of the service that will be inspected for address details to be applied to Ingress objects. If the `CONTOUR_NAMESPACE` environment variable is present, Contour will populate this field with its value. |
+| ingress-status-address | string | None | If present, this specifies the address that will be copied into the Ingress status for each Ingress that Contour manages. It is exclusive with `envoy-service-name` and `envoy-service-namespace`. |
+| incluster | boolean | `false` | This field specifies that Contour is running in a Kubernetes cluster and should use the in-cluster client access configuration. |
+| json-fields | string array | [fields][5] | This is the list the field names to include in the JSON [access log format][2]. This field only has effect if `accesslog-format` is `json`. |
+| kubeconfig | string | `$HOME/.kube/config` | Path to a Kubernetes [kubeconfig file][3] for when Contour is executed outside a cluster. |
+| kubernetesClientQPS | float32 | | QPS allowed for the Kubernetes client. |
+| kubernetesClientBurst | int | | Burst allowed for the Kubernetes client. |
+| policy | PolicyConfig | | The default [policy configuration](#policy-configuration). |
+| tls | TLS | | The default [TLS configuration](#tls-configuration). |
+| timeouts | TimeoutConfig | | The [timeout configuration](#timeout-configuration). |
+| cluster | ClusterConfig | | The [cluster configuration](#cluster-configuration). |
+| network | NetworkConfig | | The [network configuration](#network-configuration). |
+| listener | ListenerConfig | | The [listener configuration](#listener-configuration). |
+| server | ServerConfig | | The [server configuration](#server-configuration) for `contour serve` command. |
+| gateway | GatewayConfig | | The [gateway-api Gateway configuration](#gateway-configuration). |
+| rateLimitService | RateLimitServiceConfig | | The [rate limit service configuration](#rate-limit-service-configuration). |
+| enableExternalNameService | boolean | `false` | Enable ExternalName Service processing. Enabling this has security implications. Please see the [advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for more details. |
+| metrics | MetricsParameters | | The [metrics configuration](#metrics-configuration) |
+| featureFlags | string array | `[]` | Defines the toggle to enable new contour features. Available toggles are: 1. `useEndpointSlices` - configures contour to fetch endpoint data from k8s endpoint slices. |
### TLS Configuration
From 2efb693d8230eeef88cdb0a553d7d3842f72a69d Mon Sep 17 00:00:00 2001
From: geomacy
Date: Wed, 21 Aug 2024 17:57:38 +0100
Subject: [PATCH 09/30] Add disableCompression flag to configuration docs.
Signed-off-by: Geoff Macartney
---
site/content/docs/main/configuration.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/site/content/docs/main/configuration.md b/site/content/docs/main/configuration.md
index c13583b3b91..588ce55be29 100644
--- a/site/content/docs/main/configuration.md
+++ b/site/content/docs/main/configuration.md
@@ -80,6 +80,7 @@ Where Contour settings can also be specified with command-line flags, the comman
| debug | boolean | `false` | Enables debug logging. |
| default-http-versions | string array | HTTP/1.1 HTTP/2 | This array specifies the HTTP versions that Contour should program Envoy to serve. HTTP versions are specified as strings of the form "HTTP/x", where "x" represents the version number. |
| disableAllowChunkedLength | boolean | `false` | If this field is true, Contour will disable the RFC-compliant Envoy behavior to strip the `Content-Length` header if `Transfer-Encoding: chunked` is also set. This is an emergency off-switch to revert back to Envoy's default behavior in case of failures. |
+| disableCompression | boolean | `false` | This disables GZIP compression HTTP filter from the default Listener filters. Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response. |
| disableMergeSlashes | boolean | `false` | This field disables Envoy's non-standard merge_slashes path transformation behavior that strips duplicate slashes from request URL paths. |
| serverHeaderTransformation | string | `overwrite` | This field defines the action to be applied to the Server header on the response path. Values: `overwrite` (default), `append_if_absent`, `pass_through` |
| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. |
From b0cfe71408ff38baebede555600871fd9ef7f0af Mon Sep 17 00:00:00 2001
From: geomacy
Date: Thu, 22 Aug 2024 17:26:27 +0100
Subject: [PATCH 10/30] add changelog file
Signed-off-by: Geoff Macartney
---
changelogs/unreleased/6546-chaosbox-small.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 changelogs/unreleased/6546-chaosbox-small.md
diff --git a/changelogs/unreleased/6546-chaosbox-small.md b/changelogs/unreleased/6546-chaosbox-small.md
new file mode 100644
index 00000000000..18f2b2138e1
--- /dev/null
+++ b/changelogs/unreleased/6546-chaosbox-small.md
@@ -0,0 +1 @@
+Add disableCompression boolean flag to disable GZIP compression HTTP filter from the default Listener filters.
From 7e843b7a1fddb6b56d65a19385a052008250f4d0 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Sat, 7 Sep 2024 23:35:44 +0100
Subject: [PATCH 11/30] rework as --compression flag with options gzip, brotli,
zstd, disabled
Signed-off-by: Geoff Macartney
---
apis/projectcontour/v1alpha1/compression.go | 41 +++++
.../v1alpha1/compression_test.go | 32 ++++
apis/projectcontour/v1alpha1/contourconfig.go | 8 +-
changelogs/unreleased/6546-chaosbox-small.md | 2 +-
cmd/contour/serve.go | 5 +-
cmd/contour/servecontext.go | 14 +-
cmd/contour/servecontext_test.go | 5 +-
examples/contour/01-crds.yaml | 24 +--
examples/render/contour-deployment.yaml | 24 +--
.../render/contour-gateway-provisioner.yaml | 24 +--
examples/render/contour-gateway.yaml | 24 +--
examples/render/contour.yaml | 24 +--
.../contourconfig/contourconfiguration.go | 1 +
.../contourconfiguration_test.go | 5 +-
internal/envoy/v3/listener.go | 31 +++-
internal/featuretests/v3/compression_test.go | 100 +++++++++-
internal/xdscache/v3/listener.go | 14 +-
internal/xdscache/v3/listener_test.go | 174 +++++++++++++++++-
pkg/config/parameters.go | 30 ++-
pkg/config/parameters_test.go | 1 +
.../docs/main/config/api-reference.html | 41 ++++-
site/content/docs/main/configuration.md | 64 +++----
test/e2e/deployment.go | 2 +-
test/e2e/fixtures.go | 1 +
test/e2e/httpproxy/envoy_compression_test.go | 50 ++---
test/e2e/httpproxy/httpproxy_test.go | 27 ++-
26 files changed, 611 insertions(+), 157 deletions(-)
create mode 100644 apis/projectcontour/v1alpha1/compression.go
create mode 100644 apis/projectcontour/v1alpha1/compression_test.go
diff --git a/apis/projectcontour/v1alpha1/compression.go b/apis/projectcontour/v1alpha1/compression.go
new file mode 100644
index 00000000000..9c850934eda
--- /dev/null
+++ b/apis/projectcontour/v1alpha1/compression.go
@@ -0,0 +1,41 @@
+// Copyright Project Contour Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package v1alpha1
+
+import "fmt"
+
+type EnvoyCompressionType string
+
+func (c EnvoyCompressionType) Validate() error {
+ switch c {
+ case BrotliCompression, DisabledCompression, GzipCompression, ZstdCompression:
+ return nil
+ default:
+ return fmt.Errorf("invalid compression type: %q", c)
+ }
+}
+
+const (
+ // BrotliCompression specifies brotli as the default HTTP filter chain compression mechanism
+ BrotliCompression EnvoyCompressionType = "brotli"
+
+ // DisabledCompression specifies that there will be no compression in the default HTTP filter chain
+ DisabledCompression EnvoyCompressionType = "disabled"
+
+ // GzipCompression specifies gzip as the default HTTP filter chain compression mechanism
+ GzipCompression EnvoyCompressionType = "gzip"
+
+ // ZstdCompression specifies zstd as the default HTTP filter chain compression mechanism
+ ZstdCompression EnvoyCompressionType = "zstd"
+)
diff --git a/apis/projectcontour/v1alpha1/compression_test.go b/apis/projectcontour/v1alpha1/compression_test.go
new file mode 100644
index 00000000000..d90ad832aa4
--- /dev/null
+++ b/apis/projectcontour/v1alpha1/compression_test.go
@@ -0,0 +1,32 @@
+// Copyright Project Contour Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package v1alpha1_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
+)
+
+func TestValidateEnvoyCompressionType(t *testing.T) {
+ require.Error(t, contour_v1alpha1.EnvoyCompressionType("").Validate())
+ require.Error(t, contour_v1alpha1.EnvoyCompressionType("foo").Validate())
+
+ require.NoError(t, contour_v1alpha1.BrotliCompression.Validate())
+ require.NoError(t, contour_v1alpha1.DisabledCompression.Validate())
+ require.NoError(t, contour_v1alpha1.GzipCompression.Validate())
+ require.NoError(t, contour_v1alpha1.ZstdCompression.Validate())
+}
diff --git a/apis/projectcontour/v1alpha1/contourconfig.go b/apis/projectcontour/v1alpha1/contourconfig.go
index 8a51321a077..d96ff51691b 100644
--- a/apis/projectcontour/v1alpha1/contourconfig.go
+++ b/apis/projectcontour/v1alpha1/contourconfig.go
@@ -348,11 +348,11 @@ type EnvoyListenerConfig struct {
// +optional
UseProxyProto *bool `json:"useProxyProtocol,omitempty"`
- // DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- // Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- // Contour's default is false.
+ // Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ // Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ // Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
// +optional
- DisableCompression bool `json:"disableCompression,omitempty"`
+ Compression EnvoyCompressionType `json:"compression,omitempty"`
// DisableAllowChunkedLength disables the RFC-compliant Envoy behavior to
// strip the "Content-Length" header if "Transfer-Encoding: chunked" is
diff --git a/changelogs/unreleased/6546-chaosbox-small.md b/changelogs/unreleased/6546-chaosbox-small.md
index 18f2b2138e1..5f156b7289d 100644
--- a/changelogs/unreleased/6546-chaosbox-small.md
+++ b/changelogs/unreleased/6546-chaosbox-small.md
@@ -1 +1 @@
-Add disableCompression boolean flag to disable GZIP compression HTTP filter from the default Listener filters.
+Add "compression" flag to set/disable the compression type applied in the default HTTP filter chain.
diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go
index 5ab881936ec..b361a56d2b1 100644
--- a/cmd/contour/serve.go
+++ b/cmd/contour/serve.go
@@ -125,6 +125,7 @@ func registerServe(app *kingpin.Application) (*kingpin.CmdClause, *serveContext)
}
serve.Flag("accesslog-format", "Format for Envoy access logs.").PlaceHolder("").StringVar((*string)(&ctx.Config.AccessLogFormat))
+ serve.Flag("compression", "Set or disable compression type in default Listener filters.").PlaceHolder("").StringVar((*string)(&ctx.Config.Compression))
serve.Flag("config-path", "Path to base configuration.").Short('c').PlaceHolder("/path/to/file").Action(parseConfig).ExistingFileVar(&configFile)
serve.Flag("contour-cafile", "CA bundle file name for serving gRPC with TLS.").Envar("CONTOUR_CAFILE").StringVar(&ctx.caFile)
serve.Flag("contour-cert-file", "Contour certificate file name for serving gRPC over TLS.").PlaceHolder("/path/to/file").Envar("CONTOUR_CERT_FILE").StringVar(&ctx.contourCert)
@@ -447,7 +448,7 @@ func (s *Server) doServe() error {
}
listenerConfig := xdscache_v3.ListenerConfig{
- DisableCompression: contourConfiguration.Envoy.Listener.DisableCompression,
+ Compression: contourConfiguration.Envoy.Listener.Compression,
UseProxyProto: *contourConfiguration.Envoy.Listener.UseProxyProto,
HTTPAccessLog: contourConfiguration.Envoy.HTTPListener.AccessLog,
HTTPSAccessLog: contourConfiguration.Envoy.HTTPSListener.AccessLog,
@@ -472,6 +473,8 @@ func (s *Server) doServe() error {
SocketOptions: contourConfiguration.Envoy.Listener.SocketOptions,
}
+ s.log.WithField("context", "listenerConfig").Infof("compression setting: %s", listenerConfig.Compression)
+
if listenerConfig.TracingConfig, err = s.setupTracingService(contourConfiguration.Tracing); err != nil {
return err
}
diff --git a/cmd/contour/servecontext.go b/cmd/contour/servecontext.go
index 67451bc0ad7..37d0936e18f 100644
--- a/cmd/contour/servecontext.go
+++ b/cmd/contour/servecontext.go
@@ -333,6 +333,18 @@ func (ctx *serveContext) convertToContourConfigurationSpec() contour_v1alpha1.Co
accessLogLevel = contour_v1alpha1.LogLevelDisabled
}
+ var compression contour_v1alpha1.EnvoyCompressionType
+ switch ctx.Config.Compression {
+ case config.CompressionBrotli:
+ compression = contour_v1alpha1.BrotliCompression
+ case config.CompressionDisabled:
+ compression = contour_v1alpha1.DisabledCompression
+ case config.CompressionGzip:
+ compression = contour_v1alpha1.GzipCompression
+ case config.CompressionZstd:
+ compression = contour_v1alpha1.ZstdCompression
+ }
+
var defaultHTTPVersions []contour_v1alpha1.HTTPVersionType
for _, version := range ctx.Config.DefaultHTTPVersions {
switch version {
@@ -519,7 +531,7 @@ func (ctx *serveContext) convertToContourConfigurationSpec() contour_v1alpha1.Co
Envoy: &contour_v1alpha1.EnvoyConfig{
Listener: &contour_v1alpha1.EnvoyListenerConfig{
UseProxyProto: &ctx.useProxyProto,
- DisableCompression: ctx.Config.DisableCompression,
+ Compression: compression,
DisableAllowChunkedLength: &ctx.Config.DisableAllowChunkedLength,
DisableMergeSlashes: &ctx.Config.DisableMergeSlashes,
ServerHeaderTransformation: serverHeaderTransformation,
diff --git a/cmd/contour/servecontext_test.go b/cmd/contour/servecontext_test.go
index b6bf90738e1..5f946f18e6a 100644
--- a/cmd/contour/servecontext_test.go
+++ b/cmd/contour/servecontext_test.go
@@ -408,6 +408,7 @@ func TestConvertServeContext(t *testing.T) {
},
Listener: &contour_v1alpha1.EnvoyListenerConfig{
UseProxyProto: ptr.To(false),
+ Compression: "gzip",
DisableAllowChunkedLength: ptr.To(false),
DisableMergeSlashes: ptr.To(false),
ServerHeaderTransformation: contour_v1alpha1.OverwriteServerHeader,
@@ -892,14 +893,14 @@ func TestConvertServeContext(t *testing.T) {
ctx.Config.Listener.MaxRequestsPerIOCycle = ptr.To(uint32(10))
ctx.Config.Listener.HTTP2MaxConcurrentStreams = ptr.To(uint32(30))
ctx.Config.Listener.MaxConnectionsPerListener = ptr.To(uint32(50))
- ctx.Config.DisableCompression = true
+ ctx.Config.Compression = "gzip"
return ctx
},
getContourConfiguration: func(cfg contour_v1alpha1.ContourConfigurationSpec) contour_v1alpha1.ContourConfigurationSpec {
cfg.Envoy.Listener.MaxRequestsPerIOCycle = ptr.To(uint32(10))
cfg.Envoy.Listener.HTTP2MaxConcurrentStreams = ptr.To(uint32(30))
cfg.Envoy.Listener.MaxConnectionsPerListener = ptr.To(uint32(50))
- cfg.Envoy.Listener.DisableCompression = true
+ cfg.Envoy.Listener.Compression = "gzip"
return cfg
},
},
diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml
index 6118314e158..911f670200e 100644
--- a/examples/contour/01-crds.yaml
+++ b/examples/contour/01-crds.yaml
@@ -281,6 +281,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -299,12 +305,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4069,6 +4069,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4087,12 +4093,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml
index 89fa0c0118d..08de1688e9a 100644
--- a/examples/render/contour-deployment.yaml
+++ b/examples/render/contour-deployment.yaml
@@ -501,6 +501,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -519,12 +525,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4289,6 +4289,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4307,12 +4313,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml
index 8b02f26cae0..9302324f810 100644
--- a/examples/render/contour-gateway-provisioner.yaml
+++ b/examples/render/contour-gateway-provisioner.yaml
@@ -292,6 +292,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -310,12 +316,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4080,6 +4080,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4098,12 +4104,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml
index db7f84f459f..a993637fc75 100644
--- a/examples/render/contour-gateway.yaml
+++ b/examples/render/contour-gateway.yaml
@@ -317,6 +317,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -335,12 +341,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4105,6 +4105,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4123,12 +4129,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml
index 12cc1c7cd6a..ffd55e0337d 100644
--- a/examples/render/contour.yaml
+++ b/examples/render/contour.yaml
@@ -501,6 +501,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -519,12 +525,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
@@ -4289,6 +4289,12 @@ spec:
description: Listener hold various configurable Envoy listener
values.
properties:
+ compression:
+ description: |-
+ Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ type: string
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4307,12 +4313,6 @@ spec:
See: https://github.com/projectcontour/contour/issues/3221
Contour's default is false.
type: boolean
- disableCompression:
- description: |-
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
- Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Contour's default is false.
- type: boolean
disableMergeSlashes:
description: |-
DisableMergeSlashes disables Envoy's non-standard merge_slashes path transformation option
diff --git a/internal/contourconfig/contourconfiguration.go b/internal/contourconfig/contourconfiguration.go
index 0c369f170cb..9dbaf7e1d40 100644
--- a/internal/contourconfig/contourconfiguration.go
+++ b/internal/contourconfig/contourconfiguration.go
@@ -66,6 +66,7 @@ func Defaults() contour_v1alpha1.ContourConfigurationSpec {
Envoy: &contour_v1alpha1.EnvoyConfig{
Listener: &contour_v1alpha1.EnvoyListenerConfig{
UseProxyProto: ptr.To(false),
+ Compression: contour_v1alpha1.GzipCompression,
DisableAllowChunkedLength: ptr.To(false),
DisableMergeSlashes: ptr.To(false),
ServerHeaderTransformation: contour_v1alpha1.OverwriteServerHeader,
diff --git a/internal/contourconfig/contourconfiguration_test.go b/internal/contourconfig/contourconfiguration_test.go
index bb13b8229da..7ee574985cd 100644
--- a/internal/contourconfig/contourconfiguration_test.go
+++ b/internal/contourconfig/contourconfiguration_test.go
@@ -55,10 +55,11 @@ func TestOverlayOnDefaults(t *testing.T) {
Envoy: &contour_v1alpha1.EnvoyConfig{
Listener: &contour_v1alpha1.EnvoyListenerConfig{
UseProxyProto: ptr.To(true),
- DisableAllowChunkedLength: ptr.To(true),
- DisableMergeSlashes: ptr.To(true),
+ Compression: "brotli",
MaxRequestsPerConnection: ptr.To(uint32(1)),
HTTP2MaxConcurrentStreams: ptr.To(uint32(10)),
+ DisableAllowChunkedLength: ptr.To(true),
+ DisableMergeSlashes: ptr.To(true),
ServerHeaderTransformation: contour_v1alpha1.PassThroughServerHeader,
ConnectionBalancer: "yesplease",
TLS: &contour_v1alpha1.EnvoyTLS{
diff --git a/internal/envoy/v3/listener.go b/internal/envoy/v3/listener.go
index fc57b436645..63d71d77340 100644
--- a/internal/envoy/v3/listener.go
+++ b/internal/envoy/v3/listener.go
@@ -23,7 +23,9 @@ import (
envoy_config_accesslog_v3 "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v3"
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
+ envoy_compression_brotli_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/brotli/compressor/v3"
envoy_compression_gzip_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/gzip/compressor/v3"
+ envoy_compression_zstd_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/zstd/compressor/v3"
envoy_filter_http_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/compressor/v3"
envoy_filter_http_cors_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/cors/v3"
envoy_filter_http_ext_authz_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ext_authz/v3"
@@ -41,6 +43,7 @@ import (
envoy_transport_socket_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
envoy_type_v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
+ "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
@@ -188,7 +191,7 @@ type httpConnectionManagerBuilder struct {
maxRequestsPerConnection *uint32
http2MaxConcurrentStreams *uint32
enableWebsockets bool
- disableCompression bool
+ compression contour_v1alpha1.EnvoyCompressionType
}
func (b *httpConnectionManagerBuilder) EnableWebsockets(enable bool) *httpConnectionManagerBuilder {
@@ -272,8 +275,8 @@ func (b *httpConnectionManagerBuilder) MergeSlashes(enabled bool) *httpConnectio
return b
}
-func (b *httpConnectionManagerBuilder) DisableCompression(disabled bool) *httpConnectionManagerBuilder {
- b.disableCompression = disabled
+func (b *httpConnectionManagerBuilder) Compression(compressor contour_v1alpha1.EnvoyCompressionType) *httpConnectionManagerBuilder {
+ b.compression = compressor
return b
}
@@ -314,7 +317,23 @@ func (b *httpConnectionManagerBuilder) DefaultFilters() *httpConnectionManagerBu
// Add a default set of ordered http filters.
// The names are not required to match anything and are
// identified by the TypeURL of each filter.
- if !b.disableCompression {
+ var compressor proto.Message
+ compressorName := ""
+ switch b.compression {
+ case contour_v1alpha1.BrotliCompression:
+ compressorName = "brotli"
+ compressor = &envoy_compression_brotli_compressor_v3.Brotli{}
+ case contour_v1alpha1.DisabledCompression:
+ compressor = nil
+ case contour_v1alpha1.ZstdCompression:
+ compressorName = "zstd"
+ compressor = &envoy_compression_zstd_compressor_v3.Zstd{}
+ default:
+ compressorName = "gzip"
+ compressor = &envoy_compression_gzip_compressor_v3.Gzip{}
+ }
+
+ if compressor != nil {
// If compression is enabled add compressor filter
b.filters = append(b.filters,
&envoy_filter_network_http_connection_manager_v3.HttpFilter{
@@ -322,9 +341,9 @@ func (b *httpConnectionManagerBuilder) DefaultFilters() *httpConnectionManagerBu
ConfigType: &envoy_filter_network_http_connection_manager_v3.HttpFilter_TypedConfig{
TypedConfig: protobuf.MustMarshalAny(&envoy_filter_http_compressor_v3.Compressor{
CompressorLibrary: &envoy_config_core_v3.TypedExtensionConfig{
- Name: "gzip",
+ Name: compressorName,
TypedConfig: protobuf.MustMarshalAny(
- &envoy_compression_gzip_compressor_v3.Gzip{},
+ compressor,
),
},
ResponseDirectionConfig: &envoy_filter_http_compressor_v3.Compressor_ResponseDirectionConfig{
diff --git a/internal/featuretests/v3/compression_test.go b/internal/featuretests/v3/compression_test.go
index 1c16eaaa77b..a0c941438c8 100644
--- a/internal/featuretests/v3/compression_test.go
+++ b/internal/featuretests/v3/compression_test.go
@@ -72,7 +72,7 @@ func TestDefaultCompression(t *testing.T) {
func TestDisableCompression(t *testing.T) {
withDisableCompression := func(conf *xdscache_v3.ListenerConfig) {
- conf.DisableCompression = true
+ conf.Compression = "disabled"
}
rh, c, done := setup(t, withDisableCompression)
@@ -104,7 +104,103 @@ func TestDisableCompression(t *testing.T) {
httpListener := defaultHTTPListener()
httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
- DisableCompression(true).
+ Compression("disabled").
+ RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
+ MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ )
+
+ c.Request(listenerType, xdscache_v3.ENVOY_HTTP_LISTENER).Equals(&envoy_service_discovery_v3.DiscoveryResponse{
+ TypeUrl: listenerType,
+ Resources: resources(t, httpListener),
+ })
+}
+
+func TestBrotliCompression(t *testing.T) {
+ withBrotliCompression := func(conf *xdscache_v3.ListenerConfig) {
+ conf.Compression = "brotli"
+ }
+
+ rh, c, done := setup(t, withBrotliCompression)
+ defer done()
+
+ s1 := fixture.NewService("backend").
+ WithPorts(core_v1.ServicePort{Name: "http", Port: 80})
+ rh.OnAdd(s1)
+
+ hp1 := &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "simple",
+ Namespace: s1.Namespace,
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: "example.com",
+ },
+ Routes: []contour_v1.Route{{
+ Conditions: matchconditions(prefixMatchCondition("/")),
+ Services: []contour_v1.Service{{
+ Name: s1.Name,
+ Port: 80,
+ }},
+ }},
+ },
+ }
+ rh.OnAdd(hp1)
+
+ httpListener := defaultHTTPListener()
+ httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
+ Compression("brotli").
+ RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
+ MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ )
+
+ c.Request(listenerType, xdscache_v3.ENVOY_HTTP_LISTENER).Equals(&envoy_service_discovery_v3.DiscoveryResponse{
+ TypeUrl: listenerType,
+ Resources: resources(t, httpListener),
+ })
+}
+
+func TestZstdCompression(t *testing.T) {
+ withZstdCompression := func(conf *xdscache_v3.ListenerConfig) {
+ conf.Compression = "zstd"
+ }
+
+ rh, c, done := setup(t, withZstdCompression)
+ defer done()
+
+ s1 := fixture.NewService("backend").
+ WithPorts(core_v1.ServicePort{Name: "http", Port: 80})
+ rh.OnAdd(s1)
+
+ hp1 := &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "simple",
+ Namespace: s1.Namespace,
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: "example.com",
+ },
+ Routes: []contour_v1.Route{{
+ Conditions: matchconditions(prefixMatchCondition("/")),
+ Services: []contour_v1.Service{{
+ Name: s1.Name,
+ Port: 80,
+ }},
+ }},
+ },
+ }
+ rh.OnAdd(hp1)
+
+ httpListener := defaultHTTPListener()
+ httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
+ Compression("zstd").
RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
diff --git a/internal/xdscache/v3/listener.go b/internal/xdscache/v3/listener.go
index 94190b2f5d5..36ad156a32b 100644
--- a/internal/xdscache/v3/listener.go
+++ b/internal/xdscache/v3/listener.go
@@ -66,10 +66,10 @@ type ListenerConfig struct {
// If not set, defaults to false.
UseProxyProto bool
- // DisableCompression configures listener to ignore adding compression filter as part of the defaultFilters
- // Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- // If not set, defaults to false.
- DisableCompression bool
+ // Compression configures which compression, if any, the listener uses in the compression filter as part of the defaultFilters.
+ // Valid values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ // Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ Compression contour_v1alpha1.EnvoyCompressionType
// MinimumTLSVersion defines the minimum TLS protocol version the proxy should accept.
MinimumTLSVersion string
@@ -398,7 +398,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
// order for the HTTPS virtualhosts.
if len(listener.VirtualHosts) > 0 {
cm := envoy_v3.HTTPConnectionManagerBuilder().
- DisableCompression(cfg.DisableCompression).
+ Compression(cfg.Compression).
Codec(envoy_v3.CodecForVersions(cfg.DefaultHTTPVersions...)).
DefaultFilters().
RouteConfigName(httpRouteConfigName(listener)).
@@ -471,7 +471,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
// Contour versions since the metrics prefix will be
// coded into monitoring dashboards.
cm := envoy_v3.HTTPConnectionManagerBuilder().
- DisableCompression(cfg.DisableCompression).
+ Compression(cfg.Compression).
Codec(envoy_v3.CodecForVersions(cfg.DefaultHTTPVersions...)).
AddFilter(envoy_v3.FilterMisdirectedRequests(vh.VirtualHost.Name)).
DefaultFilters().
@@ -556,7 +556,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
}
cm := envoy_v3.HTTPConnectionManagerBuilder().
- DisableCompression(cfg.DisableCompression).
+ Compression(cfg.Compression).
DefaultFilters().
AddFilter(authzFilter).
RouteConfigName(fallbackCertRouteConfigName(listener)).
diff --git a/internal/xdscache/v3/listener_test.go b/internal/xdscache/v3/listener_test.go
index 1b85ab968b0..a7223d48ce3 100644
--- a/internal/xdscache/v3/listener_test.go
+++ b/internal/xdscache/v3/listener_test.go
@@ -3074,9 +3074,9 @@ func TestListenerVisit(t *testing.T) {
SocketOptions: envoy_v3.NewSocketOptions().TCPKeepalive().Build(),
}),
},
- "httpproxy with DisableCompression set in listener config": {
+ "httpproxy with disabled compression set in listener config": {
ListenerConfig: ListenerConfig{
- DisableCompression: true,
+ Compression: "disabled",
},
objs: []any{
&contour_v1.HTTPProxy{
@@ -3106,7 +3106,175 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- DisableCompression(true).
+ Compression("disabled").
+ RouteConfigName(ENVOY_HTTP_LISTENER).
+ MetricsPrefix(ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ ),
+ SocketOptions: envoy_v3.NewSocketOptions().TCPKeepalive().Build(),
+ }),
+ },
+ "httpproxy with gzip compression set in listener config": {
+ ListenerConfig: ListenerConfig{
+ Compression: "gzip",
+ },
+ objs: []any{
+ &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "simple",
+ Namespace: "default",
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: "www.example.com",
+ },
+ Routes: []contour_v1.Route{{
+ Conditions: []contour_v1.MatchCondition{{
+ Prefix: "/",
+ }},
+ Services: []contour_v1.Service{{
+ Name: "backend",
+ Port: 80,
+ }},
+ }},
+ },
+ },
+ service,
+ },
+ want: listenermap(&envoy_config_listener_v3.Listener{
+ Name: ENVOY_HTTP_LISTENER,
+ Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
+ FilterChains: envoy_v3.FilterChains(
+ envoy_v3.HTTPConnectionManagerBuilder().
+ Compression("gzip").
+ RouteConfigName(ENVOY_HTTP_LISTENER).
+ MetricsPrefix(ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ ),
+ SocketOptions: envoy_v3.NewSocketOptions().TCPKeepalive().Build(),
+ }),
+ },
+ "httpproxy with brotli compression set in listener config": {
+ ListenerConfig: ListenerConfig{
+ Compression: "brotli",
+ },
+ objs: []any{
+ &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "simple",
+ Namespace: "default",
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: "www.example.com",
+ },
+ Routes: []contour_v1.Route{{
+ Conditions: []contour_v1.MatchCondition{{
+ Prefix: "/",
+ }},
+ Services: []contour_v1.Service{{
+ Name: "backend",
+ Port: 80,
+ }},
+ }},
+ },
+ },
+ service,
+ },
+ want: listenermap(&envoy_config_listener_v3.Listener{
+ Name: ENVOY_HTTP_LISTENER,
+ Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
+ FilterChains: envoy_v3.FilterChains(
+ envoy_v3.HTTPConnectionManagerBuilder().
+ Compression("brotli").
+ RouteConfigName(ENVOY_HTTP_LISTENER).
+ MetricsPrefix(ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ ),
+ SocketOptions: envoy_v3.NewSocketOptions().TCPKeepalive().Build(),
+ }),
+ },
+ "httpproxy with zstd compression set in listener config": {
+ ListenerConfig: ListenerConfig{
+ Compression: "zstd",
+ },
+ objs: []any{
+ &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "simple",
+ Namespace: "default",
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: "www.example.com",
+ },
+ Routes: []contour_v1.Route{{
+ Conditions: []contour_v1.MatchCondition{{
+ Prefix: "/",
+ }},
+ Services: []contour_v1.Service{{
+ Name: "backend",
+ Port: 80,
+ }},
+ }},
+ },
+ },
+ service,
+ },
+ want: listenermap(&envoy_config_listener_v3.Listener{
+ Name: ENVOY_HTTP_LISTENER,
+ Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
+ FilterChains: envoy_v3.FilterChains(
+ envoy_v3.HTTPConnectionManagerBuilder().
+ Compression("zstd").
+ RouteConfigName(ENVOY_HTTP_LISTENER).
+ MetricsPrefix(ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ ),
+ SocketOptions: envoy_v3.NewSocketOptions().TCPKeepalive().Build(),
+ }),
+ },
+ "httpproxy with invalid compression set in listener config": {
+ ListenerConfig: ListenerConfig{
+ Compression: "invalid value",
+ },
+ objs: []any{
+ &contour_v1.HTTPProxy{
+ ObjectMeta: meta_v1.ObjectMeta{
+ Name: "simple",
+ Namespace: "default",
+ },
+ Spec: contour_v1.HTTPProxySpec{
+ VirtualHost: &contour_v1.VirtualHost{
+ Fqdn: "www.example.com",
+ },
+ Routes: []contour_v1.Route{{
+ Conditions: []contour_v1.MatchCondition{{
+ Prefix: "/",
+ }},
+ Services: []contour_v1.Service{{
+ Name: "backend",
+ Port: 80,
+ }},
+ }},
+ },
+ },
+ service,
+ },
+ want: listenermap(&envoy_config_listener_v3.Listener{
+ Name: ENVOY_HTTP_LISTENER,
+ Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
+ FilterChains: envoy_v3.FilterChains(
+ envoy_v3.HTTPConnectionManagerBuilder().
+ Compression("gzip").
RouteConfigName(ENVOY_HTTP_LISTENER).
MetricsPrefix(ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
index 211fb956a01..d349c632a4b 100644
--- a/pkg/config/parameters.go
+++ b/pkg/config/parameters.go
@@ -651,10 +651,11 @@ type Parameters struct {
// which strips duplicate slashes from request URL paths.
DisableMergeSlashes bool `yaml:"disableMergeSlashes,omitempty"`
- // DisableCompression disables GZIP compression HTTP filter
- // Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- // If not set, defaults to false.
- DisableCompression bool `yaml:"disableCompression,omitempty"`
+ // Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ // Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ // Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ // +optional
+ Compression EnvoyCompressionType `yaml:"compression,omitempty"`
// Defines the action to be applied to the Server header on the response path.
// When configured as overwrite, overwrites any Server header with "envoy".
@@ -971,6 +972,19 @@ const (
LogLevelDisabled AccessLogLevel = "disabled"
)
+type EnvoyCompressionType string
+
+func (c EnvoyCompressionType) Validate() error {
+ return contour_v1alpha1.EnvoyCompressionType(c).Validate()
+}
+
+const (
+ CompressionGzip EnvoyCompressionType = "gzip"
+ CompressionBrotli EnvoyCompressionType = "brotli"
+ CompressionDisabled EnvoyCompressionType = "disabled"
+ CompressionZstd EnvoyCompressionType = "zstd"
+)
+
// Validate verifies that the parameter values do not have any syntax errors.
func (p *Parameters) Validate() error {
if err := p.Cluster.DNSLookupFamily.Validate(); err != nil {
@@ -1001,6 +1015,10 @@ func (p *Parameters) Validate() error {
return err
}
+ if err := p.Compression.Validate(); err != nil {
+ return err
+ }
+
if err := p.TLS.Validate(); err != nil {
return err
}
@@ -1034,6 +1052,9 @@ func (p *Parameters) Validate() error {
return p.Listener.Validate()
}
+// DefaultCompressionFilter is the compression mechanism in the default HTTP filter chain
+const DefaultCompressionFilter = CompressionGzip
+
// Defaults returns the default set of parameters.
func Defaults() Parameters {
contourNamespace := GetenvOr("CONTOUR_NAMESPACE", "projectcontour")
@@ -1053,6 +1074,7 @@ func Defaults() Parameters {
DisablePermitInsecure: false,
DisableAllowChunkedLength: false,
DisableMergeSlashes: false,
+ Compression: DefaultCompressionFilter,
ServerHeaderTransformation: OverwriteServerHeader,
Timeouts: TimeoutParameters{
// This is chosen as a rough default to stop idle connections wasting resources,
diff --git a/pkg/config/parameters_test.go b/pkg/config/parameters_test.go
index 7f6ad7a7dcd..5ba18a0fb7c 100644
--- a/pkg/config/parameters_test.go
+++ b/pkg/config/parameters_test.go
@@ -75,6 +75,7 @@ json-fields:
- grpc_status
- grpc_status_number
accesslog-level: info
+compression: gzip
serverHeaderTransformation: overwrite
timeouts:
connection-idle-timeout: 60s
diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html
index d6c95cdb9b3..aa21e8084c8 100644
--- a/site/content/docs/main/config/api-reference.html
+++ b/site/content/docs/main/config/api-reference.html
@@ -6595,6 +6595,35 @@ DeploymentSettings
|
+EnvoyCompressionType
+(string
alias)
+
+(Appears on:
+EnvoyListenerConfig)
+
+
+
+
+
+
+Value |
+Description |
+
+
+"brotli" |
+BrotliCompression specifies brotli as the default HTTP filter chain compression mechanism
+ |
+
"disabled" |
+DisabledCompression specifies that there will be no compression in the default HTTP filter chain
+ |
+
"gzip" |
+GzipCompression specifies gzip as the default HTTP filter chain compression mechanism
+ |
+
"zstd" |
+ZstdCompression specifies zstd as the default HTTP filter chain compression mechanism
+ |
+
+
EnvoyConfig
@@ -6900,17 +6929,19 @@
EnvoyListenerConfig
-disableCompression
+compression
-bool
+
+EnvoyCompressionType
+
|
(Optional)
- DisableCompression disables GZIP compression HTTP filter from the default Listener filters
-Setting this true will enable Envoy skip “Accept-Encoding: gzip,deflate” request header and always return uncompressed response
-Contour’s default is false.
+Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
+Values: gzip (default), brotli , zstd , disabled .
+Setting this to disabled will make Envoy skip “Accept-Encoding: gzip,deflate” request header and always return uncompressed response
|
diff --git a/site/content/docs/main/configuration.md b/site/content/docs/main/configuration.md
index 588ce55be29..8e2a3e168c4 100644
--- a/site/content/docs/main/configuration.md
+++ b/site/content/docs/main/configuration.md
@@ -72,38 +72,38 @@ The Contour configuration file is optional.
In its absence, Contour will operate with reasonable defaults.
Where Contour settings can also be specified with command-line flags, the command-line value takes precedence over the configuration file.
-| Field Name | Type | Default | Description |
-|----------------------------|------------------------|------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| accesslog-format | string | `envoy` | This key sets the global [access log format][2] for Envoy. Valid options are `envoy` or `json`. |
-| accesslog-format-string | string | None | If present, this specifies custom access log format for Envoy. See [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage) for more information about the syntax. This field only has effect if `accesslog-format` is `envoy` |
-| accesslog-level | string | `info` | This field specifies the verbosity level of the access log. Valid options are `info` (default, all requests are logged), `error` (all non-success, i.e. 300+ response code, requests are logged), `critical` (all server error, i.e. 500+ response code, requests are logged) and `disabled`. |
-| debug | boolean | `false` | Enables debug logging. |
-| default-http-versions | string array | HTTP/1.1
HTTP/2
| This array specifies the HTTP versions that Contour should program Envoy to serve. HTTP versions are specified as strings of the form "HTTP/x", where "x" represents the version number. |
-| disableAllowChunkedLength | boolean | `false` | If this field is true, Contour will disable the RFC-compliant Envoy behavior to strip the `Content-Length` header if `Transfer-Encoding: chunked` is also set. This is an emergency off-switch to revert back to Envoy's default behavior in case of failures. |
-| disableCompression | boolean | `false` | This disables GZIP compression HTTP filter from the default Listener filters. Setting this true will enable Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response. |
-| disableMergeSlashes | boolean | `false` | This field disables Envoy's non-standard merge_slashes path transformation behavior that strips duplicate slashes from request URL paths. |
-| serverHeaderTransformation | string | `overwrite` | This field defines the action to be applied to the Server header on the response path. Values: `overwrite` (default), `append_if_absent`, `pass_through` |
-| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. |
-| envoy-service-name | string | `envoy` | This sets the service name that will be inspected for address details to be applied to Ingress objects. |
-| envoy-service-namespace | string | `projectcontour` | This sets the namespace of the service that will be inspected for address details to be applied to Ingress objects. If the `CONTOUR_NAMESPACE` environment variable is present, Contour will populate this field with its value. |
-| ingress-status-address | string | None | If present, this specifies the address that will be copied into the Ingress status for each Ingress that Contour manages. It is exclusive with `envoy-service-name` and `envoy-service-namespace`. |
-| incluster | boolean | `false` | This field specifies that Contour is running in a Kubernetes cluster and should use the in-cluster client access configuration. |
-| json-fields | string array | [fields][5] | This is the list the field names to include in the JSON [access log format][2]. This field only has effect if `accesslog-format` is `json`. |
-| kubeconfig | string | `$HOME/.kube/config` | Path to a Kubernetes [kubeconfig file][3] for when Contour is executed outside a cluster. |
-| kubernetesClientQPS | float32 | | QPS allowed for the Kubernetes client. |
-| kubernetesClientBurst | int | | Burst allowed for the Kubernetes client. |
-| policy | PolicyConfig | | The default [policy configuration](#policy-configuration). |
-| tls | TLS | | The default [TLS configuration](#tls-configuration). |
-| timeouts | TimeoutConfig | | The [timeout configuration](#timeout-configuration). |
-| cluster | ClusterConfig | | The [cluster configuration](#cluster-configuration). |
-| network | NetworkConfig | | The [network configuration](#network-configuration). |
-| listener | ListenerConfig | | The [listener configuration](#listener-configuration). |
-| server | ServerConfig | | The [server configuration](#server-configuration) for `contour serve` command. |
-| gateway | GatewayConfig | | The [gateway-api Gateway configuration](#gateway-configuration). |
-| rateLimitService | RateLimitServiceConfig | | The [rate limit service configuration](#rate-limit-service-configuration). |
-| enableExternalNameService | boolean | `false` | Enable ExternalName Service processing. Enabling this has security implications. Please see the [advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for more details. |
-| metrics | MetricsParameters | | The [metrics configuration](#metrics-configuration) |
-| featureFlags | string array | `[]` | Defines the toggle to enable new contour features. Available toggles are:
1. `useEndpointSlices` - configures contour to fetch endpoint data from k8s endpoint slices. |
+| Field Name | Type | Default | Description |
+|----------------------------|------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| accesslog-format | string | `envoy` | This key sets the global [access log format][2] for Envoy. Valid options are `envoy` or `json`. |
+| accesslog-format-string | string | None | If present, this specifies custom access log format for Envoy. See [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage) for more information about the syntax. This field only has effect if `accesslog-format` is `envoy` |
+| accesslog-level | string | `info` | This field specifies the verbosity level of the access log. Valid options are `info` (default, all requests are logged), `error` (all non-success, i.e. 300+ response code, requests are logged), `critical` (all server error, i.e. 500+ response code, requests are logged) and `disabled`. |
+| debug | boolean | `false` | Enables debug logging. |
+| default-http-versions | string array | HTTP/1.1
HTTP/2
| This array specifies the HTTP versions that Contour should program Envoy to serve. HTTP versions are specified as strings of the form "HTTP/x", where "x" represents the version number. |
+| disableAllowChunkedLength | boolean | `false` | If this field is true, Contour will disable the RFC-compliant Envoy behavior to strip the `Content-Length` header if `Transfer-Encoding: chunked` is also set. This is an emergency off-switch to revert back to Envoy's default behavior in case of failures. |
+| compression | string | `gzip` | Sets the compression type applied in the compression HTTP filter of the default Listener filters. Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response. Values:`gzip` (default), `brotli`, `zstd`, `disabled`. |
+| disableMergeSlashes | boolean | `false` | This field disables Envoy's non-standard merge_slashes path transformation behavior that strips duplicate slashes from request URL paths. |
+| serverHeaderTransformation | string | `overwrite` | This field defines the action to be applied to the Server header on the response path. Values: `overwrite` (default), `append_if_absent`, `pass_through` |
+| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. |
+| envoy-service-name | string | `envoy` | This sets the service name that will be inspected for address details to be applied to Ingress objects. |
+| envoy-service-namespace | string | `projectcontour` | This sets the namespace of the service that will be inspected for address details to be applied to Ingress objects. If the `CONTOUR_NAMESPACE` environment variable is present, Contour will populate this field with its value. |
+| ingress-status-address | string | None | If present, this specifies the address that will be copied into the Ingress status for each Ingress that Contour manages. It is exclusive with `envoy-service-name` and `envoy-service-namespace`. |
+| incluster | boolean | `false` | This field specifies that Contour is running in a Kubernetes cluster and should use the in-cluster client access configuration. |
+| json-fields | string array | [fields][5] | This is the list the field names to include in the JSON [access log format][2]. This field only has effect if `accesslog-format` is `json`. |
+| kubeconfig | string | `$HOME/.kube/config` | Path to a Kubernetes [kubeconfig file][3] for when Contour is executed outside a cluster. |
+| kubernetesClientQPS | float32 | | QPS allowed for the Kubernetes client. |
+| kubernetesClientBurst | int | | Burst allowed for the Kubernetes client. |
+| policy | PolicyConfig | | The default [policy configuration](#policy-configuration). |
+| tls | TLS | | The default [TLS configuration](#tls-configuration). |
+| timeouts | TimeoutConfig | | The [timeout configuration](#timeout-configuration). |
+| cluster | ClusterConfig | | The [cluster configuration](#cluster-configuration). |
+| network | NetworkConfig | | The [network configuration](#network-configuration). |
+| listener | ListenerConfig | | The [listener configuration](#listener-configuration). |
+| server | ServerConfig | | The [server configuration](#server-configuration) for `contour serve` command. |
+| gateway | GatewayConfig | | The [gateway-api Gateway configuration](#gateway-configuration). |
+| rateLimitService | RateLimitServiceConfig | | The [rate limit service configuration](#rate-limit-service-configuration). |
+| enableExternalNameService | boolean | `false` | Enable ExternalName Service processing. Enabling this has security implications. Please see the [advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for more details. |
+| metrics | MetricsParameters | | The [metrics configuration](#metrics-configuration) |
+| featureFlags | string array | `[]` | Defines the toggle to enable new contour features. Available toggles are:
1. `useEndpointSlices` - configures contour to fetch endpoint data from k8s endpoint slices. |
### TLS Configuration
diff --git a/test/e2e/deployment.go b/test/e2e/deployment.go
index 6fc95eec9a5..4128f0d524b 100644
--- a/test/e2e/deployment.go
+++ b/test/e2e/deployment.go
@@ -490,7 +490,7 @@ func (d *Deployment) EnsureResourcesForLocalContour() error {
return err
}
- session.Wait("2s")
+ session.Wait("3s")
bootstrapContents, err := io.ReadAll(bFile)
if err != nil {
return err
diff --git a/test/e2e/fixtures.go b/test/e2e/fixtures.go
index 4cc20831bf6..6d819bc1174 100644
--- a/test/e2e/fixtures.go
+++ b/test/e2e/fixtures.go
@@ -583,6 +583,7 @@ func DefaultContourConfiguration() *contour_v1alpha1.ContourConfiguration {
},
Listener: &contour_v1alpha1.EnvoyListenerConfig{
UseProxyProto: ptr.To(false),
+ Compression: "gzip",
DisableAllowChunkedLength: ptr.To(false),
ConnectionBalancer: "",
TLS: &contour_v1alpha1.EnvoyTLS{
diff --git a/test/e2e/httpproxy/envoy_compression_test.go b/test/e2e/httpproxy/envoy_compression_test.go
index 9fd81366f4c..5b069af8470 100644
--- a/test/e2e/httpproxy/envoy_compression_test.go
+++ b/test/e2e/httpproxy/envoy_compression_test.go
@@ -18,8 +18,10 @@ package httpproxy
import (
"fmt"
"net/http"
+ "time"
. "github.com/onsi/ginkgo/v2"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -27,12 +29,13 @@ import (
"github.com/projectcontour/contour/test/e2e"
)
-func testEnvoyDisableCompression(namespace string, enabled bool) {
- testSpec := "responses compressed with default settings"
- if enabled {
+func testEnvoyDisableCompression(namespace, acceptEncoding, contentEncoding string, disabled bool) {
+ testSpec := fmt.Sprintf("responses compressed with accept-encoding %s expecting content-encoding %s", acceptEncoding, contentEncoding)
+ if disabled {
testSpec = "responses are plaintext when compression disabled"
}
- FSpecify(testSpec, func() {
+
+ Specify(testSpec, func() {
resp := "minimum_text_to_enable_gzipminimum_text_to_enable_gzipminimum_text_to_enable_gzipminimum_text_to_enable_gzipminimum_text_to_enable_gzipminimum_text_to_enable_gzip"
p := &contour_v1.HTTPProxy{
ObjectMeta: meta_v1.ObjectMeta{
@@ -57,24 +60,25 @@ func testEnvoyDisableCompression(namespace string, enabled bool) {
}
require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid))
- // Send HTTP request, we will check backend connection was over HTTPS.
- res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{
- Path: "/directresponse",
- Host: p.Spec.VirtualHost.Fqdn,
- RequestOpts: []func(*http.Request){
- e2e.OptSetHeaders(map[string]string{
- "Accept-Encoding": "gzip, deflate",
- }),
- },
- Condition: e2e.HasStatusCode(200),
- })
- require.NotNil(f.T(), res, "request never succeeded")
- require.Truef(f.T(), ok, "expected 200 response code, got %d", res.StatusCode)
- fmt.Printf("response: %+v\n", res.Headers)
- if enabled {
- require.NotContains(f.T(), res.Headers["Content-Encoding"], "gzip", "expected plain text")
- return
- }
- require.Contains(f.T(), res.Headers["Content-Encoding"], "gzip", "expected plain text")
+ require.EventuallyWithT(f.T(), func(c *assert.CollectT) {
+ res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{
+ Path: "/directresponse",
+ Host: p.Spec.VirtualHost.Fqdn,
+ RequestOpts: []func(*http.Request){
+ e2e.OptSetHeaders(map[string]string{
+ "Accept-Encoding": fmt.Sprintf("%s, deflate", acceptEncoding),
+ }),
+ },
+ Condition: e2e.HasStatusCode(200),
+ })
+ assert.NotNil(c, res, "request never succeeded")
+ assert.Truef(c, ok, "expected 200 response code, got %d", res.StatusCode)
+ contentEncodingHeaderValue := res.Headers.Get("Content-Encoding")
+ if disabled {
+ assert.NotEqual(c, contentEncodingHeaderValue, contentEncoding, "expected plain text")
+ return
+ }
+ assert.Equal(c, contentEncodingHeaderValue, contentEncoding, "expected plain text")
+ }, 15*time.Second, f.RetryInterval)
})
}
diff --git a/test/e2e/httpproxy/httpproxy_test.go b/test/e2e/httpproxy/httpproxy_test.go
index 42edb73bd9c..c8e85cef70e 100644
--- a/test/e2e/httpproxy/httpproxy_test.go
+++ b/test/e2e/httpproxy/httpproxy_test.go
@@ -389,15 +389,36 @@ var _ = Describe("HTTPProxy", func() {
})
f.NamespacedTest("httpproxy-default-compression", func(namespace string) {
- testEnvoyDisableCompression(namespace, false)
+ testEnvoyDisableCompression(namespace, "gzip", "gzip", false)
})
f.NamespacedTest("httpproxy-disable-compression", func(namespace string) {
Context("with compression disabled", func() {
BeforeEach(func() {
- contourConfig.DisableCompression = true
+ contourConfig.Compression = "disabled"
+ contourConfiguration.Spec.Envoy.Listener.Compression = "disabled"
})
- testEnvoyDisableCompression(namespace, true)
+ testEnvoyDisableCompression(namespace, "gzip", "gzip", true)
+ })
+ })
+
+ f.NamespacedTest("httpproxy-brotli-compression", func(namespace string) {
+ Context("with brotli compression", func() {
+ BeforeEach(func() {
+ contourConfig.Compression = "brotli"
+ contourConfiguration.Spec.Envoy.Listener.Compression = "brotli"
+ })
+ testEnvoyDisableCompression(namespace, "br", "br", false)
+ })
+ })
+
+ f.NamespacedTest("httpproxy-zstd-compression", func(namespace string) {
+ Context("with zstd compression", func() {
+ BeforeEach(func() {
+ contourConfig.Compression = "zstd"
+ contourConfiguration.Spec.Envoy.Listener.Compression = "zstd"
+ })
+ testEnvoyDisableCompression(namespace, "zstd", "zstd", false)
})
})
From f7b261b22d9a6ddb2e5d3e0f8991ab6b3d0fc69b Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Sat, 19 Oct 2024 12:41:10 +0100
Subject: [PATCH 12/30] add validation to crd compression field
Signed-off-by: Geoff Macartney
---
apis/projectcontour/v1alpha1/contourconfig.go | 1 +
examples/contour/01-crds.yaml | 10 ++++++++++
examples/render/contour-deployment.yaml | 10 ++++++++++
examples/render/contour-gateway-provisioner.yaml | 10 ++++++++++
examples/render/contour-gateway.yaml | 10 ++++++++++
examples/render/contour.yaml | 10 ++++++++++
6 files changed, 51 insertions(+)
diff --git a/apis/projectcontour/v1alpha1/contourconfig.go b/apis/projectcontour/v1alpha1/contourconfig.go
index d96ff51691b..b4145b41edc 100644
--- a/apis/projectcontour/v1alpha1/contourconfig.go
+++ b/apis/projectcontour/v1alpha1/contourconfig.go
@@ -351,6 +351,7 @@ type EnvoyListenerConfig struct {
// Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
// Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
// Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ // +kubebuilder:validation:Enum="gzip";"brotli";"zstd";"disabled"
// +optional
Compression EnvoyCompressionType `json:"compression,omitempty"`
diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml
index 911f670200e..808b7eba36b 100644
--- a/examples/contour/01-crds.yaml
+++ b/examples/contour/01-crds.yaml
@@ -286,6 +286,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
@@ -4074,6 +4079,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml
index 08de1688e9a..1b453c8f9a4 100644
--- a/examples/render/contour-deployment.yaml
+++ b/examples/render/contour-deployment.yaml
@@ -506,6 +506,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
@@ -4294,6 +4299,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml
index 9302324f810..efec845de1f 100644
--- a/examples/render/contour-gateway-provisioner.yaml
+++ b/examples/render/contour-gateway-provisioner.yaml
@@ -297,6 +297,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
@@ -4085,6 +4090,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml
index a993637fc75..b462381a9cd 100644
--- a/examples/render/contour-gateway.yaml
+++ b/examples/render/contour-gateway.yaml
@@ -322,6 +322,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
@@ -4110,6 +4115,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml
index ffd55e0337d..b09b87cdeff 100644
--- a/examples/render/contour.yaml
+++ b/examples/render/contour.yaml
@@ -506,6 +506,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
@@ -4294,6 +4299,11 @@ spec:
Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
type: string
connectionBalancer:
description: |-
From b68f0b1dd9e7d8cfdf58c9b91719a7b65878954d Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Sat, 19 Oct 2024 12:41:31 +0100
Subject: [PATCH 13/30] delete unnecessary output log
Signed-off-by: Geoff Macartney
---
cmd/contour/serve.go | 2 --
1 file changed, 2 deletions(-)
diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go
index b361a56d2b1..b2414214c03 100644
--- a/cmd/contour/serve.go
+++ b/cmd/contour/serve.go
@@ -473,8 +473,6 @@ func (s *Server) doServe() error {
SocketOptions: contourConfiguration.Envoy.Listener.SocketOptions,
}
- s.log.WithField("context", "listenerConfig").Infof("compression setting: %s", listenerConfig.Compression)
-
if listenerConfig.TracingConfig, err = s.setupTracingService(contourConfiguration.Tracing); err != nil {
return err
}
From 5dcdc33aeb0d1b27c24527e34734857ea2583612 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Mon, 21 Oct 2024 15:11:22 +0100
Subject: [PATCH 14/30] define compression with a struct for API extensibility
Signed-off-by: Geoff Macartney
---
apis/projectcontour/v1alpha1/compression.go | 28 +++++--
.../v1alpha1/compression_test.go | 6 +-
apis/projectcontour/v1alpha1/contourconfig.go | 7 +-
changelogs/unreleased/6546-chaosbox-small.md | 2 +-
cmd/contour/serve.go | 9 ++-
cmd/contour/servecontext.go | 26 ++++---
cmd/contour/servecontext_test.go | 3 -
examples/contour/01-crds.yaml | 50 +++++++-----
examples/render/contour-deployment.yaml | 50 +++++++-----
.../render/contour-gateway-provisioner.yaml | 50 +++++++-----
examples/render/contour-gateway.yaml | 50 +++++++-----
examples/render/contour.yaml | 50 +++++++-----
.../contourconfig/contourconfiguration.go | 1 -
.../contourconfiguration_test.go | 6 +-
internal/envoy/v3/listener.go | 38 ++++-----
internal/featuretests/v3/compression_test.go | 24 ++++--
internal/xdscache/v3/listener.go | 6 +-
internal/xdscache/v3/listener_test.go | 40 +++++++---
pkg/config/parameters.go | 39 ++++++----
.../docs/main/config/api-reference.html | 77 ++++++++++++++-----
test/e2e/fixtures.go | 1 -
test/e2e/httpproxy/httpproxy_test.go | 24 ++++--
22 files changed, 375 insertions(+), 212 deletions(-)
diff --git a/apis/projectcontour/v1alpha1/compression.go b/apis/projectcontour/v1alpha1/compression.go
index 9c850934eda..3ae14097acf 100644
--- a/apis/projectcontour/v1alpha1/compression.go
+++ b/apis/projectcontour/v1alpha1/compression.go
@@ -15,27 +15,39 @@ package v1alpha1
import "fmt"
-type EnvoyCompressionType string
+// CompressionAlgorithm defines the type of compression algorithm applied in default HTTP listener filter chain.
+// Allowable values are defined as names of well known compression algorithms (plus "disabled").
+type CompressionAlgorithm string
+
+// EnvoyCompression defines configuration related to compression in the default HTTP Listener filter chain.
+type EnvoyCompression struct {
+ // Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ // Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ // Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ // +kubebuilder:validation:Enum="gzip";"brotli";"zstd";"disabled"
+ // +optional
+ Algorithm CompressionAlgorithm `json:"algorithm,omitempty"`
+}
-func (c EnvoyCompressionType) Validate() error {
- switch c {
+func (a CompressionAlgorithm) Validate() error {
+ switch a {
case BrotliCompression, DisabledCompression, GzipCompression, ZstdCompression:
return nil
default:
- return fmt.Errorf("invalid compression type: %q", c)
+ return fmt.Errorf("invalid compression type: %q", a)
}
}
const (
// BrotliCompression specifies brotli as the default HTTP filter chain compression mechanism
- BrotliCompression EnvoyCompressionType = "brotli"
+ BrotliCompression CompressionAlgorithm = "brotli"
// DisabledCompression specifies that there will be no compression in the default HTTP filter chain
- DisabledCompression EnvoyCompressionType = "disabled"
+ DisabledCompression CompressionAlgorithm = "disabled"
// GzipCompression specifies gzip as the default HTTP filter chain compression mechanism
- GzipCompression EnvoyCompressionType = "gzip"
+ GzipCompression CompressionAlgorithm = "gzip"
// ZstdCompression specifies zstd as the default HTTP filter chain compression mechanism
- ZstdCompression EnvoyCompressionType = "zstd"
+ ZstdCompression CompressionAlgorithm = "zstd"
)
diff --git a/apis/projectcontour/v1alpha1/compression_test.go b/apis/projectcontour/v1alpha1/compression_test.go
index d90ad832aa4..0251c4d97eb 100644
--- a/apis/projectcontour/v1alpha1/compression_test.go
+++ b/apis/projectcontour/v1alpha1/compression_test.go
@@ -21,9 +21,9 @@ import (
contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
)
-func TestValidateEnvoyCompressionType(t *testing.T) {
- require.Error(t, contour_v1alpha1.EnvoyCompressionType("").Validate())
- require.Error(t, contour_v1alpha1.EnvoyCompressionType("foo").Validate())
+func TestValidateEnvoyCompressionAlgorithmType(t *testing.T) {
+ require.Error(t, contour_v1alpha1.CompressionAlgorithm("").Validate())
+ require.Error(t, contour_v1alpha1.CompressionAlgorithm("foo").Validate())
require.NoError(t, contour_v1alpha1.BrotliCompression.Validate())
require.NoError(t, contour_v1alpha1.DisabledCompression.Validate())
diff --git a/apis/projectcontour/v1alpha1/contourconfig.go b/apis/projectcontour/v1alpha1/contourconfig.go
index b4145b41edc..fcc6b38638c 100644
--- a/apis/projectcontour/v1alpha1/contourconfig.go
+++ b/apis/projectcontour/v1alpha1/contourconfig.go
@@ -348,12 +348,9 @@ type EnvoyListenerConfig struct {
// +optional
UseProxyProto *bool `json:"useProxyProtocol,omitempty"`
- // Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- // Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- // Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- // +kubebuilder:validation:Enum="gzip";"brotli";"zstd";"disabled"
+ // Compression defines configuration related to compression in the default HTTP Listener filters.
// +optional
- Compression EnvoyCompressionType `json:"compression,omitempty"`
+ Compression *EnvoyCompression `json:"compression,omitempty"`
// DisableAllowChunkedLength disables the RFC-compliant Envoy behavior to
// strip the "Content-Length" header if "Transfer-Encoding: chunked" is
diff --git a/changelogs/unreleased/6546-chaosbox-small.md b/changelogs/unreleased/6546-chaosbox-small.md
index 5f156b7289d..6017d1b0588 100644
--- a/changelogs/unreleased/6546-chaosbox-small.md
+++ b/changelogs/unreleased/6546-chaosbox-small.md
@@ -1 +1 @@
-Add "compression" flag to set/disable the compression type applied in the default HTTP filter chain.
+Add "compression" object to define settings in default HTTP filters, initially just supporting changing/disabling compression algorithm.
diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go
index b2414214c03..8a4801bd137 100644
--- a/cmd/contour/serve.go
+++ b/cmd/contour/serve.go
@@ -123,9 +123,16 @@ func registerServe(app *kingpin.Application) (*kingpin.CmdClause, *serveContext)
return nil
}
+
+ if ctx.Config.Compression == nil {
+ ctx.Config.Compression = &config.CompressionParameters{
+ Algorithm: config.CompressionDefault,
+ }
+ }
+
serve.Flag("accesslog-format", "Format for Envoy access logs.").PlaceHolder("").StringVar((*string)(&ctx.Config.AccessLogFormat))
- serve.Flag("compression", "Set or disable compression type in default Listener filters.").PlaceHolder("").StringVar((*string)(&ctx.Config.Compression))
+ serve.Flag("compression", "Set or disable compression type in default Listener filters.").PlaceHolder("").StringVar((*string)(&ctx.Config.Compression.Algorithm))
serve.Flag("config-path", "Path to base configuration.").Short('c').PlaceHolder("/path/to/file").Action(parseConfig).ExistingFileVar(&configFile)
serve.Flag("contour-cafile", "CA bundle file name for serving gRPC with TLS.").Envar("CONTOUR_CAFILE").StringVar(&ctx.caFile)
serve.Flag("contour-cert-file", "Contour certificate file name for serving gRPC over TLS.").PlaceHolder("/path/to/file").Envar("CONTOUR_CERT_FILE").StringVar(&ctx.contourCert)
diff --git a/cmd/contour/servecontext.go b/cmd/contour/servecontext.go
index 37d0936e18f..3bf62e9a541 100644
--- a/cmd/contour/servecontext.go
+++ b/cmd/contour/servecontext.go
@@ -333,16 +333,22 @@ func (ctx *serveContext) convertToContourConfigurationSpec() contour_v1alpha1.Co
accessLogLevel = contour_v1alpha1.LogLevelDisabled
}
- var compression contour_v1alpha1.EnvoyCompressionType
- switch ctx.Config.Compression {
- case config.CompressionBrotli:
- compression = contour_v1alpha1.BrotliCompression
- case config.CompressionDisabled:
- compression = contour_v1alpha1.DisabledCompression
- case config.CompressionGzip:
- compression = contour_v1alpha1.GzipCompression
- case config.CompressionZstd:
- compression = contour_v1alpha1.ZstdCompression
+ var compression *contour_v1alpha1.EnvoyCompression
+ if ctx.Config.Compression != nil {
+ var algorithm contour_v1alpha1.CompressionAlgorithm
+ switch ctx.Config.Compression.Algorithm {
+ case config.CompressionBrotli:
+ algorithm = contour_v1alpha1.BrotliCompression
+ case config.CompressionDisabled:
+ algorithm = contour_v1alpha1.DisabledCompression
+ case config.CompressionGzip:
+ algorithm = contour_v1alpha1.GzipCompression
+ case config.CompressionZstd:
+ algorithm = contour_v1alpha1.ZstdCompression
+ }
+ compression = &contour_v1alpha1.EnvoyCompression{
+ Algorithm: algorithm,
+ }
}
var defaultHTTPVersions []contour_v1alpha1.HTTPVersionType
diff --git a/cmd/contour/servecontext_test.go b/cmd/contour/servecontext_test.go
index 5f946f18e6a..cf205d81a46 100644
--- a/cmd/contour/servecontext_test.go
+++ b/cmd/contour/servecontext_test.go
@@ -408,7 +408,6 @@ func TestConvertServeContext(t *testing.T) {
},
Listener: &contour_v1alpha1.EnvoyListenerConfig{
UseProxyProto: ptr.To(false),
- Compression: "gzip",
DisableAllowChunkedLength: ptr.To(false),
DisableMergeSlashes: ptr.To(false),
ServerHeaderTransformation: contour_v1alpha1.OverwriteServerHeader,
@@ -893,14 +892,12 @@ func TestConvertServeContext(t *testing.T) {
ctx.Config.Listener.MaxRequestsPerIOCycle = ptr.To(uint32(10))
ctx.Config.Listener.HTTP2MaxConcurrentStreams = ptr.To(uint32(30))
ctx.Config.Listener.MaxConnectionsPerListener = ptr.To(uint32(50))
- ctx.Config.Compression = "gzip"
return ctx
},
getContourConfiguration: func(cfg contour_v1alpha1.ContourConfigurationSpec) contour_v1alpha1.ContourConfigurationSpec {
cfg.Envoy.Listener.MaxRequestsPerIOCycle = ptr.To(uint32(10))
cfg.Envoy.Listener.HTTP2MaxConcurrentStreams = ptr.To(uint32(30))
cfg.Envoy.Listener.MaxConnectionsPerListener = ptr.To(uint32(50))
- cfg.Envoy.Listener.Compression = "gzip"
return cfg
},
},
diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml
index 808b7eba36b..48601e397a0 100644
--- a/examples/contour/01-crds.yaml
+++ b/examples/contour/01-crds.yaml
@@ -282,16 +282,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related to
+ compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4075,16 +4080,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related
+ to compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml
index 1b453c8f9a4..51aeaa1a389 100644
--- a/examples/render/contour-deployment.yaml
+++ b/examples/render/contour-deployment.yaml
@@ -502,16 +502,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related to
+ compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4295,16 +4300,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related
+ to compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml
index efec845de1f..7ea0dc3c500 100644
--- a/examples/render/contour-gateway-provisioner.yaml
+++ b/examples/render/contour-gateway-provisioner.yaml
@@ -293,16 +293,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related to
+ compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4086,16 +4091,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related
+ to compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml
index b462381a9cd..e7981bf7f37 100644
--- a/examples/render/contour-gateway.yaml
+++ b/examples/render/contour-gateway.yaml
@@ -318,16 +318,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related to
+ compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4111,16 +4116,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related
+ to compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml
index b09b87cdeff..c1b7b931224 100644
--- a/examples/render/contour.yaml
+++ b/examples/render/contour.yaml
@@ -502,16 +502,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related to
+ compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
@@ -4295,16 +4300,21 @@ spec:
values.
properties:
compression:
- description: |-
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- enum:
- - gzip
- - brotli
- - zstd
- - disabled
- type: string
+ description: Compression defines configuration related
+ to compression in the default HTTP Listener filters.
+ properties:
+ algorithm:
+ description: |-
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+ Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
+ Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ enum:
+ - gzip
+ - brotli
+ - zstd
+ - disabled
+ type: string
+ type: object
connectionBalancer:
description: |-
ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer
diff --git a/internal/contourconfig/contourconfiguration.go b/internal/contourconfig/contourconfiguration.go
index 9dbaf7e1d40..0c369f170cb 100644
--- a/internal/contourconfig/contourconfiguration.go
+++ b/internal/contourconfig/contourconfiguration.go
@@ -66,7 +66,6 @@ func Defaults() contour_v1alpha1.ContourConfigurationSpec {
Envoy: &contour_v1alpha1.EnvoyConfig{
Listener: &contour_v1alpha1.EnvoyListenerConfig{
UseProxyProto: ptr.To(false),
- Compression: contour_v1alpha1.GzipCompression,
DisableAllowChunkedLength: ptr.To(false),
DisableMergeSlashes: ptr.To(false),
ServerHeaderTransformation: contour_v1alpha1.OverwriteServerHeader,
diff --git a/internal/contourconfig/contourconfiguration_test.go b/internal/contourconfig/contourconfiguration_test.go
index 7ee574985cd..294e6a4609b 100644
--- a/internal/contourconfig/contourconfiguration_test.go
+++ b/internal/contourconfig/contourconfiguration_test.go
@@ -54,8 +54,10 @@ func TestOverlayOnDefaults(t *testing.T) {
},
Envoy: &contour_v1alpha1.EnvoyConfig{
Listener: &contour_v1alpha1.EnvoyListenerConfig{
- UseProxyProto: ptr.To(true),
- Compression: "brotli",
+ UseProxyProto: ptr.To(true),
+ Compression: &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.BrotliCompression,
+ },
MaxRequestsPerConnection: ptr.To(uint32(1)),
HTTP2MaxConcurrentStreams: ptr.To(uint32(10)),
DisableAllowChunkedLength: ptr.To(true),
diff --git a/internal/envoy/v3/listener.go b/internal/envoy/v3/listener.go
index 63d71d77340..59dcc233a67 100644
--- a/internal/envoy/v3/listener.go
+++ b/internal/envoy/v3/listener.go
@@ -16,6 +16,8 @@ package v3
import (
"errors"
"fmt"
+ envoy_compression_brotli_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/brotli/compressor/v3"
+ envoy_compression_zstd_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/zstd/compressor/v3"
"sort"
"strings"
"time"
@@ -23,9 +25,7 @@ import (
envoy_config_accesslog_v3 "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v3"
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
- envoy_compression_brotli_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/brotli/compressor/v3"
envoy_compression_gzip_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/gzip/compressor/v3"
- envoy_compression_zstd_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/zstd/compressor/v3"
envoy_filter_http_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/compressor/v3"
envoy_filter_http_cors_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/cors/v3"
envoy_filter_http_ext_authz_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ext_authz/v3"
@@ -191,7 +191,7 @@ type httpConnectionManagerBuilder struct {
maxRequestsPerConnection *uint32
http2MaxConcurrentStreams *uint32
enableWebsockets bool
- compression contour_v1alpha1.EnvoyCompressionType
+ compression *contour_v1alpha1.EnvoyCompression
}
func (b *httpConnectionManagerBuilder) EnableWebsockets(enable bool) *httpConnectionManagerBuilder {
@@ -275,7 +275,7 @@ func (b *httpConnectionManagerBuilder) MergeSlashes(enabled bool) *httpConnectio
return b
}
-func (b *httpConnectionManagerBuilder) Compression(compressor contour_v1alpha1.EnvoyCompressionType) *httpConnectionManagerBuilder {
+func (b *httpConnectionManagerBuilder) Compression(compressor *contour_v1alpha1.EnvoyCompression) *httpConnectionManagerBuilder {
b.compression = compressor
return b
}
@@ -317,20 +317,22 @@ func (b *httpConnectionManagerBuilder) DefaultFilters() *httpConnectionManagerBu
// Add a default set of ordered http filters.
// The names are not required to match anything and are
// identified by the TypeURL of each filter.
- var compressor proto.Message
- compressorName := ""
- switch b.compression {
- case contour_v1alpha1.BrotliCompression:
- compressorName = "brotli"
- compressor = &envoy_compression_brotli_compressor_v3.Brotli{}
- case contour_v1alpha1.DisabledCompression:
- compressor = nil
- case contour_v1alpha1.ZstdCompression:
- compressorName = "zstd"
- compressor = &envoy_compression_zstd_compressor_v3.Zstd{}
- default:
- compressorName = "gzip"
- compressor = &envoy_compression_gzip_compressor_v3.Gzip{}
+ var compressor proto.Message = &envoy_compression_gzip_compressor_v3.Gzip{}
+ var compressorName = string(contour_v1alpha1.GzipCompression)
+ if b.compression != nil {
+ switch b.compression.Algorithm {
+ case contour_v1alpha1.BrotliCompression:
+ compressorName = "brotli"
+ compressor = &envoy_compression_brotli_compressor_v3.Brotli{}
+ case contour_v1alpha1.DisabledCompression:
+ compressor = nil
+ case contour_v1alpha1.ZstdCompression:
+ compressorName = "zstd"
+ compressor = &envoy_compression_zstd_compressor_v3.Zstd{}
+ default:
+ compressorName = "gzip"
+ compressor = &envoy_compression_gzip_compressor_v3.Gzip{}
+ }
}
if compressor != nil {
diff --git a/internal/featuretests/v3/compression_test.go b/internal/featuretests/v3/compression_test.go
index a0c941438c8..0535242c487 100644
--- a/internal/featuretests/v3/compression_test.go
+++ b/internal/featuretests/v3/compression_test.go
@@ -72,7 +72,9 @@ func TestDefaultCompression(t *testing.T) {
func TestDisableCompression(t *testing.T) {
withDisableCompression := func(conf *xdscache_v3.ListenerConfig) {
- conf.Compression = "disabled"
+ conf.Compression = &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.DisabledCompression,
+ }
}
rh, c, done := setup(t, withDisableCompression)
@@ -104,7 +106,9 @@ func TestDisableCompression(t *testing.T) {
httpListener := defaultHTTPListener()
httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
- Compression("disabled").
+ Compression(&contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.DisabledCompression,
+ }).
RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
@@ -120,7 +124,9 @@ func TestDisableCompression(t *testing.T) {
func TestBrotliCompression(t *testing.T) {
withBrotliCompression := func(conf *xdscache_v3.ListenerConfig) {
- conf.Compression = "brotli"
+ conf.Compression = &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.BrotliCompression,
+ }
}
rh, c, done := setup(t, withBrotliCompression)
@@ -152,7 +158,9 @@ func TestBrotliCompression(t *testing.T) {
httpListener := defaultHTTPListener()
httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
- Compression("brotli").
+ Compression(&contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.BrotliCompression,
+ }).
RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
@@ -168,7 +176,9 @@ func TestBrotliCompression(t *testing.T) {
func TestZstdCompression(t *testing.T) {
withZstdCompression := func(conf *xdscache_v3.ListenerConfig) {
- conf.Compression = "zstd"
+ conf.Compression = &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.ZstdCompression,
+ }
}
rh, c, done := setup(t, withZstdCompression)
@@ -200,7 +210,9 @@ func TestZstdCompression(t *testing.T) {
httpListener := defaultHTTPListener()
httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
- Compression("zstd").
+ Compression(&contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.ZstdCompression,
+ }).
RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
diff --git a/internal/xdscache/v3/listener.go b/internal/xdscache/v3/listener.go
index 36ad156a32b..b053493861d 100644
--- a/internal/xdscache/v3/listener.go
+++ b/internal/xdscache/v3/listener.go
@@ -66,10 +66,8 @@ type ListenerConfig struct {
// If not set, defaults to false.
UseProxyProto bool
- // Compression configures which compression, if any, the listener uses in the compression filter as part of the defaultFilters.
- // Valid values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- // Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
- Compression contour_v1alpha1.EnvoyCompressionType
+ // Compression defines configuration related to compression in the default HTTP Listener filters.
+ Compression *contour_v1alpha1.EnvoyCompression
// MinimumTLSVersion defines the minimum TLS protocol version the proxy should accept.
MinimumTLSVersion string
diff --git a/internal/xdscache/v3/listener_test.go b/internal/xdscache/v3/listener_test.go
index a7223d48ce3..c4f464ef8c4 100644
--- a/internal/xdscache/v3/listener_test.go
+++ b/internal/xdscache/v3/listener_test.go
@@ -3076,7 +3076,9 @@ func TestListenerVisit(t *testing.T) {
},
"httpproxy with disabled compression set in listener config": {
ListenerConfig: ListenerConfig{
- Compression: "disabled",
+ Compression: &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.DisabledCompression,
+ },
},
objs: []any{
&contour_v1.HTTPProxy{
@@ -3106,7 +3108,9 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression("disabled").
+ Compression(&contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.DisabledCompression,
+ }).
RouteConfigName(ENVOY_HTTP_LISTENER).
MetricsPrefix(ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
@@ -3118,7 +3122,9 @@ func TestListenerVisit(t *testing.T) {
},
"httpproxy with gzip compression set in listener config": {
ListenerConfig: ListenerConfig{
- Compression: "gzip",
+ Compression: &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.GzipCompression,
+ },
},
objs: []any{
&contour_v1.HTTPProxy{
@@ -3148,7 +3154,9 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression("gzip").
+ Compression(&contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.GzipCompression,
+ }).
RouteConfigName(ENVOY_HTTP_LISTENER).
MetricsPrefix(ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
@@ -3160,7 +3168,9 @@ func TestListenerVisit(t *testing.T) {
},
"httpproxy with brotli compression set in listener config": {
ListenerConfig: ListenerConfig{
- Compression: "brotli",
+ Compression: &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.BrotliCompression,
+ },
},
objs: []any{
&contour_v1.HTTPProxy{
@@ -3190,7 +3200,9 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression("brotli").
+ Compression(&contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.BrotliCompression,
+ }).
RouteConfigName(ENVOY_HTTP_LISTENER).
MetricsPrefix(ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
@@ -3202,7 +3214,9 @@ func TestListenerVisit(t *testing.T) {
},
"httpproxy with zstd compression set in listener config": {
ListenerConfig: ListenerConfig{
- Compression: "zstd",
+ Compression: &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.ZstdCompression,
+ },
},
objs: []any{
&contour_v1.HTTPProxy{
@@ -3232,7 +3246,9 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression("zstd").
+ Compression(&contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.ZstdCompression,
+ }).
RouteConfigName(ENVOY_HTTP_LISTENER).
MetricsPrefix(ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
@@ -3244,7 +3260,9 @@ func TestListenerVisit(t *testing.T) {
},
"httpproxy with invalid compression set in listener config": {
ListenerConfig: ListenerConfig{
- Compression: "invalid value",
+ Compression: &contour_v1alpha1.EnvoyCompression{
+ Algorithm: "invalid value",
+ },
},
objs: []any{
&contour_v1.HTTPProxy{
@@ -3274,7 +3292,9 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression("gzip").
+ Compression(&contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.GzipCompression,
+ }).
RouteConfigName(ENVOY_HTTP_LISTENER).
MetricsPrefix(ENVOY_HTTP_LISTENER).
AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
index d349c632a4b..1b4d3c7d064 100644
--- a/pkg/config/parameters.go
+++ b/pkg/config/parameters.go
@@ -651,11 +651,9 @@ type Parameters struct {
// which strips duplicate slashes from request URL paths.
DisableMergeSlashes bool `yaml:"disableMergeSlashes,omitempty"`
- // Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
- // Values: `gzip` (default), `brotli`, `zstd`, `disabled`.
- // Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response
+ // Compression defines configuration relating to compression in the default HTTP filter chain.
// +optional
- Compression EnvoyCompressionType `yaml:"compression,omitempty"`
+ Compression *CompressionParameters `yaml:"compression,omitempty"`
// Defines the action to be applied to the Server header on the response path.
// When configured as overwrite, overwrites any Server header with "envoy".
@@ -972,17 +970,31 @@ const (
LogLevelDisabled AccessLogLevel = "disabled"
)
-type EnvoyCompressionType string
+// CompressionParameters holds various configurable compression related values.
+type CompressionParameters struct {
-func (c EnvoyCompressionType) Validate() error {
- return contour_v1alpha1.EnvoyCompressionType(c).Validate()
+ // Algorithm configures which compression algorithm, if any, to use in the default HTTP listener filter chain.
+ // Valid options are 'gzip' (default), 'brotli', 'zstd' and 'disabled'.
+ // +optional
+ Algorithm CompressionAlgorithm `yaml:"algorithm,omitempty"`
+}
+
+func (c CompressionParameters) Validate() error {
+ return c.Algorithm.Validate()
+}
+
+type CompressionAlgorithm string
+
+func (c CompressionAlgorithm) Validate() error {
+ return contour_v1alpha1.CompressionAlgorithm(c).Validate()
}
const (
- CompressionGzip EnvoyCompressionType = "gzip"
- CompressionBrotli EnvoyCompressionType = "brotli"
- CompressionDisabled EnvoyCompressionType = "disabled"
- CompressionZstd EnvoyCompressionType = "zstd"
+ CompressionGzip CompressionAlgorithm = "gzip"
+ CompressionBrotli CompressionAlgorithm = "brotli"
+ CompressionDisabled CompressionAlgorithm = "disabled"
+ CompressionZstd CompressionAlgorithm = "zstd"
+ CompressionDefault = CompressionGzip
)
// Validate verifies that the parameter values do not have any syntax errors.
@@ -1052,8 +1064,8 @@ func (p *Parameters) Validate() error {
return p.Listener.Validate()
}
-// DefaultCompressionFilter is the compression mechanism in the default HTTP filter chain
-const DefaultCompressionFilter = CompressionGzip
+// DefaultCompressionAlgorithm is the compression mechanism in the default HTTP filter chain
+const DefaultCompressionAlgorithm = CompressionGzip
// Defaults returns the default set of parameters.
func Defaults() Parameters {
@@ -1074,7 +1086,6 @@ func Defaults() Parameters {
DisablePermitInsecure: false,
DisableAllowChunkedLength: false,
DisableMergeSlashes: false,
- Compression: DefaultCompressionFilter,
ServerHeaderTransformation: OverwriteServerHeader,
Timeouts: TimeoutParameters{
// This is chosen as a rough default to stop idle connections wasting resources,
diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html
index aa21e8084c8..340f09b7967 100644
--- a/site/content/docs/main/config/api-reference.html
+++ b/site/content/docs/main/config/api-reference.html
@@ -5851,6 +5851,40 @@ ClusterParameters
+CompressionAlgorithm
+(string
alias)
+
+(Appears on:
+EnvoyCompression)
+
+
+
CompressionAlgorithm defines the type of compression algorithm applied in default HTTP listener filter chain.
+Allowable values are defined as names of well known compression algorithms (plus “disabled”).
+
+
+
+
+Value |
+Description |
+
+
+"brotli" |
+BrotliCompression specifies brotli as the default HTTP filter chain compression mechanism
+ |
+
"gzip" |
+DefaultCompression specifies which of the compression algorithms is used by default
+ |
+
"disabled" |
+DisabledCompression specifies that there will be no compression in the default HTTP filter chain
+ |
+
"gzip" |
+GzipCompression specifies gzip as the default HTTP filter chain compression mechanism
+ |
+
"zstd" |
+ZstdCompression specifies zstd as the default HTTP filter chain compression mechanism
+ |
+
+
ContourConfigurationSpec
@@ -6595,34 +6629,41 @@
DeploymentSettings
-EnvoyCompressionType
-(string
alias)
+EnvoyCompression
+
(Appears on:
EnvoyListenerConfig)
+
EnvoyCompression defines configuration related to compression in the default HTTP Listener filter chain.
-Value |
+Field |
Description |
-"brotli" |
-BrotliCompression specifies brotli as the default HTTP filter chain compression mechanism
- |
-
"disabled" |
-DisabledCompression specifies that there will be no compression in the default HTTP filter chain
- |
-
"gzip" |
-GzipCompression specifies gzip as the default HTTP filter chain compression mechanism
+ |
+
+
+algorithm
+
+
+
+CompressionAlgorithm
+
+
|
-
"zstd" |
-ZstdCompression specifies zstd as the default HTTP filter chain compression mechanism
+ |
+(Optional)
+ Algorithm selects the compression type applied in the compression HTTP filter of the default Listener filters.
+Values: gzip (default), brotli , zstd , disabled .
+Setting this to disabled will make Envoy skip “Accept-Encoding: gzip,deflate” request header and always return uncompressed response
|
-
+
+
EnvoyConfig
@@ -6932,16 +6973,14 @@ EnvoyListenerConfig
compression
-
-EnvoyCompressionType
+
+EnvoyCompression
(Optional)
- Compression selects the compression type applied in the compression HTTP filter of the default Listener filters.
-Values: gzip (default), brotli , zstd , disabled .
-Setting this to disabled will make Envoy skip “Accept-Encoding: gzip,deflate” request header and always return uncompressed response
+Compression defines configuration related to compression in the default HTTP Listener filters.
|
diff --git a/test/e2e/fixtures.go b/test/e2e/fixtures.go
index 6d819bc1174..4cc20831bf6 100644
--- a/test/e2e/fixtures.go
+++ b/test/e2e/fixtures.go
@@ -583,7 +583,6 @@ func DefaultContourConfiguration() *contour_v1alpha1.ContourConfiguration {
},
Listener: &contour_v1alpha1.EnvoyListenerConfig{
UseProxyProto: ptr.To(false),
- Compression: "gzip",
DisableAllowChunkedLength: ptr.To(false),
ConnectionBalancer: "",
TLS: &contour_v1alpha1.EnvoyTLS{
diff --git a/test/e2e/httpproxy/httpproxy_test.go b/test/e2e/httpproxy/httpproxy_test.go
index c8e85cef70e..7a45b8f62e9 100644
--- a/test/e2e/httpproxy/httpproxy_test.go
+++ b/test/e2e/httpproxy/httpproxy_test.go
@@ -395,8 +395,12 @@ var _ = Describe("HTTPProxy", func() {
f.NamespacedTest("httpproxy-disable-compression", func(namespace string) {
Context("with compression disabled", func() {
BeforeEach(func() {
- contourConfig.Compression = "disabled"
- contourConfiguration.Spec.Envoy.Listener.Compression = "disabled"
+ contourConfig.Compression = &config.CompressionParameters{
+ Algorithm: config.CompressionDisabled,
+ }
+ contourConfiguration.Spec.Envoy.Listener.Compression = &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.DisabledCompression,
+ }
})
testEnvoyDisableCompression(namespace, "gzip", "gzip", true)
})
@@ -405,8 +409,12 @@ var _ = Describe("HTTPProxy", func() {
f.NamespacedTest("httpproxy-brotli-compression", func(namespace string) {
Context("with brotli compression", func() {
BeforeEach(func() {
- contourConfig.Compression = "brotli"
- contourConfiguration.Spec.Envoy.Listener.Compression = "brotli"
+ contourConfig.Compression = &config.CompressionParameters{
+ Algorithm: config.CompressionBrotli,
+ }
+ contourConfiguration.Spec.Envoy.Listener.Compression = &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.BrotliCompression,
+ }
})
testEnvoyDisableCompression(namespace, "br", "br", false)
})
@@ -415,8 +423,12 @@ var _ = Describe("HTTPProxy", func() {
f.NamespacedTest("httpproxy-zstd-compression", func(namespace string) {
Context("with zstd compression", func() {
BeforeEach(func() {
- contourConfig.Compression = "zstd"
- contourConfiguration.Spec.Envoy.Listener.Compression = "zstd"
+ contourConfig.Compression = &config.CompressionParameters{
+ Algorithm: config.CompressionZstd,
+ }
+ contourConfiguration.Spec.Envoy.Listener.Compression = &contour_v1alpha1.EnvoyCompression{
+ Algorithm: contour_v1alpha1.ZstdCompression,
+ }
})
testEnvoyDisableCompression(namespace, "zstd", "zstd", false)
})
From 3d833945f44018d9cc5f0226340baae212e1511f Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Wed, 23 Oct 2024 18:04:50 +0100
Subject: [PATCH 15/30] lint fixes
Signed-off-by: Geoff Macartney
---
internal/envoy/v3/listener.go | 6 +++---
pkg/config/parameters.go | 1 -
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/internal/envoy/v3/listener.go b/internal/envoy/v3/listener.go
index 59dcc233a67..5b15021d4da 100644
--- a/internal/envoy/v3/listener.go
+++ b/internal/envoy/v3/listener.go
@@ -16,8 +16,6 @@ package v3
import (
"errors"
"fmt"
- envoy_compression_brotli_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/brotli/compressor/v3"
- envoy_compression_zstd_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/zstd/compressor/v3"
"sort"
"strings"
"time"
@@ -25,7 +23,9 @@ import (
envoy_config_accesslog_v3 "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v3"
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
+ envoy_compression_brotli_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/brotli/compressor/v3"
envoy_compression_gzip_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/gzip/compressor/v3"
+ envoy_compression_zstd_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/zstd/compressor/v3"
envoy_filter_http_compressor_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/compressor/v3"
envoy_filter_http_cors_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/cors/v3"
envoy_filter_http_ext_authz_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ext_authz/v3"
@@ -318,7 +318,7 @@ func (b *httpConnectionManagerBuilder) DefaultFilters() *httpConnectionManagerBu
// The names are not required to match anything and are
// identified by the TypeURL of each filter.
var compressor proto.Message = &envoy_compression_gzip_compressor_v3.Gzip{}
- var compressorName = string(contour_v1alpha1.GzipCompression)
+ compressorName := string(contour_v1alpha1.GzipCompression)
if b.compression != nil {
switch b.compression.Algorithm {
case contour_v1alpha1.BrotliCompression:
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
index 1b4d3c7d064..2f6d33d6384 100644
--- a/pkg/config/parameters.go
+++ b/pkg/config/parameters.go
@@ -972,7 +972,6 @@ const (
// CompressionParameters holds various configurable compression related values.
type CompressionParameters struct {
-
// Algorithm configures which compression algorithm, if any, to use in the default HTTP listener filter chain.
// Valid options are 'gzip' (default), 'brotli', 'zstd' and 'disabled'.
// +optional
From cda9c76ea6b37400c8de2641e587efe1c9036e67 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Thu, 24 Oct 2024 18:00:09 +0100
Subject: [PATCH 16/30] test fix
Avoid NPE in parameters.Validate
also tidy flag handling in registerServe, don't set compression struct unless parameter is supplied.
Signed-off-by: Geoff Macartney
---
cmd/contour/serve.go | 15 ++++++++-------
pkg/config/parameters.go | 6 ++++--
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go
index 8a4801bd137..49f3adc8647 100644
--- a/cmd/contour/serve.go
+++ b/cmd/contour/serve.go
@@ -124,15 +124,16 @@ func registerServe(app *kingpin.Application) (*kingpin.CmdClause, *serveContext)
return nil
}
- if ctx.Config.Compression == nil {
- ctx.Config.Compression = &config.CompressionParameters{
- Algorithm: config.CompressionDefault,
- }
- }
-
serve.Flag("accesslog-format", "Format for Envoy access logs.").PlaceHolder("").StringVar((*string)(&ctx.Config.AccessLogFormat))
- serve.Flag("compression", "Set or disable compression type in default Listener filters.").PlaceHolder("").StringVar((*string)(&ctx.Config.Compression.Algorithm))
+ var compressionFlag string
+ serve.Flag("compression", "Set or disable compression type in default Listener filters.").PlaceHolder("").StringVar(&compressionFlag)
+ if compressionFlag != "" {
+ if ctx.Config.Compression == nil {
+ ctx.Config.Compression = &config.CompressionParameters{}
+ }
+ ctx.Config.Compression.Algorithm = config.CompressionAlgorithm(compressionFlag)
+ }
serve.Flag("config-path", "Path to base configuration.").Short('c').PlaceHolder("/path/to/file").Action(parseConfig).ExistingFileVar(&configFile)
serve.Flag("contour-cafile", "CA bundle file name for serving gRPC with TLS.").Envar("CONTOUR_CAFILE").StringVar(&ctx.caFile)
serve.Flag("contour-cert-file", "Contour certificate file name for serving gRPC over TLS.").PlaceHolder("/path/to/file").Envar("CONTOUR_CERT_FILE").StringVar(&ctx.contourCert)
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
index 2f6d33d6384..4c1da8595e2 100644
--- a/pkg/config/parameters.go
+++ b/pkg/config/parameters.go
@@ -1026,8 +1026,10 @@ func (p *Parameters) Validate() error {
return err
}
- if err := p.Compression.Validate(); err != nil {
- return err
+ if p.Compression != nil {
+ if err := p.Compression.Validate(); err != nil {
+ return err
+ }
}
if err := p.TLS.Validate(); err != nil {
From ff84c379dc943e3a74286f7766acccdd12adb259 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Mon, 28 Oct 2024 09:24:56 +0000
Subject: [PATCH 17/30] fix flag handling
Signed-off-by: Geoff Macartney
---
cmd/contour/serve.go | 9 +--------
cmd/contour/servecontext.go | 2 +-
pkg/config/parameters.go | 4 ++--
test/e2e/httpproxy/httpproxy_test.go | 6 +++---
4 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go
index 49f3adc8647..4007437761b 100644
--- a/cmd/contour/serve.go
+++ b/cmd/contour/serve.go
@@ -126,14 +126,7 @@ func registerServe(app *kingpin.Application) (*kingpin.CmdClause, *serveContext)
serve.Flag("accesslog-format", "Format for Envoy access logs.").PlaceHolder("").StringVar((*string)(&ctx.Config.AccessLogFormat))
- var compressionFlag string
- serve.Flag("compression", "Set or disable compression type in default Listener filters.").PlaceHolder("").StringVar(&compressionFlag)
- if compressionFlag != "" {
- if ctx.Config.Compression == nil {
- ctx.Config.Compression = &config.CompressionParameters{}
- }
- ctx.Config.Compression.Algorithm = config.CompressionAlgorithm(compressionFlag)
- }
+ serve.Flag("compression", "Set or disable compression type in default Listener filters.").PlaceHolder("").StringVar((*string)(&ctx.Config.Compression.Algorithm))
serve.Flag("config-path", "Path to base configuration.").Short('c').PlaceHolder("/path/to/file").Action(parseConfig).ExistingFileVar(&configFile)
serve.Flag("contour-cafile", "CA bundle file name for serving gRPC with TLS.").Envar("CONTOUR_CAFILE").StringVar(&ctx.caFile)
serve.Flag("contour-cert-file", "Contour certificate file name for serving gRPC over TLS.").PlaceHolder("/path/to/file").Envar("CONTOUR_CERT_FILE").StringVar(&ctx.contourCert)
diff --git a/cmd/contour/servecontext.go b/cmd/contour/servecontext.go
index 3bf62e9a541..6fd2a3643e0 100644
--- a/cmd/contour/servecontext.go
+++ b/cmd/contour/servecontext.go
@@ -334,7 +334,7 @@ func (ctx *serveContext) convertToContourConfigurationSpec() contour_v1alpha1.Co
}
var compression *contour_v1alpha1.EnvoyCompression
- if ctx.Config.Compression != nil {
+ if ctx.Config.Compression.Algorithm != "" {
var algorithm contour_v1alpha1.CompressionAlgorithm
switch ctx.Config.Compression.Algorithm {
case config.CompressionBrotli:
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
index 4c1da8595e2..51aa1540a4d 100644
--- a/pkg/config/parameters.go
+++ b/pkg/config/parameters.go
@@ -653,7 +653,7 @@ type Parameters struct {
// Compression defines configuration relating to compression in the default HTTP filter chain.
// +optional
- Compression *CompressionParameters `yaml:"compression,omitempty"`
+ Compression CompressionParameters `yaml:"compression,omitempty"`
// Defines the action to be applied to the Server header on the response path.
// When configured as overwrite, overwrites any Server header with "envoy".
@@ -1026,7 +1026,7 @@ func (p *Parameters) Validate() error {
return err
}
- if p.Compression != nil {
+ if p.Compression.Algorithm != "" {
if err := p.Compression.Validate(); err != nil {
return err
}
diff --git a/test/e2e/httpproxy/httpproxy_test.go b/test/e2e/httpproxy/httpproxy_test.go
index 7a45b8f62e9..0a838a2294a 100644
--- a/test/e2e/httpproxy/httpproxy_test.go
+++ b/test/e2e/httpproxy/httpproxy_test.go
@@ -395,7 +395,7 @@ var _ = Describe("HTTPProxy", func() {
f.NamespacedTest("httpproxy-disable-compression", func(namespace string) {
Context("with compression disabled", func() {
BeforeEach(func() {
- contourConfig.Compression = &config.CompressionParameters{
+ contourConfig.Compression = config.CompressionParameters{
Algorithm: config.CompressionDisabled,
}
contourConfiguration.Spec.Envoy.Listener.Compression = &contour_v1alpha1.EnvoyCompression{
@@ -409,7 +409,7 @@ var _ = Describe("HTTPProxy", func() {
f.NamespacedTest("httpproxy-brotli-compression", func(namespace string) {
Context("with brotli compression", func() {
BeforeEach(func() {
- contourConfig.Compression = &config.CompressionParameters{
+ contourConfig.Compression = config.CompressionParameters{
Algorithm: config.CompressionBrotli,
}
contourConfiguration.Spec.Envoy.Listener.Compression = &contour_v1alpha1.EnvoyCompression{
@@ -423,7 +423,7 @@ var _ = Describe("HTTPProxy", func() {
f.NamespacedTest("httpproxy-zstd-compression", func(namespace string) {
Context("with zstd compression", func() {
BeforeEach(func() {
- contourConfig.Compression = &config.CompressionParameters{
+ contourConfig.Compression = config.CompressionParameters{
Algorithm: config.CompressionZstd,
}
contourConfiguration.Spec.Envoy.Listener.Compression = &contour_v1alpha1.EnvoyCompression{
From 5725a53c845599939b82f223b172374b3dcb7246 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Mon, 28 Oct 2024 10:33:27 +0000
Subject: [PATCH 18/30] api lint
Signed-off-by: Geoff Macartney
---
site/content/docs/main/config/api-reference.html | 3 ---
1 file changed, 3 deletions(-)
diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html
index 340f09b7967..19c8e70e9bd 100644
--- a/site/content/docs/main/config/api-reference.html
+++ b/site/content/docs/main/config/api-reference.html
@@ -5871,9 +5871,6 @@ CompressionAlgorithm
"brotli" |
BrotliCompression specifies brotli as the default HTTP filter chain compression mechanism
|
-
"gzip" |
-DefaultCompression specifies which of the compression algorithms is used by default
- |
"disabled" |
DisabledCompression specifies that there will be no compression in the default HTTP filter chain
|
From 630541e96d598108a23f6f639d71e2cd57b0919e Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Mon, 28 Oct 2024 10:58:33 +0000
Subject: [PATCH 19/30] parameters_test
Signed-off-by: Geoff Macartney
---
pkg/config/parameters_test.go | 1 -
1 file changed, 1 deletion(-)
diff --git a/pkg/config/parameters_test.go b/pkg/config/parameters_test.go
index 5ba18a0fb7c..7f6ad7a7dcd 100644
--- a/pkg/config/parameters_test.go
+++ b/pkg/config/parameters_test.go
@@ -75,7 +75,6 @@ json-fields:
- grpc_status
- grpc_status_number
accesslog-level: info
-compression: gzip
serverHeaderTransformation: overwrite
timeouts:
connection-idle-timeout: 60s
From 4610b8013497b570748771ce395a263065e5defd Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Mon, 28 Oct 2024 12:29:37 +0000
Subject: [PATCH 20/30] update comment
Signed-off-by: Geoff Macartney
---
pkg/config/parameters.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
index 51aa1540a4d..174a5077dd0 100644
--- a/pkg/config/parameters.go
+++ b/pkg/config/parameters.go
@@ -970,7 +970,8 @@ const (
LogLevelDisabled AccessLogLevel = "disabled"
)
-// CompressionParameters holds various configurable compression related values.
+// CompressionParameters is a type defining configurable compression related values.
+// At present this is just the compression algorithm but this could be extended later with algorithm specific config.
type CompressionParameters struct {
// Algorithm configures which compression algorithm, if any, to use in the default HTTP listener filter chain.
// Valid options are 'gzip' (default), 'brotli', 'zstd' and 'disabled'.
From 45ea94642cf953f2e433dfd18a7fdfac29056fa0 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Mon, 28 Oct 2024 17:45:09 +0000
Subject: [PATCH 21/30] fix assertion arg order and bump timeout
Signed-off-by: Geoff Macartney
---
test/e2e/httpproxy/envoy_compression_test.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/e2e/httpproxy/envoy_compression_test.go b/test/e2e/httpproxy/envoy_compression_test.go
index 5b069af8470..6f277815fdd 100644
--- a/test/e2e/httpproxy/envoy_compression_test.go
+++ b/test/e2e/httpproxy/envoy_compression_test.go
@@ -78,7 +78,7 @@ func testEnvoyDisableCompression(namespace, acceptEncoding, contentEncoding stri
assert.NotEqual(c, contentEncodingHeaderValue, contentEncoding, "expected plain text")
return
}
- assert.Equal(c, contentEncodingHeaderValue, contentEncoding, "expected plain text")
- }, 15*time.Second, f.RetryInterval)
+ assert.Equal(c, contentEncoding, contentEncodingHeaderValue, "expected plain text")
+ }, 20*time.Second, f.RetryInterval)
})
}
From 98225fc48e703a6d9360ff358b9c3ddd97fe1129 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Mon, 25 Nov 2024 15:04:20 +0000
Subject: [PATCH 22/30] add some servecontext tests
Signed-off-by: Geoff Macartney
---
cmd/contour/servecontext_test.go | 287 +++++++++++++++++--------------
1 file changed, 157 insertions(+), 130 deletions(-)
diff --git a/cmd/contour/servecontext_test.go b/cmd/contour/servecontext_test.go
index cf205d81a46..644edc6d68e 100644
--- a/cmd/contour/servecontext_test.go
+++ b/cmd/contour/servecontext_test.go
@@ -363,149 +363,150 @@ func TestParseHTTPVersions(t *testing.T) {
}
}
-func TestConvertServeContext(t *testing.T) {
- defaultContext := func() *serveContext {
- ctx := newServeContext()
- ctx.ServerConfig = ServerConfig{
- xdsAddr: "127.0.0.1",
- xdsPort: 8001,
- caFile: "/certs/ca.crt",
- contourCert: "/certs/cert.crt",
- contourKey: "/certs/cert.key",
- }
- return ctx
+func defaultContext() *serveContext {
+ ctx := newServeContext()
+ ctx.ServerConfig = ServerConfig{
+ xdsAddr: "127.0.0.1",
+ xdsPort: 8001,
+ caFile: "/certs/ca.crt",
+ contourCert: "/certs/cert.crt",
+ contourKey: "/certs/cert.key",
}
+ return ctx
+}
- defaultContourConfiguration := func() contour_v1alpha1.ContourConfigurationSpec {
- return contour_v1alpha1.ContourConfigurationSpec{
- XDSServer: &contour_v1alpha1.XDSServerConfig{
- Type: contour_v1alpha1.EnvoyServerType,
- Address: "127.0.0.1",
- Port: 8001,
- TLS: &contour_v1alpha1.TLS{
- CAFile: "/certs/ca.crt",
- CertFile: "/certs/cert.crt",
- KeyFile: "/certs/cert.key",
- Insecure: ptr.To(false),
- },
- },
- Ingress: &contour_v1alpha1.IngressConfig{
- ClassNames: nil,
- StatusAddress: "",
- },
- Debug: &contour_v1alpha1.DebugConfig{
- Address: "127.0.0.1",
- Port: 6060,
+func defaultContourConfiguration() contour_v1alpha1.ContourConfigurationSpec {
+ return contour_v1alpha1.ContourConfigurationSpec{
+ XDSServer: &contour_v1alpha1.XDSServerConfig{
+ Type: contour_v1alpha1.EnvoyServerType,
+ Address: "127.0.0.1",
+ Port: 8001,
+ TLS: &contour_v1alpha1.TLS{
+ CAFile: "/certs/ca.crt",
+ CertFile: "/certs/cert.crt",
+ KeyFile: "/certs/cert.key",
+ Insecure: ptr.To(false),
},
- Health: &contour_v1alpha1.HealthConfig{
- Address: "0.0.0.0",
- Port: 8000,
+ },
+ Ingress: &contour_v1alpha1.IngressConfig{
+ ClassNames: nil,
+ StatusAddress: "",
+ },
+ Debug: &contour_v1alpha1.DebugConfig{
+ Address: "127.0.0.1",
+ Port: 6060,
+ },
+ Health: &contour_v1alpha1.HealthConfig{
+ Address: "0.0.0.0",
+ Port: 8000,
+ },
+ Envoy: &contour_v1alpha1.EnvoyConfig{
+ Service: &contour_v1alpha1.NamespacedName{
+ Name: "envoy",
+ Namespace: "projectcontour",
},
- Envoy: &contour_v1alpha1.EnvoyConfig{
- Service: &contour_v1alpha1.NamespacedName{
- Name: "envoy",
- Namespace: "projectcontour",
- },
- Listener: &contour_v1alpha1.EnvoyListenerConfig{
- UseProxyProto: ptr.To(false),
- DisableAllowChunkedLength: ptr.To(false),
- DisableMergeSlashes: ptr.To(false),
- ServerHeaderTransformation: contour_v1alpha1.OverwriteServerHeader,
- TLS: &contour_v1alpha1.EnvoyTLS{
- MinimumProtocolVersion: "",
- MaximumProtocolVersion: "",
- },
- SocketOptions: &contour_v1alpha1.SocketOptions{
- TOS: 0,
- TrafficClass: 0,
- },
- },
- HTTPListener: &contour_v1alpha1.EnvoyListener{
- Address: "0.0.0.0",
- Port: 8080,
- AccessLog: "/dev/stdout",
- },
- HTTPSListener: &contour_v1alpha1.EnvoyListener{
- Address: "0.0.0.0",
- Port: 8443,
- AccessLog: "/dev/stdout",
- },
- Health: &contour_v1alpha1.HealthConfig{
- Address: "0.0.0.0",
- Port: 8002,
- },
- Metrics: &contour_v1alpha1.MetricsConfig{
- Address: "0.0.0.0",
- Port: 8002,
- },
- ClientCertificate: nil,
- Logging: &contour_v1alpha1.EnvoyLogging{
- AccessLogFormat: contour_v1alpha1.EnvoyAccessLog,
- AccessLogFormatString: "",
- AccessLogLevel: contour_v1alpha1.LogLevelInfo,
- AccessLogJSONFields: contour_v1alpha1.AccessLogJSONFields([]string{
- "@timestamp",
- "authority",
- "bytes_received",
- "bytes_sent",
- "downstream_local_address",
- "downstream_remote_address",
- "duration",
- "method",
- "path",
- "protocol",
- "request_id",
- "requested_server_name",
- "response_code",
- "response_flags",
- "uber_trace_id",
- "upstream_cluster",
- "upstream_host",
- "upstream_local_address",
- "upstream_service_time",
- "user_agent",
- "x_forwarded_for",
- "grpc_status",
- "grpc_status_number",
- }),
- },
- DefaultHTTPVersions: nil,
- Timeouts: &contour_v1alpha1.TimeoutParameters{
- ConnectionIdleTimeout: ptr.To("60s"),
- ConnectTimeout: ptr.To("2s"),
- },
- Cluster: &contour_v1alpha1.ClusterParameters{
- DNSLookupFamily: contour_v1alpha1.AutoClusterDNSFamily,
- GlobalCircuitBreakerDefaults: nil,
- UpstreamTLS: &contour_v1alpha1.EnvoyTLS{
- MinimumProtocolVersion: "",
- MaximumProtocolVersion: "",
- },
+ Listener: &contour_v1alpha1.EnvoyListenerConfig{
+ UseProxyProto: ptr.To(false),
+ DisableAllowChunkedLength: ptr.To(false),
+ DisableMergeSlashes: ptr.To(false),
+ ServerHeaderTransformation: contour_v1alpha1.OverwriteServerHeader,
+ TLS: &contour_v1alpha1.EnvoyTLS{
+ MinimumProtocolVersion: "",
+ MaximumProtocolVersion: "",
},
- Network: &contour_v1alpha1.NetworkParameters{
- EnvoyAdminPort: ptr.To(9001),
- XffNumTrustedHops: ptr.To(uint32(0)),
+ SocketOptions: &contour_v1alpha1.SocketOptions{
+ TOS: 0,
+ TrafficClass: 0,
},
},
- Gateway: nil,
- HTTPProxy: &contour_v1alpha1.HTTPProxyConfig{
- DisablePermitInsecure: ptr.To(false),
- FallbackCertificate: nil,
+ HTTPListener: &contour_v1alpha1.EnvoyListener{
+ Address: "0.0.0.0",
+ Port: 8080,
+ AccessLog: "/dev/stdout",
},
- EnableExternalNameService: ptr.To(false),
- RateLimitService: nil,
- GlobalExternalAuthorization: nil,
- Policy: &contour_v1alpha1.PolicyConfig{
- RequestHeadersPolicy: &contour_v1alpha1.HeadersPolicy{},
- ResponseHeadersPolicy: &contour_v1alpha1.HeadersPolicy{},
- ApplyToIngress: ptr.To(false),
+ HTTPSListener: &contour_v1alpha1.EnvoyListener{
+ Address: "0.0.0.0",
+ Port: 8443,
+ AccessLog: "/dev/stdout",
+ },
+ Health: &contour_v1alpha1.HealthConfig{
+ Address: "0.0.0.0",
+ Port: 8002,
},
Metrics: &contour_v1alpha1.MetricsConfig{
Address: "0.0.0.0",
- Port: 8000,
+ Port: 8002,
+ },
+ ClientCertificate: nil,
+ Logging: &contour_v1alpha1.EnvoyLogging{
+ AccessLogFormat: contour_v1alpha1.EnvoyAccessLog,
+ AccessLogFormatString: "",
+ AccessLogLevel: contour_v1alpha1.LogLevelInfo,
+ AccessLogJSONFields: contour_v1alpha1.AccessLogJSONFields([]string{
+ "@timestamp",
+ "authority",
+ "bytes_received",
+ "bytes_sent",
+ "downstream_local_address",
+ "downstream_remote_address",
+ "duration",
+ "method",
+ "path",
+ "protocol",
+ "request_id",
+ "requested_server_name",
+ "response_code",
+ "response_flags",
+ "uber_trace_id",
+ "upstream_cluster",
+ "upstream_host",
+ "upstream_local_address",
+ "upstream_service_time",
+ "user_agent",
+ "x_forwarded_for",
+ "grpc_status",
+ "grpc_status_number",
+ }),
+ },
+ DefaultHTTPVersions: nil,
+ Timeouts: &contour_v1alpha1.TimeoutParameters{
+ ConnectionIdleTimeout: ptr.To("60s"),
+ ConnectTimeout: ptr.To("2s"),
+ },
+ Cluster: &contour_v1alpha1.ClusterParameters{
+ DNSLookupFamily: contour_v1alpha1.AutoClusterDNSFamily,
+ GlobalCircuitBreakerDefaults: nil,
+ UpstreamTLS: &contour_v1alpha1.EnvoyTLS{
+ MinimumProtocolVersion: "",
+ MaximumProtocolVersion: "",
+ },
},
- }
+ Network: &contour_v1alpha1.NetworkParameters{
+ EnvoyAdminPort: ptr.To(9001),
+ XffNumTrustedHops: ptr.To(uint32(0)),
+ },
+ },
+ Gateway: nil,
+ HTTPProxy: &contour_v1alpha1.HTTPProxyConfig{
+ DisablePermitInsecure: ptr.To(false),
+ FallbackCertificate: nil,
+ },
+ EnableExternalNameService: ptr.To(false),
+ RateLimitService: nil,
+ GlobalExternalAuthorization: nil,
+ Policy: &contour_v1alpha1.PolicyConfig{
+ RequestHeadersPolicy: &contour_v1alpha1.HeadersPolicy{},
+ ResponseHeadersPolicy: &contour_v1alpha1.HeadersPolicy{},
+ ApplyToIngress: ptr.To(false),
+ },
+ Metrics: &contour_v1alpha1.MetricsConfig{
+ Address: "0.0.0.0",
+ Port: 8000,
+ },
}
+}
+
+func TestConvertServeContext(t *testing.T) {
cases := map[string]struct {
getServeContext func(ctx *serveContext) *serveContext
@@ -912,3 +913,29 @@ func TestConvertServeContext(t *testing.T) {
})
}
}
+
+func TestServeContextCompressionOptions(t *testing.T) {
+ cases := map[string]struct {
+ serveCompression config.CompressionAlgorithm
+ configCompression contour_v1alpha1.CompressionAlgorithm
+ }{
+ "Brotli": {config.CompressionBrotli, contour_v1alpha1.BrotliCompression},
+ "Disabled": {config.CompressionDisabled, contour_v1alpha1.DisabledCompression},
+ "Gzip": {config.CompressionGzip, contour_v1alpha1.GzipCompression},
+ "Zstd": {config.CompressionZstd, contour_v1alpha1.ZstdCompression},
+ }
+
+ for name, tc := range cases {
+ t.Run(name, func(t *testing.T) {
+ testServeContext := defaultContext()
+ testServeContext.Config.Compression.Algorithm = tc.serveCompression
+
+ want := defaultContourConfiguration()
+ want.Envoy.Listener.Compression = &contour_v1alpha1.EnvoyCompression{
+ Algorithm: tc.configCompression,
+ }
+
+ assert.Equal(t, want, testServeContext.convertToContourConfigurationSpec())
+ })
+ }
+}
From 661b5520b3e18928830d191ff6c4144f29ae08cb Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Mon, 25 Nov 2024 17:13:15 +0000
Subject: [PATCH 23/30] add some parameters tests
Signed-off-by: Geoff Macartney
---
pkg/config/parameters_test.go | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/pkg/config/parameters_test.go b/pkg/config/parameters_test.go
index 7f6ad7a7dcd..f83f112f2c3 100644
--- a/pkg/config/parameters_test.go
+++ b/pkg/config/parameters_test.go
@@ -325,6 +325,14 @@ func TestTLSParametersValidation(t *testing.T) {
}.Validate())
}
+func TestCompressionValidation(t *testing.T) {
+ require.NoError(t, CompressionParameters{CompressionBrotli}.Validate())
+ require.NoError(t, CompressionParameters{CompressionDisabled}.Validate())
+ require.NoError(t, CompressionParameters{CompressionGzip}.Validate())
+ require.NoError(t, CompressionParameters{CompressionZstd}.Validate())
+ require.True(t, strings.Contains(CompressionParameters{"bogus"}.Validate().Error(), "invalid compression type"))
+}
+
func TestConfigFileValidation(t *testing.T) {
check := func(yamlIn string) {
t.Helper()
From 75f8b7b909e8d4c518c8fec1ac7fc0b4dab8cce0 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Tue, 26 Nov 2024 12:37:30 +0000
Subject: [PATCH 24/30] Update internal/featuretests/v3/compression_test.go
Co-authored-by: Tero Saarni
Signed-off-by: Geoff Macartney
---
internal/featuretests/v3/compression_test.go | 212 ++++---------------
1 file changed, 40 insertions(+), 172 deletions(-)
diff --git a/internal/featuretests/v3/compression_test.go b/internal/featuretests/v3/compression_test.go
index 0535242c487..b374ed92e1c 100644
--- a/internal/featuretests/v3/compression_test.go
+++ b/internal/featuretests/v3/compression_test.go
@@ -27,62 +27,20 @@ import (
xdscache_v3 "github.com/projectcontour/contour/internal/xdscache/v3"
)
-func TestDefaultCompression(t *testing.T) {
- rh, c, done := setup(t)
- defer done()
-
- s1 := fixture.NewService("backend").
- WithPorts(core_v1.ServicePort{Name: "http", Port: 80})
- rh.OnAdd(s1)
-
- hp1 := &contour_v1.HTTPProxy{
- ObjectMeta: meta_v1.ObjectMeta{
- Name: "simple",
- Namespace: s1.Namespace,
- },
- Spec: contour_v1.HTTPProxySpec{
- VirtualHost: &contour_v1.VirtualHost{
- Fqdn: "example.com",
- },
- Routes: []contour_v1.Route{{
- Conditions: matchconditions(prefixMatchCondition("/")),
- Services: []contour_v1.Service{{
- Name: s1.Name,
- Port: 80,
- }},
- }},
- },
+func TestCompression(t *testing.T) {
+ tests := map[string]struct {
+ algorithm contour_v1alpha1.CompressionAlgorithm
+ want contour_v1alpha1.CompressionAlgorithm
+ }{
+ "default": {algorithm: "", want: contour_v1alpha1.GzipCompression},
+ "disabled": {algorithm: contour_v1alpha1.DisabledCompression, want: contour_v1alpha1.DisabledCompression},
+ "brotli": {algorithm: contour_v1alpha1.BrotliCompression, want: contour_v1alpha1.BrotliCompression},
+ "zstd": {algorithm: contour_v1alpha1.ZstdCompression, want: contour_v1alpha1.ZstdCompression},
+ "gzip": {algorithm: contour_v1alpha1.GzipCompression, want: contour_v1alpha1.GzipCompression},
}
- rh.OnAdd(hp1)
-
- httpListener := defaultHTTPListener()
- httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
- RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
- MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
- AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
- DefaultFilters().
- Get(),
- )
-
- c.Request(listenerType, xdscache_v3.ENVOY_HTTP_LISTENER).Equals(&envoy_service_discovery_v3.DiscoveryResponse{
- TypeUrl: listenerType,
- Resources: resources(t, httpListener),
- })
-}
-
-func TestDisableCompression(t *testing.T) {
- withDisableCompression := func(conf *xdscache_v3.ListenerConfig) {
- conf.Compression = &contour_v1alpha1.EnvoyCompression{
- Algorithm: contour_v1alpha1.DisabledCompression,
- }
- }
-
- rh, c, done := setup(t, withDisableCompression)
- defer done()
s1 := fixture.NewService("backend").
WithPorts(core_v1.ServicePort{Name: "http", Port: 80})
- rh.OnAdd(s1)
hp1 := &contour_v1.HTTPProxy{
ObjectMeta: meta_v1.ObjectMeta{
@@ -102,126 +60,36 @@ func TestDisableCompression(t *testing.T) {
}},
},
}
- rh.OnAdd(hp1)
- httpListener := defaultHTTPListener()
- httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
- Compression(&contour_v1alpha1.EnvoyCompression{
- Algorithm: contour_v1alpha1.DisabledCompression,
- }).
- RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
- MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
- AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
- DefaultFilters().
- Get(),
- )
-
- c.Request(listenerType, xdscache_v3.ENVOY_HTTP_LISTENER).Equals(&envoy_service_discovery_v3.DiscoveryResponse{
- TypeUrl: listenerType,
- Resources: resources(t, httpListener),
- })
-}
-
-func TestBrotliCompression(t *testing.T) {
- withBrotliCompression := func(conf *xdscache_v3.ListenerConfig) {
- conf.Compression = &contour_v1alpha1.EnvoyCompression{
- Algorithm: contour_v1alpha1.BrotliCompression,
- }
+ for name, tc := range tests {
+ t.Run(name, func(t *testing.T) {
+ rh, c, done := setup(t, func(conf *xdscache_v3.ListenerConfig) {
+ if tc.algorithm != "" {
+ conf.Compression = &contour_v1alpha1.EnvoyCompression{
+ Algorithm: tc.algorithm,
+ }
+ }
+ })
+ defer done()
+
+ rh.OnAdd(s1)
+ rh.OnAdd(hp1)
+ httpListener := defaultHTTPListener()
+ httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
+ Compression(&contour_v1alpha1.EnvoyCompression{
+ Algorithm: tc.want,
+ }).
+ RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
+ MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
+ AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
+ DefaultFilters().
+ Get(),
+ )
+
+ c.Request(listenerType, xdscache_v3.ENVOY_HTTP_LISTENER).Equals(&envoy_service_discovery_v3.DiscoveryResponse{
+ TypeUrl: listenerType,
+ Resources: resources(t, httpListener),
+ })
+ })
}
-
- rh, c, done := setup(t, withBrotliCompression)
- defer done()
-
- s1 := fixture.NewService("backend").
- WithPorts(core_v1.ServicePort{Name: "http", Port: 80})
- rh.OnAdd(s1)
-
- hp1 := &contour_v1.HTTPProxy{
- ObjectMeta: meta_v1.ObjectMeta{
- Name: "simple",
- Namespace: s1.Namespace,
- },
- Spec: contour_v1.HTTPProxySpec{
- VirtualHost: &contour_v1.VirtualHost{
- Fqdn: "example.com",
- },
- Routes: []contour_v1.Route{{
- Conditions: matchconditions(prefixMatchCondition("/")),
- Services: []contour_v1.Service{{
- Name: s1.Name,
- Port: 80,
- }},
- }},
- },
- }
- rh.OnAdd(hp1)
-
- httpListener := defaultHTTPListener()
- httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
- Compression(&contour_v1alpha1.EnvoyCompression{
- Algorithm: contour_v1alpha1.BrotliCompression,
- }).
- RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
- MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
- AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
- DefaultFilters().
- Get(),
- )
-
- c.Request(listenerType, xdscache_v3.ENVOY_HTTP_LISTENER).Equals(&envoy_service_discovery_v3.DiscoveryResponse{
- TypeUrl: listenerType,
- Resources: resources(t, httpListener),
- })
-}
-
-func TestZstdCompression(t *testing.T) {
- withZstdCompression := func(conf *xdscache_v3.ListenerConfig) {
- conf.Compression = &contour_v1alpha1.EnvoyCompression{
- Algorithm: contour_v1alpha1.ZstdCompression,
- }
- }
-
- rh, c, done := setup(t, withZstdCompression)
- defer done()
-
- s1 := fixture.NewService("backend").
- WithPorts(core_v1.ServicePort{Name: "http", Port: 80})
- rh.OnAdd(s1)
-
- hp1 := &contour_v1.HTTPProxy{
- ObjectMeta: meta_v1.ObjectMeta{
- Name: "simple",
- Namespace: s1.Namespace,
- },
- Spec: contour_v1.HTTPProxySpec{
- VirtualHost: &contour_v1.VirtualHost{
- Fqdn: "example.com",
- },
- Routes: []contour_v1.Route{{
- Conditions: matchconditions(prefixMatchCondition("/")),
- Services: []contour_v1.Service{{
- Name: s1.Name,
- Port: 80,
- }},
- }},
- },
- }
- rh.OnAdd(hp1)
-
- httpListener := defaultHTTPListener()
- httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
- Compression(&contour_v1alpha1.EnvoyCompression{
- Algorithm: contour_v1alpha1.ZstdCompression,
- }).
- RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
- MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER).
- AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, contour_v1alpha1.LogLevelInfo)).
- DefaultFilters().
- Get(),
- )
-
- c.Request(listenerType, xdscache_v3.ENVOY_HTTP_LISTENER).Equals(&envoy_service_discovery_v3.DiscoveryResponse{
- TypeUrl: listenerType,
- Resources: resources(t, httpListener),
- })
}
From 351a8200712b3b0cfeaed2010969e478cf31b123 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Tue, 26 Nov 2024 12:38:05 +0000
Subject: [PATCH 25/30] Update changelogs/unreleased/6546-chaosbox-small.md
Co-authored-by: Tero Saarni
Signed-off-by: Geoff Macartney
---
changelogs/unreleased/6546-chaosbox-small.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/changelogs/unreleased/6546-chaosbox-small.md b/changelogs/unreleased/6546-chaosbox-small.md
index 6017d1b0588..9cde1d1c957 100644
--- a/changelogs/unreleased/6546-chaosbox-small.md
+++ b/changelogs/unreleased/6546-chaosbox-small.md
@@ -1 +1 @@
-Add "compression" object to define settings in default HTTP filters, initially just supporting changing/disabling compression algorithm.
+The HTTP compression algorithm can now be configured using the `compression.algorithm` field in the configuration file or the `spec.envoy.listener.compression.algorithm` field in the `ContourConfiguration` CRD. The available values are `gzip` (default), `brotli`, `zstd`, and `disabled`.
From 95d38aff60981a92bda748bbccbb3630cacdfa35 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Tue, 26 Nov 2024 12:44:30 +0000
Subject: [PATCH 26/30] remove command flag
from review comment:
Let's remove the command line option and make configuration available only through config file and ContourConfiguration CRD.
The command line options currently are a bit of a mess, so we previously agreed to avoid introducing new options there unless absolutely necessary.
Signed-off-by: Geoff Macartney
---
cmd/contour/serve.go | 1 -
1 file changed, 1 deletion(-)
diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go
index 4007437761b..e24d7a403a3 100644
--- a/cmd/contour/serve.go
+++ b/cmd/contour/serve.go
@@ -126,7 +126,6 @@ func registerServe(app *kingpin.Application) (*kingpin.CmdClause, *serveContext)
serve.Flag("accesslog-format", "Format for Envoy access logs.").PlaceHolder("").StringVar((*string)(&ctx.Config.AccessLogFormat))
- serve.Flag("compression", "Set or disable compression type in default Listener filters.").PlaceHolder("").StringVar((*string)(&ctx.Config.Compression.Algorithm))
serve.Flag("config-path", "Path to base configuration.").Short('c').PlaceHolder("/path/to/file").Action(parseConfig).ExistingFileVar(&configFile)
serve.Flag("contour-cafile", "CA bundle file name for serving gRPC with TLS.").Envar("CONTOUR_CAFILE").StringVar(&ctx.caFile)
serve.Flag("contour-cert-file", "Contour certificate file name for serving gRPC over TLS.").PlaceHolder("/path/to/file").Envar("CONTOUR_CERT_FILE").StringVar(&ctx.contourCert)
From 366f48ddc4a19f6be1ad2a180eeef39b40ee75a1 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Tue, 26 Nov 2024 13:46:11 +0000
Subject: [PATCH 27/30] treat empty string as valid CompressionAlgorithm
From review:
Would it be cleaner to treat an empty string as a valid value here, rather than completely bypassing validation in Parameters.Validate()? While algorithm is the only field currently, that might change.
Signed-off-by: Geoff Macartney
---
apis/projectcontour/v1alpha1/compression.go | 2 +-
apis/projectcontour/v1alpha1/compression_test.go | 2 +-
pkg/config/parameters.go | 6 ++----
pkg/config/parameters_test.go | 1 +
4 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/apis/projectcontour/v1alpha1/compression.go b/apis/projectcontour/v1alpha1/compression.go
index 3ae14097acf..f3f00b3f7c3 100644
--- a/apis/projectcontour/v1alpha1/compression.go
+++ b/apis/projectcontour/v1alpha1/compression.go
@@ -31,7 +31,7 @@ type EnvoyCompression struct {
func (a CompressionAlgorithm) Validate() error {
switch a {
- case BrotliCompression, DisabledCompression, GzipCompression, ZstdCompression:
+ case BrotliCompression, DisabledCompression, GzipCompression, ZstdCompression, "":
return nil
default:
return fmt.Errorf("invalid compression type: %q", a)
diff --git a/apis/projectcontour/v1alpha1/compression_test.go b/apis/projectcontour/v1alpha1/compression_test.go
index 0251c4d97eb..a2df6266790 100644
--- a/apis/projectcontour/v1alpha1/compression_test.go
+++ b/apis/projectcontour/v1alpha1/compression_test.go
@@ -22,9 +22,9 @@ import (
)
func TestValidateEnvoyCompressionAlgorithmType(t *testing.T) {
- require.Error(t, contour_v1alpha1.CompressionAlgorithm("").Validate())
require.Error(t, contour_v1alpha1.CompressionAlgorithm("foo").Validate())
+ require.NoError(t, contour_v1alpha1.CompressionAlgorithm("").Validate())
require.NoError(t, contour_v1alpha1.BrotliCompression.Validate())
require.NoError(t, contour_v1alpha1.DisabledCompression.Validate())
require.NoError(t, contour_v1alpha1.GzipCompression.Validate())
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
index 174a5077dd0..7c9e0360364 100644
--- a/pkg/config/parameters.go
+++ b/pkg/config/parameters.go
@@ -1027,10 +1027,8 @@ func (p *Parameters) Validate() error {
return err
}
- if p.Compression.Algorithm != "" {
- if err := p.Compression.Validate(); err != nil {
- return err
- }
+ if err := p.Compression.Validate(); err != nil {
+ return err
}
if err := p.TLS.Validate(); err != nil {
diff --git a/pkg/config/parameters_test.go b/pkg/config/parameters_test.go
index f83f112f2c3..5b4bc717417 100644
--- a/pkg/config/parameters_test.go
+++ b/pkg/config/parameters_test.go
@@ -326,6 +326,7 @@ func TestTLSParametersValidation(t *testing.T) {
}
func TestCompressionValidation(t *testing.T) {
+ require.NoError(t, CompressionParameters{""}.Validate())
require.NoError(t, CompressionParameters{CompressionBrotli}.Validate())
require.NoError(t, CompressionParameters{CompressionDisabled}.Validate())
require.NoError(t, CompressionParameters{CompressionGzip}.Validate())
From 1a6465f38da9b0563ff708187bdfe9bcb99a6581 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Tue, 26 Nov 2024 16:57:39 +0000
Subject: [PATCH 28/30] update configuration docs per new types
Signed-off-by: Geoff Macartney
---
site/content/docs/main/configuration.md | 71 ++++++++++++++-----------
1 file changed, 39 insertions(+), 32 deletions(-)
diff --git a/site/content/docs/main/configuration.md b/site/content/docs/main/configuration.md
index 8e2a3e168c4..a914ffeba65 100644
--- a/site/content/docs/main/configuration.md
+++ b/site/content/docs/main/configuration.md
@@ -72,38 +72,38 @@ The Contour configuration file is optional.
In its absence, Contour will operate with reasonable defaults.
Where Contour settings can also be specified with command-line flags, the command-line value takes precedence over the configuration file.
-| Field Name | Type | Default | Description |
-|----------------------------|------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| accesslog-format | string | `envoy` | This key sets the global [access log format][2] for Envoy. Valid options are `envoy` or `json`. |
-| accesslog-format-string | string | None | If present, this specifies custom access log format for Envoy. See [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage) for more information about the syntax. This field only has effect if `accesslog-format` is `envoy` |
-| accesslog-level | string | `info` | This field specifies the verbosity level of the access log. Valid options are `info` (default, all requests are logged), `error` (all non-success, i.e. 300+ response code, requests are logged), `critical` (all server error, i.e. 500+ response code, requests are logged) and `disabled`. |
-| debug | boolean | `false` | Enables debug logging. |
-| default-http-versions | string array | HTTP/1.1
HTTP/2
| This array specifies the HTTP versions that Contour should program Envoy to serve. HTTP versions are specified as strings of the form "HTTP/x", where "x" represents the version number. |
-| disableAllowChunkedLength | boolean | `false` | If this field is true, Contour will disable the RFC-compliant Envoy behavior to strip the `Content-Length` header if `Transfer-Encoding: chunked` is also set. This is an emergency off-switch to revert back to Envoy's default behavior in case of failures. |
-| compression | string | `gzip` | Sets the compression type applied in the compression HTTP filter of the default Listener filters. Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response. Values:`gzip` (default), `brotli`, `zstd`, `disabled`. |
-| disableMergeSlashes | boolean | `false` | This field disables Envoy's non-standard merge_slashes path transformation behavior that strips duplicate slashes from request URL paths. |
-| serverHeaderTransformation | string | `overwrite` | This field defines the action to be applied to the Server header on the response path. Values: `overwrite` (default), `append_if_absent`, `pass_through` |
-| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. |
-| envoy-service-name | string | `envoy` | This sets the service name that will be inspected for address details to be applied to Ingress objects. |
-| envoy-service-namespace | string | `projectcontour` | This sets the namespace of the service that will be inspected for address details to be applied to Ingress objects. If the `CONTOUR_NAMESPACE` environment variable is present, Contour will populate this field with its value. |
-| ingress-status-address | string | None | If present, this specifies the address that will be copied into the Ingress status for each Ingress that Contour manages. It is exclusive with `envoy-service-name` and `envoy-service-namespace`. |
-| incluster | boolean | `false` | This field specifies that Contour is running in a Kubernetes cluster and should use the in-cluster client access configuration. |
-| json-fields | string array | [fields][5] | This is the list the field names to include in the JSON [access log format][2]. This field only has effect if `accesslog-format` is `json`. |
-| kubeconfig | string | `$HOME/.kube/config` | Path to a Kubernetes [kubeconfig file][3] for when Contour is executed outside a cluster. |
-| kubernetesClientQPS | float32 | | QPS allowed for the Kubernetes client. |
-| kubernetesClientBurst | int | | Burst allowed for the Kubernetes client. |
-| policy | PolicyConfig | | The default [policy configuration](#policy-configuration). |
-| tls | TLS | | The default [TLS configuration](#tls-configuration). |
-| timeouts | TimeoutConfig | | The [timeout configuration](#timeout-configuration). |
-| cluster | ClusterConfig | | The [cluster configuration](#cluster-configuration). |
-| network | NetworkConfig | | The [network configuration](#network-configuration). |
-| listener | ListenerConfig | | The [listener configuration](#listener-configuration). |
-| server | ServerConfig | | The [server configuration](#server-configuration) for `contour serve` command. |
-| gateway | GatewayConfig | | The [gateway-api Gateway configuration](#gateway-configuration). |
-| rateLimitService | RateLimitServiceConfig | | The [rate limit service configuration](#rate-limit-service-configuration). |
-| enableExternalNameService | boolean | `false` | Enable ExternalName Service processing. Enabling this has security implications. Please see the [advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for more details. |
-| metrics | MetricsParameters | | The [metrics configuration](#metrics-configuration) |
-| featureFlags | string array | `[]` | Defines the toggle to enable new contour features. Available toggles are:
1. `useEndpointSlices` - configures contour to fetch endpoint data from k8s endpoint slices. |
+| Field Name | Type | Default | Description |
+|----------------------------|------------------------|------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| accesslog-format | string | `envoy` | This key sets the global [access log format][2] for Envoy. Valid options are `envoy` or `json`. |
+| accesslog-format-string | string | None | If present, this specifies custom access log format for Envoy. See [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage) for more information about the syntax. This field only has effect if `accesslog-format` is `envoy` |
+| accesslog-level | string | `info` | This field specifies the verbosity level of the access log. Valid options are `info` (default, all requests are logged), `error` (all non-success, i.e. 300+ response code, requests are logged), `critical` (all server error, i.e. 500+ response code, requests are logged) and `disabled`. |
+| debug | boolean | `false` | Enables debug logging. |
+| default-http-versions | string array | HTTP/1.1
HTTP/2
| This array specifies the HTTP versions that Contour should program Envoy to serve. HTTP versions are specified as strings of the form "HTTP/x", where "x" represents the version number. |
+| disableAllowChunkedLength | boolean | `false` | If this field is true, Contour will disable the RFC-compliant Envoy behavior to strip the `Content-Length` header if `Transfer-Encoding: chunked` is also set. This is an emergency off-switch to revert back to Envoy's default behavior in case of failures. |
+| compression | CompressionParameters | | Sets the compression configuration applied in the compression HTTP filter of the default Listener filters. |
+| disableMergeSlashes | boolean | `false` | This field disables Envoy's non-standard merge_slashes path transformation behavior that strips duplicate slashes from request URL paths. |
+| serverHeaderTransformation | string | `overwrite` | This field defines the action to be applied to the Server header on the response path. Values: `overwrite` (default), `append_if_absent`, `pass_through` |
+| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. |
+| envoy-service-name | string | `envoy` | This sets the service name that will be inspected for address details to be applied to Ingress objects. |
+| envoy-service-namespace | string | `projectcontour` | This sets the namespace of the service that will be inspected for address details to be applied to Ingress objects. If the `CONTOUR_NAMESPACE` environment variable is present, Contour will populate this field with its value. |
+| ingress-status-address | string | None | If present, this specifies the address that will be copied into the Ingress status for each Ingress that Contour manages. It is exclusive with `envoy-service-name` and `envoy-service-namespace`. |
+| incluster | boolean | `false` | This field specifies that Contour is running in a Kubernetes cluster and should use the in-cluster client access configuration. |
+| json-fields | string array | [fields][5] | This is the list the field names to include in the JSON [access log format][2]. This field only has effect if `accesslog-format` is `json`. |
+| kubeconfig | string | `$HOME/.kube/config` | Path to a Kubernetes [kubeconfig file][3] for when Contour is executed outside a cluster. |
+| kubernetesClientQPS | float32 | | QPS allowed for the Kubernetes client. |
+| kubernetesClientBurst | int | | Burst allowed for the Kubernetes client. |
+| policy | PolicyConfig | | The default [policy configuration](#policy-configuration). |
+| tls | TLS | | The default [TLS configuration](#tls-configuration). |
+| timeouts | TimeoutConfig | | The [timeout configuration](#timeout-configuration). |
+| cluster | ClusterConfig | | The [cluster configuration](#cluster-configuration). |
+| network | NetworkConfig | | The [network configuration](#network-configuration). |
+| listener | ListenerConfig | | The [listener configuration](#listener-configuration). |
+| server | ServerConfig | | The [server configuration](#server-configuration) for `contour serve` command. |
+| gateway | GatewayConfig | | The [gateway-api Gateway configuration](#gateway-configuration). |
+| rateLimitService | RateLimitServiceConfig | | The [rate limit service configuration](#rate-limit-service-configuration). |
+| enableExternalNameService | boolean | `false` | Enable ExternalName Service processing. Enabling this has security implications. Please see the [advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for more details. |
+| metrics | MetricsParameters | | The [metrics configuration](#metrics-configuration) |
+| featureFlags | string array | `[]` | Defines the toggle to enable new contour features. Available toggles are:
1. `useEndpointSlices` - configures contour to fetch endpoint data from k8s endpoint slices. |
### TLS Configuration
@@ -302,6 +302,13 @@ Metrics and health endpoints cannot have the same port number when metrics are s
| max-requests | int | 0 | The maximum parallel requests a single Envoy instance allows to the Kubernetes Service; defaults to 1024 |
| max-retries | int | 0 | The maximum number of parallel retries a single Envoy instance allows to the Kubernetes Service; defaults to 3. This setting only makes sense if the cluster is configured to do retries.|
+### Compression Parameters
+
+| Field Name | Type | Default | Description |
+|------------|--------|--------|-------------------------|
+| algorithm | string | "gzip" | Compression algorithm. Setting this to `disabled` will make Envoy skip "Accept-Encoding: gzip,deflate" request header and always return uncompressed response. Values:`gzip` (default), `brotli`, `zstd`, `disabled`. |
+
+
### Configuration Example
The following is an example ConfigMap with configuration file included:
From 43f6598e64d2be399eae7812f20823850cda4761 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Wed, 27 Nov 2024 14:10:07 +0000
Subject: [PATCH 29/30] lint
Signed-off-by: Geoff Macartney
---
cmd/contour/servecontext_test.go | 1 -
1 file changed, 1 deletion(-)
diff --git a/cmd/contour/servecontext_test.go b/cmd/contour/servecontext_test.go
index 644edc6d68e..ce7665ef4d2 100644
--- a/cmd/contour/servecontext_test.go
+++ b/cmd/contour/servecontext_test.go
@@ -507,7 +507,6 @@ func defaultContourConfiguration() contour_v1alpha1.ContourConfigurationSpec {
}
func TestConvertServeContext(t *testing.T) {
-
cases := map[string]struct {
getServeContext func(ctx *serveContext) *serveContext
getContourConfiguration func(cfg contour_v1alpha1.ContourConfigurationSpec) contour_v1alpha1.ContourConfigurationSpec
From 2f5e15730ff1b54fb204446d8fecd31f519f5eb0 Mon Sep 17 00:00:00 2001
From: Geoff Macartney
Date: Thu, 5 Dec 2024 09:25:12 +0000
Subject: [PATCH 30/30] rename builder method for clarity
a better name is SetDefaultFilterCompression
Signed-off-by: Geoff Macartney
---
internal/envoy/v3/listener.go | 4 +++-
internal/featuretests/v3/compression_test.go | 2 +-
internal/xdscache/v3/listener.go | 6 +++---
internal/xdscache/v3/listener_test.go | 10 +++++-----
4 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/internal/envoy/v3/listener.go b/internal/envoy/v3/listener.go
index 5b15021d4da..da152e4f225 100644
--- a/internal/envoy/v3/listener.go
+++ b/internal/envoy/v3/listener.go
@@ -275,7 +275,9 @@ func (b *httpConnectionManagerBuilder) MergeSlashes(enabled bool) *httpConnectio
return b
}
-func (b *httpConnectionManagerBuilder) Compression(compressor *contour_v1alpha1.EnvoyCompression) *httpConnectionManagerBuilder {
+// SetDefaultFilterCompression configures the builder to set the compression method applied by DefaultFilters() to the
+// given value `compressor`. When chaining builder method calls, this method should be called before DefaultFilters().
+func (b *httpConnectionManagerBuilder) SetDefaultFilterCompression(compressor *contour_v1alpha1.EnvoyCompression) *httpConnectionManagerBuilder {
b.compression = compressor
return b
}
diff --git a/internal/featuretests/v3/compression_test.go b/internal/featuretests/v3/compression_test.go
index b374ed92e1c..9b1cf7cf53e 100644
--- a/internal/featuretests/v3/compression_test.go
+++ b/internal/featuretests/v3/compression_test.go
@@ -76,7 +76,7 @@ func TestCompression(t *testing.T) {
rh.OnAdd(hp1)
httpListener := defaultHTTPListener()
httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder().
- Compression(&contour_v1alpha1.EnvoyCompression{
+ SetDefaultFilterCompression(&contour_v1alpha1.EnvoyCompression{
Algorithm: tc.want,
}).
RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER).
diff --git a/internal/xdscache/v3/listener.go b/internal/xdscache/v3/listener.go
index b053493861d..9b19e3d5e92 100644
--- a/internal/xdscache/v3/listener.go
+++ b/internal/xdscache/v3/listener.go
@@ -396,7 +396,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
// order for the HTTPS virtualhosts.
if len(listener.VirtualHosts) > 0 {
cm := envoy_v3.HTTPConnectionManagerBuilder().
- Compression(cfg.Compression).
+ SetDefaultFilterCompression(cfg.Compression).
Codec(envoy_v3.CodecForVersions(cfg.DefaultHTTPVersions...)).
DefaultFilters().
RouteConfigName(httpRouteConfigName(listener)).
@@ -469,7 +469,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
// Contour versions since the metrics prefix will be
// coded into monitoring dashboards.
cm := envoy_v3.HTTPConnectionManagerBuilder().
- Compression(cfg.Compression).
+ SetDefaultFilterCompression(cfg.Compression).
Codec(envoy_v3.CodecForVersions(cfg.DefaultHTTPVersions...)).
AddFilter(envoy_v3.FilterMisdirectedRequests(vh.VirtualHost.Name)).
DefaultFilters().
@@ -554,7 +554,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) {
}
cm := envoy_v3.HTTPConnectionManagerBuilder().
- Compression(cfg.Compression).
+ SetDefaultFilterCompression(cfg.Compression).
DefaultFilters().
AddFilter(authzFilter).
RouteConfigName(fallbackCertRouteConfigName(listener)).
diff --git a/internal/xdscache/v3/listener_test.go b/internal/xdscache/v3/listener_test.go
index c4f464ef8c4..63c80d54cdb 100644
--- a/internal/xdscache/v3/listener_test.go
+++ b/internal/xdscache/v3/listener_test.go
@@ -3108,7 +3108,7 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression(&contour_v1alpha1.EnvoyCompression{
+ SetDefaultFilterCompression(&contour_v1alpha1.EnvoyCompression{
Algorithm: contour_v1alpha1.DisabledCompression,
}).
RouteConfigName(ENVOY_HTTP_LISTENER).
@@ -3154,7 +3154,7 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression(&contour_v1alpha1.EnvoyCompression{
+ SetDefaultFilterCompression(&contour_v1alpha1.EnvoyCompression{
Algorithm: contour_v1alpha1.GzipCompression,
}).
RouteConfigName(ENVOY_HTTP_LISTENER).
@@ -3200,7 +3200,7 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression(&contour_v1alpha1.EnvoyCompression{
+ SetDefaultFilterCompression(&contour_v1alpha1.EnvoyCompression{
Algorithm: contour_v1alpha1.BrotliCompression,
}).
RouteConfigName(ENVOY_HTTP_LISTENER).
@@ -3246,7 +3246,7 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression(&contour_v1alpha1.EnvoyCompression{
+ SetDefaultFilterCompression(&contour_v1alpha1.EnvoyCompression{
Algorithm: contour_v1alpha1.ZstdCompression,
}).
RouteConfigName(ENVOY_HTTP_LISTENER).
@@ -3292,7 +3292,7 @@ func TestListenerVisit(t *testing.T) {
Address: envoy_v3.SocketAddress("0.0.0.0", 8080),
FilterChains: envoy_v3.FilterChains(
envoy_v3.HTTPConnectionManagerBuilder().
- Compression(&contour_v1alpha1.EnvoyCompression{
+ SetDefaultFilterCompression(&contour_v1alpha1.EnvoyCompression{
Algorithm: contour_v1alpha1.GzipCompression,
}).
RouteConfigName(ENVOY_HTTP_LISTENER).