github.com/avenga/couper@v1.12.2/server/writer/gzip_test.go (about) 1 package writer_test 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "io" 7 "net/http" 8 "net/http/httptest" 9 "net/http/httputil" 10 "os" 11 "testing" 12 "time" 13 14 "github.com/avenga/couper/internal/test" 15 "github.com/avenga/couper/server/writer" 16 ) 17 18 func TestGzip_Flush(t *testing.T) { 19 helper := test.New(t) 20 21 origin := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { 22 fileBytes, err := os.ReadFile("gzip.go") 23 if err != nil { 24 rw.WriteHeader(http.StatusInternalServerError) 25 _, _ = rw.Write([]byte(err.Error())) 26 return 27 } 28 for _, b := range fileBytes { 29 time.Sleep(time.Millisecond / 2) 30 _, _ = rw.Write([]byte{b}) 31 } 32 })) 33 defer origin.Close() 34 35 rp := &httputil.ReverseProxy{ 36 Director: func(_ *http.Request) {}, 37 FlushInterval: time.Millisecond * 10, 38 } 39 40 clientReq, err := http.NewRequest(http.MethodGet, origin.URL, nil) 41 helper.Must(err) 42 clientReq.Header.Set("Accept-Encoding", "gzip") 43 44 rec := httptest.NewRecorder() 45 gzipWriter := writer.NewGzipWriter(rec, clientReq.Header) 46 responseWriter := writer.NewResponseWriter(gzipWriter, "") 47 48 rp.ServeHTTP(responseWriter, clientReq) 49 50 rec.Flush() 51 res := rec.Result() 52 53 if res.StatusCode != http.StatusOK { 54 t.Error("Expected StatusOK") 55 } 56 57 if res.Header.Get("Content-Encoding") != "gzip" { 58 t.Error("Expected gzip response") 59 } 60 } 61 62 func TestGzip_ByPass(t *testing.T) { 63 helper := test.New(t) 64 65 expectedBytes, e := os.ReadFile("gzip.go") 66 helper.Must(e) 67 68 origin := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { 69 if req.Header.Get(writer.AcceptEncodingHeader) == writer.GzipName { 70 rw.Header().Set(writer.ContentEncodingHeader, writer.GzipName) 71 zw := gzip.NewWriter(rw) 72 _, err := zw.Write(expectedBytes) 73 helper.Must(err) 74 helper.Must(zw.Close()) 75 return 76 } 77 78 _, err := rw.Write(expectedBytes) 79 helper.Must(err) 80 })) 81 defer origin.Close() 82 83 rp := &httputil.ReverseProxy{ 84 Director: func(_ *http.Request) {}, 85 } 86 87 for _, testcase := range []struct { 88 name string 89 encoding string 90 }{ 91 {name: "with ae gzip", encoding: "gzip"}, 92 {name: "without ae gzip", encoding: ""}, 93 } { 94 t.Run(testcase.name, func(st *testing.T) { 95 clientReq, err := http.NewRequest(http.MethodGet, origin.URL, nil) 96 helper.Must(err) 97 clientReq.Header.Set(writer.AcceptEncodingHeader, testcase.encoding) 98 99 rec := httptest.NewRecorder() 100 gzipWriter := writer.NewGzipWriter(rec, clientReq.Header) 101 102 rp.ServeHTTP(gzipWriter, clientReq) 103 104 rec.Flush() 105 res := rec.Result() 106 107 if res.StatusCode != http.StatusOK { 108 st.Errorf("Want status-code 200, got: %d", res.StatusCode) 109 } 110 111 // create gzip reader by expectation and not by content-encoding 112 if testcase.encoding == "gzip" { 113 gr, err := gzip.NewReader(res.Body) 114 if err != nil { 115 st.Fatal(err) 116 } 117 118 res.Body = gr 119 } 120 121 resultBytes, err := io.ReadAll(res.Body) 122 if err != nil { 123 st.Errorf("read error with Accept-Encoding %q: %v", testcase.encoding, err) 124 return 125 } 126 127 _ = res.Body.Close() 128 129 if !bytes.Equal(expectedBytes, resultBytes) { 130 t.Errorf("Want %d bytes with Accept-Encoding %q, got %d bytes with Content-Encoding: %s", 131 len(expectedBytes), testcase.encoding, len(resultBytes), res.Header.Get("Content-Encoding")) 132 } 133 134 }) 135 } 136 }