"Fossies" - the Fresh Open Source Software Archive

Member "gdrive-2.1.1/vendor/golang.org/x/oauth2/transport.go" (28 May 2021, 3087 Bytes) of package /linux/misc/gdrive-2.1.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    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     "io"
   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     mu     sync.Mutex                      // guards modReq
   30     modReq map[*http.Request]*http.Request // original -> modified
   31 }
   32 
   33 // RoundTrip authorizes and authenticates the request with an
   34 // access token. If no token exists or token is expired,
   35 // tries to refresh/fetch a new token.
   36 func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
   37     if t.Source == nil {
   38         return nil, errors.New("oauth2: Transport's Source is nil")
   39     }
   40     token, err := t.Source.Token()
   41     if err != nil {
   42         return nil, err
   43     }
   44 
   45     req2 := cloneRequest(req) // per RoundTripper contract
   46     token.SetAuthHeader(req2)
   47     t.setModReq(req, req2)
   48     res, err := t.base().RoundTrip(req2)
   49     if err != nil {
   50         t.setModReq(req, nil)
   51         return nil, err
   52     }
   53     res.Body = &onEOFReader{
   54         rc: res.Body,
   55         fn: func() { t.setModReq(req, nil) },
   56     }
   57     return res, nil
   58 }
   59 
   60 // CancelRequest cancels an in-flight request by closing its connection.
   61 func (t *Transport) CancelRequest(req *http.Request) {
   62     type canceler interface {
   63         CancelRequest(*http.Request)
   64     }
   65     if cr, ok := t.base().(canceler); ok {
   66         t.mu.Lock()
   67         modReq := t.modReq[req]
   68         delete(t.modReq, req)
   69         t.mu.Unlock()
   70         cr.CancelRequest(modReq)
   71     }
   72 }
   73 
   74 func (t *Transport) base() http.RoundTripper {
   75     if t.Base != nil {
   76         return t.Base
   77     }
   78     return http.DefaultTransport
   79 }
   80 
   81 func (t *Transport) setModReq(orig, mod *http.Request) {
   82     t.mu.Lock()
   83     defer t.mu.Unlock()
   84     if t.modReq == nil {
   85         t.modReq = make(map[*http.Request]*http.Request)
   86     }
   87     if mod == nil {
   88         delete(t.modReq, orig)
   89     } else {
   90         t.modReq[orig] = mod
   91     }
   92 }
   93 
   94 // cloneRequest returns a clone of the provided *http.Request.
   95 // The clone is a shallow copy of the struct and its Header map.
   96 func cloneRequest(r *http.Request) *http.Request {
   97     // shallow copy of the struct
   98     r2 := new(http.Request)
   99     *r2 = *r
  100     // deep copy of the Header
  101     r2.Header = make(http.Header, len(r.Header))
  102     for k, s := range r.Header {
  103         r2.Header[k] = append([]string(nil), s...)
  104     }
  105     return r2
  106 }
  107 
  108 type onEOFReader struct {
  109     rc io.ReadCloser
  110     fn func()
  111 }
  112 
  113 func (r *onEOFReader) Read(p []byte) (n int, err error) {
  114     n, err = r.rc.Read(p)
  115     if err == io.EOF {
  116         r.runFunc()
  117     }
  118     return
  119 }
  120 
  121 func (r *onEOFReader) Close() error {
  122     err := r.rc.Close()
  123     r.runFunc()
  124     return err
  125 }
  126 
  127 func (r *onEOFReader) runFunc() {
  128     if fn := r.fn; fn != nil {
  129         fn()
  130         r.fn = nil
  131     }
  132 }