client

package
v0.28.0 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 43 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrECHConfigUnavailable is returned for ECH=on when authenticated
	// discovery completed but did not provide a configuration usable by this
	// client.
	ErrECHConfigUnavailable = errors.New("ECH is required but no usable ECH configuration was discovered")
)

Functions

func AutomaticCompressionEnabled added in v0.28.0

func AutomaticCompressionEnabled(req *http.Request) bool

AutomaticCompressionEnabled reports whether the request's Accept-Encoding header was generated by the automatic compression policy. It has no body or replay side effects.

func ECHDiscoveryNeedsResolverWarning added in v0.28.0

func ECHDiscoveryNeedsResolverWarning(mode core.ECHMode, target *url.URL, endpoint *resolver.Endpoint, insecure bool) bool

ECHDiscoveryNeedsResolverWarning is used by inspection modes that ignore proxy options. It deliberately does not consult proxy environment settings.

func ECHDiscoveryNeedsWarning added in v0.28.0

func ECHDiscoveryNeedsWarning(mode core.ECHMode, target *url.URL, endpoint *resolver.Endpoint, insecure bool, explicitProxy *url.URL) bool

ECHDiscoveryNeedsWarning reports whether ECH configuration discovery uses a resolver whose transport is not authenticated. Discovery can protect the TLS handshake while still exposing or permitting modification of the hostname's HTTPS records. The caller decides whether the warning is shown (the CLI shows it only at -vvv and above).

func GenerateGREASEECHConfigList added in v0.28.0

func GenerateGREASEECHConfigList() ([]byte, error)

GenerateGREASEECHConfigList returns a syntactically valid, deliberately unusable ECHConfigList. Go's TLS client uses the generated public key to construct the ECH extension, while a server that does not have the matching private key rejects the offer. This lets callers exercise ECH-capable paths without pretending that ECH is available when DNS did not advertise it.

The list is generated for each connection. In particular, neither the config ID nor the public key is reused between requests.

func HTTP3StatusError added in v0.28.0

func HTTP3StatusError(resp *http.Response) error

HTTP3StatusError classifies a final remote HTTP status without changing normal response handling. A status is not a transport error, so callers that need the response body should keep the response and use this helper only for diagnostics or status policy.

func IsLoopback added in v0.19.0

func IsLoopback(host string) bool

IsLoopback returns true if the host is a loopback address. This includes "localhost" and IP addresses in the loopback range (127.0.0.0/8 for IPv4, ::1 for IPv6).

func MarkCredentialHeaders added in v0.28.0

func MarkCredentialHeaders(req *http.Request, names ...string)

MarkCredentialHeaders records credential provenance on req. It is intended for request observers and signing code that generate arbitrary header names.

func ProxyForURL added in v0.28.0

func ProxyForURL(explicit, target *url.URL) (*url.URL, error)

ProxyForURL selects the proxy for target. An explicit proxy always wins and is not affected by NO_PROXY. A nil explicit proxy enables environment selection.

func ProxyFunc added in v0.28.0

func ProxyFunc(explicit *url.URL) func(*http.Request) (*url.URL, error)

ProxyFunc returns a net/http-compatible selector shared by all HTTP-based transports, including WebSocket, gRPC, DoH, and update requests.

func RedirectCrossedOrigin added in v0.28.0

func RedirectCrossedOrigin(req *http.Request) bool

RedirectCrossedOrigin reports whether a request followed a redirect chain that crossed an origin boundary. The value remains true if a later hop returns to the original origin, preventing credentials from being restored.

func SameOrigin added in v0.28.0

func SameOrigin(a, b *url.URL) bool

SameOrigin reports whether two URLs have the same HTTP origin. URL.Host is not compared directly because an omitted default port and its explicit form represent the same origin.

func URLPort added in v0.28.0

func URLPort(target *url.URL) (int, bool)

func UncompressedRequest added in v0.28.0

func UncompressedRequest(req *http.Request) (*http.Request, bool)

UncompressedRequest returns a replay of req with automatic response compression disabled. It only succeeds when the request's Accept-Encoding header was generated by the automatic compression policy. Explicit headers are never silently changed.

func WireContentLength added in v0.28.0

func WireContentLength(resp *http.Response) int64

WireContentLength returns the encoded response length when the server supplied one. It remains available after a streaming decoder changes http.Response.ContentLength to -1.

func WithConnectBudget added in v0.28.0

func WithConnectBudget(ctx context.Context, budget core.Budget) context.Context

WithConnectBudget associates one absolute connection-establishment budget with a request. Dialers use it for DNS, proxy setup, TCP, TLS, and QUIC so a retry cannot restart the connection timeout.

func WithCredentialHeaders added in v0.28.0

func WithCredentialHeaders(ctx context.Context, names ...string) context.Context

WithCredentialHeaders records headers generated by an authentication or signing hook. The provenance survives redirect request cloning and causes the named headers to be removed at a cross-origin boundary, even when a custom name does not match the built-in classifier.

func WithDialTimingSelector added in v0.28.0

func WithDialTimingSelector(ctx context.Context, selector DialTimingSelector) context.Context

WithDialTimingSelector associates a selected-connection sink with ctx.

func WithRedirectCallback added in v0.15.0

func WithRedirectCallback(ctx context.Context, cb RedirectCallback) context.Context

WithRedirectCallback returns a context with a redirect callback.

func WithRedirectValidator added in v0.28.0

func WithRedirectValidator(ctx context.Context, validator RedirectValidator) context.Context

WithRedirectValidator returns a context that validates each redirect before the client sends the redirected request.

func WithRequestObserver added in v0.28.0

func WithRequestObserver(ctx context.Context, observer RequestObserver) context.Context

WithRequestObserver attaches an observer to a request context. The transport invokes it for the initial request and redirect requests. When an observer is already present, the new observer runs first. This lets request signing happen before observers record the effective request.

func WithoutDialTimingSelector added in v0.28.0

func WithoutDialTimingSelector(ctx context.Context) context.Context

WithoutDialTimingSelector removes a selector from ctx while an outer race is still choosing among complete connection attempts.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client represents a wrapped HTTP client.

func NewClient

func NewClient(cfg ClientConfig) *Client

NewClient returns an initialized Client given the provided configuration.

func (*Client) ApplyJarCookies added in v0.28.0

func (c *Client) ApplyJarCookies(req *http.Request) *http.Request

ApplyJarCookies adds the same cookie-jar values that net/http will add before sending a request. It is intended for dry-run metadata, which is rendered before Client.Do would normally apply the jar. The caller must not call it more than once for the same request.

func (*Client) Close added in v0.20.0

func (c *Client) Close() error

Close closes the underlying transport, releasing any resources.

func (*Client) Do

func (c *Client) Do(req *http.Request) (*http.Response, error)

func (*Client) HTTPClient added in v0.19.0

func (c *Client) HTTPClient() *http.Client

HTTPClient returns the underlying *http.Client. Its Transport may be a request-scoped proxy wrapper rather than a concrete *http.Transport.

func (*Client) LookupIPAddr added in v0.28.0

func (c *Client) LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, error)

LookupIPAddr resolves host using the resolver configured for this client. It keeps policy checks consistent with the addresses used by its transport.

func (*Client) NewRequest

func (c *Client) NewRequest(ctx context.Context, cfg RequestConfig) (*http.Request, error)

NewRequest returns an *http.Request given the provided configuration.

func (*Client) ResolverProvenance added in v0.28.0

func (c *Client) ResolverProvenance() string

ResolverProvenance identifies the resolver policy used by this client. It is safe for diagnostics because resolver endpoints redact credentials during parsing and display construction.

func (*Client) SetJar added in v0.17.0

func (c *Client) SetJar(jar http.CookieJar)

SetJar sets the cookie jar on the HTTP client.

func (*Client) UsesProxy added in v0.28.0

func (c *Client) UsesProxy(target *url.URL) bool

UsesProxy reports whether requests for target use a configured proxy. Callers that inspect the peer connection must account for the proxy because the peer is then the proxy, not the requested origin.

func (*Client) ValidateTransport added in v0.28.0

func (c *Client) ValidateTransport(req *http.Request) error

Do performs the provided http Request, returning the response. ValidateTransport checks configuration that must fail before a handshake. WebSocket uses HTTPClient directly, so it calls this method before dialing.

type ClientConfig

type ClientConfig struct {
	CACerts        []*x509.Certificate
	ClientCert     *tls.Certificate
	ConnectTimeout time.Duration
	// ResolverEndpoint is the validated endpoint from CLI/config parsing.
	// DNSServer remains for compatibility with direct internal callers/tests.
	ResolverEndpoint *resolver.Endpoint
	DNSServer        *url.URL
	// SystemLookupIPAddr is a test hook for deterministic proxy destination
	// resolution. Production callers leave it nil.
	SystemLookupIPAddr func(context.Context, string) ([]net.IPAddr, error)
	H2C                bool
	HTTP               core.HTTPVersion
	Insecure           bool
	Proxy              *url.URL
	Redirects          *int
	TLSMax             uint16
	TLSMin             uint16
	UnixSocket         string
	ECH                core.ECHMode
}

ClientConfig represents the optional configuration parameters for a Client.

type DialMode added in v0.28.0

type DialMode string

DialMode describes the first-hop strategy used by a DialRequest. A proxy mode does not implement a proxy protocol by itself. The Attempt callback does that work after the dialer has selected an address. Keeping that protocol detail outside the race coordinator lets HTTP, SOCKS, Unix-socket, and test transports share one lifecycle and timeout policy.

const (
	DialDirect     DialMode = "direct"
	DialHTTPProxy  DialMode = "http-proxy"
	DialHTTPSProxy DialMode = "https-proxy"
	DialSOCKS5     DialMode = "socks5"
	DialSOCKS5H    DialMode = "socks5h"
	DialUnix       DialMode = "unix"
)

type DialRequest added in v0.28.0

type DialRequest struct {
	Network    string
	Address    string
	Host       string
	Port       string
	OriginHost string
	Mode       DialMode

	Resolver      *resolver.Resolver
	ResolverScope string
	Candidates    []net.IPAddr
	UnixSocket    string
	Budget        core.Budget
	Timeout       time.Duration

	TLSConfig *tls.Config
	ALPN      []string
	Attempt   func(context.Context, string, net.IPAddr) (net.Conn, error)
	// AttemptWithInfo associates protocol negotiation metadata with the
	// connection that wins the address race.
	AttemptWithInfo func(context.Context, string, net.IPAddr) (net.Conn, any, error)
	Recorder        DialTimingRecorder
	Selector        DialTimingSelector
}

DialRequest describes one connection setup operation. Host and Port identify the effective service target. OriginHost is used for TLS SNI only when the TLS config does not already provide ServerName; this preserves origin authority when an HTTPS/SVCB service target differs from the origin host.

type DialResult added in v0.28.0

type DialResult struct {
	Conn          net.Conn
	RemoteIP      net.IP
	ResolvedAddrs []net.IPAddr
	Resolver      string
	Timing        DialTiming
	TLSState      *tls.ConnectionState
	// ECHInfo is populated by ECH-aware attempts and is intentionally typed as
	// any here so the generic dialer does not depend on the ECH policy model.
	ECHInfo          any
	ResolverScope    string
	EffectiveAddress string
}

DialResult is the successful connection and the metadata selected during setup. The caller owns Conn and must close it.

func DialResolverWithECH added in v0.28.0

func DialResolverWithECH(ctx context.Context, dialer *ResolverDialer, request DialRequest, cfg *tls.Config, mode core.ECHMode, real bool) (DialResult, error)

DialResolverWithECH performs a resolver-aware TLS connection and returns ECH outcome metadata for inspection callers. real must be true when cfg was built from an advertised ECHConfigList and false for GREASE.

type DialTiming added in v0.28.0

type DialTiming struct {
	ResolutionStart time.Time
	ResolutionDone  time.Time
	ConnectStart    time.Time
	ConnectDone     time.Time
	TLSStart        time.Time
	TLSDone         time.Time
	DNSDuration     time.Duration
	ConnectDuration time.Duration
	TLSDuration     time.Duration
}

DialTiming contains connection-establishment measurements. A zero field means that the phase did not run. The value describes the winning attempt; failed and cancelled race candidates are not included in the result.

type DialTimingRecorder added in v0.28.0

