-
Notifications
You must be signed in to change notification settings - Fork 5
/
handler.go
88 lines (79 loc) · 2.54 KB
/
handler.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
package goacors
import (
"context"
"net/http"
"strconv"
"strings"
"github.com/goadesign/goa"
)
// Handler defines behavior building handler
type Handler interface {
Func(handler goa.Handler) goa.Handler
}
type CorsHandler struct {
h goa.Handler
s *goa.Service
c *GoaCORSConfig
om OriginMatcher
allowMethods string
allowHeaders string
exposeHeaders string
maxAge string
}
func newCorsHandler(service *goa.Service, config *GoaCORSConfig, mb MatcherBuilder) Handler {
return &CorsHandler{
s: service,
c: config,
om: mb(config),
}
}
func (h *CorsHandler) handle(c context.Context, rw http.ResponseWriter, req *http.Request) error {
// Skipper
if h.c.Skipper(c, rw, req) {
return h.h(c, rw, req)
}
origin := req.Header.Get(HeaderOrigin)
// Check allowed origins
allowedOrigin, _ := h.om.FindMatchedOrigin(h.c.AllowOrigins, origin)
// Simple request
if req.Method == http.MethodGet || req.Method == http.MethodPost || req.Method == http.MethodHead {
rw.Header().Add(HeaderVary, HeaderOrigin)
rw.Header().Set(HeaderAccessControlAllowOrigin, allowedOrigin)
if h.c.AllowCredentials && allowedOrigin != "*" && allowedOrigin != "" {
rw.Header().Set(HeaderAccessControlAllowCredentials, "true")
}
if h.exposeHeaders != "" {
rw.Header().Set(HeaderAccessControlExposeHeaders, h.exposeHeaders)
}
return h.h(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, h.allowMethods)
if h.c.AllowCredentials && allowedOrigin != "*" && allowedOrigin != "" {
rw.Header().Set(HeaderAccessControlAllowCredentials, "true")
}
if h.allowHeaders != "" {
rw.Header().Set(HeaderAccessControlAllowHeaders, h.allowHeaders)
} else {
header := req.Header.Get(HeaderAccessControlRequestHeaders)
if header != "" {
rw.Header().Set(HeaderAccessControlAllowHeaders, header)
}
}
if h.c.MaxAge > 0 {
rw.Header().Set(HeaderAccessControlMaxAge, h.maxAge)
}
return h.s.Send(c, http.StatusNoContent, http.StatusText(http.StatusNoContent))
}
func (h *CorsHandler) Func(handler goa.Handler) goa.Handler {
h.allowMethods = strings.Join(h.c.AllowMethods, ",")
h.allowHeaders = strings.Join(h.c.AllowHeaders, ",")
h.exposeHeaders = strings.Join(h.c.ExposeHeaders, ",")
h.maxAge = strconv.Itoa(h.c.MaxAge)
h.h = handler
return h.handle
}