Documentation
¶
Overview ¶
Package cors provides Cross-Origin Resource Sharing (CORS) middleware for celeris.
The middleware handles preflight OPTIONS requests (detected via OPTIONS method + Access-Control-Request-Method header) and sets the appropriate Access-Control-* response headers. Header values are pre-joined at initialization for zero-alloc responses on the hot path.
Allow all origins (default):
server.Use(cors.New())
Restrict to specific origins with credentials:
server.Use(cors.New(cors.Config{
AllowOrigins: []string{"https://example.com"},
AllowCredentials: true,
MaxAge: 3600,
}))
Dynamic Origin Validation ¶
Config.AllowOriginsFunc validates origins with a custom function. Config.AllowOriginRequestFunc provides the full request context for tenant-based or header-dependent origin checks. Neither may be combined with a wildcard ("*") AllowOrigins entry.
server.Use(cors.New(cors.Config{
AllowOriginsFunc: func(origin string) bool {
return strings.HasSuffix(origin, ".example.com")
},
}))
Subdomain Wildcards ¶
Origins may contain a single wildcard for subdomain matching (e.g., "https://*.example.com"). Patterns with more than one wildcard panic at initialization. By default, the wildcard matches a single subdomain level only: "https://*.example.com" matches "https://api.example.com" but NOT "https://a.b.example.com". This prevents unintended deep-subdomain matching that could weaken origin restrictions. The depth limit is enforced by counting dots in the wildcard portion (max 0 additional dots for depth 1).
Cache Poisoning Prevention ¶
When specific origins (not wildcard "*") are configured, the middleware adds a Vary: Origin header even on non-CORS requests (those without an Origin header). This prevents intermediate caches from serving a response generated for one origin to a different origin.
Header Mirroring ¶
When Config.MirrorRequestHeaders is true, the middleware mirrors the value of the Access-Control-Request-Headers header from the preflight request back in Access-Control-Allow-Headers. Each header name is validated against the RFC 7230 token charset, names longer than 128 bytes are silently dropped, and at most 20 header names are accepted. When MirrorRequestHeaders is false (the default), the AllowHeaders list is used (defaults to Origin, Content-Type, Accept, Authorization).
Private Network Access ¶
Set Config.AllowPrivateNetwork to true to enable the Private Network Access spec (Access-Control-Allow-Private-Network header on preflight).
Unsafe Credentials with Wildcard Subdomains ¶
Using AllowCredentials with a subdomain wildcard origin (e.g., "https://*.example.com") panics by default because the browser receives the echoed origin (not "*") with credentials, widening the credential scope to every matching subdomain. Set Config.UnsafeAllowCredentialsWithWildcard to true to suppress the panic if you fully understand the security implications.
Null Origin Warning ¶
The literal "null" origin is sent by sandboxed iframes, data: URLs, file:// pages, and redirected requests. Because all of these share the same "null" string, allowing it effectively grants access to any sandboxed context. Treat "null" as an opaque origin and avoid adding it to AllowOrigins unless you fully understand the implications. AllowOriginsFunc is a safer alternative for case-by-case decisions.
Using AllowCredentials with a wildcard origin ("*") panics at initialization, as this combination is forbidden by the CORS spec.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func New ¶
func New(config ...Config) celeris.HandlerFunc
New creates a CORS middleware with the given config.
Example ¶
package main
import (
"github.com/goceleris/celeris/middleware/cors"
)
func main() {
// Zero-config: allows all origins (wildcard *).
_ = cors.New()
}
Output:
Example (Customize) ¶
package main
import (
"github.com/goceleris/celeris/middleware/cors"
)
func main() {
// Start from a zero Config and customize.
_ = cors.New(cors.Config{
AllowOrigins: []string{"https://example.com"},
})
}
Output:
Example (DynamicOrigin) ¶
package main
import (
"github.com/goceleris/celeris/middleware/cors"
)
func main() {
// Dynamic origin validation based on request context.
_ = cors.New(cors.Config{
AllowOrigins: []string{"https://static.example.com"},
AllowOriginsFunc: func(origin string) bool {
// Check a database or config for allowed origins.
return origin == "https://dynamic.example.com"
},
})
}
Output:
Example (Restricted) ¶
package main
import (
"github.com/goceleris/celeris/middleware/cors"
)
func main() {
// Restrict to specific origins with credentials.
_ = cors.New(cors.Config{
AllowOrigins: []string{"https://example.com"},
AllowCredentials: true,
MaxAge: 3600,
})
}
Output:
Types ¶
type Config ¶
type Config struct {
// Skip defines a function to skip this middleware for certain requests.
Skip func(c *celeris.Context) bool
// SkipPaths lists paths to skip (exact match on c.Path()).
// Requests matching these paths bypass CORS processing entirely.
SkipPaths []string
// AllowOrigins lists allowed origins. Default: ["*"].
AllowOrigins []string
// AllowOriginsFunc is a custom function to validate origins.
// Called after static and wildcard origin checks.
// Cannot be used with wildcard "*" AllowOrigins.
//
// The middleware validates that the incoming Origin header looks like a
// serialized origin (has scheme + host, no path/query/fragment/userinfo)
// before passing it to this function. Malformed origins are rejected.
AllowOriginsFunc func(origin string) bool
// AllowOriginRequestFunc validates origins with access to the full request context.
// Called after AllowOriginsFunc. Useful for tenant-based or header-dependent
// origin decisions. Cannot be used with wildcard "*" AllowOrigins.
//
// The same serialized-origin validation applies as for AllowOriginsFunc.
AllowOriginRequestFunc func(c *celeris.Context, origin string) bool
// AllowMethods lists allowed HTTP methods.
// Default: [GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS].
AllowMethods []string
// AllowHeaders lists allowed request headers.
// Default: [Origin, Content-Type, Accept, Authorization].
AllowHeaders []string
// MirrorRequestHeaders, when true, causes the middleware to reflect
// the Access-Control-Request-Headers value back in preflight responses
// instead of using a fixed AllowHeaders list. This is useful when the
// full set of request headers is not known ahead of time. When false
// (the default), the AllowHeaders list is used.
MirrorRequestHeaders bool
// ExposeHeaders lists headers the browser can access.
ExposeHeaders []string
// AllowCredentials indicates whether credentials are allowed.
AllowCredentials bool
// UnsafeAllowCredentialsWithWildcard suppresses the panic that fires when
// AllowCredentials is true and an AllowOrigins entry contains a wildcard
// (e.g. "https://*.example.com"). This combination is spec-compliant
// (the browser receives the echoed origin, not "*"), but it widens the
// credential scope to any matching subdomain. Set this only if you fully
// understand the security implications.
UnsafeAllowCredentialsWithWildcard bool
// AllowPrivateNetwork enables the Private Network Access spec.
// When true, preflight responses include Access-Control-Allow-Private-Network.
AllowPrivateNetwork bool
// MaxAge is the preflight cache duration in seconds. Default: 0 (no cache).
MaxAge int
}
Config defines the CORS middleware configuration.