fetch

package
v0.2.47 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: MPL-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package fetch is the chassis's safe public-HTTP fetcher: one GET of a public web resource on a stack's behalf, bounded in every dimension.

It is deliberately narrow. The URL must be http(s) on port 80 or 443 with no credentials; the host is resolved here and every candidate address goes through the chassis egress guard before it is dialed, so the address checked is the address connected (no second lookup for DNS rebinding to exploit), and every redirect hop is checked the same way. There is no proxy, no cookie jar, no authentication, no request body; redirects, header bytes, body bytes and the total time are capped.

It knows nothing about what the body is for: callers (txco://html/ extract) parse it. Errors are *Error values with a stable Code and a message that never names an address.

Index

Constants

View Source
const (
	CodeInvalidURL          = "invalid_url"
	CodeDestinationDenied   = "destination_denied"
	CodeDNSFailed           = "dns_failed"
	CodeConnectionFailed    = "connection_failed"
	CodeTimeout             = "timeout"
	CodeRedirectLimit       = "redirect_limit"
	CodeResponseTooLarge    = "response_too_large"
	CodeUnsupportedType     = "unsupported_content_type"
	CodeUnsupportedEncoding = "unsupported_encoding"
	CodeHTTPError           = "http_error"
)

Error codes. Callers prefix them with their op family (txco_html_…).

View Source
const (
	DefaultMaxBytes       = 3 << 20
	DefaultMaxRedirects   = 3
	DefaultTimeout        = 5 * time.Second
	DefaultMaxHeaderBytes = 64 << 10
)

Defaults for the zero values in Options.

Variables

This section is empty.

Functions

This section is empty.

Types

type DialFunc

type DialFunc func(ctx context.Context, network, address string) (net.Conn, error)

DialFunc connects to an address the guard has already approved: always an "ip:port", never a hostname.

type Error

type Error struct {
	Code        string
	Message     string
	Status      int
	ContentType string
	// Bytes is how many body bytes were read before the failure (for
	// metering a refused oversize body).
	Bytes int64
}

Error is a failed fetch. Message is fixed text written for the rule author: it never names an address, a resolver or a connection detail. Status and ContentType are set when a response arrived.

func CheckURL

func CheckURL(rawURL string) (*url.URL, *Error)

CheckURL parses rawURL and applies the URL policy: http or https only, no userinfo, port 80 or 443 (or none), a host that IDNA-normalizes. It returns the normalized URL. The same check runs on every redirect target. Where the host resolves is decided later, at the dial.

func (*Error) Error

func (e *Error) Error() string

type Fetcher

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

Fetcher is safe for concurrent use. Its connection pool is keyed by scheme and host, so a reused connection is one dialed (and checked) for that same host.

func New

func New(opts Options) (*Fetcher, error)

New builds a Fetcher.

func (*Fetcher) Get

func (f *Fetcher) Get(ctx context.Context, r Request) (*Result, error)

Get fetches one URL. The deadline is the earlier of ctx's and the Fetcher's Timeout.

type Options

type Options struct {
	Guard        egress.Guard
	MaxBytes     int64         // body bytes; one more fails the fetch
	MaxRedirects int           // hops followed; one more fails the fetch
	Timeout      time.Duration // the whole fetch: dial, TLS, headers, body
	// MediaTypes are the Content-Type media types accepted (lowercase,
	// no parameters). Empty accepts any.
	MediaTypes []string
	// Accept is sent as the Accept header.
	Accept string

	// Resolver, Dial and TLSConfig are seams for tests; nil means the
	// system resolver, a guarded TCP dial and the system roots.
	Resolver  Resolver
	Dial      DialFunc
	TLSConfig *tls.Config
}

Options configure a Fetcher. Guard is required.

type Request

type Request struct {
	URL       string
	UserAgent string
}

Request is one fetch.

type Resolver

type Resolver interface {
	LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error)
}

Resolver looks a host up. net.DefaultResolver satisfies it; tests substitute their own answers.

type Result

type Result struct {
	URL         string // as requested (normalized)
	FinalURL    string // after redirects
	Status      int
	ContentType string // the header as sent
	Body        []byte
	Redirects   int
	Bytes       int64 // body bytes read off the wire (compressed, if it was)
}

Result is a successful fetch: a 2xx response of an accepted media type whose body fit.

Jump to

Keyboard shortcuts

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