httpx

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package httpx is the one outbound HTTP policy this app has. Every request that leaves the box - a router being asked for a new address, a page being crawled, a debrid API being polled - is made by a client built here, so that a proxy, a user agent, a redirect rule or a connection ceiling is one edit instead of fifteen scattered http.Client literals.

Clients come from New rather than from one client the package exports. A package-level client is a dependency nothing declares: a test cannot give one subsystem a stub without every other subsystem silently receiving the same stub, and nothing in the wiring shows which of them share a connection pool. Sharing is still fine here, it just has to be written down at the call site where it can be seen.

This is not the download path. Downloaded bytes are metered through internal/netproxy and must not carry a whole-request deadline: a transfer that runs for an hour is not a stuck request. Clients from here are for the short control-plane calls that happen around a download.

Index

Constants

View Source
const (
	// DefaultTimeout bounds a whole request, body included. Everything this
	// package is pointed at answers in a few kilobytes, so a minute is already a
	// server that has effectively refused.
	DefaultTimeout = 60 * time.Second

	// DefaultDialTimeout bounds reaching the host at all. A dropped packet to a
	// dead LAN address otherwise sits in the kernel's SYN retry schedule for
	// well over a minute, which the user reads as the app being broken.
	DefaultDialTimeout = 15 * time.Second

	// DefaultTLSHandshakeTimeout bounds the handshake separately, because a
	// middlebox that completes the TCP connection and then eats the ClientHello
	// is indistinguishable from a slow server without it.
	DefaultTLSHandshakeTimeout = 10 * time.Second

	// DefaultResponseHeaderTimeout is the one that catches the nastiest case: a
	// host that accepts everything and answers nothing. Without it such a peer
	// is only noticed when the overall Timeout expires, and a caller that opted
	// out of that ceiling would wait forever.
	DefaultResponseHeaderTimeout = 30 * time.Second

	// DefaultMaxRedirects bounds the hop chain. An unbounded chain is the
	// cheapest way to send a client in circles; no legitimate endpoint needs
	// anywhere near this many.
	DefaultMaxRedirects = 10
)

The ceilings. None of these is tuning: each one exists so that a specific way of hanging terminates on its own instead of pinning the goroutine that started it for the life of the process.

View Source
const NoTimeout = time.Duration(-1)

NoTimeout switches the whole-request ceiling off for a caller that streams a response rather than reading a small one. The transport ceilings still apply, so a peer that accepts the connection and then stops talking is still not immortal.

Variables

This section is empty.

Functions

func New

func New(o Options) *http.Client

New builds a client with the whole policy applied: the transport below, the redirect rule, the user agent and the request ceiling.

func NewTransport

func NewTransport(o Options) *http.Transport

NewTransport builds just the transport, for the callers that need to hand one to a library instead of a whole client. It carries the ceilings and the pool; the user agent and the redirect rule live on the client, because a transport never sees a redirect.

func NoProxy

func NoProxy(*http.Request) (*url.URL, error)

NoProxy is the Proxy for a client that must never be sent through one - a loopback call, or a LAN router that an operator's HTTP_PROXY would otherwise swallow.

func UserAgent

func UserAgent() string

UserAgent identifies the app and the build to the far end. A host that decides to refuse us can then say who it is refusing, and a server log line in a bug report names the version it came from.

Types

type Options

type Options struct {
	// UserAgent overrides the app's own identification. Empty means UserAgent();
	// a caller only sets this when a host refuses anything that does not look
	// like a browser.
	UserAgent string

	// Timeout bounds the whole request. Zero means DefaultTimeout, NoTimeout
	// removes the ceiling for a streaming caller.
	Timeout time.Duration

	DialTimeout           time.Duration // zero means DefaultDialTimeout
	TLSHandshakeTimeout   time.Duration // zero means DefaultTLSHandshakeTimeout
	ResponseHeaderTimeout time.Duration // zero means DefaultResponseHeaderTimeout

	// MaxRedirects bounds the hop chain. Zero means DefaultMaxRedirects;
	// negative follows none at all and hands the caller the 3xx itself, which is
	// what a resolver wants when the redirect target *is* the answer.
	MaxRedirects int

	// Proxy resolves the proxy for a request. Nil means the environment, which
	// is what a container operator expects HTTP_PROXY to do; NoProxy pins a
	// client to direct connections.
	Proxy func(*http.Request) (*url.URL, error)

	// Jar keeps cookies for callers that need a session. Nil means cookies are
	// not kept at all, so nothing leaks between two unrelated hosts.
	Jar http.CookieJar
}

Options tunes one client. The zero value is the policy, so a caller with no opinion of its own writes New(Options{}) and gets every ceiling above.

Jump to

Keyboard shortcuts

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