httpclient

package
v1.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 21, 2025 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package httpclient contains helpers for doing HTTP requests (for example, round trippers for retrying and rate limiting).

Index

Examples

Constants

View Source
const (
	DefaultRateLimitingBurst       = 1
	DefaultRateLimitingWaitTimeout = 15 * time.Second
)

Default parameter values for RateLimitingRoundTripper.

View Source
const (
	DefaultMaxRetryAttempts                  = 10
	DefaultExponentialBackoffInitialInterval = time.Second
	DefaultExponentialBackoffMultiplier      = 2
)

Default parameter values for RetryableRoundTripper.

View Source
const RetryAttemptNumberHeader = "X-Retry-Attempt"

RetryAttemptNumberHeader is an HTTP header name that will contain the serial number of the retry attempt.

View Source
const UnlimitedRetryAttempts = -1

UnlimitedRetryAttempts should be used as RetryableRoundTripperOpts.MaxRetryAttempts value when we want to stop retries only by RetryableRoundTripperOpts.BackoffPolicy.

Variables

View Source
var DefaultBackoffPolicy = retry.PolicyFunc(func() backoff.BackOff {
	bf := backoff.NewExponentialBackOff()
	bf.InitialInterval = DefaultExponentialBackoffInitialInterval
	bf.Multiplier = DefaultExponentialBackoffMultiplier
	bf.Reset()
	return bf
})

DefaultBackoffPolicy is a default backoff policy.

Functions

func CheckErrorIsTemporary

func CheckErrorIsTemporary(err error) bool

CheckErrorIsTemporary checks either error is temporary or not.

func DefaultCheckRetry

func DefaultCheckRetry(
	ctx context.Context, resp *http.Response, roundTripErr error, doneRetryAttempts int,
) (needRetry bool, err error)

DefaultCheckRetry represents default function to determine either retry is needed or not.

func GetRequestTypeFromContext added in v1.7.0

func GetRequestTypeFromContext(ctx context.Context) string

GetRequestTypeFromContext extracts request type from the context.

func MustNew added in v1.6.0

func MustNew(cfg *Config) *http.Client

MustNew wraps delegate transports with logging, rate limiting, retryable, request id and panics if any error occurs.

func MustNewWithOpts added in v1.6.0

func MustNewWithOpts(cfg *Config, opts Opts) *http.Client

MustNewWithOpts wraps delegate transports with options logging, metrics, rate limiting, retryable, user agent, request id and panics if any error occurs.

func New added in v1.6.0

func New(cfg *Config) (*http.Client, error)

New wraps delegate transports with logging, rate limiting, retryable, request id and returns an error if any occurs.

func NewContextWithRequestType added in v1.7.0

func NewContextWithRequestType(ctx context.Context, requestType string) context.Context

NewContextWithRequestType creates a new context with request type.

func NewLoggingRoundTripper added in v1.6.0

func NewLoggingRoundTripper(delegate http.RoundTripper) http.RoundTripper

NewLoggingRoundTripper creates an HTTP transport that log requests.

func NewLoggingRoundTripperWithOpts added in v1.6.0

func NewLoggingRoundTripperWithOpts(
	delegate http.RoundTripper, opts LoggingRoundTripperOpts,
) http.RoundTripper

NewLoggingRoundTripperWithOpts creates an HTTP transport that log requests with options.

func NewMetricsRoundTripper added in v1.6.0

func NewMetricsRoundTripper(delegate http.RoundTripper, collector MetricsCollector) http.RoundTripper

NewMetricsRoundTripper creates an HTTP transport that measures requests done.

func NewMetricsRoundTripperWithOpts added in v1.6.0

func NewMetricsRoundTripperWithOpts(
	delegate http.RoundTripper,
	collector MetricsCollector,
	opts MetricsRoundTripperOpts,
) http.RoundTripper

NewMetricsRoundTripperWithOpts creates an HTTP transport that measures requests done.

func NewRequestIDRoundTripper added in v1.6.0

func NewRequestIDRoundTripper(delegate http.RoundTripper) http.RoundTripper

