From fe1fef439118721320192e1b1422399cf19c3949 Mon Sep 17 00:00:00 2001 From: Carlo Alberto Ferraris Date: Mon, 25 Jan 2021 22:31:29 +0900 Subject: [PATCH] add tests for the prefer logic --- adapter.go | 3 +- adapter_test.go | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ prefer.go | 12 +++---- 3 files changed, 103 insertions(+), 8 deletions(-) diff --git a/adapter.go b/adapter.go index 8b455fc..2b6bb11 100644 --- a/adapter.go +++ b/adapter.go @@ -17,7 +17,6 @@ const ( contentType = "Content-Type" contentLength = "Content-Length" gzipEncoding = "gzip" - brotliEncoding = "br" ) type codings map[string]float64 @@ -176,7 +175,7 @@ func GzipCompressor(g CompressorProvider) Option { // BrotliCompressor is an option to specify a custom compressor factory for Brotli. func BrotliCompressor(b CompressorProvider) Option { - return Compressor(brotliEncoding, 1, b) + return Compressor(brotli.Encoding, 1, b) } func errorOption(err error) Option { diff --git a/adapter_test.go b/adapter_test.go index 818dfe4..65b9df3 100644 --- a/adapter_test.go +++ b/adapter_test.go @@ -115,6 +115,74 @@ func TestGzipHandler(t *testing.T) { assert.Equal(t, brotliStrLevel(testBody, brotli.DefaultCompression), resp.Body.Bytes()) } + // same, but with accept-encoding:gzip,br;q=0.5 (gzip wins) + // because the server has no preference, we use the client preference (gzip) + { + c, _ := NewDefaultGzipCompressor(gzip.DefaultCompression) + + req, _ := http.NewRequest("GET", "/whatever", nil) + req.Header.Set("Accept-Encoding", "gzip,br;q=0.5") + resp := httptest.NewRecorder() + newTestHandler(testBody, Compressor(gzipEncoding, 1, c)).ServeHTTP(resp, req) + res := resp.Result() + + assert.Equal(t, 200, res.StatusCode) + assert.Equal(t, "gzip", res.Header.Get("Content-Encoding")) + assert.Equal(t, "Accept-Encoding", res.Header.Get("Vary")) + assert.Equal(t, gzipStrLevel(testBody, gzip.DefaultCompression), resp.Body.Bytes()) + } + + // same, but with accept-encoding:gzip,br (br wins) + // because the server has no preference, we use the client preference + // becuase the client has no preference, we rely on the encoding name + { + c, _ := NewDefaultGzipCompressor(gzip.DefaultCompression) + + req, _ := http.NewRequest("GET", "/whatever", nil) + req.Header.Set("Accept-Encoding", "gzip,br") + resp := httptest.NewRecorder() + newTestHandler(testBody, Compressor(gzipEncoding, 1, c)).ServeHTTP(resp, req) + res := resp.Result() + + assert.Equal(t, 200, res.StatusCode) + assert.Equal(t, "br", res.Header.Get("Content-Encoding")) + assert.Equal(t, "Accept-Encoding", res.Header.Get("Vary")) + assert.Equal(t, brotliStrLevel(testBody, brotli.DefaultCompression), resp.Body.Bytes()) + } + + // same, but with accept-encoding:gzip,br and PreferClient (br wins) + // because the client use q=1 for both, we rely on the server preference + { + req, _ := http.NewRequest("GET", "/whatever", nil) + req.Header.Set("Accept-Encoding", "gzip,br") + resp := httptest.NewRecorder() + newTestHandler(testBody, Prefer(PreferClient)).ServeHTTP(resp, req) + res := resp.Result() + + assert.Equal(t, 200, res.StatusCode) + assert.Equal(t, "br", res.Header.Get("Content-Encoding")) + assert.Equal(t, "Accept-Encoding", res.Header.Get("Vary")) + assert.Equal(t, brotliStrLevel(testBody, brotli.DefaultCompression), resp.Body.Bytes()) + } + + // same, but with accept-encoding:gzip,br and PreferClient (br wins) + // because the client use q=1 for both, we rely on the server preference + // becuase the server preference is the same, we rely on the encoding name + { + c, _ := NewDefaultGzipCompressor(gzip.DefaultCompression) + + req, _ := http.NewRequest("GET", "/whatever", nil) + req.Header.Set("Accept-Encoding", "gzip,br") + resp := httptest.NewRecorder() + newTestHandler(testBody, Prefer(PreferClient), Compressor(gzipEncoding, 1, c)).ServeHTTP(resp, req) + res := resp.Result() + + assert.Equal(t, 200, res.StatusCode) + assert.Equal(t, "br", res.Header.Get("Content-Encoding")) + assert.Equal(t, "Accept-Encoding", res.Header.Get("Vary")) + assert.Equal(t, brotliStrLevel(testBody, brotli.DefaultCompression), resp.Body.Bytes()) + } + // same, but with accept-encoding:gzip,br;q=0.5 and PreferClient (gzip wins) { req, _ := http.NewRequest("GET", "/whatever", nil) @@ -129,6 +197,34 @@ func TestGzipHandler(t *testing.T) { assert.Equal(t, gzipStrLevel(testBody, gzip.DefaultCompression), resp.Body.Bytes()) } + // same, but with accept-encoding:gzip;q=0.1,br;q=0.5 and PreferClient (br wins) + { + req, _ := http.NewRequest("GET", "/whatever", nil) + req.Header.Set("Accept-Encoding", "gzip;q=0.1,br;q=0.5") + resp := httptest.NewRecorder() + newTestHandler(testBody, Prefer(PreferClient)).ServeHTTP(resp, req) + res := resp.Result() + + assert.Equal(t, 200, res.StatusCode) + assert.Equal(t, "br", res.Header.Get("Content-Encoding")) + assert.Equal(t, "Accept-Encoding", res.Header.Get("Vary")) + assert.Equal(t, brotliStrLevel(testBody, brotli.DefaultCompression), resp.Body.Bytes()) + } + + // same, but with accept-encoding:gzip;q=0,br;q=0.5 and PreferClient (br wins) + { + req, _ := http.NewRequest("GET", "/whatever", nil) + req.Header.Set("Accept-Encoding", "gzip;q=0,br;q=0.5") + resp := httptest.NewRecorder() + newTestHandler(testBody, Prefer(PreferClient)).ServeHTTP(resp, req) + res := resp.Result() + + assert.Equal(t, 200, res.StatusCode) + assert.Equal(t, "br", res.Header.Get("Content-Encoding")) + assert.Equal(t, "Accept-Encoding", res.Header.Get("Vary")) + assert.Equal(t, brotliStrLevel(testBody, brotli.DefaultCompression), resp.Body.Bytes()) + } + // same, but with accept-encoding:gzip,br;q=0.5 and PreferServer (brotli wins) { req, _ := http.NewRequest("GET", "/whatever", nil) diff --git a/prefer.go b/prefer.go index 7c3fcee..eddf559 100644 --- a/prefer.go +++ b/prefer.go @@ -47,25 +47,25 @@ func preferredEncoding(accept codings, comps comps, common []string, prefer Pref sort.Slice(common, func(i, j int) bool { ci, cj := comps[common[i]].priority, comps[common[j]].priority if ci != cj { - return ci > cj + return ci > cj // desc } ai, aj := accept[common[i]], accept[common[j]] if ai != aj { - return ai > aj + return ai > aj // desc } - return common[i] > common[j] + return common[i] < common[j] // asc }) case PreferClient: sort.Slice(common, func(i, j int) bool { ai, aj := accept[common[i]], accept[common[j]] if ai != aj { - return ai > aj + return ai > aj // desc } ci, cj := comps[common[i]].priority, comps[common[j]].priority if ci != cj { - return ci > cj + return ci > cj // desc } - return common[i] > common[j] + return common[i] < common[j] // asc }) default: panic("unknown prefer type")