Documentation
¶
Overview ¶
Package httpclient is the only way out to the network: every source and registry fetches through a Client (ADR 0002).
A Client sends GET requests over HTTPS to an exact list of hosts, follows a redirect only to one of them, bounds every phase of a call with its own timeout, refuses a body over a size limit and retries 429 and 5xx answers with exponential backoff, full jitter and Retry-After.
A Client never uses a proxy, even when HTTP_PROXY or HTTPS_PROXY is set: an inherited proxy would see every query and widen the egress surface without anyone choosing it. Filtering egress belongs to the network.
Index ¶
Constants ¶
const ( DefaultTimeout = 30 * time.Second DefaultDialTimeout = 5 * time.Second DefaultTLSHandshakeTimeout = 5 * time.Second DefaultResponseHeaderTimeout = 10 * time.Second DefaultMaxBodyBytes = 16 << 20 DefaultAttempts = 3 DefaultBaseBackoff = 500 * time.Millisecond DefaultMaxBackoff = 30 * time.Second )
Defaults applied by New to a zero Config field. They are choices, sized for the files and registries listed in docs/sources.md (the largest file, ARCEP MAJNUM, is about 1.1 MB).
const DefaultUserAgent = "arnakoff (+https://github.com/arnakoff/api)"
DefaultUserAgent identifies Arnakoff to upstreams and points to the project, so an operator who sees the traffic knows whom to contact.
Variables ¶
var ( // ErrURLNotAllowed means a URL, or a redirect target, is not HTTPS on an // allowed host, or carries credentials. No request was sent to it. ErrURLNotAllowed = errors.New("URL not allowed") // ErrBodyTooLarge means a response body exceeds Config.MaxBodyBytes. ErrBodyTooLarge = errors.New("response body too large") // ErrInvalidConfig means New was given a Config it cannot use. ErrInvalidConfig = errors.New("invalid HTTP client config") )
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is an outbound HTTP client restricted to allowed hosts. It is safe for concurrent use.
func (*Client) Get ¶
Get fetches rawURL and returns its body. It returns ErrURLNotAllowed without sending anything when rawURL is not HTTPS on an allowed host, ErrBodyTooLarge, a *StatusError for a non-2xx answer, or the error of the transport or of ctx.
type Config ¶
type Config struct {
// AllowedHosts are the exact hosts the client may reach, as in URL.Host:
// "rdap.nic.fr", or "127.0.0.1:8443" with a port. Required.
AllowedHosts []string
// UserAgent is sent with every request.
UserAgent string
// Timeout bounds a whole Get call: every attempt, every pause between
// attempts and the reading of the body.
Timeout time.Duration
// DialTimeout bounds opening a TCP connection.
DialTimeout time.Duration
// TLSHandshakeTimeout bounds the TLS handshake.
TLSHandshakeTimeout time.Duration
// ResponseHeaderTimeout bounds the wait for response headers once the
// request is sent.
ResponseHeaderTimeout time.Duration
// MaxBodyBytes is the largest response body Get accepts.
MaxBodyBytes int64
// Attempts is the number of tries for a 429 or 5xx answer, the first
// one included.
Attempts int
// BaseBackoff is the ceiling of the first pause between two attempts;
// the ceiling doubles at each retry, up to MaxBackoff.
BaseBackoff time.Duration
// MaxBackoff caps a pause. A Retry-After longer than MaxBackoff ends
// the retries rather than hammer the upstream sooner than it asked.
MaxBackoff time.Duration
// RootCAs are the trusted certificate authorities; nil means the
// system pool.
RootCAs *x509.CertPool
}
Config configures a Client. Every zero field but AllowedHosts and RootCAs takes its Default value; a negative one is invalid.
type StatusError ¶
type StatusError struct {
// StatusCode is the HTTP status of the last response.
StatusCode int
// contains filtered or unexported fields
}
StatusError is a response whose status is not 2xx, returned once retries, if any, are over. Match it with errors.As to read StatusCode, for example to read a 404 from a registry as "not found".
func (*StatusError) Error ¶
func (e *StatusError) Error() string
Error returns the status, such as "unexpected HTTP status 404 Not Found".
func (*StatusError) RetryAfter ¶ added in v0.20.0
func (e *StatusError) RetryAfter() (time.Duration, bool)
RetryAfter returns the wait the last response asked for in a valid Retry-After header, and false when it had none, so a caller can stay away from an upstream that throttles it.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package httpclienttest builds httpclient.Client values for tests against an httptest TLS server.
|
Package httpclienttest builds httpclient.Client values for tests against an httptest TLS server. |