code.vegaprotocol.io/vega@v0.79.0/datanode/gateway/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  	"io/ioutil"
    21  	"net/http"
    22  	"net/http/httptest"
    23  	"net/http/httputil"
    24  	"testing"
    25  
    26  	"code.vegaprotocol.io/vega/logging"
    27  )
    28  
    29  func headerNotPresent(t *testing.T, x *httptest.ResponseRecorder, key string) {
    30  	t.Helper()
    31  	res := x.Result() //nolint:bodyclose
    32  	h, found := res.Header[key]
    33  	if found || len(h) > 0 {
    34  		t.Fatalf("Unexpected header: %s", key)
    35  	}
    36  }
    37  
    38  func headerPresent(t *testing.T, x *httptest.ResponseRecorder, key string, expected []string) {
    39  	t.Helper()
    40  	res := x.Result() //nolint:bodyclose
    41  	h, found := res.Header[key]
    42  	if !found || len(h) == 0 {
    43  		t.Fatalf("Missing header: %s", key)
    44  	}
    45  	if len(h) != len(expected) {
    46  		t.Fatalf("Unexpected number of headers for \"%s\": expected %d, got %d", key, len(expected), len(h))
    47  	}
    48  	for i := range h {
    49  		if h[i] != expected[i] {
    50  			t.Fatalf("Unexpected header for \"%s\": #%d, expected \"%s\", got \"%s\"", key, i, expected[i], h[i])
    51  		}
    52  	}
    53  }
    54  
    55  func TestNoGzip(t *testing.T) {
    56  	req, err := http.NewRequest(http.MethodGet, "http://example.com/", nil)
    57  	if err != nil {
    58  		t.Fatal(err)
    59  	}
    60  
    61  	logger := logging.NewTestLogger()
    62  	defer logger.Sync()
    63  
    64  	rec := httptest.NewRecorder()
    65  	NewGzipHandler(*logger, func(w http.ResponseWriter, r *http.Request) {
    66  		w.Write([]byte("test"))
    67  	})(rec, req)
    68  
    69  	if rec.Code != 200 {
    70  		t.Fatalf("expected 200 got %d", rec.Code)
    71  	}
    72  
    73  	headerNotPresent(t, rec, "Content-Encoding")
    74  
    75  	if rec.Body.String() != "test" {
    76  		t.Fatalf(`expected "test" go "%s"`, rec.Body.String())
    77  	}
    78  
    79  	if testing.Verbose() {
    80  		b, _ := httputil.DumpResponse(rec.Result(), true) //nolint:bodyclose
    81  		t.Log("\n" + string(b))
    82  	}
    83  }
    84  
    85  func TestGzip(t *testing.T) {
    86  	req, err := http.NewRequest(http.MethodGet, "http://example.com/", nil)
    87  	if err != nil {
    88  		t.Fatal(err)
    89  	}
    90  	req.Header.Set("Accept-Encoding", "gzip, deflate")
    91  
    92  	logger := logging.NewTestLogger()
    93  	defer logger.Sync()
    94  
    95  	rec := httptest.NewRecorder()
    96  	NewGzipHandler(*logger, func(w http.ResponseWriter, r *http.Request) {
    97  		w.Header().Set("Content-Length", "4")
    98  		w.Header().Set("Content-Type", "text/test")
    99  		w.Write([]byte("test"))
   100  	})(rec, req)
   101  
   102  	if rec.Code != 200 {
   103  		t.Fatalf("expected 200 got %d", rec.Code)
   104  	}
   105  
   106  	headerPresent(t, rec, "Content-Encoding", []string{"gzip"})
   107  	headerNotPresent(t, rec, "Content-Length")
   108  	headerPresent(t, rec, "Content-Type", []string{"text/test"})
   109  
   110  	r, err := gzip.NewReader(rec.Body)
   111  	if err != nil {
   112  		t.Fatal(err)
   113  	}
   114  
   115  	body, err := ioutil.ReadAll(r)
   116  	if err != nil {
   117  		t.Fatal(err)
   118  	}
   119  
   120  	if string(body) != "test" {
   121  		t.Fatalf(`expected "test" go "%s"`, string(body))
   122  	}
   123  
   124  	if testing.Verbose() {
   125  		b, _ := httputil.DumpResponse(rec.Result(), true) //nolint:bodyclose
   126  		t.Log("\n" + string(b))
   127  	}
   128  }
   129  
   130  func TestNoBody(t *testing.T) {
   131  	req, err := http.NewRequest(http.MethodGet, "http://example.com/", nil)
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	req.Header.Set("Accept-Encoding", "gzip, deflate")
   136  
   137  	logger := logging.NewTestLogger()
   138  	defer logger.Sync()
   139  
   140  	rec := httptest.NewRecorder()
   141  	NewGzipHandler(*logger, func(w http.ResponseWriter, r *http.Request) {
   142  		w.WriteHeader(http.StatusNoContent)
   143  	})(rec, req)
   144  
   145  	if rec.Code != http.StatusNoContent {
   146  		t.Fatalf("expected %d got %d", http.StatusNoContent, rec.Code)
   147  	}
   148  
   149  	headerNotPresent(t, rec, "Content-Encoding")
   150  
   151  	if rec.Body.Len() > 0 {
   152  		t.Logf("%q", rec.Body.String())
   153  		t.Fatalf("no body expected for %d bytes", rec.Body.Len())
   154  	}
   155  
   156  	if testing.Verbose() {
   157  		b, _ := httputil.DumpResponse(rec.Result(), true) // nolint: bodyclose
   158  		t.Log("\n" + string(b))
   159  	}
   160  }
   161  
   162  func BenchmarkGzip(b *testing.B) {
   163  	body := []byte("testtesttesttesttesttesttesttesttesttesttesttesttest")
   164  
   165  	req, err := http.NewRequest(http.MethodGet, "http://example.com/", nil)
   166  	if err != nil {
   167  		b.Fatal(err)
   168  	}
   169  	req.Header.Set("Accept-Encoding", "gzip, deflate")
   170  
   171  	logger := logging.NewTestLogger()
   172  	defer logger.Sync()
   173  
   174  	b.ResetTimer()
   175  	b.RunParallel(func(pb *testing.PB) {
   176  		for pb.Next() {
   177  			rec := httptest.NewRecorder()
   178  			NewGzipHandler(*logger, func(w http.ResponseWriter, r *http.Request) {
   179  				w.Write(body)
   180  			})(rec, req)
   181  
   182  			if rec.Code != http.StatusOK {
   183  				b.Fatalf("expected %d got %d", http.StatusOK, rec.Code)
   184  			}
   185  			if rec.Body.Len() != 49 {
   186  				b.Fatalf("expected 49 bytes, got %d bytes", rec.Body.Len())
   187  			}
   188  		}
   189  	})
   190  }