http

package
v0.0.0-...-41a30da Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2026 License: MIT Imports: 56 Imported by: 0

Documentation

Overview

Package middleware provides chaos engineering primitives for Astra.

Chaos middleware injects configurable faults (latency spikes, random errors, connection resets) to test distributed system resilience under adversarial conditions. It must ONLY be enabled in non-production environments.

Package http provides the web layer for the Astra framework, integrating routing, middleware, and a high-performance request context.

The package is built on top of go-chi but provides a much richer Context object that simplifies binding, validation, and response handling.

Key Components:

  • Router: A fluent routing engine with support for groups and versioning.
  • Context: The central piece of a request's lifecycle. Wraps http.Request/Response.
  • Middleware: A suite of built-in middleware for security, logging, recovery, and more.
  • SSR: Components for Server-Side Rendering, including flash messages and asset helpers.

Example:

router.Get("/users/{id}", func(c *Context) error {
    return c.JSON(map[string]string{"id": c.Param("id")})
})

Index

Constants

View Source
const (
	ErrCodeValidation   = "VALIDATION_ERROR"
	ErrCodeNotFound     = "NOT_FOUND"
	ErrCodeUnauthorized = "UNAUTHORIZED"
	ErrCodeForbidden    = "FORBIDDEN"
	ErrCodeConflict     = "CONFLICT"
	ErrCodeRateLimit    = "RATE_LIMIT_EXCEEDED"
	ErrCodeInternal     = "INTERNAL_ERROR"
	ErrCodeBadRequest   = "BAD_REQUEST"
)
View Source
const (
	ContextLocaleKey = "astra_locale"
	CookieLocaleKey  = "astra_locale"
)
View Source
const AuthUserKey = "astra_auth_user"
View Source
const SessionContextKey = "astra.session"

SessionContextKey is the key used to store the session in the Astra context.

Variables

View Source
var RateLimitScript = goredis.NewScript(`
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local member = ARGV[4]
local minScore = now - window

redis.call("ZREMRANGEBYSCORE", key, "-inf", minScore)

local count = redis.call("ZCARD", key)
local allowed = 0

if count < limit then
	redis.call("ZADD", key, now, member)
	redis.call("PEXPIRE", key, window)
	count = count + 1
	allowed = 1
end

local oldest = redis.call("ZRANGE", key, 0, 0, "WITHSCORES")
local resetAt = now + window
if oldest[2] ~= nil then
	resetAt = tonumber(oldest[2]) + window
end

local remaining = limit - count
if remaining < 0 then
	remaining = 0
end

return {allowed, remaining, resetAt}
`)

RateLimitScript is the Lua script used for sliding window rate limiting in Redis.

View Source
var TokenBucketScript = goredis.NewScript(`
local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])

local state = redis.call("HMGET", key, "tokens", "last_refill")
local tokens = tonumber(state[1])
local last_refill = tonumber(state[2])

if not tokens then
    tokens = capacity
    last_refill = now
else
    local elapsed = math.max(0, now - last_refill)
    local refill = elapsed * (capacity / window)
    tokens = math.min(capacity, tokens + refill)
    last_refill = now
end

local allowed = 0
if tokens >= requested then
    tokens = tokens - requested
    allowed = 1
end

redis.call("HMSET", key, "tokens", tokens, "last_refill", last_refill)
redis.call("PEXPIRE", key, window)

local resetAt = now + window
if tokens < capacity then
	local time_to_fill = ((capacity - tokens) / (capacity / window))
	resetAt = now + math.ceil(time_to_fill)
end

return {allowed, math.floor(tokens), resetAt}
`)

TokenBucketScript is the Lua script used for token bucket rate limiting in Redis.

Functions

func ByAPIKey

func ByAPIKey(r *http.Request) string

ByAPIKey buckets requests by API key header.

func ByIP

func ByIP(r *http.Request) string

ByIP buckets requests by client IP address.

func ByUser

func ByUser(r *http.Request) string

ByUser buckets requests by authenticated user ID.

func Chain

func Chain(mws []MiddlewareFunc, h http.Handler) http.Handler

Chain stacks standard middleware around an http.Handler.

func GetClientIP

func GetClientIP(r *http.Request, trustedProxies []netip.Prefix) string

GetClientIP returns the client's real IP address, respecting trusted proxies. It uses a secure backwards-walking algorithm on the X-Forwarded-For header.

func IsTrustedProxy

func IsTrustedProxy(addr netip.Addr, trusted []netip.Prefix) bool

IsTrustedProxy checks if an IP address matches any of the trusted proxy prefixes.

func ParseRateLimitResult

func ParseRateLimitResult(result []interface{}) (bool, int64, int64, error)

ParseRateLimitResult converts the Redis Lua script result into typed values.

func PrometheusHandler

func PrometheusHandler() http.Handler

