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:

  1. 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.
  2. 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:

  1. 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 in API or Service 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, and Credentials which are only used in the Origin 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.

Expand ▾ Collapse ▴

Documentation

Index

Constants

This section is empty.

Variables

View Source
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