Skip to content

Commit e487ccb

Browse files
committed
Guard DefaultTransport assertion in transportForAuth
Fall back to &http.Transport{} if DefaultTransport is not a *http.Transport, to avoid a panic when another component has replaced the global default.
1 parent 2e74fc9 commit e487ccb

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

internal/bundlereader/charturl.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,13 @@ func transportForAuth(insecureSkipVerify bool, caBundle []byte) http.RoundTrippe
290290
}
291291

292292
// Create new transport
293-
transport := http.DefaultTransport.(*http.Transport).Clone()
293+
baseTransport, ok := http.DefaultTransport.(*http.Transport)
294+
if !ok {
295+
// Another component has replaced the global default transport.
296+
// Use a plain transport rather than panicking on the failed assertion.
297+
baseTransport = &http.Transport{}
298+
}
299+
transport := baseTransport.Clone()
294300
transport.TLSClientConfig = &tls.Config{
295301
InsecureSkipVerify: insecureSkipVerify, //nolint:gosec
296302
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package bundlereader
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
// fakeRoundTripper is a RoundTripper that is not *http.Transport, so substituting
12+
// it for http.DefaultTransport triggers the type-assertion path in transportForAuth.
13+
type fakeRoundTripper struct{}
14+
15+
func (fakeRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, nil }
16+
17+
// TestTransportForAuthNonDefaultTransport verifies that transportForAuth does not
18+
// panic when http.DefaultTransport has been replaced by a value that is not
19+
// *http.Transport, and that it still returns a usable RoundTripper.
20+
//
21+
// Not parallel: the test mutates the process-global http.DefaultTransport.
22+
func TestTransportForAuthNonDefaultTransport(t *testing.T) {
23+
orig := http.DefaultTransport
24+
t.Cleanup(func() { http.DefaultTransport = orig })
25+
26+
http.DefaultTransport = fakeRoundTripper{}
27+
28+
// The transport cache is package-level; clear it so a fresh entry is built.
29+
transportsCacheMutex.Lock()
30+
transportsCache = map[string]http.RoundTripper{}
31+
transportsCacheMutex.Unlock()
32+
33+
require.NotPanics(t, func() {
34+
rt := transportForAuth(false, nil)
35+
assert.NotNil(t, rt)
36+
}, "transportForAuth must not panic when http.DefaultTransport is not *http.Transport")
37+
38+
// Also verify the custom-CA path does not panic.
39+
transportsCacheMutex.Lock()
40+
transportsCache = map[string]http.RoundTripper{}
41+
transportsCacheMutex.Unlock()
42+
43+
require.NotPanics(t, func() {
44+
rt := transportForAuth(false, []byte("not-a-real-cert"))
45+
assert.NotNil(t, rt)
46+
}, "transportForAuth must not panic with a CA bundle when DefaultTransport is not *http.Transport")
47+
}

0 commit comments

Comments
 (0)