NewRequestIDRoundTripper creates an HTTP transport with X-Request-ID header support.

func NewRequestIDRoundTripperWithOpts added in v1.6.0

func NewRequestIDRoundTripperWithOpts(delegate http.RoundTripper, opts RequestIDRoundTripperOpts) http.RoundTripper

NewRequestIDRoundTripperWithOpts creates an HTTP transport with X-Request-ID header support with options.

func NewWithOpts added in v1.6.0

func NewWithOpts(cfg *Config, opts Opts) (*http.Client, error)

NewWithOpts wraps delegate transports with options logging, metrics, rate limiting, retryable, user agent, request id and returns an error if any occurs.

Types

type AuthBearerRoundTripper

type AuthBearerRoundTripper struct {
	Delegate     http.RoundTripper
	AuthProvider AuthProvider
	// contains filtered or unexported fields
}

AuthBearerRoundTripper implements http.RoundTripper interface and sets Authorization HTTP header in all outgoing requests.

func NewAuthBearerRoundTripper

func NewAuthBearerRoundTripper(delegate http.RoundTripper, authProvider AuthProvider) *AuthBearerRoundTripper

NewAuthBearerRoundTripper creates a new AuthBearerRoundTripper.

func NewAuthBearerRoundTripperWithOpts

func NewAuthBearerRoundTripperWithOpts(delegate http.RoundTripper, authProvider AuthProvider,
	opts AuthBearerRoundTripperOpts) *AuthBearerRoundTripper

NewAuthBearerRoundTripperWithOpts creates a new AuthBearerRoundTripper with options.

func (*AuthBearerRoundTripper) RoundTrip

func (rt *AuthBearerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip executes a single HTTP transaction, returning a Response for the provided Request.

type AuthBearerRoundTripperError

type AuthBearerRoundTripperError struct {
	Inner error
}

AuthBearerRoundTripperError is returned in RoundTrip method of AuthBearerRoundTripper when the original request cannot be potentially retried.

func (*AuthBearerRoundTripperError) Error

func (*AuthBearerRoundTripperError) Unwrap

func (e *AuthBearerRoundTripperError) Unwrap() error

Unwrap returns the next error in the error chain.

type AuthBearerRoundTripperOpts

type AuthBearerRoundTripperOpts struct {
	TokenScope []string
}

AuthBearerRoundTripperOpts is options for AuthBearerRoundTripper.

type AuthProvider

type AuthProvider interface {
	GetToken(ctx context.Context, scope ...string) (string, error)
}

AuthProvider provide auth information that used for barear authrization

type CheckRetryFunc

type CheckRetryFunc func(ctx context.Context, resp *http.Response, roundTripErr error, doneRetryAttempts int) (bool, error)

CheckRetryFunc is a function that is called right after RoundTrip() method and determines if the next retry attempt is needed.

type Config added in v1.6.0

type Config struct {
	// Retries is a configuration for HTTP client retries policy.
	Retries RetriesConfig

	// RateLimits is a configuration for HTTP client rate limits.
	RateLimits RateLimitsConfig

	// Log is a configuration for HTTP client logs.
	Log LogConfig

	// Metrics is a configuration for HTTP client metrics.
	Metrics MetricsConfig

	// Timeout is the maximum time to wait for a request to be made.
	Timeout time.Duration
	// contains filtered or unexported fields
}

Config represents options for HTTP client configuration.

func NewConfig added in v1.6.0

func NewConfig() *Config

NewConfig creates a new instance of the Config.

func NewConfigWithKeyPrefix added in v1.6.0

func NewConfigWithKeyPrefix(keyPrefix string) *Config

NewConfigWithKeyPrefix creates a new instance of the Config. Allows specifying key prefix which will be used for parsing configuration parameters.

func (*Config) KeyPrefix added in v1.6.0

func (c *Config) KeyPrefix() string

KeyPrefix returns a key prefix with which all configuration parameters should be presented.

func (*Config) Set added in v1.6.0

func (c *Config) Set(dp config.DataProvider) error

Set is part of config interface implementation.

func (*Config) SetProviderDefaults added in v1.6.0

func (c *Config) SetProviderDefaults(_ config.DataProvider)

SetProviderDefaults is part of config interface implementation.

type ConstantBackoffConfig added in v1.6.0

type ConstantBackoffConfig struct {
	// Interval is the interval for constant backoff.
	Interval time.Duration
}

ConstantBackoffConfig represents configuration options for constant backoff.

type ExponentialBackoffConfig added in v1.6.0

type ExponentialBackoffConfig struct {
	// InitialInterval is the initial interval for exponential backoff.
	InitialInterval time.Duration

	// Multiplier is the multiplier for exponential backoff.
	Multiplier float64
}

ExponentialBackoffConfig represents configuration options for exponential backoff.

type LogConfig added in v1.6.0

type LogConfig struct {
	// Enabled is a flag that enables logging.
	Enabled bool

	// SlowRequestThreshold is a threshold for slow requests.
	SlowRequestThreshold time.Duration

	// Mode of logging: [all, failed]. 'all' by default.
	Mode LoggingMode
}

LogConfig represents configuration options for HTTP client logs.

func (*LogConfig) Set added in v1.6.0

func (c *LogConfig) Set(dp config.DataProvider) error

Set is part of config interface implementation.

func (*LogConfig) SetProviderDefaults added in v1.6.0

func (c *LogConfig) SetProviderDefaults(_ config.DataProvider)

SetProviderDefaults is part of config interface implementation.

func (*LogConfig) TransportOpts added in v1.6.0

func (c *LogConfig) TransportOpts() LoggingRoundTripperOpts

TransportOpts returns transport options.

type LoggingMode added in v1.6.0

type LoggingMode string

LoggingMode represents a mode of logging.

const (
	LoggingModeAll    LoggingMode = "all"
	LoggingModeFailed LoggingMode = "failed"
)

func (LoggingMode) IsValid added in v1.6.0

func (lm LoggingMode) IsValid() bool

IsValid checks if the logger mode is valid.

type LoggingRoundTripper added in v1.6.0

type LoggingRoundTripper struct {
	// Delegate is the next RoundTripper in the chain.
	Delegate http.RoundTripper

	// ClientType represents a type of client, it's a service component reference. e.g. 'auth-service'
	ClientType string

	// Mode of logging: [all, failed]. 'all' by default.
	Mode LoggingMode

	// SlowRequestThreshold is a threshold for slow requests.
	SlowRequestThreshold time.Duration

	// LoggerProvider is a function that provides a context-specific logger.
	// middleware.GetLoggerFromContext is used by default.
	LoggerProvider func(ctx context.Context) log.FieldLogger
}

LoggingRoundTripper implements http.RoundTripper for logging requests.

func (*LoggingRoundTripper) RoundTrip added in v1.6.0

func (rt *LoggingRoundTripper) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip adds logging capabilities to the HTTP transport.

type LoggingRoundTripperOpts added in v1.6.0

type LoggingRoundTripperOpts struct {
	// ClientType represents a type of client, it's a service component reference. e.g. 'auth-service'
	ClientType string

	// Mode of logging: [all, failed]. 'all' by default.
	Mode LoggingMode

	// SlowRequestThreshold is a threshold for slow requests.
	SlowRequestThreshold time.Duration

	// LoggerProvider is a function that provides a context-specific logger.
	// middleware.GetLoggerFromContext is used by default.
	LoggerProvider func(ctx context.Context) log.FieldLogger
}

LoggingRoundTripperOpts represents an options for LoggingRoundTripper.

type MetricsCollector added in v1.6.0

type MetricsCollector interface {
	// RequestDuration observes the duration of the request and the status code.
	RequestDuration(clientType, remoteAddress, summary, status, requestType string, duration float64)
}

MetricsCollector is an interface for collecting metrics for client requests.

type MetricsConfig added in v1.6.0

type MetricsConfig struct {
	// Enabled is a flag that enables metrics.
	Enabled bool
}

MetricsConfig represents configuration options for HTTP client logs.

func (*MetricsConfig) Set added in v1.6.0

Set is part of config interface implementation.

func (*MetricsConfig) SetProviderDefaults added in v1.6.0

func (c *MetricsConfig) SetProviderDefaults(_ config.DataProvider)

SetProviderDefaults is part of config interface implementation.

type MetricsRoundTripper added in v1.6.0

type MetricsRoundTripper struct {
	// Delegate is the next RoundTripper in the chain.
	Delegate http.RoundTripper

	// ClientType represents a type of client, it's a service component reference. e.g. 'auth-service'
	ClientType string

	// MetricsCollector is a metrics collector.
	MetricsCollector MetricsCollector

	// ClassifyRequest does request classification, producing non-parameterized summary for given request.
	ClassifyRequest func(r *http.Request, clientType string) string
}

MetricsRoundTripper is an HTTP transport that measures requests done.

func (*MetricsRoundTripper) RoundTrip added in v1.6.0

func (rt *MetricsRoundTripper) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip measures external requests done.

type MetricsRoundTripperOpts added in v1.6.0

type MetricsRoundTripperOpts struct {
	// ClientType represents a type of client, it's a service component reference. e.g. 'auth-service'
	ClientType string

	// ClassifyRequest does request classification, producing non-parameterized summary for given request.
	ClassifyRequest func(r *http.Request, clientType string) string
}

MetricsRoundTripperOpts is an HTTP transport that measures requests done.

type Opts added in v1.6.0

type Opts struct {
	// UserAgent is a user agent string.
	UserAgent string

	// ClientType represents a type of client, it's a service component reference. e.g. 'auth-service'.
	ClientType string

	// Delegate is the next RoundTripper in the chain.
	Delegate http.RoundTripper

	// LoggerProvider is a function that provides a context-specific logger.
	LoggerProvider func(ctx context.Context) log.FieldLogger

	// RequestIDProvider is a function that provides a request ID.
	RequestIDProvider func(ctx context.Context) string

	// MetricsCollector is a metrics collector.
	MetricsCollector MetricsCollector

	// ClassifyRequest does request classification, producing non-parameterized summary in metrics round tripper.
	ClassifyRequest func(r *http.Request, clientType string) string
}

Opts provides options for NewWithOpts and MustWithOpts functions.

type PrometheusMetricsCollector added in v1.6.0

type PrometheusMetricsCollector struct {
	// Durations is a histogram of the http client requests durations.
	Durations *prometheus.HistogramVec
}

PrometheusMetricsCollector is a Prometheus metrics collector.

func NewPrometheusMetricsCollector added in v1.6.0

func NewPrometheusMetricsCollector(namespace string) *PrometheusMetricsCollector

NewPrometheusMetricsCollector creates a new Prometheus metrics collector.

func (*PrometheusMetricsCollector) MustRegister added in v1.6.0

func (p *PrometheusMetricsCollector) MustRegister()

MustRegister registers the Prometheus metrics.

func (*PrometheusMetricsCollector) RequestDuration added in v1.6.0

func (p *PrometheusMetricsCollector) RequestDuration(
	clientType, host, summary, status, requestType string, duration float64,
)

RequestDuration observes the duration of the request and the status code.

func (*PrometheusMetricsCollector) Unregister added in v1.6.0

func (p *PrometheusMetricsCollector) Unregister()

Unregister the Prometheus metrics.

type RateLimitingRoundTripper

type RateLimitingRoundTripper struct {
	Delegate http.RoundTripper

	RateLimit   int
	Burst       int
	WaitTimeout time.Duration
	Adaptation  RateLimitingRoundTripperAdaptation
	// contains filtered or unexported fields
}

RateLimitingRoundTripper wraps implementing http.RoundTripper interface object and provides adaptive (can use limit from response's HTTP header) rate limiting mechanism for outgoing requests.

func NewRateLimitingRoundTripper

func NewRateLimitingRoundTripper(delegate http.RoundTripper, rateLimit int) (*RateLimitingRoundTripper, error)

NewRateLimitingRoundTripper creates a new RateLimitingRoundTripper with specified rate limit.

Example

ExampleNewRateLimitingRoundTripper demonstrates the use of RateLimitingRoundTripper with default parameters.

Add "// Output:" in the end of the function and run:

$ go test ./httpclient -v -run ExampleNewRateLimitingRoundTripper

Output will be like:

[Req#1] 204 (0ms)
[Req#2] 204 (502ms)
[Req#3] 204 (497ms)
[Req#4] 204 (500ms)
[Req#5] 204 (503ms)
// Note: error handling is intentionally omitted so as not to overcomplicate the example.
// It is strictly necessary to handle all errors in real code.

server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
	rw.WriteHeader(http.StatusNoContent)
}))

// Let's make transport that may do maximum 2 requests per second.
tr, _ := NewRateLimitingRoundTripper(http.DefaultTransport, 2)
httpClient := &http.Client{Transport: tr}

start := time.Now()
prev := time.Now()
for i := 0; i < 5; i++ {
	resp, _ := httpClient.Get(server.URL)
	_ = resp.Body.Close()
	now := time.Now()
	_, _ = fmt.Fprintf(os.Stderr, "[Req#%d] %d (%dms)\n", i+1, resp.StatusCode, now.Sub(prev).Milliseconds())
	prev = now
}
delta := time.Since(start) - time.Second*2
if delta > time.Millisecond*20 {
	fmt.Println("Total time is much greater than 2s")
} else {
	fmt.Println("Total time is about 2s")
}
Output:

Total time is about 2s

func NewRateLimitingRoundTripperWithOpts

func NewRateLimitingRoundTripperWithOpts(
	delegate http.RoundTripper, rateLimit int, opts RateLimitingRoundTripperOpts,
) (*RateLimitingRoundTripper, error)

NewRateLimitingRoundTripperWithOpts creates a new RateLimitingRoundTripper with specified rate limit and options. For options that are not presented, the default values will be used.

Example

ExampleNewRateLimitingRoundTripperWithOpts demonstrates the use of RateLimitingRoundTripper.

// Note: error handling is intentionally omitted so as not to overcomplicate the example.
// It is strictly necessary to handle all errors in real code.

server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
	rw.WriteHeader(http.StatusNoContent)
}))

// Let's make transport that may do maximum 2 requests per second.
tr, _ := NewRateLimitingRoundTripperWithOpts(http.DefaultTransport, 2, RateLimitingRoundTripperOpts{
	WaitTimeout: time.Millisecond * 100, // Wait maximum 100ms.
})
httpClient := &http.Client{Transport: tr}

for i := 0; i < 2; i++ {
	resp, err := httpClient.Get(server.URL)
	if err != nil {
		var waitErr *RateLimitingWaitError
		if errors.As(err, &waitErr) {
			fmt.Printf("trying to do too many requests")
		}
		continue
	}
	_ = resp.Body.Close()
}
Output:

trying to do too many requests

func (*RateLimitingRoundTripper) RoundTrip

func (rt *RateLimitingRoundTripper) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip executes a single HTTP transaction, returning a Response for the provided Request.

type RateLimitingRoundTripperAdaptation

type RateLimitingRoundTripperAdaptation struct {
	ResponseHeaderName string
	SlackPercent       int
}

RateLimitingRoundTripperAdaptation represents a params to adapt rate limiting in accordance with value in response.

type RateLimitingRoundTripperOpts

type RateLimitingRoundTripperOpts struct {
	Burst       int
	WaitTimeout time.Duration
	Adaptation  RateLimitingRoundTripperAdaptation
}

RateLimitingRoundTripperOpts represents an options for RateLimitingRoundTripper.

type RateLimitingWaitError

type RateLimitingWaitError struct {
	Inner error
}

RateLimitingWaitError is returned in RoundTrip method of RateLimitingRoundTripper when rate limit is exceeded.

func (*RateLimitingWaitError) Error

func (e *RateLimitingWaitError) Error() string

func (*RateLimitingWaitError) Unwrap

func (e *RateLimitingWaitError) Unwrap() error

Unwrap returns the next error in the error chain.

type RateLimitsConfig added in v1.6.0

type RateLimitsConfig struct {
	// Enabled is a flag that enables rate limiting.
	Enabled bool

	// Limit is the maximum number of requests that can be made.
	Limit int

	// Burst allow temporary spikes in request rate.
	Burst int

	// WaitTimeout is the maximum time to wait for a request to be made.
	WaitTimeout time.Duration
}

RateLimitsConfig represents configuration options for HTTP client rate limits.

func (*RateLimitsConfig) Set added in v1.6.0

func (c *RateLimitsConfig) Set(dp config.DataProvider) (err error)

Set is part of config interface implementation.

func (*RateLimitsConfig) SetProviderDefaults added in v1.6.0

func (c *RateLimitsConfig) SetProviderDefaults(_ config.DataProvider)

SetProviderDefaults is part of config interface implementation.

func (*RateLimitsConfig) TransportOpts added in v1.6.0

TransportOpts returns transport options.

type RequestIDRoundTripper added in v1.6.0

type RequestIDRoundTripper struct {
	// Delegate is the next RoundTripper in the chain.
	Delegate http.RoundTripper

	// Opts are the options for the request ID round tripper.
	Opts RequestIDRoundTripperOpts
}

RequestIDRoundTripper for X-Request-ID header to the request.

func (*RequestIDRoundTripper) RoundTrip added in v1.6.0

func (rt *RequestIDRoundTripper) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip adds X-Request-ID header to the request.

type RequestIDRoundTripperOpts added in v1.6.0

type RequestIDRoundTripperOpts struct {
	// RequestIDProvider is a function that provides a request ID.
	// middleware.GetRequestIDFromContext is used by default.
	RequestIDProvider func(ctx context.Context) string
}

RequestIDRoundTripperOpts for X-Request-ID header to the request options.

type RetriesConfig added in v1.6.0

type RetriesConfig struct {
	// Enabled is a flag that enables retries.
	Enabled bool

	// MaxAttempts is the maximum number of attempts to retry the request.
	MaxAttempts int

	// Policy of a retry: [exponential, constant].
	Policy RetryPolicy

	// ExponentialBackoff is the configuration for exponential backoff.
	ExponentialBackoff ExponentialBackoffConfig

	// ConstantBackoff is the configuration for constant backoff.
	ConstantBackoff ConstantBackoffConfig
}

RetriesConfig represents configuration options for HTTP client retries policy.

func (*RetriesConfig) GetPolicy added in v1.6.0

func (c *RetriesConfig) GetPolicy() retry.Policy

GetPolicy returns a retry policy based on strategy or nil if none is provided.

func (*RetriesConfig) Set added in v1.6.0

Set is part of config interface implementation.

func (*RetriesConfig) SetProviderDefaults added in v1.6.0

func (c *RetriesConfig) SetProviderDefaults(_ config.DataProvider)

SetProviderDefaults is part of config interface implementation.

func (*RetriesConfig) TransportOpts added in v1.6.0

func (c *RetriesConfig) TransportOpts() RetryableRoundTripperOpts

TransportOpts returns transport options.

type RetryPolicy added in v1.6.0

type RetryPolicy string

RetryPolicy represents a retry policy strategy.

const (
	// DefaultClientWaitTimeout is a default timeout for a client to wait for a request.
	DefaultClientWaitTimeout = 10 * time.Second

	// RetryPolicyExponential is a policy for exponential retries.
	RetryPolicyExponential RetryPolicy = "exponential"

	// RetryPolicyConstant is a policy for constant retries.
	RetryPolicyConstant RetryPolicy = "constant"
)

type RetryableRoundTripper

type RetryableRoundTripper struct {
	// Delegate is an object that implements http.RoundTripper interface
	// and is used for sending HTTP requests under the hood.
	Delegate http.RoundTripper

	// Logger is used for logging.
	// When it's necessary to use context-specific logger, LoggerProvider should be used instead.
	Logger log.FieldLogger

	// LoggerProvider is a function that provides a context-specific logger.
	// One of the typical use cases is to use a retryable client in the context of a request handler,
	// where the logger should produce logs with request-specific information (e.g., request ID).
	LoggerProvider func(ctx context.Context) log.FieldLogger

	// MaxRetryAttempts determines how many maximum retry attempts can be done.
	// The total number of sending HTTP request may be MaxRetryAttempts + 1 (the first request is not a retry attempt).
	// If its value is UnlimitedRetryAttempts, it's supposed that retry mechanism will be stopped by BackoffPolicy.
	// By default, DefaultMaxRetryAttempts const is used.
	MaxRetryAttempts int

	// CheckRetry is called right after RoundTrip() method and determines if the next retry attempt is needed.
	// By default, DefaultCheckRetry function is used.
	CheckRetry CheckRetryFunc

	// IgnoreRetryAfter determines if Retry-After HTTP header of the response is parsed and
	// used as a wait time before doing the next retry attempt.
	// If it's true or response doesn't contain Retry-After HTTP header, BackoffPolicy will be used for computing delay.
	IgnoreRetryAfter bool

	// BackoffPolicy is used for computing wait time before doing the next retry attempt
	// when the given response doesn't contain Retry-After HTTP header or IgnoreRetryAfter is true.
	// By default, DefaultBackoffPolicy is used.
	BackoffPolicy retry.Policy
}

RetryableRoundTripper wraps an object that implements http.RoundTripper interface and provides a retrying mechanism for HTTP requests.

func NewRetryableRoundTripper

func NewRetryableRoundTripper(delegate http.RoundTripper) (*RetryableRoundTripper, error)

NewRetryableRoundTripper returns a new instance of RetryableRoundTripper.

Example

ExampleNewRetryableRoundTripper demonstrates the use of RetryableRoundTripper with default parameters.

To execute this example: 1) Add "// Output: Got 200 after 10 retry attempts" in the end of function. 2) Run:

