diff --git a/github/github.go b/github/github.go index 8bc35e5efe2..a7326a7bd5d 100644 --- a/github/github.go +++ b/github/github.go @@ -450,15 +450,18 @@ func (c *Client) copy() *Client { c.clientMu.Lock() // can't use *c here because that would copy mutexes by value. clone := Client{ - client: c.client, + client: &http.Client{}, UserAgent: c.UserAgent, BaseURL: c.BaseURL, UploadURL: c.UploadURL, secondaryRateLimitReset: c.secondaryRateLimitReset, } c.clientMu.Unlock() - if clone.client == nil { - clone.client = &http.Client{} + if c.client != nil { + clone.client.Transport = c.client.Transport + clone.client.CheckRedirect = c.client.CheckRedirect + clone.client.Jar = c.client.Jar + clone.client.Timeout = c.client.Timeout } c.rateMu.Lock() copy(clone.rateLimits[:], c.rateLimits[:]) diff --git a/github/github_test.go b/github/github_test.go index 45ac57c0019..9a369a25fd4 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -2599,3 +2599,32 @@ func TestParseTokenExpiration(t *testing.T) { } } } + +func TestClientCopy_leak_transport(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + accessToken := r.Header.Get("Authorization") + _, _ = fmt.Fprintf(w, `{"login": "%s"}`, accessToken) + })) + clientPreconfiguredWithURLs, err := NewClient(nil).WithEnterpriseURLs(srv.URL, srv.URL) + if err != nil { + t.Fatal(err) + } + + aliceClient := clientPreconfiguredWithURLs.WithAuthToken("alice") + bobClient := clientPreconfiguredWithURLs.WithAuthToken("bob") + + alice, _, err := aliceClient.Users.Get(context.Background(), "") + if err != nil { + t.Fatal(err) + } + + assertNoDiff(t, "Bearer alice", alice.GetLogin()) + + bob, _, err := bobClient.Users.Get(context.Background(), "") + if err != nil { + t.Fatal(err) + } + + assertNoDiff(t, "Bearer bob", bob.GetLogin()) +}