Skip to content

Commit

Permalink
oauth2: document that provided context will be used in refresh requests.
Browse files Browse the repository at this point in the history
The context given to Client() will be stored and reused for token
refreshes througout the life of the Config. If the context expires e.g.
during application startup, refresh attempts will fail.

Updates golang#388
  • Loading branch information
jacobsevart committed Feb 3, 2021
1 parent 0101308 commit bdee15b
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
4 changes: 3 additions & 1 deletion clientcredentials/clientcredentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ func (c *Config) Token(ctx context.Context) (*oauth2.Token, error) {
// The token will auto-refresh as necessary.
//
// The provided context optionally controls which HTTP client
// is returned. See the oauth2.HTTPClient variable.
// is returned. See the oauth2.HTTPClient variable. It will be
// used for all refresh requests for the life of the Config, so
// do not pass a context with a deadline.
//
// The returned Client and its Transport should not be modified.
func (c *Config) Client(ctx context.Context) *http.Client {
Expand Down
2 changes: 1 addition & 1 deletion internal/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string,
func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
r, err := ctxhttp.Do(ctx, ContextClient(ctx), req)
if err != nil {
return nil, err
return nil, fmt.Errorf("oauth2: cannot fetch token: %w", err)
}
body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
r.Body.Close()
Expand Down
17 changes: 17 additions & 0 deletions oauth2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -452,6 +453,22 @@ func TestTokenRefreshRequest(t *testing.T) {
c.Get(ts.URL + "/somethingelse")
}

func TestTokenRefreshRequest_Expired(t *testing.T) {
internal.ResetAuthCache()
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Errorf("should not make http request")
}))
defer ts.Close()
conf := newConf(ts.URL)
ctx, cancel := context.WithCancel(context.Background())
cancel()
c := conf.Client(ctx, &Token{RefreshToken: "REFRESH_TOKEN"})
_, getErr := c.Get(ts.URL + "/somethingelse")
if !strings.Contains(getErr.Error(), "oauth2: cannot fetch token: context canceled") {
t.Errorf("Unexpected error refreshing with expired context: %s", getErr.Error())
}
}

func TestFetchWithNoRefreshToken(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.String() == "/somethingelse" {
Expand Down

0 comments on commit bdee15b

Please sign in to comment.