diff --git a/docs/user-guide/nginx-configuration/configmap.md b/docs/user-guide/nginx-configuration/configmap.md index 4fdda21ba9..21cb2799e4 100755 --- a/docs/user-guide/nginx-configuration/configmap.md +++ b/docs/user-guide/nginx-configuration/configmap.md @@ -98,6 +98,7 @@ The following table shows a configuration option's name, type, and the default v |[use-geoip2](#use-geoip2)|bool|"false"| |[enable-brotli](#enable-brotli)|bool|"false"| |[brotli-level](#brotli-level)|int|4| +|[brotli-min-length](#brotli-min-length)|int|20| |[brotli-types](#brotli-types)|string|"application/xml+rss application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/javascript text/plain text/x-component"| |[use-http2](#use-http2)|bool|"true"| |[gzip-level](#gzip-level)|int|1| @@ -665,6 +666,10 @@ The default mime type list to compress is: `application/xml+rss application/atom Sets the Brotli Compression Level that will be used. _**default:**_ 4 +## brotli-min-length + +Minimum length of responses, in bytes, that will be eligible for brotli compression. _**default:**_ 20 + ## brotli-types Sets the MIME Types that will be compressed on-the-fly by brotli. diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index b1a5fc8c47..2d853cfb0a 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -413,6 +413,9 @@ type Configuration struct { // Brotli Compression Level that will be used BrotliLevel int `json:"brotli-level,omitempty"` + // Minimum length of responses, in bytes, that will be eligible for brotli compression + BrotliMinLength int `json:"brotli-min-length,omitempty"` + // MIME Types that will be compressed on-the-fly using Brotli module BrotliTypes string `json:"brotli-types,omitempty"` @@ -778,6 +781,7 @@ func NewDefault() Configuration { BlockUserAgents: defBlockEntity, BlockReferers: defBlockEntity, BrotliLevel: 4, + BrotliMinLength: 20, BrotliTypes: brotliTypes, ClientHeaderBufferSize: "1k", ClientHeaderTimeout: 60, diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index bfe0703ffa..9beca463b4 100755 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -320,6 +320,7 @@ http { {{ if $cfg.EnableBrotli }} brotli on; brotli_comp_level {{ $cfg.BrotliLevel }}; + brotli_min_length {{ $cfg.BrotliMinLength }}; brotli_types {{ $cfg.BrotliTypes }}; {{ end }} diff --git a/test/e2e/settings/brotli.go b/test/e2e/settings/brotli.go new file mode 100644 index 0000000000..52092ee83b --- /dev/null +++ b/test/e2e/settings/brotli.go @@ -0,0 +1,74 @@ +/* +Copyright 2021 The Kubernetes 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 settings + +import ( + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/onsi/ginkgo" + + "k8s.io/ingress-nginx/test/e2e/framework" +) + +var _ = framework.IngressNginxDescribe("brotli", func() { + f := framework.NewDefaultFramework("brotli") + + host := "brotli" + + ginkgo.BeforeEach(func() { + f.NewHttpbinDeployment() + }) + + ginkgo.It("should only compress responses that meet the `brotli-min-length` condition", func() { + brotliMinLength := 24 + contentEncoding := "application/octet-stream" + f.UpdateNginxConfigMapData("enable-brotli", "true") + f.UpdateNginxConfigMapData("brotli-types", contentEncoding) + f.UpdateNginxConfigMapData("brotli-min-length", strconv.Itoa(brotliMinLength)) + + f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, nil)) + + f.WaitForNginxConfiguration( + func(server string) bool { + return strings.Contains(server, fmt.Sprintf("server_name %v", host)) && + strings.Contains(server, "brotli on") && + strings.Contains(server, fmt.Sprintf("brotli_types %v", contentEncoding)) && + strings.Contains(server, fmt.Sprintf("brotli_min_length %d", brotliMinLength)) + }) + + f.HTTPTestClient(). + GET(fmt.Sprintf("/bytes/%d", brotliMinLength)). + WithHeader("Host", host). + WithHeader("Accept-Encoding", "br"). + Expect(). + Status(http.StatusOK). + ContentType(contentEncoding). + ContentEncoding("br") + + f.HTTPTestClient(). + GET(fmt.Sprintf("/bytes/%d", brotliMinLength-1)). + WithHeader("Host", host). + WithHeader("Accept-Encoding", "br"). + Expect(). + Status(http.StatusOK). + ContentType(contentEncoding). + ContentEncoding() + }) +})