Documentation
¶
Overview ¶
Package middleware provides HTTP middleware for ChronosOS.
Index ¶
- func CORS(cfg CORSConfig) func(http.Handler) http.Handler
- func IPKeyFunc(r *http.Request) string
- func RateLimit(cfg RateLimitConfig) func(http.Handler) http.Handler
- func Recovery(logger *log.Logger) func(http.Handler) http.Handler
- func RequestLogger(logger *log.Logger) func(http.Handler) http.Handler
- type CORSConfig
- type Dialect
- type InProcessLimiter
- type Limiter
- type RateLimitConfig
- type Result
- type SQLLimiter
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 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.
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.
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.