Package rehttp implements an HTTP transport that handles retries. An HTTP client can be created with a *rehttp.Transport as RoundTripper and it will apply the retry strategy to its requests.
The retry strategy is provided by the Transport, which determines whether or not the request should be retried, and if so, what delay to apply before retrying, based on the RetryFn and DelayFn functions passed to NewTransport.
The package offers common delay strategies as ready-made functions that return a DelayFn:
- ConstDelay(delay time.Duration) DelayFn - ExpJitterDelay(base, max time.Duration) DelayFn
It also provides common retry helpers that return a RetryFn:
- RetryIsErr(func(error) bool) RetryFn - RetryHTTPMethods(methods ...string) RetryFn - RetryMaxRetries(max int) RetryFn - RetryStatuses(statuses ...int) RetryFn - RetryStatusInterval(fromStatus, toStatus int) RetryFn - RetryTemporaryErr() RetryFn
Those can be combined with RetryAny or RetryAll as needed. RetryAny enables retries if any of the RetryFn return true, while RetryAll enables retries if all RetryFn return true. Typically, the RetryFn of the Transport should use at least RetryMaxRetries and some other retry condition(s), combined using RetryAll.
By default, the Transport will buffer the request's body in order to be able to retry the request, as a request attempt will consume and close the existing body. Sometimes this is not desirable, so it can be prevented by setting PreventRetryWithBody to true on the Transport. Doing so will disable retries when a request has a non-nil body.
This package requires Go version 1.6+, since it uses the new http.Request.Cancel field in order to cancel requests. It doesn't implement the deprecated http.Transport.CancelRequest method (https://golang.org/pkg/net/http/#Transport.CancelRequest).
On Go1.7+, it uses the context returned by http.Request.Context to check for cancelled requests.
It should work on Go1.5, but only if there is no timeout set on the *http.Client. Go's stdlib will return an error on the first request if that's the case, because it requires a RoundTripper that implements the CancelRequest method.