cors
Configurable CORS middleware for the Gin web framework in Go, with fine-grained origin, header, and credential rules.
Repository Health
Technical Analysis
gin-contrib/cors is the official Cross-Origin Resource Sharing (CORS) middleware for the Gin HTTP framework. It plugs into a Gin router as a single Use() call and handles preflight OPTIONS requests and response headers for cross-origin browser requests, so application code never has to hand-roll Access-Control-* header logic.
Configuration is driven by a single Config struct covering allowed origins (exact, wildcard, or a custom validator function), allowed methods and headers, credentialed requests, exposed headers, preflight cache duration (MaxAge), private network access, and non-HTTP origin schemes such as browser extensions, WebSockets, and file://. A Validate() step catches conflicting settings (e.g. allowing all origins while also requiring credentials) before the middleware is even constructed, turning a class of runtime CORS bugs into an explicit startup error.
For teams running a Gin API that’s consumed from a separate frontend origin, it replaces bespoke header-setting middleware with a well-tested, actively maintained package that already handles the edge cases (wildcard subdomains, custom schemes, per-request origin callbacks) that are easy to get subtly wrong when implemented by hand.
What You Get
- One-line integration via
cors.Default()(allow-all) orcors.New(config)for custom rules, added with a singlerouter.Use()call - A
Configstruct covering allowed origins, methods, headers, exposed headers, credentials, and preflight cache duration (MaxAge) - Wildcard origin matching (
https://*.example.com) and support for non-HTTP schemes: browser extensions, WebSockets (ws:///wss://), andfile:// - Custom origin validation via
AllowOriginFuncor the context-awareAllowOriginWithContextFuncfor per-request logic (e.g. header-gated origins) - Fluent helper methods (
AddAllowMethods,AddAllowHeaders,AddExposeHeaders) to extend a base config incrementally - Built-in
Validate()that rejects conflicting configuration (e.g.AllowAllOriginscombined with credentials) at construction time instead of failing silently at request time
Common Use Cases
- Allowing a separately hosted single-page app (React/Vue/etc.) to call a Gin-based JSON API from a different origin
- Locking down a production API to an explicit list of trusted origins while allowing credentialed (cookie/auth-header) requests
- Supporting wildcard subdomains for multi-tenant SaaS apps where each tenant gets its own subdomain origin
- Enabling CORS for desktop or extension clients that call the API from non-HTTP origins like
tauri://orchrome-extension:// - Tuning preflight caching (
MaxAge) to reduce redundantOPTIONSround-trips for high-traffic browser clients
Under The Hood
Architecture
The package splits cleanly into three files by responsibility: cors.go exposes the public surface — the Config struct, its Validate()/parseWildcardRules() methods, and the Default()/New() constructors that return a gin.HandlerFunc; config.go holds the internal cors struct that does the actual per-request work (applyCors, validateOrigin, validateWildcardOrigin), constructed once via newCors() from a validated Config; and utils.go contains pure header-generation and string-normalization helpers. A deliberate performance choice runs through the design: normal-request and preflight-request header sets (normalHeaders, preflightHeaders) are computed once at middleware-construction time rather than rebuilt on every request, so the hot path in applyCors only does origin comparison and a header-map copy.
Tech Stack
A small, dependency-light Go module (go 1.25) whose only non-test runtime dependency is github.com/gin-gonic/gin (the framework it extends); stretchr/testify is used for test assertions. Releases are cut with GoReleaser (.goreleaser.yaml), CI runs on GitHub Actions (go.yml), and the repo layers in CodeQL static analysis and a Trivy vulnerability scan as separate workflows alongside Dependabot for automated dependency bumps.
Code Quality
Testing is extensive relative to the package’s size — cors_test.go alone covers single- and multi-route-group routers, mixed-case HTTP methods, every origin-matching mode (exact, wildcard, regex-style, browser-extension schemes), credentialed vs. non-credentialed flows, and preflight-specific headers, all via table-driven-style helpers (performRequestWithHeaders) and testify/assert. A .golangci.yml pins the linter configuration, and the CodeQL/Trivy workflows add static and dependency-vulnerability scanning on top of the standard test suite. No test files were found to be missing coverage for any exported behavior observed during review.
API Design
The public API favors progressive disclosure: cors.Default() needs zero configuration for a permissive dev setup, cors.DefaultConfig() gives sane starting defaults to customize, and cors.New(cors.Config{...}) exposes every knob for production use. Every exported field on Config carries a doc comment explaining its default and effect, and the README pairs a full configuration-reference table with runnable snippets for the most common patterns (custom origin functions, context-aware validation, wildcard subdomains). Misconfiguration fails fast and explicitly via Validate() rather than producing silently-wrong CORS headers, which is a meaningfully better failure mode than most hand-rolled middleware of this kind.
Used by 4 apps in this directory
Gotify
Monitoring · Developer Tools
A lightweight, self-hosted push notification server that sends and receives messages in real time over WebSocket, with a sleek web UI and a native Go plugin system.
Ollama
AI Development · Developer Tools
Run Llama, Gemma, DeepSeek, and other open LLMs on your own machine with one command and an OpenAI-compatible API.
Owlistic
Note Taking · Productivity
Self-hosted, open-source real-time note-taking and task management with WYSIWYG editing, live sync, and role-based access control.
TDengine
Databases
A high-performance, open-source time-series database built in C for IoT, connected vehicles, and industrial monitoring workloads, with built-in stream processing, caching, and data subscription.