summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-03-05 15:34:37 +0700
committerShulhan <ms@kilabit.info>2024-03-05 16:21:54 +0700
commitf27e172853a81d97d37c95f7154c84128e2d6219 (patch)
tree3a1fcb7287caa69d4ca216a41aadf1df36fb26c2
parent9e781fabef12b3ce4fa1938061f8a3152420a9f4 (diff)
downloadpakakeh.go-f27e172853a81d97d37c95f7154c84128e2d6219.tar.xz
lib/http: handle CORS independently
Previously, if [CORSOptions.AllowOrigins] not found we return it immediately without checking request "Access-Control-Request-Method", "Access-Control-Request-Headers", and other CORS options. This changes check each of them, a missing allow origins does not means empty allowed method, headers, MaxAge, or credentials.
-rw-r--r--lib/http/server.go49
1 files changed, 26 insertions, 23 deletions
diff --git a/lib/http/server.go b/lib/http/server.go
index 4bcfd19a..b982b88c 100644
--- a/lib/http/server.go
+++ b/lib/http/server.go
@@ -389,45 +389,43 @@ func (srv *Server) getFSNode(reqPath string) (node *memfs.Node, isDir bool) {
//
// Reference: https://www.html5rocks.com/static/images/cors_server_flowchart.png
func (srv *Server) handleCORS(res http.ResponseWriter, req *http.Request) {
- var found bool
- preflightOrigin := req.Header.Get(HeaderOrigin)
+ var preflightOrigin = req.Header.Get(HeaderOrigin)
if len(preflightOrigin) == 0 {
return
}
+ // Set the "Access-Control-Allow-Origin" header based on the request
+ // Origin and matched allowed origin.
+ // If one of the AllowOrigins contains wildcard "*", then allow all.
+
for _, origin := range srv.Options.CORS.AllowOrigins {
if origin == corsWildcard {
res.Header().Set(HeaderACAllowOrigin, preflightOrigin)
- found = true
break
}
if origin == preflightOrigin {
res.Header().Set(HeaderACAllowOrigin, preflightOrigin)
- found = true
break
}
}
- if !found {
- return
- }
- preflightMethod := req.Header.Get(HeaderACRequestMethod)
+ // Set the "Access-Control-Allow-Method" header based on the request
+ // header "Access-Control-Request-Method", only allow HTTP method
+ // DELETE, GET, PATCH, POST, and PUT.
+ // If no "Access-Control-Request-Method", set the response header
+ // "Access-Control-Expose-Headers" based on predefined values.
+
+ var preflightMethod = req.Header.Get(HeaderACRequestMethod)
if len(preflightMethod) == 0 {
if len(srv.Options.CORS.exposeHeaders) > 0 {
- res.Header().Set(
- HeaderACExposeHeaders,
- srv.Options.CORS.exposeHeaders,
- )
+ res.Header().Set(HeaderACExposeHeaders, srv.Options.CORS.exposeHeaders)
}
- return
- }
-
- switch preflightMethod {
- case http.MethodGet, http.MethodPost, http.MethodPut,
- http.MethodPatch, http.MethodDelete:
+ } else if preflightMethod == http.MethodDelete ||
+ preflightMethod == http.MethodGet ||
+ preflightMethod == http.MethodPatch ||
+ preflightMethod == http.MethodPost ||
+ preflightMethod == http.MethodPut {
res.Header().Set(HeaderACAllowMethod, preflightMethod)
- default:
- return
}
srv.handleCORSRequestHeaders(res, req)
@@ -440,9 +438,14 @@ func (srv *Server) handleCORS(res http.ResponseWriter, req *http.Request) {
}
}
-func (srv *Server) handleCORSRequestHeaders(
- res http.ResponseWriter, req *http.Request,
-) {
+// handleCORSRequestHeaders set the response header
+// "Access-Control-Allow-Headers" based on the request header
+// "Access-Control-Request-Headers".
+// If [CORSOptions.AllowHeaders] is empty, no requested headers will be
+// allowed.
+// If [CORSOptions.AllowHeaders] contains wildcard "*", all requested
+// headers are allowed.
+func (srv *Server) handleCORSRequestHeaders(res http.ResponseWriter, req *http.Request) {
preflightHeaders := req.Header.Get(HeaderACRequestHeaders)
if len(preflightHeaders) == 0 {
return