transport.go raw

   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 [http.RoundTripper] and adding an Authorization header
  16  // with a token from the supplied [TokenSource].
  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 := req.Clone(req.Context())
  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 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