middleware

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package middleware provides built-in OniWorks middleware.

Index

Constants

This section is empty.

Variables

View Source
var DefaultCORSConfig = CORSConfig{
	AllowOrigins: []string{"*"},
	AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"},
	AllowHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-Requested-With"},
	MaxAge:       12 * time.Hour,
}

DefaultCORSConfig is a permissive default suitable for development.

Functions

func Auth

func Auth(guard *auth.Guard, sessions *session.Manager) onihttp.MiddlewareFunc

Auth returns a session-based authentication middleware. Unauthenticated requests receive a 401 JSON response (or redirect for HTML clients).

When SessionMiddleware already loaded a session for this request, Auth reuses it (no double Start, and SessionMiddleware remains responsible for saving it). When Auth starts the session itself, it also saves it after the handler runs so session mutations are not lost.

func AuthJWT

func AuthJWT(guard *auth.Guard) onihttp.MiddlewareFunc

AuthJWT returns a JWT bearer token authentication middleware. The token must be provided as "Authorization: Bearer <token>".

func CORS

func CORS(cfg ...CORSConfig) onihttp.MiddlewareFunc

CORS returns a middleware that adds Cross-Origin Resource Sharing headers.

func CSRF

func CSRF() onihttp.MiddlewareFunc

CSRF returns a CSRF protection middleware. It validates the token on mutating requests (POST/PUT/PATCH/DELETE). GET, HEAD, and OPTIONS always pass through. The token must be sent via X-CSRF-Token header (AJAX) or _token form field (HTML forms).

func CSRFToken

func CSRFToken(c *onihttp.Context) string

CSRFToken returns the CSRF token for the current session, generating one if needed. Embed this in HTML templates: <input type="hidden" name="_token" value="{{ .CSRFToken }}">

func Compress

func Compress(level ...int) onihttp.MiddlewareFunc

Compress returns gzip compression middleware. It only compresses responses when the client advertises "gzip" in Accept-Encoding AND the response is a compressible type (text/JSON/XML/JS) with content — already-encoded bodies, images, and empty 204/304 responses are passed through untouched. When the handler never sets a Content-Type, the first written chunk is sniffed with http.DetectContentType and the header is set from the UNCOMPRESSED bytes (otherwise net/http would sniff the gzipped bytes and mislabel the response as application/x-gzip). The optional level (gzip.BestSpeed … gzip.BestCompression) is honored.

func CurrentSession

func CurrentSession(c *onihttp.Context) *session.Session

CurrentSession retrieves the active session from the context store.

func CurrentUser

func CurrentUser(c *onihttp.Context) auth.User

CurrentUser retrieves the authenticated user from the context store. Returns nil if not authenticated.

func Logger

func Logger(opts ...LoggerConfig) onihttp.MiddlewareFunc

Logger returns a middleware that logs every request using structured slog output. It records method, path, status, latency, bytes written, and client IP.

func RateLimit

func RateLimit(max int, window time.Duration, opts ...RateLimitConfig) onihttp.MiddlewareFunc

RateLimit returns a sliding-window rate limiter middleware.

middleware.RateLimit(100, time.Minute)  // 100 req/min per IP

func Recovery

func Recovery(opts ...RecoveryConfig) onihttp.MiddlewareFunc

Recovery returns a middleware that recovers from panics and returns a 500 response. The panic value and stack trace are logged via slog.

func SessionMiddleware

func SessionMiddleware(sessions *session.Manager) onihttp.MiddlewareFunc

SessionMiddleware loads the session for every request (without enforcing auth). Use this globally; use Auth/AuthJWT on protected routes only.

func Timeout

Timeout returns a middleware that cancels the request context after d and, if the handler has not finished by then, responds 503 Service Unavailable.

It follows http.TimeoutHandler semantics: the handler writes into an in-memory buffer rather than straight to the socket. If the handler finishes in time, the buffered response is replayed to the real writer; if it times out, a 503 is written and the handler's continued writes are discarded. The handler goroutine gets its own Response wrapping the buffer, so it never shares mutable state with the timeout path — and outer middleware (Logger, Recovery) observe the true final status on c.Response. A panic in the handler is re-raised on the request goroutine so an outer Recovery can catch it (a recover cannot cross goroutines). As with the standard library, a handler that ignores context cancellation may keep running in the background, and response streaming/Hijack are not supported under Timeout.

Types

type CORSConfig

type CORSConfig struct {
	// AllowOrigins is a list of origins that are allowed (e.g. "https://example.com").
	// Use ["*"] to allow all origins (not recommended for credentialed requests).
	AllowOrigins []string
	// AllowMethods specifies which HTTP methods are allowed.
	AllowMethods []string
	// AllowHeaders specifies which request headers are allowed.
	AllowHeaders []string
	// ExposeHeaders lists headers the browser is allowed to access.
	ExposeHeaders []string
	// AllowCredentials indicates that the request can include user credentials.
	AllowCredentials bool
	// MaxAge is how long the preflight result can be cached (0 = browser default).
	MaxAge time.Duration
}

CORSConfig configures the CORS middleware.

type LoggerConfig

type LoggerConfig struct {
	// Logger is the slog.Logger to write to. Defaults to slog.Default().
	Logger *slog.Logger
	// SkipPaths is a list of request paths to skip logging for (e.g. "/health").
	SkipPaths []string
}

LoggerConfig configures the Logger middleware.

type RateLimitConfig

type RateLimitConfig struct {
	// Max is the maximum number of requests allowed in the window.
	Max int
	// Window is the sliding window duration.
	Window time.Duration
	// KeyFunc extracts the rate-limit key from the request (default: client IP).
	KeyFunc func(c *onihttp.Context) string
	// OnExceeded is called when the limit is exceeded (default: 429 JSON response).
	OnExceeded func(c *onihttp.Context) error
	// Context bounds the lifetime of the limiter's background cleanup
	// goroutine: cancel it (e.g. on server shutdown) and the goroutine exits.
	// Defaults to context.Background(), i.e. the goroutine lives for the
	// process lifetime — appropriate for a server-wide limiter.
	Context context.Context
}

RateLimitConfig configures the rate limiter.

type RecoveryConfig

type RecoveryConfig struct {
	// Logger is used to log recovered panics. Defaults to slog.Default().
	Logger *slog.Logger
	// Handler is called after recovery; if nil the default 500 JSON response is sent.
	Handler func(c *onihttp.Context, recovered any, stack []byte) error
}

RecoveryConfig configures the Recovery middleware.

Jump to

Keyboard shortcuts

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