1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
package gziphandler
import (
"bytes"
"compress/gzip"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestParseEncodings(t *testing.T) {
examples := map[string]codings{
// Examples from RFC 2616
"compress, gzip": codings{"compress": 1.0, "gzip": 1.0},
"": codings{},
"*": codings{"*": 1.0},
"compress;q=0.5, gzip;q=1.0": codings{"compress": 0.5, "gzip": 1.0},
"gzip;q=1.0, identity; q=0.5, *;q=0": codings{"gzip": 1.0, "identity": 0.5, "*": 0.0},
// More random stuff
"AAA;q=1": codings{"aaa": 1.0},
"BBB ; q = 2": codings{"bbb": 1.0},
}
for eg, exp := range examples {
act, _ := parseEncodings(eg)
assert.Equal(t, exp, act)
}
}
func TestGzipHandler(t *testing.T) {
testBody := "aaabbbccc"
// This just exists to provide something for GzipHandler to wrap.
handler := newTestHandler(testBody)
// requests without accept-encoding are passed along as-is
req1, _ := http.NewRequest("GET", "/whatever", nil)
res1 := httptest.NewRecorder()
handler.ServeHTTP(res1, req1)
assert.Equal(t, 200, res1.Code)
assert.Equal(t, "", res1.Header().Get("Content-Encoding"))
assert.Equal(t, "Accept-Encoding", res1.Header().Get("Vary"))
assert.Equal(t, testBody, res1.Body.String())
// but requests with accept-encoding:gzip are compressed if possible
req2, _ := http.NewRequest("GET", "/whatever", nil)
req2.Header.Set("Accept-Encoding", "gzip")
res2 := httptest.NewRecorder()
handler.ServeHTTP(res2, req2)
assert.Equal(t, 200, res2.Code)
assert.Equal(t, "gzip", res2.Header().Get("Content-Encoding"))
assert.Equal(t, "Accept-Encoding", res2.Header().Get("Vary"))
assert.Equal(t, gzipStr(testBody), res2.Body.Bytes())
// content-type header is correctly set based on uncompressed body
req3, _ := http.NewRequest("GET", "/whatever", nil)
req3.Header.Set("Accept-Encoding", "gzip")
res3 := httptest.NewRecorder()
handler.ServeHTTP(res3, req3)
assert.Equal(t, http.DetectContentType([]byte(testBody)), res3.Header().Get("Content-Type"))
}
// --------------------------------------------------------------------
func BenchmarkGzipHandler_S2k(b *testing.B) { benchmark(b, false, 2048) }
func BenchmarkGzipHandler_S20k(b *testing.B) { benchmark(b, false, 20480) }
func BenchmarkGzipHandler_S100k(b *testing.B) { benchmark(b, false, 102400) }
func BenchmarkGzipHandler_P2k(b *testing.B) { benchmark(b, true, 2048) }
func BenchmarkGzipHandler_P20k(b *testing.B) { benchmark(b, true, 20480) }
func BenchmarkGzipHandler_P100k(b *testing.B) { benchmark(b, true, 102400) }
// --------------------------------------------------------------------
func gzipStr(s string) []byte {
var b bytes.Buffer
w := gzip.NewWriter(&b)
io.WriteString(w, s)
w.Close()
return b.Bytes()
}
func benchmark(b *testing.B, parallel bool, size int) {
bin, err := ioutil.ReadFile("testdata/benchmark.json")
if err != nil {
b.Fatal(err)
}
req, _ := http.NewRequest("GET", "/whatever", nil)
req.Header.Set("Accept-Encoding", "gzip")
handler := newTestHandler(string(bin[:size]))
if parallel {
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
runBenchmark(b, req, handler)
}
})
} else {
b.ResetTimer()
for i := 0; i < b.N; i++ {
runBenchmark(b, req, handler)
}
}
}
func runBenchmark(b *testing.B, req *http.Request, handler http.Handler) {
res := httptest.NewRecorder()
handler.ServeHTTP(res, req)
if code := res.Code; code != 200 {
b.Fatalf("Expected 200 but got %d", code)
} else if blen := res.Body.Len(); blen < 500 {
b.Fatalf("Expected complete response body, but got %d bytes", blen)
}
}
func newTestHandler(body string) http.Handler {
return GzipHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, body)
}))
}
|