httpapi

package
v0.56.1 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: AGPL-3.0 Imports: 28 Imported by: 0

Documentation

Overview

Package httpapi serves the public HTTP API, following its contract (api/openapi.yaml): the server and its timeouts, the probes, and the middleware every request goes through (request identifier, access log, panic recovery, security headers). It never serves HTML: every error is an RFC 9457 problem.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewHandler

func NewHandler(opts Options) http.Handler

NewHandler returns the handler of the API: its routes behind the request middleware.

func NewProbeHandler added in v0.53.0

func NewProbeHandler(ready Readiness) http.Handler

NewProbeHandler serves only the liveness and readiness probes, for a process that answers nothing else, such as `admin migrate -listen`.

func NewServer

func NewServer(h http.Handler, logger *slog.Logger) *http.Server

NewServer returns a server for h with every phase of a request bounded; Serve gives it its listener. Its own errors, such as TLS handshake failures, go to logger.

func ProbeAlive added in v0.48.0

func ProbeAlive(ctx context.Context, addr string) error

ProbeAlive asks GET /healthz of the server listening on addr, the "host:port" it was given, and returns nil when it answers 200. An address listening on every interface is probed on 127.0.0.1: the probe runs in the server's container, where no shell or curl is available.

It is a call to this process, not a way out to the network: it neither uses the platform client, which is HTTPS-only, nor a proxy, and it follows no redirect.

func Serve

func Serve(ctx context.Context, srv *http.Server, ln net.Listener) error

Serve serves srv on ln until ctx is done, then shuts it down: it stops accepting connections and lets in-flight requests finish, for at most shutdownTimeout. It returns nil after a clean shutdown.

Types

type Authenticator added in v0.39.0

type Authenticator interface {
	// Authenticate returns the record of the key raw. A malformed,
	// unknown or revoked key is refused with domain.ErrInvalidAPIKey,
	// app.ErrKeyNotFound or app.ErrKeyRevoked; any other error means the
	// key could not be checked.
	Authenticate(ctx context.Context, raw string) (domain.KeyRecord, error)
}

Authenticator tells whether an API key may call the API.

type ChallengeVerifier added in v0.42.0

type ChallengeVerifier interface {
	// Verify reports whether token is valid; a token is valid once. An
	// error means it could not be checked.
	Verify(ctx context.Context, token string) (bool, error)
}

ChallengeVerifier tells whether an anti-abuse token, solved by a visitor of the site, is valid.

type Checker added in v0.35.0

type Checker interface {
	// Check returns the report of in; a source it could not consult is
	// reported unavailable, never an error.
	Check(ctx context.Context, in domain.Input) domain.Report
	// CheckAll returns the report of each input, in the order of ins.
	CheckAll(ctx context.Context, ins []domain.Input) []domain.Report
}

Checker checks an input against the sources.

type ClientSource added in v0.52.0

type ClientSource struct {
	// Trusted are the proxies whose X-Forwarded-For field tells the
	// client's address.
	Trusted []netip.Prefix
	// Header is a field, in canonical form, that the platform in front of
	// the API overwrites with the client's address; it replaces Trusted.
	Header string
}

ClientSource tells where the address of a client is read. The zero value reads the peer address.

type DemoOptions added in v0.42.0

type DemoOptions struct {
	// Origin is the site's origin, the only one CORS allows; empty allows
	// none.
	Origin string
	// Verifier checks the anti-abuse token of each request; nil answers
	// every request with a 503.
	Verifier ChallengeVerifier
	// Limit limits the demo checks of each client address; nil applies
	// config.DefaultRateLimitDemo a minute.
	Limit Limiter
	// GlobalLimit limits the demo checks of every client together; nil
	// applies config.DefaultRateLimitDemoGlobal a minute.
	GlobalLimit Limiter
}

DemoOptions configures POST /v1/demo/check, the demo access of the site's checker.

type KeyRequestOptions added in v0.52.0

