diff --git a/pkg/getter/getter.go b/pkg/getter/getter.go index a2d0f0ee2..ba0ffce28 100644 --- a/pkg/getter/getter.go +++ b/pkg/getter/getter.go @@ -45,6 +45,7 @@ type getterOptions struct { passCredentialsAll bool userAgent string version string + enableCompression bool registryClient *registry.Client timeout time.Duration transport *http.Transport @@ -132,6 +133,13 @@ func WithRegistryClient(client *registry.Client) Option { } } +// WithCompression enables compression +func WithCompression() Option { + return func(opts *options) { + opts.enableCompression = true + } +} + func WithUntar() Option { return func(opts *getterOptions) { opts.unTar = true diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go index 110f45c54..e3996dd6f 100644 --- a/pkg/getter/httpgetter.go +++ b/pkg/getter/httpgetter.go @@ -17,6 +17,7 @@ package getter import ( "bytes" + "compress/gzip" "crypto/tls" "fmt" "io" @@ -80,6 +81,10 @@ func (g *HTTPGetter) get(href string) (*bytes.Buffer, error) { } } + if g.opts.enableCompression { + req.Header.Add("Accept-Encoding", "gzip") + } + client, err := g.httpClient() if err != nil { return nil, err @@ -95,7 +100,19 @@ func (g *HTTPGetter) get(href string) (*bytes.Buffer, error) { } buf := bytes.NewBuffer(nil) - _, err = io.Copy(buf, resp.Body) + + body := resp.Body + + if g.opts.enableCompression && resp.Header.Get("Content-Encoding") == "gzip" { + body, err = gzip.NewReader(resp.Body) + if err != nil { + return nil, err + } + defer body.Close() + } + + _, err = io.Copy(buf, body) + return buf, err } diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go index f87d71877..583a6a58a 100644 --- a/pkg/getter/httpgetter_test.go +++ b/pkg/getter/httpgetter_test.go @@ -16,6 +16,8 @@ limitations under the License. package getter import ( + "bytes" + "compress/gzip" "fmt" "io" "net/http" @@ -513,6 +515,30 @@ func TestDownloadInsecureSkipTLSVerify(t *testing.T) { } +func TestHTTPGetterWithCompression(t *testing.T) { + expectedData := []byte("index.yaml") + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Encoding", "gzip") + gzipWriter := gzip.NewWriter(w) + gzipWriter.Write(expectedData) + gzipWriter.Close() + })) + + defer srv.Close() + + g, err := NewHTTPGetter(WithURL(srv.URL), WithCompression()) + if err != nil { + t.Fatal(err) + } + + data, _ := g.Get(srv.URL) + + if bytes.Compare(data.Bytes(), expectedData) != 0 { + t.Fatalf("Expected response with uncompressed data %s, but got %s", expectedData, data.Bytes()) + } +} + func TestHTTPGetterTarDownload(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { f, _ := os.Open("testdata/empty-0.0.1.tgz") diff --git a/pkg/repo/chartrepo.go b/pkg/repo/chartrepo.go index c54197d60..0771343aa 100644 --- a/pkg/repo/chartrepo.go +++ b/pkg/repo/chartrepo.go @@ -86,6 +86,7 @@ func (r *ChartRepository) DownloadIndexFile() (string, error) { getter.WithTLSClientConfig(r.Config.CertFile, r.Config.KeyFile, r.Config.CAFile), getter.WithBasicAuth(r.Config.Username, r.Config.Password), getter.WithPassCredentialsAll(r.Config.PassCredentialsAll), + getter.WithCompression(), ) if err != nil { return "", err