1
0
mirror of https://github.com/labstack/echo.git synced 2026-05-16 09:48:24 +02:00
Files
echo/middleware/cors.go
T

139 lines
4.3 KiB
Go
Raw Normal View History

2016-04-07 16:16:58 -07:00
package middleware
import (
"net/http"
"strconv"
"strings"
"github.com/labstack/echo"
)
type (
// CORSConfig defines the config for CORS middleware.
CORSConfig struct {
2016-07-27 09:34:44 -07:00
// Skipper defines a function to skip middleware.
Skipper Skipper
2016-04-07 16:16:58 -07:00
// AllowOrigin defines a list of origins that may access the resource.
2016-11-12 20:24:53 -08:00
// Optional. If request header `Origin` is set, value is []string{"<Origin>"}
// else []string{"*"}.
2016-05-18 18:53:54 -07:00
AllowOrigins []string `json:"allow_origins"`
2016-04-07 16:16:58 -07:00
// AllowMethods defines a list methods allowed when accessing the resource.
// This is used in response to a preflight request.
// Optional. Default value DefaultCORSConfig.AllowMethods.
2016-05-18 18:53:54 -07:00
AllowMethods []string `json:"allow_methods"`
2016-04-07 16:16:58 -07:00
// AllowHeaders defines a list of request headers that can be used when
// making the actual request. This in response to a preflight request.
// Optional. Default value []string{}.
2016-05-18 18:53:54 -07:00
AllowHeaders []string `json:"allow_headers"`
2016-04-07 16:16:58 -07:00
// AllowCredentials indicates whether or not the response to the request
// can be exposed when the credentials flag is true. When used as part of
// a response to a preflight request, this indicates whether or not the
// actual request can be made using credentials.
// Optional. Default value false.
2016-05-18 18:53:54 -07:00
AllowCredentials bool `json:"allow_credentials"`
2016-04-07 16:16:58 -07:00
// ExposeHeaders defines a whitelist headers that clients are allowed to
// access.
// Optional. Default value []string{}.
2016-05-18 18:53:54 -07:00
ExposeHeaders []string `json:"expose_headers"`
2016-04-07 16:16:58 -07:00
// MaxAge indicates how long (in seconds) the results of a preflight request
// can be cached.
// Optional. Default value 0.
2016-05-18 18:53:54 -07:00
MaxAge int `json:"max_age"`
2016-04-07 16:16:58 -07:00
}
)
var (
// DefaultCORSConfig is the default CORS middleware config.
DefaultCORSConfig = CORSConfig{
2016-07-27 09:34:44 -07:00
Skipper: defaultSkipper,
2016-05-31 15:41:09 +03:00
AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE},
2016-04-07 16:16:58 -07:00
}
)
2016-04-07 16:57:57 -07:00
// CORS returns a Cross-Origin Resource Sharing (CORS) middleware.
2016-05-12 17:45:00 -07:00
// See: https://developer.mozilla.org/en/docs/Web/HTTP/Access_control_CORS
2016-04-07 16:16:58 -07:00
func CORS() echo.MiddlewareFunc {
2016-04-07 21:20:50 -07:00
return CORSWithConfig(DefaultCORSConfig)
2016-04-07 16:16:58 -07:00
}
2016-08-31 20:10:14 -07:00
// CORSWithConfig returns a CORS middleware with config.
2016-05-12 17:45:00 -07:00
// See: `CORS()`.
2016-04-07 21:20:50 -07:00
func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
2016-04-07 16:16:58 -07:00
// Defaults
2016-07-27 09:34:44 -07:00
if config.Skipper == nil {
config.Skipper = DefaultCORSConfig.Skipper
}
2016-04-07 16:16:58 -07:00
if len(config.AllowMethods) == 0 {
config.AllowMethods = DefaultCORSConfig.AllowMethods
}
2016-11-12 20:24:53 -08:00
2016-11-12 14:05:41 -08:00
allowedOrigins := strings.Join(config.AllowOrigins, ",")
2016-04-07 16:16:58 -07:00
allowMethods := strings.Join(config.AllowMethods, ",")
allowHeaders := strings.Join(config.AllowHeaders, ",")
exposeHeaders := strings.Join(config.ExposeHeaders, ",")
maxAge := strconv.Itoa(config.MaxAge)
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
2016-07-27 09:34:44 -07:00
if config.Skipper(c) {
return next(c)
}
2016-04-24 10:21:23 -07:00
req := c.Request()
2016-05-03 08:32:28 -07:00
res := c.Response()
2016-11-12 20:24:53 -08:00
origin := req.Header.Get(echo.HeaderOrigin)
if allowedOrigins == "" {
if origin != "" {
allowedOrigins = origin
} else {
if !config.AllowCredentials {
allowedOrigins = "*"
}
}
}
2016-04-07 16:16:58 -07:00
// Simple request
2016-09-22 22:53:44 -07:00
if req.Method != echo.OPTIONS {
2016-05-03 08:32:28 -07:00
res.Header().Add(echo.HeaderVary, echo.HeaderOrigin)
2016-11-12 14:05:41 -08:00
res.Header().Set(echo.HeaderAccessControlAllowOrigin, allowedOrigins)
2016-04-07 16:16:58 -07:00
if config.AllowCredentials {
2016-05-03 08:32:28 -07:00
res.Header().Set(echo.HeaderAccessControlAllowCredentials, "true")
2016-04-07 16:16:58 -07:00
}
if exposeHeaders != "" {
2016-05-03 08:32:28 -07:00
res.Header().Set(echo.HeaderAccessControlExposeHeaders, exposeHeaders)
2016-04-07 16:16:58 -07:00
}
return next(c)
}
// Preflight request
2016-05-03 08:32:28 -07:00
res.Header().Add(echo.HeaderVary, echo.HeaderOrigin)
res.Header().Add(echo.HeaderVary, echo.HeaderAccessControlRequestMethod)
res.Header().Add(echo.HeaderVary, echo.HeaderAccessControlRequestHeaders)
2016-11-12 14:05:41 -08:00
res.Header().Set(echo.HeaderAccessControlAllowOrigin, allowedOrigins)
2016-05-03 08:32:28 -07:00
res.Header().Set(echo.HeaderAccessControlAllowMethods, allowMethods)
2016-04-07 16:16:58 -07:00
if config.AllowCredentials {
2016-05-03 08:32:28 -07:00
res.Header().Set(echo.HeaderAccessControlAllowCredentials, "true")
2016-04-07 16:16:58 -07:00
}
if allowHeaders != "" {
2016-05-03 08:32:28 -07:00
res.Header().Set(echo.HeaderAccessControlAllowHeaders, allowHeaders)
2016-04-07 16:16:58 -07:00
} else {
2016-09-22 22:53:44 -07:00
h := req.Header.Get(echo.HeaderAccessControlRequestHeaders)
2016-04-07 16:16:58 -07:00
if h != "" {
2016-05-03 08:32:28 -07:00
res.Header().Set(echo.HeaderAccessControlAllowHeaders, h)
2016-04-07 16:16:58 -07:00
}
}
if config.MaxAge > 0 {
2016-05-03 08:32:28 -07:00
res.Header().Set(echo.HeaderAccessControlMaxAge, maxAge)
2016-04-07 16:16:58 -07:00
}
return c.NoContent(http.StatusNoContent)
}
}
}