type DialTimingRecorder interface {
	ResolutionStarted(host string)
	ResolutionDone(host string, addrs []net.IPAddr, err error)
	ConnectionStarted(network, address string)
	ConnectionDone(network, address string, err error)
	TLSStarted()
	TLSDone(state tls.ConnectionState, err error)
}

DialTimingRecorder is an optional low-overhead event sink. Implementations must not retain mutable address slices supplied to ResolutionDone.

type DialTimingSelector added in v0.28.0

type DialTimingSelector interface {
	ConnectionSelected(DialTiming)
}

DialTimingSelector receives the timing for the connection selected by an address race. It is separate from DialTimingRecorder because trace hooks also report attempts that lose the race.

type ECHConnectionConfig added in v0.28.0

type ECHConnectionConfig struct {
	// contains filtered or unexported fields
}

func DiscoverECHForConnection added in v0.28.0

func DiscoverECHForConnection(ctx context.Context, res *resolver.Resolver, host, port string, base *tls.Config, mode core.ECHMode, version core.HTTPVersion) (*ECHConnectionConfig, error)

DiscoverECHForConnection performs host-scoped HTTPS/SVCB discovery and prepares the TLS configuration for an inspection or application dial.

func (*ECHConnectionConfig) Addresses added in v0.28.0

func (c *ECHConnectionConfig) Addresses() []net.IPAddr

Addresses returns the validated service addresses, if discovery supplied them. The returned slice is independent of the connection configuration.

func (*ECHConnectionConfig) Offered added in v0.28.0

func (c *ECHConnectionConfig) Offered() bool

Offered reports whether this connection will send an ECH extension.

func (*ECHConnectionConfig) OuterServerName added in v0.28.0

func (c *ECHConnectionConfig) OuterServerName() string

OuterServerName returns the public SNI used for the outer ClientHello.

func (*ECHConnectionConfig) Real added in v0.28.0

func (c *ECHConnectionConfig) Real() bool

Real reports whether the TLS configuration came from an advertised ECH configuration rather than generated GREASE.

func (*ECHConnectionConfig) TLSConfig added in v0.28.0

func (c *ECHConnectionConfig) TLSConfig() *tls.Config

TLSConfig returns the cloned, connection-specific TLS configuration.

func (*ECHConnectionConfig) Target added in v0.28.0

func (c *ECHConnectionConfig) Target() (string, string)

Target returns the effective SVCB service target and port.

type ECHHandshakeInfo added in v0.28.0

type ECHHandshakeInfo struct {
	Offered         bool
	Real            bool
	Accepted        bool
	Rejected        bool
	Fallback        bool
	OuterServerName string
	// TCPDuration and TLSDuration cover all attempts, including ECH retry
	// connections. They let inspection separate the raw connect from the
	// TLS handshake when ECH is performed inside an address-race callback.
	TCPDuration time.Duration
	TLSDuration time.Duration
}

ECHHandshakeInfo describes the ECH offer and the final outcome of a TLS connection. It is used by TLS inspection; normal HTTP callers do not need to interpret it.

type HTTP3Error added in v0.28.0

type HTTP3Error struct {
	Kind HTTP3ErrorKind
	Err  error
}

HTTP3Error preserves the underlying error while identifying the HTTP/3 lifecycle stage. In particular, timeout errors remain discoverable through errors.Is/errors.As.

func (*HTTP3Error) Error added in v0.28.0

func (e *HTTP3Error) Error() string

func (*HTTP3Error) Unwrap added in v0.28.0

func (e *HTTP3Error) Unwrap() error

type HTTP3ErrorKind added in v0.28.0

type HTTP3ErrorKind uint8

HTTP3ErrorKind identifies the stage at which an HTTP/3 exchange failed. The kind is deliberately small and stable so callers can present useful diagnostics without parsing quic-go error strings.

const (
	HTTP3HandshakeFailure HTTP3ErrorKind = iota + 1
	HTTP3SettingsFailure
	HTTP3StreamFailure
	HTTP3BodyTimeout
	HTTP3RemoteStatusFailure
)

func (HTTP3ErrorKind) String added in v0.28.0

func (kind HTTP3ErrorKind) String() string

type HTTP3RequestBodyError added in v0.28.0

