gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

transport.go (2403B)


      1 // Copyright 2014 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package oauth2
      6 
      7 import (
      8 	"errors"
      9 	"log"
     10 	"net/http"
     11 	"sync"
     12 )
     13 
     14 // Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests,
     15 // wrapping a base RoundTripper and adding an Authorization header
     16 // with a token from the supplied Sources.
     17 //
     18 // Transport is a low-level mechanism. Most code will use the
     19 // higher-level Config.Client method instead.
     20 type Transport struct {
     21 	// Source supplies the token to add to outgoing requests'
     22 	// Authorization headers.
     23 	Source TokenSource
     24 
     25 	// Base is the base RoundTripper used to make HTTP requests.
     26 	// If nil, http.DefaultTransport is used.
     27 	Base http.RoundTripper
     28 }
     29 
     30 // RoundTrip authorizes and authenticates the request with an
     31 // access token from Transport's Source.
     32 func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
     33 	reqBodyClosed := false
     34 	if req.Body != nil {
     35 		defer func() {
     36 			if !reqBodyClosed {
     37 				req.Body.Close()
     38 			}
     39 		}()
     40 	}
     41 
     42 	if t.Source == nil {
     43 		return nil, errors.New("oauth2: Transport's Source is nil")
     44 	}
     45 	token, err := t.Source.Token()
     46 	if err != nil {
     47 		return nil, err
     48 	}
     49 
     50 	req2 := cloneRequest(req) // per RoundTripper contract
     51 	token.SetAuthHeader(req2)
     52 
     53 	// req.Body is assumed to be closed by the base RoundTripper.
     54 	reqBodyClosed = true
     55 	return t.base().RoundTrip(req2)
     56 }
     57 
     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.
     64 func (t *Transport) CancelRequest(req *http.Request) {
     65 	cancelOnce.Do(func() {
     66 		log.Printf("deprecated: golang.org/x/oauth2: Transport.CancelRequest no longer does anything; use contexts")
     67 	})
     68 }
     69 
     70 func (t *Transport) base() http.RoundTripper {
     71 	if t.Base != nil {
     72 		return t.Base
     73 	}
     74 	return http.DefaultTransport
     75 }
     76 
     77 // cloneRequest returns a clone of the provided *http.Request.
     78 // The clone is a shallow copy of the struct and its Header map.
     79 func cloneRequest(r *http.Request) *http.Request {
     80 	// shallow copy of the struct
     81 	r2 := new(http.Request)
     82 	*r2 = *r
     83 	// deep copy of the Header
     84 	r2.Header = make(http.Header, len(r.Header))
     85 	for k, s := range r.Header {
     86 		r2.Header[k] = append([]string(nil), s...)
     87 	}
     88 	return r2
     89 }