code.vegaprotocol.io/vega@v0.79.0/core/api/rest/gziphandler_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package rest 17 18 import ( 19 "compress/gzip" 20 "context" 21 "io/ioutil" 22 "net/http" 23 "net/http/httptest" 24 "net/http/httputil" 25 "testing" 26 27 "code.vegaprotocol.io/vega/logging" 28 ) 29 30 func headerNotPresent(t *testing.T, x *httptest.ResponseRecorder, key string) { 31 t.Helper() 32 res := x.Result() 33 defer res.Body.Close() 34 h, found := res.Header[key] 35 if found || len(h) > 0 { 36 t.Fatalf("Unexpected header: %s", key) 37 } 38 } 39 40 func headerPresent(t *testing.T, x *httptest.ResponseRecorder, key string, expected []string) { 41 t.Helper() 42 res := x.Result() 43 defer res.Body.Close() 44 h, found := res.Header[key] 45 if !found || len(h) == 0 { 46 t.Fatalf("Missing header: %s", key) 47 } 48 if len(h) != len(expected) { 49 t.Fatalf("Unexpected number of headers for \"%s\": expected %d, got %d", key, len(expected), len(h)) 50 } 51 for i := range h { 52 if h[i] != expected[i] { 53 t.Fatalf("Unexpected header for \"%s\": #%d, expected \"%s\", got \"%s\"", key, i, expected[i], h[i]) 54 } 55 } 56 } 57 58 func TestNoGzip(t *testing.T) { 59 req, err := http.NewRequestWithContext( 60 context.Background(), http.MethodGet, "http://example.com/", nil) 61 if err != nil { 62 t.Fatal(err) 63 } 64 65 logger := logging.NewTestLogger() 66 defer logger.Sync() 67 68 rec := httptest.NewRecorder() 69 newGzipHandler(*logger, func(w http.ResponseWriter, r *http.Request) { 70 w.Write([]byte("test")) 71 })(rec, req) 72 73 if rec.Code != 200 { 74 t.Fatalf("expected 200 got %d", rec.Code) 75 } 76 77 headerNotPresent(t, rec, "Content-Encoding") 78 79 if rec.Body.String() != "test" { 80 t.Fatalf(`expected "test" go "%s"`, rec.Body.String()) 81 } 82 83 if testing.Verbose() { 84 res := rec.Result() 85 defer res.Body.Close() 86 b, _ := httputil.DumpResponse(res, true) 87 t.Log("\n" + string(b)) 88 } 89 } 90 91 func TestGzip(t *testing.T) { 92 req, err := http.NewRequestWithContext( 93 context.Background(), http.MethodGet, "http://example.com/", nil) 94 if err != nil { 95 t.Fatal(err) 96 } 97 req.Header.Set("Accept-Encoding", "gzip, deflate") 98 99 logger := logging.NewTestLogger() 100 defer logger.Sync() 101 102 rec := httptest.NewRecorder() 103 newGzipHandler(*logger, func(w http.ResponseWriter, r *http.Request) { 104 w.Header().Set("Content-Length", "4") 105 w.Header().Set("Content-Type", "text/test") 106 w.Write([]byte("test")) 107 })(rec, req) 108 109 if rec.Code != 200 { 110 t.Fatalf("expected 200 got %d", rec.Code) 111 } 112 113 headerPresent(t, rec, "Content-Encoding", []string{"gzip"}) 114 headerNotPresent(t, rec, "Content-Length") 115 headerPresent(t, rec, "Content-Type", []string{"text/test"}) 116 117 r, err := gzip.NewReader(rec.Body) 118 if err != nil { 119 t.Fatal(err) 120 } 121 122 body, err := ioutil.ReadAll(r) 123 if err != nil { 124 t.Fatal(err) 125 } 126 127 if string(body) != "test" { 128 t.Fatalf(`expected "test" go "%s"`, string(body)) 129 } 130 131 if testing.Verbose() { 132 res := rec.Result() 133 defer res.Body.Close() 134 b, _ := httputil.DumpResponse(res, true) 135 t.Log("\n" + string(b)) 136 } 137 } 138 139 func TestNoBody(t *testing.T) { 140 req, err := http.NewRequestWithContext( 141 context.Background(), http.MethodGet, "http://example.com/", nil) 142 if err != nil { 143 t.Fatal(err) 144 } 145 req.Header.Set("Accept-Encoding", "gzip, deflate") 146 147 logger := logging.NewTestLogger() 148 defer logger.Sync() 149 150 rec := httptest.NewRecorder() 151 newGzipHandler(*logger, func(w http.ResponseWriter, r *http.Request) { 152 w.WriteHeader(http.StatusNoContent) 153 })(rec, req) 154 155 if rec.Code != http.StatusNoContent { 156 t.Fatalf("expected %d got %d", http.StatusNoContent, rec.Code) 157 } 158 159 headerNotPresent(t, rec, "Content-Encoding") 160 161 if rec.Body.Len() > 0 { 162 t.Logf("%q", rec.Body.String()) 163 t.Fatalf("no body expected for %d bytes", rec.Body.Len()) 164 } 165 166 if testing.Verbose() { 167 res := rec.Result() 168 defer res.Body.Close() 169 b, _ := httputil.DumpResponse(res, true) 170 t.Log("\n" + string(b)) 171 } 172 } 173 174 func BenchmarkGzip(b *testing.B) { 175 body := []byte("testtesttesttesttesttesttesttesttesttesttesttesttest") 176 177 req, err := http.NewRequest(http.MethodGet, "http://example.com/", nil) 178 if err != nil { 179 b.Fatal(err) 180 } 181 req.Header.Set("Accept-Encoding", "gzip, deflate") 182 183 logger := logging.NewTestLogger() 184 defer logger.Sync() 185 186 b.ResetTimer() 187 b.RunParallel(func(pb *testing.PB) { 188 for pb.Next() { 189 rec := httptest.NewRecorder() 190 newGzipHandler(*logger, func(w http.ResponseWriter, r *http.Request) { 191 w.Write(body) 192 })(rec, req) 193 194 if rec.Code != http.StatusOK { 195 b.Fatalf("expected %d got %d", http.StatusOK, rec.Code) 196 } 197 if rec.Body.Len() != 49 { 198 b.Fatalf("expected 49 bytes, got %d bytes", rec.Body.Len()) 199 } 200 } 201 }) 202 }