type KeyRequestOptions struct {
	// Requests mails the links and redeems them; nil answers both routes
	// with a 503.
	Requests KeyRequester
	// Origin is the site's origin, the only one CORS allows; empty allows
	// none.
	Origin string
	// Verifier checks the anti-abuse token of each link request; nil
	// answers them with a 503.
	Verifier ChallengeVerifier
	// Limit limits the requests of each client address to both routes;
	// nil applies config.DefaultRateLimitKeyRequest a minute.
	Limit Limiter
	// AddressLimit limits the links mailed to each email address; nil
	// applies config.DefaultRateLimitKeyRequestAddress an hour. Over it, a
	// request is answered as any other, and no link is mailed.
	AddressLimit Limiter
}

KeyRequestOptions configures POST /v1/keys/request and POST /v1/keys/redeem, the free keys requested from the site.

type KeyRequester added in v0.52.0

type KeyRequester interface {
	// RequestLink mails a login link to to.
	RequestLink(ctx context.Context, to domain.Email) error
	// Redeem issues a key for the login link of token, or fails with
	// app.ErrLoginLinkInvalid.
	Redeem(ctx context.Context, token string) (domain.APIKey, domain.KeyRecord, error)
}

KeyRequester issues free API keys by login link.

type Limiter added in v0.40.0

type Limiter interface {
	// Allow spends one request of key.
	Allow(key string) ratelimit.Decision
	// Policy returns the policy applied to each key.
	Policy() ratelimit.Policy
	// Refund gives back one request of key, spent by Allow.
	Refund(key string)
}

Limiter limits the requests of each client, known by a key.

type Options

type Options struct {
	// Ready backs /readyz.
	Ready Readiness
	// Check backs /v1/check and /v1/check/batch.
	Check Checker
	// Auth checks the API key of /v1/check and /v1/check/batch; nil
	// answers them all with a 503.
	Auth Authenticator
	// Sources backs /v1/sources.
	Sources SourceLister
	// Logger receives the access log and the recovered panics.
	Logger *slog.Logger
	// NewID makes a request identifier when the client sent no valid one;
	// nil means crypto/rand.Text.
	NewID func() string
	// ProblemBase is the URL of the documentation of the problems, ending
	// with a slash: the type of a problem is its code under it.
	ProblemBase string
	// BatchMaxItems is the most items POST /v1/check/batch accepts, at
	// least one: config.Config.BatchMaxItems.
	BatchMaxItems int
	// KeyLimit limits the requests of each API key to the check routes;
	// nil applies config.DefaultRateLimitKey a minute.
	KeyLimit Limiter
	// IPLimit limits the requests of each client address to the routes
	// needing no key; nil applies config.DefaultRateLimitIP a minute.
	IPLimit Limiter
	// AuthLimit limits the refused API keys of each client address on the
	// check routes: an address it refuses is answered 429 before its key is
	// looked up. nil applies config.DefaultRateLimitAuth a minute.
	AuthLimit RefusalLimiter
	// TrustedProxies are the proxies whose X-Forwarded-For field tells the
	// client's address: config.Config.TrustedProxies.
	TrustedProxies []netip.Prefix
	// ClientIPHeader is the field the platform overwrites with the
	// client's address, replacing TrustedProxies:
	// config.Config.ClientIPHeader.
	ClientIPHeader string
	// Demo configures POST /v1/demo/check.
	Demo DemoOptions
	// Keys configures POST /v1/keys/request and POST /v1/keys/redeem.
	Keys KeyRequestOptions
	// MCP serves the remote MCP endpoint, POST /mcp, behind the API key
	// and the quota of the check routes; nil leaves the route out.
	MCP http.Handler
}

Options configures the handler.

type Readiness

type Readiness interface {
	// Ready reports whether every snapshot is loaded.
	Ready() bool
}

Readiness tells whether the API can answer checks.

type RefusalLimiter added in v0.44.1

type RefusalLimiter interface {
	// Peek returns whether key may be refused once more, spending nothing.
	Peek(key string) ratelimit.Decision
	// Charge spends one refusal of key, even one it does not have.
	Charge(key string)
	// Policy returns the policy applied to each key.
	Policy() ratelimit.Policy
}

RefusalLimiter limits the refusals of each client, known by a key, counted once they happen.

type SourceLister added in v0.37.0

type SourceLister interface {
	// Sources returns every source and the state of its data in service.
	Sources() []app.ListedSource
}

SourceLister lists the sources a check consults.

Jump to

Keyboard shortcuts

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