Documentation
¶
Overview ¶
Package ratelimit implements optional atomic GCRA quotas with bounded, expiring state.
Design ¶
Callers choose route families, bucket keys and quotas. Each decision accounts for all buckets or none, using transactional store time. Keys are hashed, capacity is bounded, and typed unavailable errors distinguish storage/capacity failures from quota exhaustion. A decision can carry a retry delay.
The limiter does not choose enrollment admission policy or trust forwarded addresses. The reference server configures peer and aggregate buckets and serializes capacity accounting within its limiter namespace. Do not include raw credentials in bucket keys.
References ¶
- https://github.com/deploymenttheory/go-apple-dm/blob/main/docs/research/decisions/0047-enrollment-authentication-and-optional-security-services.md
- RFC 6585 section 4 (429), RFC 9110 section 10.2.3 (Retry-After)
- Fleet server/platform/middleware/ratelimit and server/datastore/redis
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalid = errors.New("ratelimit: invalid quota") ErrCapacity = errors.New("ratelimit: state capacity reached") )
Functions ¶
func Middleware ¶
func Middleware(cfg HTTPConfig, next http.Handler) http.Handler
Middleware enforces configured quotas. Unavailability answers 503 and a denied quota answers 429 with a Retry-After rounded up to whole seconds.
Types ¶
type Bucket ¶
Bucket permits one request per Interval, accumulating at most Burst requests. Key is caller-selected; it is hashed before persistence.
type HTTPConfig ¶
type HTTPConfig struct {
Limiter Checker
Buckets func(*http.Request) []Bucket
Reject func(http.ResponseWriter, *http.Request, int)
}
HTTPConfig selects quotas before parsing an inbound request body. A nil bucket list exempts the route. Reject may encode a protocol-specific error such as ACME.