PrometheusHandler returns an Astra HandlerFunc that serves Prometheus metrics.

Usage:

router.Handle(http.MethodGet, "/metrics", http.PrometheusHandler())

func RateLimitCheck

func RateLimitCheck(ctx context.Context, client goredis.UniversalClient, key string, limit int, window time.Duration, algo RateLimitAlgorithm) (bool, int64, int64, error)

RateLimitCheck performs a manual rate limit check against Redis.

func RegisterDashboardRoutes

func RegisterDashboardRoutes(r *Router, env *config.Config, dash *telemetry.Dashboard, mail *platformtelemetry.MailSandbox, queue *telemetry.QueueMonitor)

RegisterDashboardRoutes registers the dashboard API and UI routes.

func WithCSRFCookieHTTPOnly

func WithCSRFCookieHTTPOnly(httpOnly bool) func(*CSRFConfig)

WithCSRFCookieHTTPOnly controls whether the CSRF cookie should be HttpOnly

func WithCSRFCookieName

func WithCSRFCookieName(name string) func(*CSRFConfig)

WithCSRFCookieName sets a custom CSRF cookie name

func WithCSRFExemptMethods

func WithCSRFExemptMethods(methods ...string) func(*CSRFConfig)

WithCSRFExemptMethods sets HTTP methods that should be exempt from CSRF protection

func WithCSRFExemptPaths

func WithCSRFExemptPaths(paths ...string) func(*CSRFConfig)

WithCSRFExemptPaths sets paths that should be exempt from CSRF protection

func WithCSRFHeaderName

func WithCSRFHeaderName(name string) func(*CSRFConfig)

WithCSRFHeaderName sets a custom CSRF header name

func WithCSRFMode

func WithCSRFMode(mode CSRFMode) func(*CSRFConfig)

WithCSRFMode sets the CSRF protection mode (auto, spa, api)

func WithCSRFSPAHeaderName

func WithCSRFSPAHeaderName(name string) func(*CSRFConfig)

WithCSRFSPAHeaderName sets the SPA detection header name

func WithCSRFSameSite

func WithCSRFSameSite(policy http.SameSite) func(*CSRFConfig)

WithCSRFSameSite sets the SameSite policy for CSRF cookies

func WithCSRFSecureCookie

func WithCSRFSecureCookie(secure bool) func(*CSRFConfig)

WithCSRFSecureCookie controls whether the CSRF cookie should be secure

func WithCSRFTokenExpiry

func WithCSRFTokenExpiry(expiry time.Duration) func(*CSRFConfig)

WithCSRFTokenExpiry sets the expiration time for CSRF tokens

Types

type APIError

type APIError struct {
	Error APIErrorBody `json:"error"`
}

APIError is the standard JSON envelope for error responses.

type APIErrorBody

type APIErrorBody struct {
	Code    string         `json:"code"`
	Message string         `json:"message"`
	Details map[string]any `json:"details,omitempty"`
}

APIErrorBody holds the structured error fields.

type APIKeyMiddleware

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

func NewAPIKeyMiddleware

func NewAPIKeyMiddleware(m *keys.Manager) *APIKeyMiddleware

func (*APIKeyMiddleware) RequireAPIKey

func (m *APIKeyMiddleware) RequireAPIKey(scope string) MiddlewareFunc

type APIResponse

type APIResponse struct {
	Data any            `json:"data"`
	Meta map[string]any `json:"meta,omitempty"`
}

APIResponse is the standard JSON envelope for successful responses.

type CSRFConfig

type CSRFConfig struct {
	Mode           CSRFMode
	CookieName     string
	HeaderName     string
	SPAHeaderName  string
	SecureCookie   bool
	CookieHTTPOnly bool // If true, the JS cannot read the cookie (recommended for most, except SPA reflection)
	SameSitePolicy http.SameSite
	ExemptPaths    []string
	ExemptMethods  []string
	TokenExpiry    time.Duration
	IsProd         bool // Explicit dependency
}

func DefaultCSRFConfig

func DefaultCSRFConfig() *CSRFConfig

type CSRFMode

type CSRFMode int
const (
	CSRFModeAuto CSRFMode = iota // Automatically detect client type
	CSRFModeSPA                  // SPA/Vite frontend (cookie-to-header token reflection)
	CSRFModeAPI                  // API clients (stateless JWTs, skip CSRF)
)

type ChainBuilder

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

ChainBuilder provides a fluent interface for building standard middleware chains.

func NewChainBuilder

func NewChainBuilder() *ChainBuilder

NewChainBuilder creates a new chain builder.

func (*ChainBuilder) Add

Add adds standard middleware to the chain.

func (*ChainBuilder) Build

func (cb *ChainBuilder) Build(handler http.Handler) http.Handler

Build wraps the final handler with the middleware chain.

