@@ -8,7 +8,7 @@ package auth
88
99import (
1010 "context"
11- "log "
11+ "errors "
1212 "net/http"
1313 "sync"
1414
@@ -40,7 +40,12 @@ type HTTPTransport struct {
4040// It is called only once per transport. Once a TokenSource is obtained, it is used
4141// for the lifetime of the transport; subsequent 401s are not processed.
4242func NewHTTPTransport (handler OAuthHandler , opts * HTTPTransportOptions ) (* HTTPTransport , error ) {
43- t := & HTTPTransport {}
43+ if handler == nil {
44+ return nil , errors .New ("handler cannot be nil" )
45+ }
46+ t := & HTTPTransport {
47+ handler : handler ,
48+ }
4449 if opts != nil {
4550 t .opts = * opts
4651 }
@@ -60,7 +65,6 @@ type HTTPTransportOptions struct {
6065func (t * HTTPTransport ) RoundTrip (req * http.Request ) (* http.Response , error ) {
6166 t .mu .Lock ()
6267 base := t .opts .Base
63- _ , haveTokenSource := base .(* oauth2.Transport )
6468 t .mu .Unlock ()
6569
6670 resp , err := base .RoundTrip (req )
@@ -70,12 +74,15 @@ func (t *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
7074 if resp .StatusCode != http .StatusUnauthorized {
7175 return resp , nil
7276 }
73- if haveTokenSource {
77+ if _ , ok := base .( * oauth2. Transport ); ok {
7478 // We failed to authorize even with a token source; give up.
7579 return resp , nil
7680 }
81+
82+ resp .Body .Close ()
7783 // Try to authorize.
7884 t .mu .Lock ()
85+ defer t .mu .Unlock ()
7986 // If we don't have a token source, get one by following the OAuth flow.
8087 // (We may have obtained one while t.mu was not held above.)
8188 if _ , ok := t .opts .Base .(* oauth2.Transport ); ! ok {
@@ -84,20 +91,16 @@ func (t *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
8491 ResourceMetadataURL : extractResourceMetadataURL (authHeaders ),
8592 })
8693 if err != nil {
87- t .mu .Unlock ()
8894 return nil , err
8995 }
9096 t .opts .Base = & oauth2.Transport {Base : t .opts .Base , Source : ts }
9197 }
92- t .mu .Unlock ()
93- // Only one level of recursion, because we now have a token source.
94- return t .RoundTrip (req )
98+ return t .opts .Base .RoundTrip (req .Clone (req .Context ()))
9599}
96100
97101func extractResourceMetadataURL (authHeaders []string ) string {
98102 cs , err := oauthex .ParseWWWAuthenticate (authHeaders )
99103 if err != nil {
100- log .Printf ("parsing auth headers %q: %v" , authHeaders , err )
101104 return ""
102105 }
103106 return oauthex .ResourceMetadataURL (cs )
0 commit comments