-
Notifications
You must be signed in to change notification settings - Fork 5
/
cors.go
94 lines (86 loc) · 2.82 KB
/
cors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package goacors
import (
"context"
"net/http"
"strconv"
"strings"
"github.com/goadesign/goa"
)
// New return middleware implements checking cors with default config
func New(service *goa.Service) goa.Middleware {
return WithConfig(service, &DefaultGoaCORSConfig)
}
// WithConfig create middleware with configure for this
func WithConfig(service *goa.Service, conf *GoaCORSConfig) goa.Middleware {
if conf == nil {
conf = &DefaultGoaCORSConfig
}
if conf.Skipper == nil {
conf.Skipper = DefaultGoaCORSConfig.Skipper
}
if len(conf.AllowOrigins) == 0 {
conf.AllowOrigins = DefaultGoaCORSConfig.AllowOrigins
}
if len(conf.AllowMethods) == 0 {
conf.AllowMethods = DefaultGoaCORSConfig.AllowMethods
}
if conf.DomainStrategy != AllowIntermediateMatch {
conf.DomainStrategy = AllowStrict
}
allowMethods := strings.Join(conf.AllowMethods, ",")
allowHeaders := strings.Join(conf.AllowHeaders, ",")
exposeHeaders := strings.Join(conf.ExposeHeaders, ",")
maxAge := strconv.Itoa(conf.MaxAge)
var om OriginMatcher
switch conf.DomainStrategy {
case AllowIntermediateMatch:
om = newInterMediateMatcher(conf)
default:
om = newStrictOriginMatcher(conf)
}
return func(next goa.Handler) goa.Handler {
return func(c context.Context, rw http.ResponseWriter, req *http.Request) error {
// Skipper
if conf.Skipper(c, rw, req) {
return next(c, rw, req)
}
origin := req.Header.Get(HeaderOrigin)
// Check allowed origins
allowedOrigin, _ := om.FindMatchedOrigin(conf.AllowOrigins, origin)
// Simple request
if req.Method != http.MethodOptions {
rw.Header().Add(HeaderVary, HeaderOrigin)
rw.Header().Set(HeaderAccessControlAllowOrigin, allowedOrigin)
if conf.AllowCredentials && allowedOrigin != "*" && allowedOrigin != "" {
rw.Header().Set(HeaderAccessControlAllowCredentials, "true")
}
if exposeHeaders != "" {
rw.Header().Set(HeaderAccessControlExposeHeaders, exposeHeaders)
}
return next(c, rw, req)
}
// Preflight request
rw.Header().Add(HeaderVary, HeaderOrigin)
rw.Header().Add(HeaderVary, HeaderAccessControlRequestMethod)
rw.Header().Add(HeaderVary, HeaderAccessControlRequestHeaders)
rw.Header().Set(HeaderAccessControlAllowOrigin, allowedOrigin)
rw.Header().Set(HeaderAccessControlAllowMethods, allowMethods)
if conf.AllowCredentials && allowedOrigin != "*" && allowedOrigin != "" {
rw.Header().Set(HeaderAccessControlAllowCredentials, "true")
}
if allowHeaders != "" {
rw.Header().Set(HeaderAccessControlAllowHeaders, allowHeaders)
} else {
header := req.Header.Get(HeaderAccessControlRequestHeaders)
if header != "" {
rw.Header().Set(HeaderAccessControlAllowHeaders, header)
}
}
if conf.MaxAge > 0 {
rw.Header().Set(HeaderAccessControlMaxAge, maxAge)
}
rw.WriteHeader(http.StatusNoContent)
return nil
}
}
}