apiserver: refactor cors filter
Kubernetes-commit: ea251b5605c22d82962d4e699d933428e4c9c211
This commit is contained in:
parent
5b1e3f38d8
commit
c44ad6bb02
|
@ -38,44 +38,76 @@ func WithCORS(handler http.Handler, allowedOriginPatterns []string, allowedMetho
|
|||
return handler
|
||||
}
|
||||
allowedOriginPatternsREs := allowedOriginRegexps(allowedOriginPatterns)
|
||||
|
||||
// Set defaults for methods and headers if nothing was passed
|
||||
if allowedMethods == nil {
|
||||
allowedMethods = []string{"POST", "GET", "OPTIONS", "PUT", "DELETE", "PATCH"}
|
||||
}
|
||||
allowMethodsResponseHeader := strings.Join(allowedMethods, ", ")
|
||||
|
||||
if allowedHeaders == nil {
|
||||
allowedHeaders = []string{"Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization", "X-Requested-With", "If-Modified-Since"}
|
||||
}
|
||||
allowHeadersResponseHeader := strings.Join(allowedHeaders, ", ")
|
||||
|
||||
if exposedHeaders == nil {
|
||||
exposedHeaders = []string{"Date"}
|
||||
}
|
||||
exposeHeadersResponseHeader := strings.Join(exposedHeaders, ", ")
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
origin := req.Header.Get("Origin")
|
||||
if origin != "" {
|
||||
allowed := false
|
||||
for _, re := range allowedOriginPatternsREs {
|
||||
if allowed = re.MatchString(origin); allowed {
|
||||
break
|
||||
}
|
||||
}
|
||||
if allowed {
|
||||
w.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
// Set defaults for methods and headers if nothing was passed
|
||||
if allowedMethods == nil {
|
||||
allowedMethods = []string{"POST", "GET", "OPTIONS", "PUT", "DELETE", "PATCH"}
|
||||
}
|
||||
if allowedHeaders == nil {
|
||||
allowedHeaders = []string{"Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization", "X-Requested-With", "If-Modified-Since"}
|
||||
}
|
||||
if exposedHeaders == nil {
|
||||
exposedHeaders = []string{"Date"}
|
||||
}
|
||||
w.Header().Set("Access-Control-Allow-Methods", strings.Join(allowedMethods, ", "))
|
||||
w.Header().Set("Access-Control-Allow-Headers", strings.Join(allowedHeaders, ", "))
|
||||
w.Header().Set("Access-Control-Expose-Headers", strings.Join(exposedHeaders, ", "))
|
||||
w.Header().Set("Access-Control-Allow-Credentials", allowCredentials)
|
||||
|
||||
// Stop here if its a preflight OPTIONS request
|
||||
if req.Method == "OPTIONS" {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
}
|
||||
if origin == "" {
|
||||
handler.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
if !isOriginAllowed(origin, allowedOriginPatternsREs) {
|
||||
handler.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
w.Header().Set("Access-Control-Allow-Methods", allowMethodsResponseHeader)
|
||||
w.Header().Set("Access-Control-Allow-Headers", allowHeadersResponseHeader)
|
||||
w.Header().Set("Access-Control-Expose-Headers", exposeHeadersResponseHeader)
|
||||
w.Header().Set("Access-Control-Allow-Credentials", allowCredentials)
|
||||
|
||||
// Stop here if its a preflight OPTIONS request
|
||||
if req.Method == "OPTIONS" {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
// Dispatch to the next handler
|
||||
handler.ServeHTTP(w, req)
|
||||
})
|
||||
}
|
||||
|
||||
// isOriginAllowed returns true if the given origin header in the
|
||||
// request is allowed CORS.
|
||||
//
|
||||
// From https://www.rfc-editor.org/rfc/rfc6454#page-13
|
||||
//
|
||||
// a) The origin header can contain host and/or port
|
||||
// serialized-origin = scheme "://" host [ ":" port ]
|
||||
//
|
||||
// b) In some cases, a number of origins contribute to causing the user
|
||||
// agents to issue an HTTP request. In those cases, the user agent MAY
|
||||
// list all the origins in the Origin header field. For example, if the
|
||||
// HTTP request was initially issued by one origin but then later
|
||||
// redirected by another origin, the user agent MAY inform the server
|
||||
// that two origins were involved in causing the user agent to issue the
|
||||
// request
|
||||
// origin-list = serialized-origin *( SP serialized-origin )
|
||||
func isOriginAllowed(originHeader string, allowedOriginPatternsREs []*regexp.Regexp) bool {
|
||||
for _, re := range allowedOriginPatternsREs {
|
||||
if re.MatchString(originHeader) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func allowedOriginRegexps(allowedOrigins []string) []*regexp.Regexp {
|
||||
res, err := compileRegexps(allowedOrigins)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue