xhttp

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2024 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package xhttp provides utility functions for HTTP requests.

Index

Constants

View Source
const (
	// ErrNotHTTPS is returned when trying to fetch resources from a non-secure
	// URI.
	ErrNotHTTPS xerrors.Error = "uri is not secure; must use HTTPS"

	// ErrDomainNotTrusted is returned when trying to fetch resources from a
	// domain outside the list of allowed domains.
	ErrDomainNotTrusted xerrors.Error = "domain is not trusted"

	// ErrNilHTTPClient is returned when trying to fetch resources without an
	// HTTP client.
	ErrNilHTTPClient xerrors.Error = "HTTP client cannot be nil"

	// ErrRequestFailed is returned when a request fails for unknown reasons.
	ErrRequestFailed xerrors.Error = "request failed with status code"

	// ErrExceededMaxContentLength is returned when trying to fetch resources
	// bigger than the allowed MaxContentLength.
	ErrExceededMaxContentLength xerrors.Error = "response body exceeds maximum content length"
)
View Source
const (
	Age                           string = "Age"
	AltSCV                        string = "Alt-Svc"
	Accept                        string = "Accept"
	AcceptCharset                 string = "Accept-Charset"
	AcceptPatch                   string = "Accept-Patch"
	AcceptRanges                  string = "Accept-Ranges"
	AcceptedLanguage              string = "Accept-Language"
	AcceptEncoding                string = "Accept-Encoding"
	Authorization                 string = "Authorization"
	CrossOriginResourcePolicy     string = "Cross-Origin-Resource-Policy"
	CacheControl                  string = "Cache-Control"
	Connection                    string = "Connection"
	ContentDisposition            string = "Content-Disposition"
	ContentEncoding               string = "Content-Encoding"
	ContentLength                 string = "Content-Length"
	ContentType                   string = "Content-Type"
	ContentLanguage               string = "Content-Language"
	ContentLocation               string = "Content-Location"
	ContentRange                  string = "Content-Range"
	Date                          string = "Date"
	DeltaBase                     string = "Delta-Base"
	ETag                          string = "ETag"
	Expires                       string = "Expires"
	Host                          string = "Host"
	IM                            string = "IM"
	IfMatch                       string = "If-Match"
	IfModifiedSince               string = "If-Modified-Since"
	IfNoneMatch                   string = "If-None-Match"
	IfRange                       string = "If-Range"
	IfUnmodifiedSince             string = "If-Unmodified-Since"
	KeepAliveK                    string = "Keep-Alive"
	LastModified                  string = "Last-Modified"
	Link                          string = "Link"
	Pragma                        string = "Pragma"
	ProxyAuthenticate             string = "Proxy-Authenticate"
	ProxyAuthorization            string = "Proxy-Authorization"
	PublicKeyPins                 string = "Public-Key-Pins"
	RetryAfter                    string = "Retry-After"
	Referer                       string = "Referer"
	Server                        string = "Server"
	SetCookie                     string = "Set-Cookie"
	StrictTransportSecurity       string = "Strict-Transport-Security"
	Trailer                       string = "Trailer"
	TK                            string = "Tk"
	TransferEncoding              string = "Transfer-Encoding"
	Location                      string = "Location"
	Upgrade                       string = "Upgrade"
	Vary                          string = "Vary"
	Via                           string = "Via"
	Warning                       string = "Warning"
	WWWAuthenticate               string = "WWW-Authenticate"
	XForwardedFor                 string = "X-Forwarded-For"
	XForwardedHost                string = "X-Forwarded-Host"
	XForwardedProto               string = "X-Forwarded-Proto"
	XRealIP                       string = "X-Real-Ip"
	XContentTypeOptions           string = "X-Content-Type-Options"
	XFrameOptions                 string = "X-Frame-Options"
	XXSSProtection                string = "X-XSS-Protection"
	XDNSPrefetchControl           string = "X-DNS-Prefetch-Control"
	Allow                         string = "Allow"
	Origin                        string = "Origin"
	AccessControlAllowOrigin      string = "Access-Control-Allow-Origin"
	AccessControlAllowCredentials string = "Access-Control-Allow-Credentials"
	AccessControlAllowHeaders     string = "Access-Control-Allow-Headers"
	AccessControlAllowMethods     string = "Access-Control-Allow-Methods"
	AccessControlExposeHeaders    string = "Access-Control-Expose-Headers"
	AccessControlMaxAge           string = "Access-Control-Max-Age"
	AccessControlRequestHeaders   string = "Access-Control-Request-Headers"
	AccessControlRequestMethod    string = "Access-Control-Request-Method"
	TimingAllowOrigin             string = "Timing-Allow-Origin"
	UserAgent                     string = "User-Agent"
)

Common HTTP header keys. Copied from pkg/net/http/header.go for convenience.

