...

Source file src/github.com/hashicorp/go-retryablehttp/roundtripper.go

Documentation: github.com/hashicorp/go-retryablehttp

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package retryablehttp
     5  
     6  import (
     7  	"errors"
     8  	"net/http"
     9  	"net/url"
    10  	"sync"
    11  )
    12  
    13  // RoundTripper implements the http.RoundTripper interface, using a retrying
    14  // HTTP client to execute requests.
    15  //
    16  // It is important to note that retryablehttp doesn't always act exactly as a
    17  // RoundTripper should. This is highly dependent on the retryable client's
    18  // configuration.
    19  type RoundTripper struct {
    20  	// The client to use during requests. If nil, the default retryablehttp
    21  	// client and settings will be used.
    22  	Client *Client
    23  
    24  	// once ensures that the logic to initialize the default client runs at
    25  	// most once, in a single thread.
    26  	once sync.Once
    27  }
    28  
    29  // init initializes the underlying retryable client.
    30  func (rt *RoundTripper) init() {
    31  	if rt.Client == nil {
    32  		rt.Client = NewClient()
    33  	}
    34  }
    35  
    36  // RoundTrip satisfies the http.RoundTripper interface.
    37  func (rt *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
    38  	rt.once.Do(rt.init)
    39  
    40  	// Convert the request to be retryable.
    41  	retryableReq, err := FromRequest(req)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	// Execute the request.
    47  	resp, err := rt.Client.Do(retryableReq)
    48  	// If we got an error returned by standard library's `Do` method, unwrap it
    49  	// otherwise we will wind up erroneously re-nesting the error.
    50  	if _, ok := err.(*url.Error); ok {
    51  		return resp, errors.Unwrap(err)
    52  	}
    53  
    54  	return resp, err
    55  }
    56  

View as plain text