transport.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. package oauth2
  5. import (
  6. "errors"
  7. "log"
  8. "net/http"
  9. "sync"
  10. )
  11. // Transport is an [http.RoundTripper] that makes OAuth 2.0 HTTP requests,
  12. // wrapping a base [http.RoundTripper] and adding an Authorization header
  13. // with a token from the supplied [TokenSource].
  14. //
  15. // Transport is a low-level mechanism. Most code will use the
  16. // higher-level [Config.Client] method instead.
  17. type Transport struct {
  18. // Source supplies the token to add to outgoing requests'
  19. // Authorization headers.
  20. Source TokenSource
  21. // Base is the base RoundTripper used to make HTTP requests.
  22. // If nil, http.DefaultTransport is used.
  23. Base http.RoundTripper
  24. }
  25. // RoundTrip authorizes and authenticates the request with an
  26. // access token from Transport's Source.
  27. func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
  28. reqBodyClosed := false
  29. if req.Body != nil {
  30. defer func() {
  31. if !reqBodyClosed {
  32. req.Body.Close()
  33. }
  34. }()
  35. }
  36. if t.Source == nil {
  37. return nil, errors.New("oauth2: Transport's Source is nil")
  38. }
  39. token, err := t.Source.Token()
  40. if err != nil {
  41. return nil, err
  42. }
  43. req2 := req.Clone(req.Context())
  44. token.SetAuthHeader(req2)
  45. // req.Body is assumed to be closed by the base RoundTripper.
  46. reqBodyClosed = true
  47. return t.base().RoundTrip(req2)
  48. }
  49. var cancelOnce sync.Once
  50. // CancelRequest does nothing. It used to be a legacy cancellation mechanism
  51. // but now only it only logs on first use to warn that it's deprecated.
  52. //
  53. // Deprecated: use contexts for cancellation instead.
  54. func (t *Transport) CancelRequest(req *http.Request) {
  55. cancelOnce.Do(func() {
  56. log.Printf("deprecated: golang.org/x/oauth2: Transport.CancelRequest no longer does anything; use contexts")
  57. })
  58. }
  59. func (t *Transport) base() http.RoundTripper {
  60. if t.Base != nil {
  61. return t.Base
  62. }
  63. return http.DefaultTransport
  64. }