diff options
| author | Paul Zabelin | 2016-04-17 03:22:31 -0700 | 
|---|---|---|
| committer | Paul Zabelin | 2016-04-17 03:22:31 -0700 | 
| commit | b5eb2866cfceb69b0d4dd4948273d679a884fbb2 (patch) | |
| tree | 1fdb61a7138642a1612bb201434e8ebda141cc8a /vendor/golang.org/x/oauth2/transport.go | |
| parent | 8de8e05c483c6b5f23b14742315f1860211dcef7 (diff) | |
| download | gdrive-b5eb2866cfceb69b0d4dd4948273d679a884fbb2.tar.bz2 | |
add Go dependencies by godep
see https://github.com/tools/godep
Diffstat (limited to 'vendor/golang.org/x/oauth2/transport.go')
| -rw-r--r-- | vendor/golang.org/x/oauth2/transport.go | 132 | 
1 files changed, 132 insertions, 0 deletions
| diff --git a/vendor/golang.org/x/oauth2/transport.go b/vendor/golang.org/x/oauth2/transport.go new file mode 100644 index 0000000..92ac7e2 --- /dev/null +++ b/vendor/golang.org/x/oauth2/transport.go @@ -0,0 +1,132 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package oauth2 + +import ( +	"errors" +	"io" +	"net/http" +	"sync" +) + +// Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests, +// wrapping a base RoundTripper and adding an Authorization header +// with a token from the supplied Sources. +// +// Transport is a low-level mechanism. Most code will use the +// higher-level Config.Client method instead. +type Transport struct { +	// Source supplies the token to add to outgoing requests' +	// Authorization headers. +	Source TokenSource + +	// Base is the base RoundTripper used to make HTTP requests. +	// If nil, http.DefaultTransport is used. +	Base http.RoundTripper + +	mu     sync.Mutex                      // guards modReq +	modReq map[*http.Request]*http.Request // original -> modified +} + +// RoundTrip authorizes and authenticates the request with an +// access token. If no token exists or token is expired, +// tries to refresh/fetch a new token. +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { +	if t.Source == nil { +		return nil, errors.New("oauth2: Transport's Source is nil") +	} +	token, err := t.Source.Token() +	if err != nil { +		return nil, err +	} + +	req2 := cloneRequest(req) // per RoundTripper contract +	token.SetAuthHeader(req2) +	t.setModReq(req, req2) +	res, err := 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. +func (t *Transport) CancelRequest(req *http.Request) { +	type canceler interface { +		CancelRequest(*http.Request) +	} +	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 { +	if t.Base != nil { +		return t.Base +	} +	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. +// The clone is a shallow copy of the struct and its Header map. +func cloneRequest(r *http.Request) *http.Request { +	// shallow copy of the struct +	r2 := new(http.Request) +	*r2 = *r +	// deep copy of the Header +	r2.Header = make(http.Header, len(r.Header)) +	for k, s := range r.Header { +		r2.Header[k] = append([]string(nil), s...) +	} +	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 +	} +} | 