$ go test ./httpclient -v -run ExampleNewRetryableRoundTripper

Stderr will contain something like this:

[Req#1] wait time: 0.001s
[Req#2] wait time: 1.109s
[Req#3] wait time: 2.882s
[Req#4] wait time: 4.661s
[Req#5] wait time: 7.507s
[Req#6] wait time: 14.797s
[Req#7] wait time: 37.984s
[Req#8] wait time: 33.942s
[Req#9] wait time: 39.394s
[Req#10] wait time: 35.820s
[Req#11] wait time: 48.060s
// Note: error handling is intentionally omitted so as not to overcomplicate the example.
// It is strictly necessary to handle all errors in real code.

reqTimes := make(chan time.Time, DefaultMaxRetryAttempts+1)

server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
	reqTimes <- time.Now()
	if n, err := strconv.Atoi(r.Header.Get(RetryAttemptNumberHeader)); err == nil && n == DefaultMaxRetryAttempts {
		rw.WriteHeader(http.StatusOK)
		_, _ = rw.Write([]byte("ok, you win..."))
		return
	}
	rw.WriteHeader(http.StatusServiceUnavailable)
}))

prevTime := time.Now()

// Create RetryableRoundTripper with default params:
//	+ maximum retry attempts = 10 (DefaultMaxRetryAttempts)
//	+ respect Retry-After response HTTP header
//	+ exponential backoff policy (DefaultBackoffPolicy, multiplier = 2, initial interval = 1s)
tr, _ := NewRetryableRoundTripper(http.DefaultTransport)
httpClient := &http.Client{Transport: tr}

resp, err := httpClient.Get(server.URL)
if err != nil {
	log.Fatal(err)
}
_ = resp.Body.Close()
close(reqTimes)

reqsCount := 0
for reqTime := range reqTimes {
	reqsCount++
	_, _ = fmt.Fprintf(os.Stderr, "[Req#%d] wait time: %.3fs\n", reqsCount, reqTime.Sub(prevTime).Seconds())
	prevTime = reqTime
}
doneRetryAttempts := reqsCount - 1
fmt.Printf("Got %d after %d retry attempts", resp.StatusCode, doneRetryAttempts)

func NewRetryableRoundTripperWithOpts

func NewRetryableRoundTripperWithOpts(
	delegate http.RoundTripper, opts RetryableRoundTripperOpts,
) (*RetryableRoundTripper, error)

NewRetryableRoundTripperWithOpts creates a new instance of RateLimitingRoundTripper with specified options.

func (*RetryableRoundTripper) RoundTrip

func (rt *RetryableRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip performs request with retry logic. nolint: gocyclo

type RetryableRoundTripperError

type RetryableRoundTripperError struct {
	Inner error
}

RetryableRoundTripperError is returned in RoundTrip method of RetryableRoundTripper when the original request cannot be potentially retried.

func (*RetryableRoundTripperError) Error

func (*RetryableRoundTripperError) Unwrap

func (e *RetryableRoundTripperError) Unwrap() error

Unwrap returns the next error in the error chain.

type RetryableRoundTripperOpts

type RetryableRoundTripperOpts struct {
	// Logger is used for logging.
	// When it's necessary to use context-specific logger, LoggerProvider should be used instead.
	Logger log.FieldLogger

	// LoggerProvider is a function that provides a context-specific logger.
	// One of the typical use cases is to use a retryable client in the context of a request handler,
	// where the logger should produce logs with request-specific information (e.g., request ID).
	LoggerProvider func(ctx context.Context) log.FieldLogger

	// MaxRetryAttempts determines how many maximum retry attempts can be done.
	// The total number of sending HTTP request may be MaxRetryAttempts + 1 (the first request is not a retry attempt).
	// If its value is UnlimitedRetryAttempts, it's supposed that retry mechanism will be stopped by BackoffPolicy.
	// By default, DefaultMaxRetryAttempts const is used.
	MaxRetryAttempts int

	// CheckRetry is called right after RoundTrip() method and determines if the next retry attempt is needed.
	// By default, DefaultCheckRetry function is used.
	CheckRetryFunc CheckRetryFunc

	// IgnoreRetryAfter determines if Retry-After HTTP header of the response is parsed and
	// used as a wait time before doing the next retry attempt.
	// If it's true or response doesn't contain Retry-After HTTP header, BackoffPolicy will be used for computing delay.
	IgnoreRetryAfter bool

	// BackoffPolicy is used for computing wait time before doing the next retry attempt
	// when the given response doesn't contain Retry-After HTTP header or IgnoreRetryAfter is true.
	// By default, DefaultBackoffPolicy is used.
	BackoffPolicy retry.Policy
}

RetryableRoundTripperOpts represents an options for RetryableRoundTripper.

type UserAgentRoundTripper

type UserAgentRoundTripper struct {
	Delegate       http.RoundTripper
	UserAgent      string
	UpdateStrategy UserAgentUpdateStrategy
}

UserAgentRoundTripper implements http.RoundTripper interface and sets User-Agent HTTP header in all outgoing requests.

func NewUserAgentRoundTripper

func NewUserAgentRoundTripper(delegate http.RoundTripper, userAgent string) *UserAgentRoundTripper

NewUserAgentRoundTripper creates a new UserAgentRoundTripper.

func NewUserAgentRoundTripperWithOpts

func NewUserAgentRoundTripperWithOpts(
	delegate http.RoundTripper, userAgent string, opts UserAgentRoundTripperOpts,
) *UserAgentRoundTripper

NewUserAgentRoundTripperWithOpts creates a new UserAgentRoundTripper with specified options.

func (*UserAgentRoundTripper) RoundTrip

func (rt *UserAgentRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip executes a single HTTP transaction, returning a Response for the provided Request.

type UserAgentRoundTripperOpts

type UserAgentRoundTripperOpts struct {
	UpdateStrategy UserAgentUpdateStrategy
}

UserAgentRoundTripperOpts represents an options for UserAgentRoundTripper.

type UserAgentUpdateStrategy

type UserAgentUpdateStrategy int

UserAgentUpdateStrategy represents a strategy for updating User-Agent HTTP header.

const (
	UserAgentUpdateStrategySetIfEmpty UserAgentUpdateStrategy = iota
	UserAgentUpdateStrategyAppend
	UserAgentUpdateStrategyPrepend
)

User-Agent update strategies.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL