middleware

package
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Aug 13, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package middleware provides HTTP middleware for ChronosOS.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CORS

func CORS(cfg CORSConfig) func(http.Handler) http.Handler

CORS returns middleware that handles Cross-Origin Resource Sharing.

func IPKeyFunc

func IPKeyFunc(r *http.Request) string

IPKeyFunc extracts the client IP for rate limiting.

func RateLimit

func RateLimit(cfg RateLimitConfig) func(http.Handler) http.Handler

RateLimit returns middleware that limits requests using a fixed-window counter. The backend is cfg.Limiter, defaulting to a fresh in-process limiter.

func Recovery added in v0.4.0

func Recovery(logger *log.Logger) func(http.Handler) http.Handler

Recovery returns middleware that recovers from panics in downstream handlers, logs the panic (if a logger is provided), and responds with 500 instead of crashing the server. It is intended to be the outermost middleware in the chain.

func RequestLogger added in v0.4.0

func RequestLogger(logger *log.Logger) func(http.Handler) http.Handler

RequestLogger returns middleware that logs each request's method, path, status code, and duration. If logger is nil, logging is skipped.

Types

type CORSConfig

type CORSConfig struct {
	AllowOrigins     []string
	AllowMethods     []string
	AllowHeaders     []string
	ExposeHeaders    []string
	AllowCredentials bool
	MaxAge           int
}

CORSConfig holds CORS middleware configuration.

func DefaultCORSConfig

func DefaultCORSConfig() CORSConfig

DefaultCORSConfig returns a permissive CORS config suitable for development.

type Dialect added in v0.4.0

type Dialect string

Dialect selects SQL syntax for the SQLLimiter's target database.

const (
	// DialectSQLite targets SQLite (dev/test). Writers are serialized, so the
	// read-modify-write in Allow is atomic without an explicit row lock.
	DialectSQLite Dialect = "sqlite"
	// DialectPostgres targets PostgreSQL (production). Allow locks the bucket row
	// FOR UPDATE so concurrent replicas serialize their counter updates.
	DialectPostgres Dialect = "postgres"
)

type InProcessLimiter added in v0.4.0

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

InProcessLimiter is an in-memory fixed-window counter. It is the default backend and is safe for concurrent use, but its counts are per-process: run multiple replicas and each enforces the limit independently. Use SQLLimiter for a shared, cluster-wide limit.

func NewInProcessLimiter added in v0.4.0

func NewInProcessLimiter() *InProcessLimiter

NewInProcessLimiter creates an in-process limiter.

func (*InProcessLimiter) Allow added in v0.4.0

func (l *InProcessLimiter) Allow(_ context.Context, key string, limit int, window time.Duration) (Result, error)

Allow implements Limiter.

type Limiter added in v0.4.0

type Limiter interface {
	// Allow records one hit for key within a fixed window of the given size and
	// reports whether the hit is within limit, the remaining allowance, and the
	// window reset time.
	Allow(ctx context.Context, key string, limit int, window time.Duration) (Result, error)
}

Limiter is the pluggable backend for the rate-limit middleware. The default is an in-process counter (InProcessLimiter); a store-backed Limiter (SQLLimiter) shares counts across replicas so the limit holds cluster-wide.

type RateLimitConfig

type RateLimitConfig struct {
	RequestsPerWindow int
	Window            time.Duration
	KeyFunc           func(r *http.Request) string
	// Limiter selects the backend. A nil Limiter uses a per-middleware in-process
	// limiter (single-replica semantics; the historical default).
	Limiter Limiter
}

RateLimitConfig holds configuration for the rate limiter.

func DefaultRateLimitConfig

func DefaultRateLimitConfig() RateLimitConfig

DefaultRateLimitConfig returns a rate limiter that allows 100 requests per minute keyed by client IP.

type Result added in v0.4.0

type Result struct {
	// Allowed reports whether the current request is within the limit.
	Allowed bool
	// Remaining is the number of further requests permitted in the window (>=0).
	Remaining int
	// ResetAt is when the current fixed window resets.
	ResetAt time.Time
}

Result is the outcome of a single rate-limit check.

type SQLLimiter added in v0.4.0

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

SQLLimiter is a store-backed fixed-window limiter. It shares its counters in a database table so the limit holds across all replicas pointing at the same database, rather than per-process like InProcessLimiter. It implements Limiter.

func NewSQLLimiter added in v0.4.0

func NewSQLLimiter(db *sql.DB, dialect Dialect) *SQLLimiter

NewSQLLimiter constructs a shared limiter over an already-open *sql.DB. Call Migrate before first use. The caller owns the DB lifecycle.

func (*SQLLimiter) Allow added in v0.4.0

func (l *SQLLimiter) Allow(ctx context.Context, key string, limit int, window time.Duration) (Result, error)

Allow implements Limiter with a shared fixed-window counter. The read (locked on Postgres), decide, and write happen in one transaction so concurrent replicas cannot both increment past the boundary.

func (*SQLLimiter) Migrate added in v0.4.0

func (l *SQLLimiter) Migrate(ctx context.Context) error

Migrate creates the rate-limit schema.

Jump to

Keyboard shortcuts

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