pull/32478/merge
R@V 3 days ago committed by GitHub
commit 914b46ae6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -17,6 +17,7 @@ package getter
import (
"bytes"
"compress/gzip"
"context"
"crypto/tls"
"fmt"
@ -24,6 +25,7 @@ import (
"log/slog"
"net/http"
"net/url"
"strings"
"sync"
"helm.sh/helm/v4/internal/tlsutil"
@ -55,9 +57,14 @@ func (g *HTTPGetter) get(href string, opts getterOptions) (*bytes.Buffer, error)
return nil, err
}
isRepositoryIndexRequest := isRepositoryIndexRequestURL(href)
if opts.acceptHeader != "" {
req.Header.Set("Accept", opts.acceptHeader)
}
if isRepositoryIndexRequest {
req.Header.Set("Accept-Encoding", "gzip")
}
req.Header.Set("User-Agent", version.GetUserAgent())
if opts.userAgent != "" {
@ -100,11 +107,42 @@ func (g *HTTPGetter) get(href string, opts getterOptions) (*bytes.Buffer, error)
return nil, fmt.Errorf("failed to fetch %s : %s", href, resp.Status)
}
reader := io.Reader(resp.Body)
if isRepositoryIndexRequest && isGzipEncoded(resp.Header) {
gzipReader, err := gzip.NewReader(resp.Body)
if err != nil {
return nil, err
}
defer gzipReader.Close()
reader = gzipReader
}
buf := bytes.NewBuffer(nil)
_, err = io.Copy(buf, resp.Body)
_, err = io.Copy(buf, reader)
return buf, err
}
func isRepositoryIndexRequestURL(href string) bool {
u, err := url.Parse(href)
if err != nil {
return false
}
return u.Path == "index.yaml" || strings.HasSuffix(u.Path, "/index.yaml")
}
func isGzipEncoded(header http.Header) bool {
for _, value := range header.Values("Content-Encoding") {
for _, encoding := range strings.Split(value, ",") {
if strings.EqualFold(strings.TrimSpace(encoding), "gzip") {
return true
}
}
}
return false
}
// NewHTTPGetter constructs a valid http/https client as a Getter
func NewHTTPGetter(options ...Option) (Getter, error) {
var client HTTPGetter

@ -18,6 +18,7 @@ package repo
import (
"bytes"
"compress/gzip"
"net/http"
"net/http/httptest"
"os"
@ -124,6 +125,47 @@ func TestConcurrencyDownloadIndex(t *testing.T) {
wg.Wait()
}
func TestDownloadIndexFileWithGzipContentEncoding(t *testing.T) {
fileBytes, err := os.ReadFile("testdata/local-index.yaml")
require.NoError(t, err)
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "gzip", r.Header.Get("Accept-Encoding"))
w.Header().Set("Content-Encoding", "gzip")
gzipWriter := gzip.NewWriter(w)
_, err := gzipWriter.Write(fileBytes)
require.NoError(t, err)
require.NoError(t, gzipWriter.Close())
})
srv, err := startLocalServerForTests(handler)
require.NoError(t, err)
defer srv.Close()
r, err := NewChartRepository(&Entry{
Name: testRepo,
URL: srv.URL,
}, getter.All(&cli.EnvSettings{}))
require.NoError(t, err)
idx, err := r.DownloadIndexFile()
require.NoError(t, err)
i, err := LoadIndexFile(idx)
require.NoError(t, err)
verifyLocalIndex(t, i)
writtenIndex, err := os.ReadFile(idx)
require.NoError(t, err)
assert.Equal(t, fileBytes, writtenIndex)
assert.NotContains(t, string(writtenIndex), "\x1f\x8b")
assert.NotEmpty(t, writtenIndex)
assert.Equal(t, filepath.Base(idx), helmpath.CacheIndexFile(r.Config.Name))
assert.Equal(t, filepath.Dir(idx), r.CachePath)
}
// startLocalServerForTests Start the local helm server
func startLocalServerForTests(handler http.Handler) (*httptest.Server, error) {
if handler == nil {

Loading…
Cancel
Save