diff --git a/pkg/action/install.go b/pkg/action/install.go index ae50327fe..d9da2f14f 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -761,6 +761,10 @@ func portOrDefault(u *url.URL) string { } } +func urlEqual(u1, u2 *url.URL) bool { + return u1.Scheme == u2.Scheme && u1.Hostname() == u2.Hostname() && portOrDefault(u1) == portOrDefault(u2) +} + // LocateChart looks for a chart directory in known places, and returns either the full path or an error. // // This does not ensure that the chart is well-formed; only that the requested filename exists. @@ -848,7 +852,7 @@ func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) ( // Host on URL (returned from url.Parse) contains the port if present. // This check ensures credentials are not passed between different // services on different ports. - if c.PassCredentialsAll || (u1.Scheme == u2.Scheme && u1.Hostname() == u2.Hostname() && portOrDefault(u1) == portOrDefault(u2)) { + if c.PassCredentialsAll || urlEqual(u1, u2) { dl.Options = append(dl.Options, getter.WithBasicAuth(c.Username, c.Password)) } else { dl.Options = append(dl.Options, getter.WithBasicAuth("", "")) diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index 6c2c91d0a..1882f19e7 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -24,6 +24,7 @@ import ( "io" "io/fs" "net/http" + "net/url" "os" "path/filepath" "regexp" @@ -933,3 +934,68 @@ func TestInstallWithSystemLabels(t *testing.T) { is.Equal(fmt.Errorf("user supplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels()), err) } + +func TestUrlEqual(t *testing.T) { + is := assert.New(t) + + tests := []struct { + name string + url1 string + url2 string + expected bool + }{ + { + name: "identical URLs", + url1: "https://example.com:443", + url2: "https://example.com:443", + expected: true, + }, + { + name: "same host, scheme, default HTTPS port vs explicit", + url1: "https://example.com", + url2: "https://example.com:443", + expected: true, + }, + { + name: "same host, scheme, default HTTP port vs explicit", + url1: "http://example.com", + url2: "http://example.com:80", + expected: true, + }, + { + name: "different schemes", + url1: "http://example.com", + url2: "https://example.com", + expected: false, + }, + { + name: "different hosts", + url1: "https://example.com", + url2: "https://www.example.com", + expected: false, + }, + { + name: "different ports", + url1: "https://example.com:8080", + url2: "https://example.com:9090", + expected: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + u1, err := url.Parse(tc.url1) + if err != nil { + t.Fatalf("Failed to parse URL1 %s: %v", tc.url1, err) + } + u2, err := url.Parse(tc.url2) + if err != nil { + t.Fatalf("Failed to parse URL2 %s: %v", tc.url2, err) + } + + is.Equal(tc.expected, urlEqual(u1, u2)) + }) + } +}