func (*ChainBuilder) HandleContext

func (cb *ChainBuilder) HandleContext(h HandlerFunc) http.Handler

HandleContext wraps an Astra HandlerFunc with the middleware chain.

type ChaosConfig

type ChaosConfig struct {
	// Enabled switches chaos mode on. If false, the middleware is a no-op.
	// Forced to false when APP_ENV == "production".
	Enabled bool

	// LatencyProb is the probability [0,1] that a request gets an injected delay.
	LatencyProb float64
	// MinDelay / MaxDelay define the injected latency range.
	MinDelay time.Duration
	MaxDelay time.Duration

	// ErrorProb is the probability [0,1] that a request is immediately failed
	// with a 500 Internal Server Error.
	ErrorProb float64

	// TimeoutProb is the probability [0,1] that the handler context is cancelled
	// before calling next, simulating an upstream timeout / DB hang.
	TimeoutProb float64

	// ExcludePaths contains URL path prefixes that are immune to fault injection
	// (useful to protect health-check and metrics endpoints).
	ExcludePaths []string
}

ChaosConfig controls the fault injection behaviour.

type Context

type Context struct {
	Writer  nethttp.ResponseWriter
	Request *nethttp.Request

	// Explicit Dependencies
	ViewEngine engine.ViewEngine
	Translator engine.Translator
	Sessions   engine.SessionStore
	// contains filtered or unexported fields
}

Context represents the Astra-specific request/response context. It is recycled via a sync.Pool to minimize GC pressure.

func FromRequest

func FromRequest(r *nethttp.Request) *Context

FromRequest retrieves the Astra context from an http.Request.

func NewContext

func NewContext(w nethttp.ResponseWriter, r *nethttp.Request) *Context

NewContext initializes or retrieves a Context from the pool.

func (*Context) AuthUser

func (c *Context) AuthUser() *identityclaims.AuthClaims

func (*Context) BadRequestError

func (c *Context) BadRequestError(message string) error

BadRequestError sends a 400 error for malformed requests.

func (*Context) Bind

func (c *Context) Bind(v any) error

Bind decodes the request body into v.

func (*Context) BindAndValidate

func (c *Context) BindAndValidate(v any) error

BindAndValidate is a placeholder for the actual implementation.

func (*Context) ClearFlashes

func (c *Context) ClearFlashes()

ClearFlashes clears flash messages from the session.

func (*Context) ClientIP

func (c *Context) ClientIP() string

ClientIP returns the client's IP address.

func (*Context) ConflictError

func (c *Context) ConflictError(message string) error

ConflictError sends a 409 error for resource conflicts.

c.ConflictError("email already exists")

func (*Context) Ctx

func (c *Context) Ctx() context.Context

Ctx returns the underlying request context.

func (*Context) CursorJSON

func (c *Context) CursorJSON(data any, nextCursor string, hasMore bool) error

CursorJSON sends a cursor-paginated response with standard cursor metadata.

result, _ := qb.CursorPaginate(ctx, "id", cursor, limit)
c.CursorJSON(result.Data, result.NextCursor, result.HasMore)

func (*Context) Error

func (c *Context) Error(status int, message string) error

Error sends a specific status and message.

func (*Context) ErrorFlash

func (c *Context) ErrorFlash(message string)

ErrorFlash is a convenience method for flashing error messages.

func (*Context) ErrorWithDetails

func (c *Context) ErrorWithDetails(status int, code string, message string, details map[string]any) error

ErrorWithDetails sends a structured error with optional extra detail fields.

c.ErrorWithDetails(409, "CONFLICT", "email taken", map[string]any{"field": "email"})

func (*Context) Flash

func (c *Context) Flash(key, message string)

Flash adds a flash message to the session.

func (*Context) ForbiddenError

func (c *Context) ForbiddenError(message string) error

ForbiddenError sends a 403 error.

func (*Context) Get

func (c *Context) Get(key any) any

Get retrieves a value from the request context.

func (*Context) GetFlashes

func (c *Context) GetFlashes() map[string]string

GetFlashes retrieves all flash messages and clears them from the session.

func (*Context) GetRequest

func (c *Context) GetRequest() *nethttp.Request

func (*Context) GetString

func (c *Context) GetString(key string) string

GetString retrieves a string value from the request context.

func (*Context) InternalError

func (c *Context) InternalError(message string) error

InternalError sends a 500 error.

func (*Context) IsAuthenticated

func (c *Context) IsAuthenticated() bool

IsAuthenticated returns true if a user is logged in.

func (*Context) JSON

func (c *Context) JSON(v any, status ...int) error

JSON sends a JSON response with an optional status code (defaults to 200).

func (*Context) Locale

func (c *Context) Locale() string

func (*Context) NoContent

func (c *Context) NoContent() error

NoContent sends an empty 204 response.

func (*Context) Nonce

func (c *Context) Nonce() string

Nonce is a helper to retrieve the CSP nonce.

func (*Context) NotFoundError

func (c *Context) NotFoundError(resource string) error

NotFoundError sends a 404 error for a specific resource type.

c.NotFoundError("User")
→ {"error": {"code": "NOT_FOUND", "message": "User not found"}}

func (*Context) PaginatedJSON

func (c *Context) PaginatedJSON(data any, total, page, perPage, lastPage int) error

PaginatedJSON sends a paginated response with standard pagination metadata. Works with any db.Paginated[T] result by accepting its components.

result, _ := qb.Paginate(ctx, page, perPage)
c.PaginatedJSON(result.Data, result.Total, result.Page, result.PerPage, result.LastPage)

func (*Context) Param

func (c *Context) Param(name string) string

Param retrieves a path parameter.

func (*Context) Query

func (c *Context) Query(name string) string

Query retrieves a URL query parameter.

func (*Context) Redirect

func (c *Context) Redirect(url string, code int) error

Redirect performs an HTTP redirect.

func (*Context) RegenerateSession

func (c *Context) RegenerateSession() error

func (*Context) Render

func (c *Context) Render(name string, data any, status ...int) error

Render renders an HTML template using the registered view engine and sends the response.

c.Render("pages/home", map[string]any{"title": "Home"})

func (*Context) SendString

func (c *Context) SendString(s string) error

SendString sends a plain text response.

func (*Context) Session

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

Session retrieves the session for the current request.

func (*Context) Set

func (c *Context) Set(key string, val any)

Set stores a value in the request context (standard lib interop).

func (*Context) SetAuthUser

func (c *Context) SetAuthUser(claims *identityclaims.AuthClaims)

func (*Context) SetCookie

func (c *Context) SetCookie(cookie *nethttp.Cookie)

func (*Context) SetParam

func (c *Context) SetParam(name, value string)

SetParam manually sets a path parameter (used by some middlewares).

func (*Context) Status

func (c *Context) Status(code int) *Context

Status sets the HTTP response status code.

func (*Context) Success

func (c *Context) Success(data any) error

Success sends a 200 JSON response wrapped in the standard envelope.

c.Success(user)
→ {"data": {...}}

func (*Context) SuccessFlash

func (c *Context) SuccessFlash(message string)

SuccessFlash is a convenience method for flashing success messages.

func (*Context) SuccessWithMeta

func (c *Context) SuccessWithMeta(data any, meta map[string]any) error

SuccessWithMeta sends a 200 JSON response with custom metadata.

c.SuccessWithMeta(users, map[string]any{"cached": true})
→ {"data": [...], "meta": {"cached": true}}

func (*Context) T

func (c *Context) T(key string, args ...any) string

T translates a key using the registered Translator.

func (*Context) UnauthorizedError

func (c *Context) UnauthorizedError(message string) error

UnauthorizedError sends a 401 error.

func (*Context) Validate

func (c *Context) Validate(v any) error

Validate uses the BindAndValidate helper.

type CorsConfig

type CorsConfig struct {
	AllowOrigins     []string
	AllowMethods     []string
	AllowHeaders     []string
	ExposeHeaders    []string
	AllowCredentials bool
	MaxAge           int  // Cache duration for preflight in seconds (Access-Control-Max-Age)
	Strict           bool // If true, return 403 for disallowed origins (default: pass through)
}

CorsConfig defines the CORS configuration.

func DefaultCors

func DefaultCors() CorsConfig

DefaultCors returns a permissive CORS config suitable for local development.

type CursorMeta

type CursorMeta struct {
	NextCursor string `json:"next_cursor"`
	HasMore    bool   `json:"has_more"`
}

CursorMeta is the metadata for cursor-based pagination responses.

type DashboardHandler

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

DashboardHandler handles requests for the Astra Dev Dashboard.

func NewDashboardHandler

func NewDashboardHandler(
	dash *telemetry.Dashboard,
	cfg *config.AstraConfig,
	env *config.Config,
	router *Router,
	mailSandbox *platformtelemetry.MailSandbox,
	queueMon *telemetry.QueueMonitor,
) *DashboardHandler

NewDashboardHandler creates a new DashboardHandler.

func (*DashboardHandler) ClearEntries

func (h *DashboardHandler) ClearEntries(c *Context) error

ClearEntries clears all entries in the dashboard.

func (*DashboardHandler) ClearMails

func (h *DashboardHandler) ClearMails(c *Context) error

ClearMails removes all captured sandbox emails.

func (*DashboardHandler) GetConfig

func (h *DashboardHandler) GetConfig(c *Context) error

GetConfig returns the application configuration as JSON (filtered for security).

func (*DashboardHandler) GetEntries

func (h *DashboardHandler) GetEntries(c *Context) error

GetEntries returns the current dashboard entries as JSON.

func (*DashboardHandler) GetMails

func (h *DashboardHandler) GetMails(c *Context) error

GetMails returns all emails captured by the MailSandbox.

func (*DashboardHandler) GetQueues

func (h *DashboardHandler) GetQueues(c *Context) error

GetQueues returns real-time stats for all Redis queues.

func (*DashboardHandler) GetRoutes

func (h *DashboardHandler) GetRoutes(c *Context) error

GetRoutes returns all registered routes as JSON.

func (*DashboardHandler) GetSQLTimeline

func (h *DashboardHandler) GetSQLTimeline(c *Context) error

GetSQLTimeline returns all captured SQL queries with params and durations.

func (*DashboardHandler) HealthCheck

func (h *DashboardHandler) HealthCheck(c *Context) error

HealthCheck returns the health status.

func (*DashboardHandler) HealthReady

func (h *DashboardHandler) HealthReady(c *Context) error

HealthReady returns 200 if the app is healthy.

func (*DashboardHandler) Index

func (h *DashboardHandler) Index(c *Context) error

Index serves the dashboard UI.

func (*DashboardHandler) PurgeQueue

func (h *DashboardHandler) PurgeQueue(c *Context) error

PurgeQueue removes all pending jobs from a queue.

func (*DashboardHandler) RetryFailedJobs

func (h *DashboardHandler) RetryFailedJobs(c *Context) error

RetryFailedJobs moves dead-letter jobs back to the pending queue.

func (*DashboardHandler) Stream

func (h *DashboardHandler) Stream(c *Context) error

Stream streams dashboard entries as Server-Sent Events (SSE).

type ErrorMiddleware

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

ErrorMiddleware handles error recovery and reporting.

func NewErrorMiddleware

func NewErrorMiddleware(logger *slog.Logger) *ErrorMiddleware

func (*ErrorMiddleware) HandleErrors

func (m *ErrorMiddleware) HandleErrors(next http.Handler) http.Handler

type HTTPError

type HTTPError struct {
	Status  int
	Message string
}

HTTPError represents an error that occurred during the processing of an HTTP request.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type HandlerFunc

type HandlerFunc func(c *Context) error

HandlerFunc is the standard Astra request handler function. It returns an error to allow for centralized error handling.

func HealthHandler

func HealthHandler(checks map[string]engine.HealthProvider) HandlerFunc

HealthHandler returns a sophisticated health check handler that runs all registered probes. It is fully decoupled from the kernel and accepts an explicit health check registry.

func ReadyHandler

func ReadyHandler() HandlerFunc

ReadyHandler returns a simple liveness probe handler.

type IdentifierFunc

type IdentifierFunc func(r *http.Request) string

IdentifierFunc resolves the rate-limit bucket key for a request.

type InteractiveErrorHandler

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

InteractiveErrorHandler renders rich debug error pages in development and structured JSON / minimal HTML in production.

func NewInteractiveErrorHandler

func NewInteractiveErrorHandler(cfg *config.AstraConfig, env *config.Config, logger *slog.Logger) *InteractiveErrorHandler

NewInteractiveErrorHandler creates an InteractiveErrorHandler with explicit dependencies.

func (*InteractiveErrorHandler) Handle

func (h *InteractiveErrorHandler) Handle(c *Context, err error)

Handle is the error handler function compatible with Router.errorHandler.

type LoadShedConfig

type LoadShedConfig struct {
	// MinConcurrency is the floor below which the limit will never drop.
	MinConcurrency int64
	// MaxConcurrency is the ceiling (default: runtime.GOMAXPROCS*16).
	MaxConcurrency int64
	// LimitMultiplier is the AIMD decrease factor when overloaded (default: 0.9).
	LimitMultiplier float64
	// WindowDuration is how often the limit is recalculated (default: 200ms).
	WindowDuration time.Duration
	// QueueDepth is how many requests may wait above the limit before shedding.
	// 0 means shed immediately when the limit is reached.
	QueueDepth int64
	// BackgroundLatencyThreshold is the latency multiplier (relative to baseline)
	// at which background traffic starts being shed. Default: 1.5.
	BackgroundLatencyThreshold float64
	// NormalLatencyThreshold is the latency multiplier at which normal
	// traffic starts being shed. Default: 2.0.
	NormalLatencyThreshold float64
	// CriticalLatencyThreshold is the latency multiplier at which even
	// critical traffic starts being shed. Default: 5.0.
	CriticalLatencyThreshold float64
	// RetryAfter is the value of the Retry-After header sent on 503s (seconds).
	RetryAfter int
}

type MiddlewareFunc

type MiddlewareFunc func(http.Handler) http.Handler

MiddlewareFunc is a function that wraps an http.Handler.

