Package ratelimit

import "funnyhaha.technology/httpkit/ratelimit"
View the source code

Overview

Package ratelimit limits how many requests a client may make in a sliding window, as middleware, answering requests past the limit with 429 Too Many Requests (RFC 6585, Section 4) and Retry-After.

Requests are counted per key, the client's IP by default, as chi's ClientIPFromRemoteAddr or ClientIPFromXFF middleware resolved it, so it trusts X-Forwarded-For only from the proxies that middleware does:

perIP := ratelimit.New(60, time.Minute).Middleware()
perSubject := ratelimit.New(30, time.Minute).WithKey(bearer.SubjectKey).Middleware()
r.With(perIP, protect, perSubject).Post("/mcp", handler)

Each call to Middleware has its own counters, in memory, so give each endpoint that should count separately its own. Counters aren't shared between instances: with N instances, a client gets up to N times the limit.

Index

Variables

var ErrNoClientIP = errors.New("no client IP: add chi's ClientIPFromRemoteAddr or ClientIPFromXFF middleware")
source

ErrNoClientIP is returned by ClientIP for a request that didn't pass through chi's client IP middleware.

Functions

ClientIP source

func ClientIP(r *http.Request) (string, error)

ClientIP is the default KeyFunc: the client's IP, as chi's client IP middleware resolved it. It returns ErrNoClientIP if that middleware didn't run, rather than counting every client under one key.

Types

Builder source

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

Builder configures the middleware. Its With methods return a modified copy.

New source

func New(limit int, window time.Duration) Builder

New returns a builder for middleware that lets each key make limit requests in any window. It panics if limit or window isn't positive.

(Builder) Middleware source

func (b Builder) Middleware() func(http.Handler) http.Handler

Middleware returns the middleware, with counters of its own.

(Builder) WithKey source

func (b Builder) WithKey(key KeyFunc) Builder

WithKey sets what requests are counted under, in place of the client IP.

KeyFunc source

type KeyFunc func(*http.Request) (string, error)

KeyFunc returns the key a request is counted under. An error answers the request with 500, since it means the middleware is misconfigured.