Skip to content

Commit be53fe7

Browse files
committed
oauth2: Handle nil headers in Transport.RoundTrip
Fixes an issue where setting auth headers on requests with nil Headers would cause a panic. This change ensures that Transport.RoundTrip properly handles HTTP requests with nil headers by initializing the header map before setting the authorization header. Added a test case to verify this behavior as well. The bug was introduced in 696f7b3 Signed-off-by: Davanum Srinivas <[email protected]>
1 parent cf14319 commit be53fe7

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

transport.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
4848
}
4949

5050
req2 := req.Clone(req.Context())
51+
if req2.Header == nil {
52+
req2.Header = make(http.Header)
53+
}
5154
token.SetAuthHeader(req2)
5255

5356
// req.Body is assumed to be closed by the base RoundTripper.

transport_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io"
66
"net/http"
77
"net/http/httptest"
8+
"net/url"
89
"testing"
910
"time"
1011
)
@@ -154,3 +155,51 @@ func TestExpiredWithExpiry(t *testing.T) {
154155
func newMockServer(handler func(w http.ResponseWriter, r *http.Request)) *httptest.Server {
155156
return httptest.NewServer(http.HandlerFunc(handler))
156157
}
158+
159+
// TestTransportWithNilHeader tests that the Transport.RoundTrip method
160+
// correctly handles requests with nil Headers.
161+
func TestTransportWithNilHeader(t *testing.T) {
162+
// Create a mock token source that returns a fixed token
163+
tokenSource := StaticTokenSource(&Token{
164+
AccessToken: "test-access-token",
165+
TokenType: "Bearer",
166+
})
167+
168+
// Create a mock http server to verify the request
169+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
170+
// Check that the Authorization header was correctly set
171+
authHeader := r.Header.Get("Authorization")
172+
expectedHeader := "Bearer test-access-token"
173+
if authHeader != expectedHeader {
174+
t.Errorf("expected authorization header %q, got %q", expectedHeader, authHeader)
175+
}
176+
w.WriteHeader(http.StatusOK)
177+
}))
178+
defer server.Close()
179+
180+
// Create Transport with our token source
181+
transport := &Transport{
182+
Source: tokenSource,
183+
Base: http.DefaultTransport,
184+
}
185+
186+
// Create a request with nil Header
187+
reqURL, _ := url.Parse(server.URL)
188+
req := &http.Request{
189+
Method: "GET",
190+
URL: reqURL,
191+
// Header is intentionally nil
192+
}
193+
194+
// Make the request using our Transport
195+
resp, err := transport.RoundTrip(req)
196+
if err != nil {
197+
t.Fatalf("roundTrip failed with nil Header: %v", err)
198+
}
199+
defer resp.Body.Close()
200+
201+
// Verify response status
202+
if resp.StatusCode != http.StatusOK {
203+
t.Errorf("expected status code %d, got %d", http.StatusOK, resp.StatusCode)
204+
}
205+
}

0 commit comments

Comments
 (0)