Help us shape the future of Go! Take the 2026 Go Developer Survey

middleware

package
v0.9.1 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CORS

func CORS(options ...Option) (func(http.Handler) http.Handler, error)

CORS validates the configuration immediately and returns an opt-in middleware.

func MustCORS

func MustCORS(options ...Option) func(http.Handler) http.Handler

MustCORS panics when CORS configuration is invalid, for applications that prefer configuration failures during startup.

func NoStoreAPIResponses added in v0.9.0

func NoStoreAPIResponses(next http.Handler) http.Handler

NoStoreAPIResponses disables caching for API paths under /api/.

func Recovery

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

Recovery catches panics that escape from downstream handlers and middleware, converts them into a 500 response, and logs the panic with its stack trace.

func RequestScope

func RequestScope(next http.Handler) http.Handler

RequestScope provisions a pooled xctx.RequestScope for every HTTP request. It MUST be the outermost middleware in the chain.

func SecurityHeaders

func SecurityHeaders(next http.Handler) http.Handler

SecurityHeaders applies a conservative set of HTTP hardening headers to every response. The set is deliberately narrow: it improves defaults without being so opinionated that it breaks legitimate same-host UI such as Scalar docs, GraphiQL, or embedded consoles.

Content-Security-Policy is intentionally NOT set. CSP is genuinely application-specific — a policy that works for a JSON API breaks a dashboard with inline styles — and silently shipping a default has caused more outages than it has prevented. Applications that serve HTML should add their own CSP middleware after this one.

Zero-allocation contract: net/http pre-sizes the response header map, so each Set is a map write without growth. No allocation on the fast path.

func TenantFromHeader

func TenantFromHeader(headerName string) func(http.Handler) http.Handler

TenantFromHeader reads a tenant identifier from a request header and attaches it to the execution context.

This is the correct place for tenant extraction on HTTP paths. The header is presumed to have been set by an upstream trusted authority: a gateway, a service mesh, or an authentication middleware that has already verified the caller's claims and rewritten the request.

This middleware deliberately does NOT trust a tenant id supplied in the request body. Placing tenant selection under client control is an authorization bypass in any multi-tenant system. When the tenant comes from verified JWT claims, do not use this middleware — set the tenant on the context inside the authentication middleware instead.

Use this middleware when:

  • the service sits behind a trusted proxy that sets X-Tenant-ID
  • a batch or internal service invocation carries the tenant in a well-known header
  • local development needs to simulate a specific tenant

Do not use this middleware when the tenant is derived from a verified claim; extract the claim in the authentication middleware and call xctx.WithTenantID there.

Zero-allocation contract: the fast path does one header lookup and one field write inside the pooled scope. No allocation.

func TenantFromSubdomain

func TenantFromSubdomain(baseDomain string) func(http.Handler) http.Handler

TenantFromSubdomain extracts the tenant identifier from the request's leftmost subdomain label and attaches it to the context.

Example: acme.api.example.com → "acme"

This is a common SaaS pattern where each tenant gets a DNS alias. It is a shape-based extraction: the middleware does not verify that the subdomain corresponds to a real tenant — downstream actions validate that. Like TenantFromHeader, it assumes the deployment terminates at a trusted edge that controls DNS.

The baseDomain argument is not consulted at request time; it exists only to make the deployment intent explicit at the call site and to allow future validation. Pass an empty string for a purely local setup.

func WAF

func WAF(cfg WAFConfig) func(http.Handler) http.Handler

WAF returns an HTTP middleware that enforces the configured policy.

Types

type Option

type Option func(*corsConfig) error

Option configures CORS middleware.

func WithCredentials

func WithCredentials() Option

WithCredentials enables Access-Control-Allow-Credentials. It cannot be used with a wildcard origin.

func WithEnv

func WithEnv() Option

WithEnv reads CORS_ORIGINS, CORS_HEADERS, CORS_METHODS, CORS_EXPOSED, CORS_MAX_AGE, and CORS_CREDENTIALS from the process environment. It is evaluated when CORS is constructed, not on each request.

func WithExposedHeaders

func WithExposedHeaders(headers ...string) Option

WithExposedHeaders sets response headers visible to browser JavaScript.

func WithHeaders

func WithHeaders(headers ...string) Option

WithHeaders sets allowed request headers for preflight requests.

func WithMaxAge

func WithMaxAge(seconds int) Option

WithMaxAge sets the preflight cache lifetime in seconds.

func WithMethods

func WithMethods(methods ...string) Option

WithMethods overrides the methods advertised for preflight requests.

func WithOrigins

func WithOrigins(origins ...string) Option

WithOrigins sets the allowed origins. Use "*" to allow any origin. Wildcard origins cannot be combined with credentials.

type WAFConfig

type WAFConfig struct {
	MaxBodySize int64
	BlockedIPs  map[string]struct{}
	EnableSQLi  bool
	EnableXSS   bool
}

WAFConfig controls the Web Application Firewall.

Jump to

Keyboard shortcuts

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