summaryrefslogtreecommitdiffhomepage
path: root/tsweb/compress_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'tsweb/compress_test.go')
-rw-r--r--tsweb/compress_test.go140
1 files changed, 140 insertions, 0 deletions
diff --git a/tsweb/compress_test.go b/tsweb/compress_test.go
new file mode 100644
index 000000000..f1c8b6e89
--- /dev/null
+++ b/tsweb/compress_test.go
@@ -0,0 +1,140 @@
+// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tsweb
+
+import (
+ "compress/gzip"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/andybalholm/brotli"
+)
+
+func TestCompressingHandler(t *testing.T) {
+ h := compressingHandler{nil}
+ var _ http.Handler = h
+
+ w := &compressingResponseWriter{}
+ var (
+ _ http.ResponseWriter = w
+ _ http.Flusher = w
+ _ http.Hijacker = w
+ )
+
+ // testRequest constructs a response recorder and a compressing handler that
+ // wraps the given handler h, it calls the handler with r, and returns the
+ // response recorder. If r is nil, then a GET request is made to "/" with no
+ // additional headers.
+ testRequest := func(r *http.Request, h http.HandlerFunc) *httptest.ResponseRecorder {
+ t.Helper()
+ w := httptest.NewRecorder()
+ if r == nil {
+ r = httptest.NewRequest("GET", "/", nil)
+ }
+ compressingHandler{h}.ServeHTTP(w, r)
+ return w
+ }
+
+ checkBody := func(r io.Reader, want string) {
+ t.Helper()
+ body, err := ioutil.ReadAll(r)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if string(body) != want {
+ t.Errorf("got body %q, want %q", body, want)
+ }
+ }
+
+ checkHeader := func(h http.Header, key, want string) {
+ t.Helper()
+ if got := h.Get(key); got != want {
+ t.Errorf("got header %q=%q, want %q", key, got, want)
+ }
+ }
+
+ t.Run("transparently compresses content with brotli", func(t *testing.T) {
+ r := httptest.NewRequest("GET", "/", nil)
+ r.Header.Set("Accept-Encoding", "br")
+
+ w := testRequest(r, func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "text/plain")
+ w.Write([]byte("hello world"))
+ })
+
+ checkHeader(w.Header(), "Content-Encoding", "br")
+ checkBody(brotli.NewReader(w.Body), "hello world")
+ })
+
+ t.Run("transparently compresses content with gzip", func(t *testing.T) {
+ r := httptest.NewRequest("GET", "/", nil)
+ r.Header.Set("Accept-Encoding", "gzip")
+
+ w := testRequest(r, func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "text/plain")
+ w.Write([]byte("hello world"))
+ })
+
+ checkHeader(w.Header(), "Content-Encoding", "gzip")
+ br, err := gzip.NewReader(w.Body)
+ if err != nil {
+ t.Fatal(err)
+ }
+ checkBody(br, "hello world")
+ })
+
+ t.Run("does not compress content if client does not accept compressed content", func(t *testing.T) {
+ w := testRequest(nil, func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "text/plain")
+ w.Write([]byte("hello world"))
+ })
+
+ checkHeader(w.Header(), "Content-Encoding", "")
+ checkBody(w.Body, "hello world")
+ })
+
+ t.Run("does not recompress content if client accepts compressed content but content is already compressed", func(t *testing.T) {
+ r := httptest.NewRequest("GET", "/", nil)
+ r.Header.Set("Accept-Encoding", "br")
+
+ w := testRequest(r, func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "text/plain")
+ w.Header().Set("Content-Encoding", "magic")
+ w.Write([]byte("hello world"))
+ })
+
+ checkHeader(w.Header(), "Content-Encoding", "magic")
+ checkBody(w.Body, "hello world")
+ })
+
+ t.Run("integration", func(t *testing.T) {
+ s := httptest.NewServer(compressingHandler{http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "text/plain")
+ w.Write([]byte("hello world"))
+ })})
+ defer s.Close()
+
+ r, err := http.NewRequest("GET", s.URL, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ r.Header.Set("Accept-Encoding", "gzip")
+ res, err := s.Client().Do(r)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ checkHeader(res.Header, "Content-Encoding", "gzip")
+ br, err := gzip.NewReader(res.Body)
+ if err != nil {
+ t.Fatal(err)
+ }
+ checkBody(br, "hello world")
+ })
+
+}