View Source
const (
	NoCache               string = "no-cache"
	KeepAliveV            string = "keep-alive"
	Close                 string = "close"
	ApplicationJSON       string = "application/json"
	FormData              string = "multipart/form-data"
	TextHTML              string = "text/html"
	TextPlain             string = "text/plain"
	TextCSS               string = "text/css"
	TextJavascript        string = "text/javascript"
	ApplicationJavascript string = "application/javascript"
	ApplicationXML        string = "application/xml"
	ImageJPEG             string = "image/jpeg"
	ImagePNG              string = "image/png"
	ImageGIF              string = "image/gif"
	ImageSVG              string = "image/svg+xml"
	CharsetUTF8           string = "charset=utf-8"
	Gzip                  string = "gzip"
	Deflate               string = "deflate"
	Brotli                string = "br"
	Wildcard              string = "*"
	SameOrigin            string = "same-origin"
	Deny                  string = "deny"
	SameSiteLax           string = "Lax"
	SameSiteStrict        string = "Strict"
	SameSiteNone          string = "None"
	Secure                string = "secure"
	NoTransform           string = "no-transform"
	Chunked               string = "chunked"
	True                  string = "true"
	False                 string = "false"
)

Common HTTP header values.

View Source
const (
	// ErrMissingRequest indicates that a nil http.Request was provided to the
	// ClientIP function.
	ErrMissingRequest xerrors.Error = "missing http.Request"

	// ErrInvalidIP indicates that no valid IP address could be extracted from
	// the given http.Request.
	ErrInvalidIP xerrors.Error = "invalid IP address"
)
View Source
const (
	// ErrCannotDrainResponse is returned when a response body cannot be drained.
	ErrCannotDrainResponse xerrors.Error = "cannot drain response body"

	// ErrCannotCloseResponse is returned when a response body cannot be closed.
	ErrCannotCloseResponse xerrors.Error = "cannot close response body"
)
View Source
const (
	// DefaultMaxRetries is the default maximum number of times a request will
	// be retried.
	DefaultMaxRetries int = 3

	// DefaultMinRetryDelay is the default minimum duration to wait before
	// retrying a request.
	DefaultMinRetryDelay time.Duration = 1 * time.Second

	// DefaultMaxRetryDelay is the default maximum duration to wait before
	// retrying a request.
	DefaultMaxRetryDelay time.Duration = 30 * time.Second
)
View Source
const (
	// DefaultTransportMaxIddleConns is the default maximum number of idle
	// connections in the pool.
	DefaultTransportMaxIddleConns int = 100

	// DefaultTransportIdleConnTimeout is the default maximum amount of time a
	// connection can remain idle before being closed.
	DefaultTransportIdleConnTimeout = 90 * time.Second

	// DefaultTransportTLSHandshakeTimeout is the default maximum amount of time
	// allowed to complete a TLS handshake.
	DefaultTransportTLSHandshakeTimeout = 10 * time.Second

	// DefaultTransportExpectContinueTimeout is the default maximum amount of
	// time to wait for a server's first response headers after fully writing
	// the request headers if the request has an "Expect: 100-continue" header.
	DefaultTransportExpectContinueTimeout = 1 * time.Second
)
View Source
const (
	UAEdgeWindows    = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0"
	UAChromeWindows  = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
	UAFirefoxWindows = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0"
	UASafariMacOS    = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.1"
)

Common user agent strings. Copied from Useragents.me for convenience.

View Source
const DefaultClientTimeout = 15 * time.Second

DefaultClientTimeout is the default timeout for the http.Client.

View Source
const ErrExceededMaxRetries xerrors.Error = "exceeded max retries"

ErrExceededMaxRetries is returned when the maximum number of retries has been exceeded.

Variables

This section is empty.

Functions

func ClientIP

func ClientIP(req *http.Request) (string, error)

ClientIP implements a best-effort algorithm for determining the real IP address of the client.

Under the hood, it prioritizes the rightmost IP from the last instance of the X-Forwarded-For header and falls back to the RemoteAddr field of http.Request if the header is missing.

func DefaultIsRetryable added in v0.7.0

func DefaultIsRetryable(resp *http.Response, err error) bool

DefaultIsRetryable defines the default logic to determine if a request should be retried.

It returns true if an error occurs or the response status code indicates a retry may be successful (e.g., 408, 429, 502, 503, 504).

func DrainResponseBody added in v0.5.0

func DrainResponseBody(resp *http.Response) error

DrainResponseBody reads and discards the remaining content of the response body until EOF, then closes it. If an error occurs while draining or closing the response body, an error is returned.

func NewClient added in v0.5.0

func NewClient(timeout time.Duration) *http.Client

NewClient returns a new http.Client given the provided timeout. Unlike Go's http.DefaultClient: - It is not shared, thus cannot be altered by other modules. - It doesn't follow redirects. - It doesn't accept cookies.

A zero timeout means to use a default timeout.

func NewRetryingClient added in v0.6.0

func NewRetryingClient(timeout time.Duration, policy *RetryPolicy, logger *slog.Logger) *http.Client