func AdaptiveLoadShedding

func AdaptiveLoadShedding(cfg LoadShedConfig) MiddlewareFunc

AdaptiveLoadShedding returns an AIMD-based adaptive concurrency middleware.

func Auth

func Auth(guard auth.Guard) MiddlewareFunc

Auth returns a standard middleware that protects routes using the provided guard.

func AuthRateLimit

func AuthRateLimit(client goredis.UniversalClient, opts ...RateLimitOption) (MiddlewareFunc, error)

AuthRateLimit is a preset for general authentication-related routes. By default, it allows 10 requests per minute.

func CORS

func CORS(config CorsConfig) MiddlewareFunc

CORS returns a middleware that handles CORS requests securely.

func CSRF

func CSRF(isProd bool, opts ...func(*CSRFConfig)) MiddlewareFunc

CSRF implements Cross-Site Request Forgery protection with smart client detection.

func Chaos

func Chaos(cfg ChaosConfig) MiddlewareFunc

Chaos returns a middleware that injects faults according to cfg. It is automatically disabled in production regardless of cfg.Enabled.

r.Use(middleware.Chaos(middleware.ChaosConfig{
    Enabled:     true,
    LatencyProb: 0.05,
    MinDelay:    50 * time.Millisecond,
    MaxDelay:    500 * time.Millisecond,
    ErrorProb:   0.01,
}))

func DashboardLogger

func DashboardLogger(dash *telemetry.Dashboard) MiddlewareFunc

DashboardLogger tracks HTTP requests in the Dev Dashboard. It is fully decoupled from the kernel and accepts an explicit Dashboard dependency.

func Gzip

func Gzip() MiddlewareFunc

Gzip returns a standard middleware that compresses HTTP responses using gzip.

func LocaleMiddleware

func LocaleMiddleware(fallback string) MiddlewareFunc

LocaleMiddleware detects the user locale and stores it in the request context.

func Logger

func Logger(logger *slog.Logger) MiddlewareFunc

Logger returns a middleware that logs incoming requests.

func NonceMiddleware

func NonceMiddleware() MiddlewareFunc

NonceMiddleware generates a random nonce for CSP and stores it in the context.

func OpenTelemetry

func OpenTelemetry() MiddlewareFunc

OpenTelemetry returns a middleware that injects OTEL tracing into the request.

func RateLimit

func RateLimit(client goredis.UniversalClient, limit int, window time.Duration, opts ...RateLimitOption) (MiddlewareFunc, error)

RateLimit returns a standard Redis-backed rate limiter middleware.

func RateLimiter

func RateLimiter(client goredis.UniversalClient, limit int, window time.Duration, opts ...RateLimitOption) (MiddlewareFunc, error)

RateLimiter is an alias for RateLimit.

func Recover

func Recover(logger *slog.Logger) MiddlewareFunc

Recover returns a middleware that recovers from panics and returns a 500 error.

func RequestID

func RequestID() MiddlewareFunc

RequestID returns a middleware that injects a unique request ID into the context and response headers.

func SecureHeaders

func SecureHeaders(isProd bool, config ...SecurityConfig) MiddlewareFunc

SecureHeaders returns a standard middleware that sets common security headers.

func SensitiveRateLimit

func SensitiveRateLimit(client goredis.UniversalClient, opts ...RateLimitOption) (MiddlewareFunc, error)

SensitiveRateLimit returns a restrictive rate limiter for sensitive routes like Login or Register. By default, it allows 5 requests per minute per IP.

func SessionMiddleware

func SessionMiddleware(store session.Store) MiddlewareFunc

SessionMiddleware returns a standard middleware that loads the session from the request and stores it in the request context.

func Timeout

func Timeout(timeout time.Duration) MiddlewareFunc

Timeout returns a standard middleware that wraps the handler with http.TimeoutHandler.

func UltraFastLogger

func UltraFastLogger(logger *slog.Logger) MiddlewareFunc

UltraFastLogger provides high-performance request logging. Accepts an explicit logger to remain decoupled from the kernel App.

func UltraFastRecover

func UltraFastRecover(logger *slog.Logger) MiddlewareFunc

UltraFastRecover provides high-performance panic recovery.

func UltraFastRequestID

func UltraFastRequestID() MiddlewareFunc

UltraFastRequestID provides high-performance request ID generation

func ValidateMiddleware

func ValidateMiddleware(validator engine.Validator, logger *slog.Logger) MiddlewareFunc

ValidateMiddleware handles request validation by injecting the validator service.

type PaginationMeta

type PaginationMeta struct {
	Total    int `json:"total"`
	Page     int `json:"page"`
	PerPage  int `json:"per_page"`
	LastPage int `json:"last_page"`
}

PaginationMeta is the standard pagination metadata included in list responses.

type Priority

type Priority string
const (
	PriorityCritical   Priority = "critical"
	PriorityNormal     Priority = "normal"
	PriorityBackground Priority = "background"
	PriorityAnalytics  Priority = "analytics"
)

type RBACHandler

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

RBACHandler provides RBAC HTTP handlers

func NewRBACHandler

func NewRBACHandler(r *rbac.RBAC, logger *slog.Logger) *RBACHandler

NewRBACHandler creates new RBAC handler

func (*RBACHandler) CheckAccess

func (h *RBACHandler) CheckAccess(c *Context) error

CheckAccess handles access check requests

func (*RBACHandler) ServeHTTP

func (h *RBACHandler) ServeHTTP(w stdhttp.ResponseWriter, r *stdhttp.Request)

ServeHTTP makes RBACHandler a standard net/http handler

type RBACMiddleware

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

RBACMiddleware provides RBAC middleware for HTTP handlers

func NewRBACMiddleware

func NewRBACMiddleware(r *rbac.RBAC, logger *slog.Logger) *RBACMiddleware

NewRBACMiddleware creates new RBAC middleware

func (*RBACMiddleware) RequirePermission

func (m *RBACMiddleware) RequirePermission(resource, action string) MiddlewareFunc

RequirePermission creates middleware that requires specific permission.

type RateLimitAlgorithm

type RateLimitAlgorithm int
const (
	SlidingWindow RateLimitAlgorithm = iota
	TokenBucket
)

type RateLimitOption

type RateLimitOption func(*rateLimitConfig)

RateLimitOption configures Redis-backed rate limiting.

func WithAPIKeyHeader

func WithAPIKeyHeader(header string) RateLimitOption

WithAPIKeyHeader changes the header used by ByAPIKey.

func WithAlgorithm

func WithAlgorithm(algo RateLimitAlgorithm) RateLimitOption

WithAlgorithm sets the rate limiting algorithm to use (SlidingWindow or TokenBucket).

func WithIPHeaderValidation

func WithIPHeaderValidation(enabled bool) RateLimitOption

WithIPHeaderValidation enables or disables validation of IP headers.

func WithIPSpoofingProtection

func WithIPSpoofingProtection(enabled bool) RateLimitOption

WithIPSpoofingProtection enables or disables IP spoofing protection.

func WithIdentifier

func WithIdentifier(fn IdentifierFunc) RateLimitOption

WithIdentifier sets the request bucket resolver.

func WithKeyPrefix

func WithKeyPrefix(prefix string) RateLimitOption

WithKeyPrefix overrides the Redis key namespace prefix used by rate limiting.

func WithMaxProxyDepth

func WithMaxProxyDepth(depth int) RateLimitOption

WithMaxProxyDepth sets the maximum number of proxy hops to trust in X-Forwarded-For headers.

func WithTrustedProxies

func WithTrustedProxies(values ...string) RateLimitOption

WithTrustedProxies configures proxies allowed to supply forwarded IP headers.

type Router

type Router struct {
	Config *config.AstraConfig
	Logger *slog.Logger
	// contains filtered or unexported fields
}

Router represents the Astra HTTP router. It is fully decoupled from the engine.App kernel and accepts explicit dependencies.

func NewRouter

func NewRouter(cfg *config.AstraConfig, logger *slog.Logger) *Router

NewRouter creates a new Astra HTTP router.

func (*Router) Delete

func (r *Router) Delete(path string, h HandlerFunc)

func (*Router) Get

func (r *Router) Get(path string, h HandlerFunc)

func (*Router) Group

func (r *Router) Group(prefix string, fn func(*Router))

func (*Router) Handle

func (r *Router) Handle(method, path string, h http.Handler)

Handle registers a standard http.Handler.

func (*Router) HandleContext

func (r *Router) HandleContext(method, path string, h HandlerFunc)

HandleContext registers an Astra-style HandlerFunc.

func (*Router) Patch

func (r *Router) Patch(path string, h HandlerFunc)

func (*Router) Post

func (r *Router) Post(path string, h HandlerFunc)

func (*Router) Put

func (r *Router) Put(path string, h HandlerFunc)

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

func (*Router) Use

func (r *Router) Use(m MiddlewareFunc)

type SecurityConfig

type SecurityConfig struct {
	XSSProtection         string
	ContentTypeOptions    string
	FrameOptions          string
	ReferrerPolicy        string
	ContentSecurityPolicy string
	PermissionsPolicy     string
	HSTSMaxAge            int
	HSTSPreload           bool
	HSTSIncludeSubdomains bool
}

SecurityConfig defines the configuration for secure headers.

func DefaultAPISecurityConfig

func DefaultAPISecurityConfig() SecurityConfig

DefaultAPISecurityConfig returns the recommended security defaults for API endpoints.

func DefaultSSRSecurityConfig

