23 Source TokenSource |
23 Source TokenSource |
24 |
24 |
25 // Base is the base RoundTripper used to make HTTP requests. |
25 // Base is the base RoundTripper used to make HTTP requests. |
26 // If nil, http.DefaultTransport is used. |
26 // If nil, http.DefaultTransport is used. |
27 Base http.RoundTripper |
27 Base http.RoundTripper |
28 |
|
29 mu sync.Mutex // guards modReq |
|
30 modReq map[*http.Request]*http.Request // original -> modified |
|
31 } |
28 } |
32 |
29 |
33 // RoundTrip authorizes and authenticates the request with an |
30 // RoundTrip authorizes and authenticates the request with an |
34 // access token from Transport's Source. |
31 // access token from Transport's Source. |
35 func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { |
32 func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { |
50 return nil, err |
47 return nil, err |
51 } |
48 } |
52 |
49 |
53 req2 := cloneRequest(req) // per RoundTripper contract |
50 req2 := cloneRequest(req) // per RoundTripper contract |
54 token.SetAuthHeader(req2) |
51 token.SetAuthHeader(req2) |
55 t.setModReq(req, req2) |
|
56 res, err := t.base().RoundTrip(req2) |
|
57 |
52 |
58 // req.Body is assumed to have been closed by the base RoundTripper. |
53 // req.Body is assumed to be closed by the base RoundTripper. |
59 reqBodyClosed = true |
54 reqBodyClosed = true |
60 |
55 return t.base().RoundTrip(req2) |
61 if err != nil { |
|
62 t.setModReq(req, nil) |
|
63 return nil, err |
|
64 } |
|
65 res.Body = &onEOFReader{ |
|
66 rc: res.Body, |
|
67 fn: func() { t.setModReq(req, nil) }, |
|
68 } |
|
69 return res, nil |
|
70 } |
56 } |
71 |
57 |
72 // CancelRequest cancels an in-flight request by closing its connection. |
58 var cancelOnce sync.Once |
|
59 |
|
60 // CancelRequest does nothing. It used to be a legacy cancellation mechanism |
|
61 // but now only it only logs on first use to warn that it's deprecated. |
|
62 // |
|
63 // Deprecated: use contexts for cancellation instead. |
73 func (t *Transport) CancelRequest(req *http.Request) { |
64 func (t *Transport) CancelRequest(req *http.Request) { |
74 type canceler interface { |
65 cancelOnce.Do(func() { |
75 CancelRequest(*http.Request) |
66 log.Printf("deprecated: golang.org/x/oauth2: Transport.CancelRequest no longer does anything; use contexts") |
76 } |
67 }) |
77 if cr, ok := t.base().(canceler); ok { |
|
78 t.mu.Lock() |
|
79 modReq := t.modReq[req] |
|
80 delete(t.modReq, req) |
|
81 t.mu.Unlock() |
|
82 cr.CancelRequest(modReq) |
|
83 } |
|
84 } |
68 } |
85 |
69 |
86 func (t *Transport) base() http.RoundTripper { |
70 func (t *Transport) base() http.RoundTripper { |
87 if t.Base != nil { |
71 if t.Base != nil { |
88 return t.Base |
72 return t.Base |
89 } |
73 } |
90 return http.DefaultTransport |
74 return http.DefaultTransport |
91 } |
|
92 |
|
93 func (t *Transport) setModReq(orig, mod *http.Request) { |
|
94 t.mu.Lock() |
|
95 defer t.mu.Unlock() |
|
96 if t.modReq == nil { |
|
97 t.modReq = make(map[*http.Request]*http.Request) |
|
98 } |
|
99 if mod == nil { |
|
100 delete(t.modReq, orig) |
|
101 } else { |
|
102 t.modReq[orig] = mod |
|
103 } |
|
104 } |
75 } |
105 |
76 |
106 // cloneRequest returns a clone of the provided *http.Request. |
77 // cloneRequest returns a clone of the provided *http.Request. |
107 // The clone is a shallow copy of the struct and its Header map. |
78 // The clone is a shallow copy of the struct and its Header map. |
108 func cloneRequest(r *http.Request) *http.Request { |
79 func cloneRequest(r *http.Request) *http.Request { |
114 for k, s := range r.Header { |
85 for k, s := range r.Header { |
115 r2.Header[k] = append([]string(nil), s...) |
86 r2.Header[k] = append([]string(nil), s...) |
116 } |
87 } |
117 return r2 |
88 return r2 |
118 } |
89 } |
119 |
|
120 type onEOFReader struct { |
|
121 rc io.ReadCloser |
|
122 fn func() |
|
123 } |
|
124 |
|
125 func (r *onEOFReader) Read(p []byte) (n int, err error) { |
|
126 n, err = r.rc.Read(p) |
|
127 if err == io.EOF { |
|
128 r.runFunc() |
|
129 } |
|
130 return |
|
131 } |
|
132 |
|
133 func (r *onEOFReader) Close() error { |
|
134 err := r.rc.Close() |
|
135 r.runFunc() |
|
136 return err |
|
137 } |
|
138 |
|
139 func (r *onEOFReader) runFunc() { |
|
140 if fn := r.fn; fn != nil { |
|
141 fn() |
|
142 r.fn = nil |
|
143 } |
|
144 } |
|