NewRetryingClient returns a new http.Client given the provided timeout and RetryPolicy. Unlike Go's http.DefaultClient: - It is not shared, thus cannot be altered by other modules. - It doesn't follow redirects. - It doesn't accept cookies. - It retries failed requests.

A zero timeout means to use a default timeout. A nil policy means to use a default policy. A nil logger means to not log.

func NewTransport added in v0.5.0

func NewTransport() *http.Transport

NewTransport returns a new http.Transport with similar default values to http.DefaultTransport, but is not shared, thus cannot be altered by other modules.

Types

type Fetcher added in v0.8.0

type Fetcher interface {
	// Fetch fetches the resource at the given URL and returns the response as
	// a byte array.
	Fetch(ctx context.Context, uri string) ([]byte, error)
}

Fetcher is an interface implemented by HTTP clients to fetch resources from a given URL.

type ResponseError added in v0.3.0

type ResponseError struct {
	// Message is a human-readable message describing the error.
	Message string `json:"message"`

	// Documentation is a link to documentation describing the error.
	Documentation string `json:"documentation,omitempty"`

	// Code is a machine-readable code describing the error.
	Code int `json:"code"`
}

ResponseError represents the response returned by the HTTP server when an error occurs.

func (ResponseError) Error added in v0.3.0

func (e ResponseError) Error() string

Error implements the Error interface.

func (ResponseError) Write added in v0.3.0

func (e ResponseError) Write(ctx context.Context, logger *slog.Logger, w http.ResponseWriter)

Write serializes the ResponseError as a JSON object and writes it to the given HTTP response writer.

type RetryPolicy added in v0.6.0

type RetryPolicy struct {
	// IsRetryable determines whether a given response and error combination
	// should be retried.
	IsRetryable func(*http.Response, error) bool

	// MaxRetries is the maximum number of times a request will be retried.
	MaxRetries int

	// MinRetryDelay is the minimum duration to wait before retrying a request.
	MinRetryDelay time.Duration

	// MaxRetryDelay is the maximum duration to wait before retrying a request.
	MaxRetryDelay time.Duration
}

RetryPolicy defines a policy for retrying HTTP requests.

func NewRetryPolicy added in v0.6.0

func NewRetryPolicy() *RetryPolicy

NewRetryPolicy returns a new RetryPolicy with sane default values.

The default values are: - IsRetryable: Retries if the status code is 408, 429, 502, 503, or 504. - MaxRetries: 3. - MinRetryDelay: 1 second. - MaxRetryDelay: 30 seconds.

func (*RetryPolicy) Wait added in v0.6.0

func (p *RetryPolicy) Wait(ctx context.Context, attempt int) error

Wait calculates the time to wait before the next retry attempt and blocks until it is time to retry the request or the context is canceled. It incorporates an exponential backoff strategy with jitter to prevent the "thundering herd" problem.

If the context is canceled before the wait is over, Wait returns the context's error.

type RetryRoundTripper added in v0.6.0

type RetryRoundTripper struct {
	// Policy defines the retry behavior.
	Policy *RetryPolicy

	// Logger is used for structured logging. It should be provided if logging
	// of the retry process is required. If nil, logging is disabled.
	Logger *slog.Logger
	// contains filtered or unexported fields
}

RetryRoundTripper is an implementation of http.RoundTripper that retries requests.

func NewRetryRoundTripper added in v0.6.0

func NewRetryRoundTripper(policy *RetryPolicy, logger *slog.Logger) *RetryRoundTripper

NewRetryRoundTripper creates a new instance of RetryRoundTripper with the specified RetryPolicy and Logger.

If policy is nil, NewRetryRoundTripper will use NewRetryPolicy. If logger is nil, NewRetryRoundTripper will not log.

func (*RetryRoundTripper) RoundTrip added in v0.6.0

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

RoundTrip executes an HTTP transaction with retry logic.

type SafeFetcher added in v0.8.0

type SafeFetcher struct {
	// Client is the underlying HTTP client. If nil, ErrNilHTTPClient is
	// returned.
	Client *http.Client

	// Logger is the logger to use when logging events. If nil, no events are
	// logged.
	Logger *slog.Logger

	// Header specifies additional headers to be included in each request.
	Header http.Header

	// TrustedDomain specifies domains from which fetching is permitted.
	TrustedDomain []string

	// MaxContentLength limits the size of the response body. Fetch operations
	// exceeding this limit are aborted to prevent potential resource exhaustion
	// attacks.
	MaxContentLength int64
}

SafeFetcher is an implementation of Fetcher that tries to provide secure-by-default fetching of remote resources.

func (*SafeFetcher) Fetch added in v0.8.0

func (sf *SafeFetcher) Fetch(ctx context.Context, uri string) ([]byte, error)

Fetch fetches the resource at the given URL and returns the response as a byte array.

Directories

Path Synopsis
Package xhttputil provides utility functions for HTTP requests and responses.
Package xhttputil provides utility functions for HTTP requests and responses.
Package xmiddleware contains simple middleware functions.
Package xmiddleware contains simple middleware functions.

Jump to

Keyboard shortcuts

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