diff options
| author | Shulhan <ms@kilabit.info> | 2024-03-05 15:34:37 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2024-03-05 16:21:54 +0700 |
| commit | f27e172853a81d97d37c95f7154c84128e2d6219 (patch) | |
| tree | 3a1fcb7287caa69d4ca216a41aadf1df36fb26c2 | |
| parent | 9e781fabef12b3ce4fa1938061f8a3152420a9f4 (diff) | |
| download | pakakeh.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.go | 49 |
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 |
