README
¶
CORS Plugin
The cors
plugin is a goa v2 plugin
that makes it possible to define Cross-Origin Resource Sharing (CORS) policies for
the server endpoints.
Enabling the Plugin
To enable the plugin and make use of the CORS DSL simply import both the cors
and
the dsl
packages as follows:
import (
_ "goa.design/plugins/cors/dsl"
. "goa.design/goa/dsl"
)
Note the use of blank identifier to import the cors
package which is necessary
as the package is imported solely for its side-effects (initialization).
Effects on Code Generation
Enabling the plugin changes the behavior of both the gen
and example
commands
of the goa
tool.
The gen
command output is modified as follows:
- A new CORS handler is appended to the HTTP server initialization code. This handler is configured to handle the preflight (OPTIONS) request from the client (browser) for the applicable endpoints. The handler simply returns a 200 OK response containing the CORS headers.
- All HTTP endpoint handlers are modified to add the CORS headers in the response based on the CORS policy definition.
The example
command output is modified as follows:
- The example server is initialized with the CORS handler to handle the preflight requests.
Design
This plugin adds the following functions to the goa DSL:
Origin
is used inAPI
orService
DSLs to define the CORS policy that apply globally to all the endpoints defined in the design (API
) or to all the endpoints in a service (Service
).- Origin specific functions such as
Methods
,Expose
,Headers
,MaxAge
, andCredentials
which are only used in theOrigin
DSL to define CORS headers to be set in the response.
The usage and effect of the DSL functions are described in the Godocs
Here is an example defining a CORS policy at a service level.
var _ = Service("calc", func() {
// Sets CORS response headers for requests with Origin header matching the string "localhost"
Origin("localhost")
// Sets CORS response headers for requests with Origin header matching strings ending with ".domain.com" (e.g. "my.domain.com")
Origin("*.domain.com", func() {
Headers("X-Shared-Secret", "X-Api-Version")
MaxAge(100)
Credentials()
})
// Sets CORS response headers for requests with any Origin header
Origin("*")
// Sets CORS response headers for requests with Origin header matching the regular expression ".*domain.*"
Origin("/.*domain.*/", func() {
Headers("*")
Methods("GET", "POST")
Expose("X-Time")
})
})
Defining a CORS policy at the API-level is similar to the example above.
Documentation
¶
Index ¶
- Variables
- func Generate(genpkg string, roots []eval.Root, files []*codegen.File) ([]*codegen.File, error)
- func MatchOrigin(origin, spec string) bool
- func MatchOriginRegexp(origin string, spec *regexp.Regexp) bool
- func TweakExample(genpkg string, roots []eval.Root, files []*codegen.File) ([]*codegen.File, error)
- type ServiceData
Constants ¶
This section is empty.
Variables ¶
var ServicesData = make(map[string]*ServiceData)
ServicesData holds the all the ServiceData indexed by service name.
Functions ¶
func Generate ¶
func Generate(genpkg string, roots []eval.Root, files []*codegen.File) ([]*codegen.File, error)
Generate produces server code that handle preflight requests and updates the HTTP responses with the appropriate CORS headers.
func MatchOrigin ¶
func MatchOrigin(origin, spec string) bool
MatchOrigin returns true if the given Origin header value matches the origin specification. Spec can be one of: - a plain string identifying an origin. eg http://swagger.goa.design - a plain string containing a wildcard. eg *.goa.design - the special string * that matches every host
func MatchOriginRegexp ¶
func MatchOriginRegexp(origin string, spec *regexp.Regexp) bool
MatchOriginRegexp returns true if the given Origin header value matches the origin specification. Spec must be a valid regex
func TweakExample ¶
func TweakExample(genpkg string, roots []eval.Root, files []*codegen.File) ([]*codegen.File, error)
TweakExample handles the special case where a service only has file servers and no method in which case the Goa generator generate a Mount method that does not take a second argument but this plugin generates one that does. The second argument is the actual HTTP server which is needed so it can be configured with the CORS endpoint. So this method simply removes the special case from the Goa template generating the example.
Types ¶
type ServiceData ¶
type ServiceData struct {
// Name is the name of the service.
Name string
// Origins is a list of origin expressions defined in API and service levels.
Origins []*expr.OriginExpr
// OriginHandler is the name of the handler function that sets CORS headers.
OriginHandler string
// PreflightPaths is the list of paths that should handle OPTIONS requests.
PreflightPaths []string
// Endpoint is the CORS endpoint data.
Endpoint *httpcodegen.EndpointData
}
ServiceData contains the data necessary to generate origin handlers