type HTTP3RequestBodyError struct {
	Err error
}

HTTP3RequestBodyError marks a failure in the upload reader. It is separate from a transport failure because automatic HTTP/3 must not evict a healthy candidate when the caller's file or stream failed.

func (*HTTP3RequestBodyError) Error added in v0.28.0

func (e *HTTP3RequestBodyError) Error() string

func (*HTTP3RequestBodyError) Unwrap added in v0.28.0

func (e *HTTP3RequestBodyError) Unwrap() error

type ProxyDecision added in v0.28.0

type ProxyDecision struct {
	URL          *url.URL
	Source       string
	Bypassed     bool
	BypassReason string
}

ProxyDecision describes the proxy selected for one request. URL is nil for a direct request. The source and bypass fields are intended for diagnostics; they never contain proxy credentials.

func SelectProxy added in v0.28.0

func SelectProxy(explicit, target *url.URL) (ProxyDecision, error)

SelectProxy applies the fetch proxy precedence rules to target.

The selector reads the environment for each call. This avoids the process global caching used by net/http.ProxyFromEnvironment and makes redirects, tests, and long-running callers use the same current policy.

type RedirectCallback added in v0.15.0

type RedirectCallback func(hop RedirectHop)

RedirectCallback is called when a redirect occurs.

type RedirectHop added in v0.15.0

type RedirectHop struct {
	Request     *http.Request  // The request that triggered the redirect
	Response    *http.Response // The redirect response (e.g., 302)
	NextRequest *http.Request  // The new request about to be made
}

RedirectHop represents a single redirect in the chain.

type RedirectValidator added in v0.28.0

type RedirectValidator func(hop RedirectHop) error

RedirectValidator can reject a redirect before the next request is sent. It is useful for narrow clients, such as the updater, that need a stricter redirect policy than ordinary fetch requests.

type RequestConfig

type RequestConfig struct {
	Article     bool
	Basic       *core.KeyVal[string]
	Bearer      string
	Compression core.CompressionMode
	ContentType string
	Data        io.Reader
	Form        []core.KeyVal[string]
	Headers     []core.KeyVal[string]
	HTTP        core.HTTPVersion
	Method      string
	Multipart   *multipart.Multipart
	NoEncode    bool // Compatibility override for --no-encode.
	QueryParams []core.KeyVal[string]
	Range       []string
	URL         *url.URL
}

RequestConfig represents the configuration for creating an HTTP request.

type RequestObserver added in v0.28.0

type RequestObserver func(req *http.Request)

RequestObserver is called immediately before a request is sent and for every request created by a redirect. Observers may replace the request body and mutate the request context.

type ResolverDialer added in v0.28.0

type ResolverDialer struct {
	Resolver       *resolver.Resolver
	ConnectTimeout time.Duration
	BaseDial       func(context.Context, string, string) (net.Conn, error)
}

ResolverDialer is the shared resolver-aware Happy Eyeballs coordinator. It resolves a target once, preserves the resolver's preferred family, races bounded candidates, and applies one absolute connection budget to DNS, proxy callbacks, TCP, and optional TLS.

func NewResolverDialer added in v0.28.0

func NewResolverDialer(res *resolver.Resolver, connectTimeout time.Duration) *ResolverDialer

NewResolverDialer constructs the dialer used by application transports.

func (*ResolverDialer) Dial added in v0.28.0

Dial performs one resolver-aware connection setup operation.

func (*ResolverDialer) DialContext added in v0.28.0

func (d *ResolverDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error)

DialContext is the net/http-compatible direct TCP entry point. Use Dial for optional TLS, timing metadata, proxy strategies, or Unix sockets.

type TLSDialConfig added in v0.19.0

type TLSDialConfig struct {
	CACerts    []*x509.Certificate
	ClientCert *tls.Certificate
	Insecure   bool
	TLSMax     uint16
	TLSMin     uint16
}

TLSDialConfig holds the common configuration for building a TLS config and dial function.

func (*TLSDialConfig) BuildTLSConfig added in v0.19.0

func (c *TLSDialConfig) BuildTLSConfig() *tls.Config

BuildTLSConfig returns a *tls.Config from the common configuration fields.

Jump to

Keyboard shortcuts

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