mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 17:07:16 +00:00
Signed-off-by: Max Verbeek <m4xv3rb33k@gmail.com>
This commit is contained in:
parent
0191c1684d
commit
1042e12c6a
4 changed files with 108 additions and 0 deletions
|
|
@ -373,6 +373,7 @@ func (c *nativeHelmChart) loadRepoIndex(ctx context.Context, maxIndexSize int64)
|
|||
Proxy: proxy.GetCallback(c.proxy, c.noProxy),
|
||||
TLSClientConfig: tlsConf,
|
||||
DisableKeepAlives: true,
|
||||
ForceAttemptHTTP2: true,
|
||||
}
|
||||
client := http.Client{Transport: tr}
|
||||
resp, err := client.Do(req)
|
||||
|
|
@ -492,6 +493,7 @@ func (c *nativeHelmChart) GetTags(chart string, noCache bool) ([]string, error)
|
|||
Proxy: proxy.GetCallback(c.proxy, c.noProxy),
|
||||
TLSClientConfig: tlsConf,
|
||||
DisableKeepAlives: true,
|
||||
ForceAttemptHTTP2: true,
|
||||
}
|
||||
|
||||
// Wrap transport to add User-Agent header to all requests
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package helm
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
|
|
@ -10,6 +11,7 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
|
@ -574,6 +576,68 @@ func TestGetTagsCaching(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestGetTagsUsesHTTP2(t *testing.T) {
|
||||
t.Run("should negotiate HTTP/2 when TLS is configured", func(t *testing.T) {
|
||||
var requestProtos []string
|
||||
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
requestProtos = append(requestProtos, r.Proto)
|
||||
t.Logf("called %s with proto %s", r.URL.Path, r.Proto)
|
||||
|
||||
responseTags := fakeTagsList{
|
||||
Tags: []string{"1.0.0"},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
require.NoError(t, json.NewEncoder(w).Encode(responseTags))
|
||||
}))
|
||||
// httptest.NewTLSServer only advertises http/1.1 in ALPN, so we must
|
||||
// configure the server to also offer h2 for HTTP/2 negotiation to work.
|
||||
server.TLS = &tls.Config{NextProtos: []string{"h2", "http/1.1"}}
|
||||
server.StartTLS()
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
client := NewClient(server.URL, HelmCreds{InsecureSkipVerify: true}, true, "", "")
|
||||
|
||||
tags, err := client.GetTags("mychart", true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{"1.0.0"}, tags)
|
||||
|
||||
// Verify that at least one request used HTTP/2. When ForceAttemptHTTP2 is
|
||||
// not set on the Transport, Go's TLS stack won't negotiate h2 even though
|
||||
// the server supports it, because a custom TLSClientConfig disables the
|
||||
// automatic HTTP/2 setup.
|
||||
require.NotEmpty(t, requestProtos, "expected at least one request to the server")
|
||||
hasHTTP2 := slices.Contains(requestProtos, "HTTP/2.0")
|
||||
assert.True(t, hasHTTP2, "expected at least one HTTP/2 request, but got protocols: %v", requestProtos)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLoadRepoIndexUsesHTTP2(t *testing.T) {
|
||||
t.Run("should negotiate HTTP/2 when fetching index", func(t *testing.T) {
|
||||
var requestProto string
|
||||
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
requestProto = r.Proto
|
||||
t.Logf("called %s with proto %s", r.URL.Path, r.Proto)
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte(`apiVersion: v1
|
||||
entries: {}
|
||||
`))
|
||||
}))
|
||||
server.TLS = &tls.Config{NextProtos: []string{"h2", "http/1.1"}}
|
||||
server.StartTLS()
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
client := NewClient(server.URL, HelmCreds{InsecureSkipVerify: true}, false, "", "")
|
||||
|
||||
_, err := client.GetIndex(false, 10000)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "HTTP/2.0", requestProto, "expected HTTP/2 request for index fetch, but got %s", requestProto)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserAgentIsSet(t *testing.T) {
|
||||
t.Run("Default User-Agent for traditional Helm repo", func(t *testing.T) {
|
||||
// Create a test server that captures the User-Agent header
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ func NewClientWithLock(repoURL string, creds Creds, repoLock sync.KeyLock, proxy
|
|||
Proxy: proxy.GetCallback(proxyURL, noProxy),
|
||||
TLSClientConfig: tlsConf,
|
||||
DisableKeepAlives: true,
|
||||
ForceAttemptHTTP2: true,
|
||||
},
|
||||
/*
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
|
|
|
|||
|
|
@ -5,16 +5,22 @@ import (
|
|||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/specs-go"
|
||||
imagev1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"oras.land/oras-go/v2"
|
||||
"oras.land/oras-go/v2/content"
|
||||
|
|
@ -761,6 +767,38 @@ func Test_nativeOCIClient_ResolveRevision(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewClientUsesHTTP2(t *testing.T) {
|
||||
t.Run("should negotiate HTTP/2 when TLS is configured", func(t *testing.T) {
|
||||
var requestProtos []string
|
||||
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
requestProtos = append(requestProtos, r.Proto)
|
||||
t.Logf("called %s with proto %s", r.URL.Path, r.Proto)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
// httptest.NewTLSServer only advertises http/1.1 in ALPN, so we must
|
||||
// configure the server to also offer h2 for HTTP/2 negotiation to work.
|
||||
server.TLS = &tls.Config{NextProtos: []string{"h2", "http/1.1"}}
|
||||
server.StartTLS()
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
serverURL, err := url.Parse(server.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
// NewClient expects oci://host/path format.
|
||||
repoURL := "oci://" + serverURL.Host + "/myorg/myrepo"
|
||||
client, err := NewClient(repoURL, Creds{InsecureSkipVerify: true}, "", "", nil,
|
||||
WithEventHandlers(fakeEventHandlers(t, serverURL.Host+"/myorg/myrepo")))
|
||||
require.NoError(t, err)
|
||||
|
||||
// TestRepo pings the registry's /v2/ endpoint, exercising the transport.
|
||||
_, _ = client.TestRepo(t.Context())
|
||||
|
||||
require.NotEmpty(t, requestProtos, "expected at least one request to the server")
|
||||
hasHTTP2 := slices.Contains(requestProtos, "HTTP/2.0")
|
||||
assert.True(t, hasHTTP2, "expected at least one HTTP/2 request, but got protocols: %v", requestProtos)
|
||||
})
|
||||
}
|
||||
|
||||
func fakeEventHandlers(t *testing.T, repoURL string) EventHandlers {
|
||||
t.Helper()
|
||||
return EventHandlers{
|
||||
|
|
@ -772,6 +810,9 @@ func fakeEventHandlers(t *testing.T, repoURL string) EventHandlers {
|
|||
OnGetTagsFail: func(repo string) func() {
|
||||
return func() { require.Equal(t, repoURL, repo) }
|
||||
},
|
||||
OnTestRepoFail: func(repo string) func() {
|
||||
return func() { require.Equal(t, repoURL, repo) }
|
||||
},
|
||||
OnExtractFail: func(repo string) func(revision string) {
|
||||
return func(_ string) { require.Equal(t, repoURL, repo) }
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue