Documentation
¶
Overview ¶
Package cors provides CORS middleware with a fluent, composable API.
Basic usage:
http.Handle("/api", cors.AnyOrigin().Wrap(handler))
http.Handle("/app", cors.Origins("https://app.com").MustWrap(handler))
With error handling:
h, err := cors.Origins("https://app.com").AllowCredentials().Handler()
if err != nil {
log.Fatal(err)
}
Multiple policies:
cors.Or(
cors.Origins("https://trusted.com").AllowCredentials(),
cors.AnyOrigin(), // fallback without credentials
).MustHandler()
Index ¶
- type CombinedRule
- type OriginMatcher
- type PublicRule
- func (r PublicRule) AllowHeaders(headers ...string) PublicRule
- func (r PublicRule) AllowMethods(methods ...string) PublicRule
- func (r PublicRule) ExposeHeaders(headers ...string) PublicRule
- func (r PublicRule) Handler() func(http.Handler) http.Handler
- func (r PublicRule) MaxAge(seconds int) PublicRule
- func (r PublicRule) Wrap(h http.Handler) http.Handler
- type Rule
- func (r Rule) AllowCredentials() Rule
- func (r Rule) AllowHeaders(headers ...string) Rule
- func (r Rule) AllowMethods(methods ...string) Rule
- func (r Rule) ExposeHeaders(headers ...string) Rule
- func (r Rule) Handler() (func(http.Handler) http.Handler, error)
- func (r Rule) MaxAge(seconds int) Rule
- func (r Rule) MustHandler() func(http.Handler) http.Handler
- func (r Rule) MustWrap(h http.Handler) http.Handler
- func (r Rule) Wrap(h http.Handler) (http.Handler, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CombinedRule ¶
type CombinedRule struct {
// contains filtered or unexported fields
}
CombinedRule is a set of rules combined with Or. The first matching rule wins.
func Or ¶
func Or(rules ...OriginMatcher) CombinedRule
Or combines multiple rules. The first matching rule wins. Accepts both Rule and PublicRule.
Example:
cors.Or(
cors.Origins("https://trusted.com").AllowCredentials(),
cors.AnyOrigin(), // fallback without credentials
)
Example ¶
package main
import (
"fmt"
"net/http"
"github.com/ahimsalabs/cors"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello")
})
// Different policies for different origins:
// - Trusted origins get credentials
// - Everything else is allowed without credentials
mux := http.NewServeMux()
mux.Handle("/", cors.Or(
cors.Origins("https://trusted.com").AllowCredentials(),
cors.AnyOrigin(), // fallback, no credentials
).MustWrap(handler))
}
func (CombinedRule) Handler ¶
Handler returns the CORS middleware. Returns an error if any rule has invalid configuration.
func (CombinedRule) MustHandler ¶
func (cr CombinedRule) MustHandler() func(http.Handler) http.Handler
MustHandler returns the CORS middleware, panicking if any rule configuration is invalid.
type OriginMatcher ¶
type OriginMatcher interface {
// contains filtered or unexported methods
}
OriginMatcher is implemented by origin matching rule types (PublicRule and Rule). It cannot be implemented outside this package.
type PublicRule ¶
type PublicRule struct {
// contains filtered or unexported fields
}
PublicRule is a CORS rule that allows any origin. It does not have Rule.AllowCredentials because allowing credentials with any origin is a security vulnerability (CORS spec violation). Use OriginFunc if you need this escape hatch.
func AnyOrigin ¶
func AnyOrigin() PublicRule
AnyOrigin creates a rule that matches all origins. Returns PublicRule which does NOT have Rule.AllowCredentials. This prevents the dangerous AnyOrigin + Credentials combination.
Example ¶
package main
import (
"fmt"
"net/http"
"github.com/ahimsalabs/cors"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello")
})
// Allow all origins (suitable for public APIs)
// Note: AnyOrigin() returns PublicRule which does NOT have AllowCredentials()
mux := http.NewServeMux()
mux.Handle("/", cors.AnyOrigin().Wrap(handler))
}
func (PublicRule) AllowHeaders ¶
func (r PublicRule) AllowHeaders(headers ...string) PublicRule
AllowHeaders returns a copy with the specified allowed headers.
func (PublicRule) AllowMethods ¶
func (r PublicRule) AllowMethods(methods ...string) PublicRule
AllowMethods returns a copy with the specified allowed methods.
func (PublicRule) ExposeHeaders ¶
func (r PublicRule) ExposeHeaders(headers ...string) PublicRule
ExposeHeaders returns a copy with the specified exposed headers.
func (PublicRule) Handler ¶
func (r PublicRule) Handler() func(http.Handler) http.Handler
Handler returns the CORS middleware. Panics if configuration is invalid (e.g., forbidden methods/headers, negative MaxAge).
func (PublicRule) MaxAge ¶
func (r PublicRule) MaxAge(seconds int) PublicRule
MaxAge returns a copy with the specified preflight cache duration in seconds. Use MaxAge(0) to explicitly disable preflight caching (overrides browser default).
type Rule ¶
type Rule struct {
// contains filtered or unexported fields
}
Rule is a CORS rule for specific origins. It supports Rule.AllowCredentials because specific origins are safe.
func OriginFunc ¶
OriginFunc creates a Rule with a custom origin matching function. This is the escape hatch for complex scenarios including dynamic origins.
Note: This allocates 1 object per request due to the function call. For static origins, prefer Origins or OriginSuffix.
Warning: If you use this with Rule.AllowCredentials, ensure your function validates origins strictly. A function that returns true for all origins combined with credentials is a security vulnerability.
Example ¶
package main
import (
"fmt"
"net/http"
"github.com/ahimsalabs/cors"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello")
})
// Custom origin matching logic - escape hatch for complex scenarios
// This is the only way to use AllowCredentials with dynamic origins
mux := http.NewServeMux()
mux.Handle("/", cors.OriginFunc(func(origin string) bool {
// Your custom logic here (e.g., database lookup)
return origin == "https://allowed.com"
}).AllowCredentials().MustWrap(handler))
}
func OriginSuffix ¶
OriginSuffix creates a Rule that matches origins by domain suffix.
Patterns:
"example.com" → example.com and *.example.com ".example.com" → *.example.com only (subdomains) "localhost:*" → localhost on any port ".example.com:*" → *.example.com on any port
Matching requires a dot boundary, preventing "evilexample.com" from matching "example.com".
Example ¶
package main
import (
"fmt"
"net/http"
"github.com/ahimsalabs/cors"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello")
})
// "example.com" matches example.com AND *.example.com
// ".example.com" matches only *.example.com (subdomains only)
mux := http.NewServeMux()
mux.Handle("/", cors.OriginSuffix("example.com").MustWrap(handler))
}
func Origins ¶
Origins creates a Rule that matches specific origins exactly.
Example ¶
package main
import (
"fmt"
"net/http"
"github.com/ahimsalabs/cors"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello")
})
// Allow only specific origins (can use AllowCredentials)
// Use MustWrap for examples/tests; use Wrap with error handling in production
mux := http.NewServeMux()
mux.Handle("/", cors.Origins(
"https://app.example.com",
"https://admin.example.com",
).AllowCredentials().MustWrap(handler))
}
func (Rule) AllowCredentials ¶
AllowCredentials returns a copy with credentials enabled. When enabled, Access-Control-Allow-Credentials: true is sent, allowing browsers to send cookies and auth headers.
This also adds "Authorization" to allowed headers if not already present, since most credentialed APIs use Bearer tokens.
func (Rule) AllowHeaders ¶
AllowHeaders returns a copy with the specified allowed headers.
func (Rule) AllowMethods ¶
AllowMethods returns a copy with the specified allowed methods.
func (Rule) ExposeHeaders ¶
ExposeHeaders returns a copy with the specified exposed headers.
func (Rule) Handler ¶
Handler returns the CORS middleware. Returns an error if the configuration is invalid.
For scripts and tests where panics are acceptable, use MustHandler instead.
func (Rule) MaxAge ¶
MaxAge returns a copy with the specified preflight cache duration in seconds. Use MaxAge(0) to explicitly disable preflight caching (overrides browser default).
func (Rule) MustHandler ¶
MustHandler returns the CORS middleware, panicking if the configuration is invalid. Use this for variable initialization and tests:
var corsHandler = cors.Origins("https://app.com").MustHandler()
For production code that cannot tolerate panics, use Handler instead.
