@@ -185,7 +185,7 @@ func cloneURLValues(v url.Values) url.Values {
185
185
return v2
186
186
}
187
187
188
- func RetrieveToken (ctx context.Context , clientID , clientSecret , tokenURL string , v url.Values , authStyle AuthStyle ) (* Token , error ) {
188
+ func PostRawRequest (ctx context.Context , clientID , clientSecret , tokenURL string , v url.Values , authStyle AuthStyle ) (* http. Response , error ) {
189
189
needsAuthStyleProbe := authStyle == 0
190
190
if needsAuthStyleProbe {
191
191
if style , ok := lookupAuthStyle (tokenURL ); ok {
@@ -199,8 +199,11 @@ func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string,
199
199
if err != nil {
200
200
return nil , err
201
201
}
202
- token , err := doTokenRoundTrip (ctx , req )
203
- if err != nil && needsAuthStyleProbe {
202
+ resp , err := ctxhttp .Do (ctx , ContextClient (ctx ), req )
203
+ if err != nil {
204
+ return nil , err // transport errors are not related to auth style
205
+ }
206
+ if resp .StatusCode >= 400 && resp .StatusCode <= 499 && needsAuthStyleProbe {
204
207
// If we get an error, assume the server wants the
205
208
// clientID & clientSecret in a different form.
206
209
// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
@@ -215,24 +218,27 @@ func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string,
215
218
// So just try both ways.
216
219
authStyle = AuthStyleInParams // the second way we'll try
217
220
req , _ = newTokenRequest (tokenURL , clientID , clientSecret , v , authStyle )
218
- token , err = doTokenRoundTrip (ctx , req )
221
+ resp , err = ctxhttp . Do (ctx , ContextClient ( ctx ) , req )
219
222
}
220
- if needsAuthStyleProbe && err == nil {
223
+ if needsAuthStyleProbe && err == nil && ( resp . StatusCode < 400 || resp . StatusCode > 499 ) {
221
224
setAuthStyle (tokenURL , authStyle )
222
225
}
223
- // Don't overwrite `RefreshToken` with an empty value
224
- // if this was a token refreshing request.
226
+ return resp , err
227
+ }
228
+
229
+ func RetrieveToken (ctx context.Context , clientID , clientSecret , tokenURL string , v url.Values , authStyle AuthStyle ) (* Token , error ) {
230
+ resp , err := PostRawRequest (ctx , clientID , clientSecret , tokenURL , v , authStyle )
231
+ if err != nil {
232
+ return nil , err
233
+ }
234
+ token , err := parseTokenResponse (resp )
225
235
if token != nil && token .RefreshToken == "" {
226
236
token .RefreshToken = v .Get ("refresh_token" )
227
237
}
228
238
return token , err
229
239
}
230
240
231
- func doTokenRoundTrip (ctx context.Context , req * http.Request ) (* Token , error ) {
232
- r , err := ctxhttp .Do (ctx , ContextClient (ctx ), req )
233
- if err != nil {
234
- return nil , err
235
- }
241
+ func parseTokenResponse (r * http.Response ) (* Token , error ) {
236
242
body , err := ioutil .ReadAll (io .LimitReader (r .Body , 1 << 20 ))
237
243
r .Body .Close ()
238
244
if err != nil {
0 commit comments