oauth2: turn Transport.CancelRequest into a no-op

Request cancellation should be done via http.Request.Context.

Fixes #271

Change-Id: Ia6251898e55bd15b27968504fc6efe14f05b1def
Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/121438
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Tim Cooper 2018-06-28 19:10:32 -03:00 committed by Brad Fitzpatrick
parent 5d9234df09
commit 858c2ad4c8
1 changed files with 12 additions and 67 deletions

View File

@ -6,7 +6,7 @@ package oauth2
import ( import (
"errors" "errors"
"io" "log"
"net/http" "net/http"
"sync" "sync"
) )
@ -25,9 +25,6 @@ type Transport struct {
// Base is the base RoundTripper used to make HTTP requests. // Base is the base RoundTripper used to make HTTP requests.
// If nil, http.DefaultTransport is used. // If nil, http.DefaultTransport is used.
Base http.RoundTripper Base http.RoundTripper
mu sync.Mutex // guards modReq
modReq map[*http.Request]*http.Request // original -> modified
} }
// RoundTrip authorizes and authenticates the request with an // RoundTrip authorizes and authenticates the request with an
@ -52,35 +49,22 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
req2 := cloneRequest(req) // per RoundTripper contract req2 := cloneRequest(req) // per RoundTripper contract
token.SetAuthHeader(req2) token.SetAuthHeader(req2)
t.setModReq(req, req2)
res, err := t.base().RoundTrip(req2)
// req.Body is assumed to have been closed by the base RoundTripper. // req.Body is assumed to be closed by the base RoundTripper.
reqBodyClosed = true reqBodyClosed = true
return t.base().RoundTrip(req2)
if err != nil {
t.setModReq(req, nil)
return nil, err
}
res.Body = &onEOFReader{
rc: res.Body,
fn: func() { t.setModReq(req, nil) },
}
return res, nil
} }
// CancelRequest cancels an in-flight request by closing its connection. var cancelOnce sync.Once
// CancelRequest does nothing. It used to be a legacy cancellation mechanism
// but now only it only logs on first use to warn that it's deprecated.
//
// Deprecated: use contexts for cancellation instead.
func (t *Transport) CancelRequest(req *http.Request) { func (t *Transport) CancelRequest(req *http.Request) {
type canceler interface { cancelOnce.Do(func() {
CancelRequest(*http.Request) log.Printf("deprecated: golang.org/x/oauth2: Transport.CancelRequest no longer does anything; use contexts")
} })
if cr, ok := t.base().(canceler); ok {
t.mu.Lock()
modReq := t.modReq[req]
delete(t.modReq, req)
t.mu.Unlock()
cr.CancelRequest(modReq)
}
} }
func (t *Transport) base() http.RoundTripper { func (t *Transport) base() http.RoundTripper {
@ -90,19 +74,6 @@ func (t *Transport) base() http.RoundTripper {
return http.DefaultTransport return http.DefaultTransport
} }
func (t *Transport) setModReq(orig, mod *http.Request) {
t.mu.Lock()
defer t.mu.Unlock()
if t.modReq == nil {
t.modReq = make(map[*http.Request]*http.Request)
}
if mod == nil {
delete(t.modReq, orig)
} else {
t.modReq[orig] = mod
}
}
// cloneRequest returns a clone of the provided *http.Request. // cloneRequest returns a clone of the provided *http.Request.
// The clone is a shallow copy of the struct and its Header map. // The clone is a shallow copy of the struct and its Header map.
func cloneRequest(r *http.Request) *http.Request { func cloneRequest(r *http.Request) *http.Request {
@ -116,29 +87,3 @@ func cloneRequest(r *http.Request) *http.Request {
} }
return r2 return r2
} }
type onEOFReader struct {
rc io.ReadCloser
fn func()
}
func (r *onEOFReader) Read(p []byte) (n int, err error) {
n, err = r.rc.Read(p)
if err == io.EOF {
r.runFunc()
}
return
}
func (r *onEOFReader) Close() error {
err := r.rc.Close()
r.runFunc()
return err
}
func (r *onEOFReader) runFunc() {
if fn := r.fn; fn != nil {
fn()
r.fn = nil
}
}