httpclient

package
v2.4.1 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: GPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package httpclient is the shared HTTP client used by aptcache, aptrepo, apkindex, and pacmandb for short metadata fetches.

It exposes one *http.Client with a global timeout so a stalled mirror cannot hang the build, plus helpers for size-capped body reads and a 2xx status check. Large package downloads use grab directly and don't route through this client.

Index

Constants

View Source
const DefaultMaxBytes int64 = 2 << 30 // 2 GiB

DefaultMaxBytes caps individual HTTP responses to 2 GiB. Package indexes are typically a few MB; .deb / .apk / .rpm files top out around a few hundred MB. The cap prevents OOM from a malicious or buggy mirror serving an unbounded stream.

View Source
const DefaultTimeout = 10 * time.Minute

DefaultTimeout bounds a complete HTTP request (connection, TLS handshake, header read, body read) at 10 minutes. Large .deb downloads over slow links should still fit; stalled mirrors will fail rather than hang.

Variables

View Source
var ErrTooLarge = errors.New("httpclient: response body exceeds size cap")

ErrTooLarge is returned when a response body exceeds the configured cap.

Functions

func AtomicWrite

func AtomicWrite(destPath string, fn func(io.Writer) error) error

AtomicWrite writes to destPath via a temp file + rename so readers never see a partial file. fn receives a writer for the temp file; if fn returns an error the temp file is removed.

func CheckStatus

func CheckStatus(resp *http.Response, fetchURL string) error

CheckStatus returns a descriptive error if resp.StatusCode is not 2xx. The caller still owns resp.Body.Close().

func Client

func Client() *http.Client

Client returns the package-wide *http.Client. Reuse by all aptcache / aptrepo / apkindex / pacmandb / aptinstall callers so timeout and redirect behaviour stays consistent.

func FetchBytes

func FetchBytes(ctx context.Context, url string, maxBytes int64) ([]byte, error)

FetchBytes downloads url and returns the body, capped at maxBytes. A non-positive maxBytes falls back to DefaultMaxBytes. Transient failures are retried per the package retry policy.

func FetchBytesConditional added in v2.1.7

func FetchBytesConditional(
	ctx context.Context,
	url string,
	maxBytes int64,
	ifModSince time.Time,
) (body []byte, notModified bool, err error)

FetchBytesConditional is like FetchBytes but sends If-Modified-Since when ifModSince is non-zero. On HTTP 304 it returns (nil, true, nil) so the caller can use its on-disk copy. On 200 it returns (data, false, nil). On any other error it returns (nil, false, err).

This is the warm-cache primitive that lets dnfcache / aptrepo / aptcache skip re-downloading metadata files whose upstream hasn't moved.

Transient failures (network errors, HTTP 5xx) are retried per the package retry policy.

func FetchToFile

func FetchToFile(ctx context.Context, url, destPath string, maxBytes int64) error

FetchToFile downloads url and writes it atomically to destPath, capped at maxBytes. Content-Length is checked as a cheap preflight when available. A non-positive maxBytes falls back to DefaultMaxBytes. Transient failures are retried per the package retry policy; the atomic temp-file + rename write guarantees a failed attempt leaves no partial file.

func IsRetryable added in v2.3.3

func IsRetryable(err error) bool

IsRetryable reports whether err looks like a transient network failure worth retrying: transport-level errors (DNS, connection reset/refused, timeouts, mid-body EOF) and HTTP 408/429/5xx responses.

Context cancellation, response-size caps, and all other HTTP 4xx codes are NOT retryable: they are definitive answers, not blips.

func LimitedBody

func LimitedBody(resp *http.Response) io.Reader

LimitedBody wraps resp.Body in an io.LimitReader with DefaultMaxBytes. Callers should still defer resp.Body.Close() on the original response.

func LimitedBodyN

func LimitedBodyN(resp *http.Response, maxBytes int64) io.Reader

LimitedBodyN wraps resp.Body in an io.LimitReader with the supplied cap. Use when the caller knows a tighter bound (e.g. control.tar is always small). A non-positive cap falls back to DefaultMaxBytes.

func SetRetryPolicy added in v2.3.3

func SetRetryPolicy(attempts int, baseDelay time.Duration)

SetRetryPolicy overrides the global retry policy. attempts is the total number of tries (minimum 1); baseDelay is the first backoff interval (doubled on each subsequent retry). Intended for tests and callers that need faster failure (e.g. offline detection).

func WithRetry added in v2.3.3

func WithRetry(ctx context.Context, label string, fn func() error) error

WithRetry runs fn until it succeeds, fails with a non-retryable error, or the retry budget is exhausted. label identifies the fetch in retry logs (typically the URL). The last error is returned verbatim so callers can still classify it (errors.As on HTTPStatusError, etc.).

fn must be safe to re-run from scratch: helpers in this package re-issue the full request and rewrite output atomically, so a half-read body from a failed attempt is never observable.

Types

type HTTPStatusError

type HTTPStatusError struct {
	Code int
	URL  string
}

HTTPStatusError is returned by CheckStatus when the response is not 2xx. Callers can use errors.As to extract the status code without parsing the Error() string.

func (*HTTPStatusError) Error

func (e *HTTPStatusError) Error() string

Error returns the error message for HTTPStatusError.

func (*HTTPStatusError) IsClientError

func (e *HTTPStatusError) IsClientError() bool

IsClientError reports whether the status is in the 4xx range. Useful for classifying transient repo failures (auth, rate-limit, not-found) as non-fatal vs systemic failures (network, 5xx, disk full).

Jump to

Keyboard shortcuts

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