|
|
|
@ -17,6 +17,7 @@ package getter
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"bytes"
|
|
|
|
|
|
|
|
"compress/gzip"
|
|
|
|
"context"
|
|
|
|
"context"
|
|
|
|
"crypto/tls"
|
|
|
|
"crypto/tls"
|
|
|
|
"fmt"
|
|
|
|
"fmt"
|
|
|
|
@ -24,6 +25,7 @@ import (
|
|
|
|
"log/slog"
|
|
|
|
"log/slog"
|
|
|
|
"net/http"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"net/url"
|
|
|
|
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
|
|
|
|
"helm.sh/helm/v4/internal/tlsutil"
|
|
|
|
"helm.sh/helm/v4/internal/tlsutil"
|
|
|
|
@ -55,9 +57,14 @@ func (g *HTTPGetter) get(href string, opts getterOptions) (*bytes.Buffer, error)
|
|
|
|
return nil, err
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
isRepositoryIndexRequest := isRepositoryIndexRequestURL(href)
|
|
|
|
|
|
|
|
|
|
|
|
if opts.acceptHeader != "" {
|
|
|
|
if opts.acceptHeader != "" {
|
|
|
|
req.Header.Set("Accept", opts.acceptHeader)
|
|
|
|
req.Header.Set("Accept", opts.acceptHeader)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if isRepositoryIndexRequest {
|
|
|
|
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
req.Header.Set("User-Agent", version.GetUserAgent())
|
|
|
|
req.Header.Set("User-Agent", version.GetUserAgent())
|
|
|
|
if opts.userAgent != "" {
|
|
|
|
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)
|
|
|
|
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)
|
|
|
|
buf := bytes.NewBuffer(nil)
|
|
|
|
_, err = io.Copy(buf, resp.Body)
|
|
|
|
_, err = io.Copy(buf, reader)
|
|
|
|
return buf, err
|
|
|
|
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
|
|
|
|
// NewHTTPGetter constructs a valid http/https client as a Getter
|
|
|
|
func NewHTTPGetter(options ...Option) (Getter, error) {
|
|
|
|
func NewHTTPGetter(options ...Option) (Getter, error) {
|
|
|
|
var client HTTPGetter
|
|
|
|
var client HTTPGetter
|
|
|
|
|