Documentation
¶
Overview ¶
Package middleware provides HTTP middleware for use with go-httpkit and chi.
Client IP ¶
ClientIP resolves the client IP (using trusted proxy CIDRs for X-Real-IP and X-Forwarded-For) and stores it in the request context. CIDRs are parsed once at build time. Use GetClientIPFromContext in handlers to read it. Returns an error if all CIDR entries are invalid; empty or nil slice means no proxy trust.
Logging ¶
Logger logs each request (method, path, redacted query, IP, user-agent, request_id) and after the handler adds status, latency_ms, and bytes. Log level: Info for 2xx, Warn for 4xx, Error for 5xx. Sensitive query params (token, password, etc.) are redacted. If log is nil, the middleware is a no-op. CIDRs are parsed once at build time.
Metrics ¶
Metrics records http_requests_total and http_request_duration_seconds (Prometheus). Pass a PathFromRequest that returns route patterns (e.g. httputil.ChiPathFromRequest), not raw paths, to avoid unbounded label cardinality. reg can be nil for DefaultRegisterer. Optional logger for registration errors.
Recoverer ¶
Recoverer recovers panics, logs the panic and stack trace (if log is non-nil), and responds with 500 JSON. Place it at the top of the middleware chain.
Request ID ¶
RequestID sets or propagates X-Request-ID (from header or new UUID), validates format to prevent response splitting, and stores it in context. Use GetRequestID to read it.
Security headers ¶
SecurityHeaders sets X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, Content-Security-Policy, and optionally Strict-Transport-Security (HSTS). Set addHSTS true for HTTPS. style-src is 'self'.
Timeout ¶
Timeout runs the handler with a context deadline. On timeout it responds with 503 JSON. The full response body is buffered in memory—do not use for streaming or large responses. TimeoutWithLimit adds a max response body size; when exceeded the response is truncated and ErrResponseBodyTooLarge is returned. The handler goroutine may continue after the response; handlers should check context cancellation.
Index ¶
- Variables
- func ClientIP(trustedProxyCIDRs []string) (func(http.Handler) http.Handler, error)
- func GetClientIPFromContext(ctx context.Context) string
- func GetRequestID(ctx context.Context) string
- func Logger(log logger.Logger, trustedProxyCIDRs []string) func(next http.Handler) http.Handler
- func Metrics(reg prometheus.Registerer, pathFromRequest PathFromRequest, ...) func(http.Handler) http.Handler
- func Recoverer(log logger.Logger) func(http.Handler) http.Handler
- func RequestID() func(http.Handler) http.Handler
- func SecurityHeaders(addHSTS bool, opts ...SecurityOption) func(http.Handler) http.Handler
- func Timeout(d time.Duration, log ...logger.Logger) func(http.Handler) http.Handler
- func TimeoutWithLimit(d time.Duration, maxResponseBytes int64, log ...logger.Logger) func(http.Handler) http.Handler
- type PathFromRequest
- type SecurityOption
Constants ¶
This section is empty.
Variables ¶
var ErrResponseBodyTooLarge = errors.New("response body size limit exceeded")
ErrResponseBodyTooLarge is returned by TimeoutWithLimit when the handler writes more than maxResponseBytes.
Functions ¶
func ClientIP ¶ added in v0.1.4
ClientIP returns middleware that resolves the client IP (using trustedProxyCIDRs for X-Real-IP and X-Forwarded-For) and stores it in the request context. CIDRs are parsed once at build time. Returns an error if all entries are invalid; empty or nil slice is valid (no proxy trust).
func GetClientIPFromContext ¶ added in v0.1.4
GetClientIPFromContext returns the client IP stored by the ClientIP middleware, or "" if not set.
func GetRequestID ¶ added in v0.1.3
GetRequestID returns the request ID from the context (set by RequestID middleware), or "" if not set.
func Logger ¶ added in v0.1.4
Logger returns middleware that logs each request (method, path, redacted query, IP, user-agent, request_id) and after the handler adds status, latency_ms, and bytes. Sensitive query params are redacted. If log is nil, the middleware is a no-op.
func Metrics ¶
func Metrics(reg prometheus.Registerer, pathFromRequest PathFromRequest, log ...logger.Logger) func(http.Handler) http.Handler
Metrics returns middleware that records http_requests_total and http_request_duration_seconds. reg can be nil for DefaultRegisterer. pathFromRequest can be nil. Optional logger for registration errors; if nil, errors are silently ignored.
func Recoverer ¶ added in v0.1.3
Recoverer returns middleware that recovers panics, logs the panic and stack trace (if log is non-nil), and responds with 500 JSON. Place at the top of the chain.
func RequestID ¶ added in v0.1.3
RequestID returns middleware that sets X-Request-ID from the request header or generates a new UUID, and stores it in the context. Invalid header values are replaced with a new UUID to prevent response splitting.
func SecurityHeaders ¶ added in v0.1.3
SecurityHeaders returns middleware that sets common security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, Content-Security-Policy). If addHSTS is true, adds Strict-Transport-Security (max-age=2 years, includeSubDomains, preload). Set addHSTS for HTTPS-only services. Options (e.g. WithCSP) override defaults.
Types ¶
type PathFromRequest ¶
PathFromRequest returns the route pattern for the request (e.g. from chi.RouteContext). Used by Metrics for the path label. Must return a stable pattern like "/users/{id}", not the raw path, to avoid unbounded Prometheus cardinality. If the function is nil, path is "/unknown" or "/not-found" for 404.
type SecurityOption ¶ added in v0.2.0
type SecurityOption func(*securityOpts)
SecurityOption configures SecurityHeaders.
func WithCSP ¶ added in v0.2.0
func WithCSP(csp string) SecurityOption
WithCSP sets the Content-Security-Policy header. Empty string leaves CSP unset for this middleware.