httpapi

package
v0.62.0 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 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 NewBackupHandler added in v0.57.0

func NewBackupHandler(b BackupRunner, logger *slog.Logger) http.Handler

NewBackupHandler serves the probes and POST /backup, which runs b: 204 once the backup is kept, 409 while another one runs, 500 when it fails. It is the handler of `admin backup -listen`, inside the private network, called by a cron trigger only.

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 BackupRunner added in v0.57.0

type BackupRunner interface {
	Run(ctx context.Context) (string, error)
}

BackupRunner runs one backup and returns the name it is kept under.

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
	// GlobalLimit limits the links mailed to every address together; nil
	// applies config.DefaultRateLimitKeyRequestGlobal an hour. Over it, a
	// request is answered 503 and a warning is logged for the alert.
	GlobalLimit 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
	// AllowN spends n requests of key, or none when it has fewer.
	AllowN(key string, n int) 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