mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-02 16:52:25 -06:00 
			
		
		
		
	
		
			
	
	
		
			90 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			90 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								// 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"
							 | 
						||
| 
								 | 
							
									"log"
							 | 
						||
| 
								 | 
							
									"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
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// RoundTrip authorizes and authenticates the request with an
							 | 
						||
| 
								 | 
							
								// access token from Transport's Source.
							 | 
						||
| 
								 | 
							
								func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
							 | 
						||
| 
								 | 
							
									reqBodyClosed := false
							 | 
						||
| 
								 | 
							
									if req.Body != nil {
							 | 
						||
| 
								 | 
							
										defer func() {
							 | 
						||
| 
								 | 
							
											if !reqBodyClosed {
							 | 
						||
| 
								 | 
							
												req.Body.Close()
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}()
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// req.Body is assumed to be closed by the base RoundTripper.
							 | 
						||
| 
								 | 
							
									reqBodyClosed = true
							 | 
						||
| 
								 | 
							
									return t.base().RoundTrip(req2)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var cancelOnce sync.Once
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// CancelRequest does nothing. It used to be a legacy cancellation mechanism
							 | 
						||
| 
								 | 
							
								// but now only it only logs on first use to warn that it's deprecated.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Deprecated: use contexts for cancellation instead.
							 | 
						||
| 
								 | 
							
								func (t *Transport) CancelRequest(req *http.Request) {
							 | 
						||
| 
								 | 
							
									cancelOnce.Do(func() {
							 | 
						||
| 
								 | 
							
										log.Printf("deprecated: golang.org/x/oauth2: Transport.CancelRequest no longer does anything; use contexts")
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (t *Transport) base() http.RoundTripper {
							 | 
						||
| 
								 | 
							
									if t.Base != nil {
							 | 
						||
| 
								 | 
							
										return t.Base
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return http.DefaultTransport
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 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
							 | 
						||
| 
								 | 
							
								}
							 |