func DefaultSSRSecurityConfig() SecurityConfig

DefaultSSRSecurityConfig returns the recommended security defaults for server-rendered HTML applications.

func DefaultSecurityConfig

func DefaultSecurityConfig() SecurityConfig

DefaultSecurityConfig is an alias for DefaultSSRSecurityConfig for backwards compatibility.

type Server

type Server struct {
	*http.Server
	// contains filtered or unexported fields
}

Server wraps the standard http.Server to provide Astra-specific features.

func NewServer

func NewServer(addr string, handler http.Handler) *Server

NewServer creates a new Astra HTTP server with TLS support.

func (*Server) ServeGRPC

func (s *Server) ServeGRPC(grpcSrv *grpc.Server) *Server

ServeGRPC registers a gRPC server to be multiplexed on the same port as the HTTP server. When a gRPC server is registered, both Astra REST handlers and gRPC endpoints share a single TCP listener via cmux content-based routing.

If grpcSrv is nil, this is a no-op and the server behaves as a pure HTTP server.

srv := http.NewServer(":8080", router)
srv.ServeGRPC(grpc.NewServer())
srv.Start(ctx) // now serves HTTP/1.1 + gRPC on :8080

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start runs the server in a goroutine and returns nil. It complies with the framework.Starter interface.

When a gRPC server has been registered via ServeGRPC, cmux is used to route HTTP/1.1 traffic to the Astra router and HTTP/2 gRPC traffic to the gRPC server on the same port, with zero configuration overhead for the application.

type TLSConfig

type TLSConfig struct {
	Enabled    bool
	CertFile   string
	KeyFile    string
	MinVersion uint16
}

TLSConfig holds TLS/HTTPS configuration

func LoadTLSConfig

func LoadTLSConfig() *TLSConfig

LoadTLSConfig loads TLS configuration from environment

func (*TLSConfig) GetTLSConfig

func (c *TLSConfig) GetTLSConfig() (*tls.Config, error)

GetTLSConfig returns a tls.Config with secure defaults

type TemplateEngine

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

TemplateEngine is the default view engine that wraps html/template with layout support, helper functions, and optional auto-reload in dev mode.

func NewTemplateEngine

func NewTemplateEngine(dir string, opts ...TemplateOption) *TemplateEngine

NewTemplateEngine creates a new TemplateEngine.

Usage:

engine := http.NewTemplateEngine("views",
    http.WithLayout("layouts/app"),
    http.WithDevMode(true),
)
app.Register("views", engine)

func (*TemplateEngine) Render

func (e *TemplateEngine) Render(wr io.Writer, name string, data any) error

Render renders a template by name with the given data and returns the result.

func (*TemplateEngine) Warmup

func (e *TemplateEngine) Warmup() error

Warmup pre-compiles all templates found in the engine's directory. Useful for production to avoid late compilation latency.

type TemplateOption

type TemplateOption func(*TemplateEngine)

TemplateOption is a functional option for configuring the TemplateEngine.

func WithDevMode

func WithDevMode(isDev bool) TemplateOption

WithDevMode enables auto-reload of templates on every render (no caching).

func WithExtension

func WithExtension(ext string) TemplateOption

WithExtension sets the template file extension (default: ".html").

func WithFS

func WithFS(filesystem fs.FS) TemplateOption

WithFS sets a custom filesystem (e.g., embed.FS) for templates.

func WithFuncMap

func WithFuncMap(funcMap template.FuncMap) TemplateOption

WithFuncMap adds custom template functions.

func WithLayout

func WithLayout(layout string) TemplateOption

WithLayout sets the default layout template name (e.g., "layouts/app").

type TenantMiddleware

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

TenantMiddleware handles multi-tenancy resolution and access control.

func NewTenantMiddleware

func NewTenantMiddleware(m *multitenancy.Manager, logger *slog.Logger) *TenantMiddleware

func (*TenantMiddleware) RequireTenant

func (m *TenantMiddleware) RequireTenant() MiddlewareFunc

type UploadMiddleware

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

func NewUploadMiddleware

func NewUploadMiddleware(s engine.Storage, logger *slog.Logger) *UploadMiddleware

func (*UploadMiddleware) UploadFile

func (m *UploadMiddleware) UploadFile(maxSize int64, allowedTypes []string) MiddlewareFunc

type ViewEngine

type ViewEngine interface {
	Render(wr io.Writer, name string, data any) error
}

ViewEngine defines the interface for template rendering.

type WebSocketHandler

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

WebSocketHandler handles WebSocket connections.

func NewWebSocketHandler

func NewWebSocketHandler(manager *realtime.RoomManager, app *engine.App) *WebSocketHandler

func (*WebSocketHandler) Connect

func (h *WebSocketHandler) Connect(c *Context) error

Jump to

Keyboard shortcuts

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