@@ -3,6 +3,7 @@ package middlewares
33import (
44 "net/http"
55 "net/url"
6+ "slices"
67 "strings"
78
89 "github.com/codeshelldev/secured-signal-api/internals/config"
@@ -31,6 +32,12 @@ func corsHandler(next http.Handler) http.Handler {
3132 }
3233
3334 origin := req .Header .Get ("Origin" )
35+
36+ if origin == "" {
37+ next .ServeHTTP (w , req )
38+ return
39+ }
40+
3441 originURL , err := url .Parse (origin )
3542
3643 var matchingOrigin * structure.Origin
@@ -50,14 +57,49 @@ func corsHandler(next http.Handler) http.Handler {
5057
5158 w .Header ().Set ("Access-Control-Allow-Origin" , origin )
5259
53- w .Header ().Set ("Access-Control-Allow-Credentials" , "true" )
54-
60+ // CORS preflight request
5561 if req .Method == "OPTIONS" {
56- methods := matchingOrigin .Methods .ValueOrFallback (defaultMethods )
57- headers := matchingOrigin .Headers .ValueOrFallback (defaultHeaders )
62+ requestedMethod := req .Header .Get ("Access-Control-Request-Method" )
63+
64+ if requestedMethod != "" {
65+ allowedMethods := matchingOrigin .Methods .ValueOrFallback (defaultMethods )
66+
67+ if len (allowedMethods ) != 0 {
68+ // only set if any (matching) methods
69+ w .Header ().Set ("Access-Control-Allow-Methods" , strings .Join (allowedMethods , "," ))
70+ }
71+ }
5872
59- w .Header ().Set ("Access-Control-Allow-Methods" , strings .Join (methods , "," ))
60- w .Header ().Set ("Access-Control-Allow-Headers" , strings .Join (headers , "," ))
73+ requestedHeaders := req .Header .Get ("Access-Control-Request-Headers" )
74+
75+ if requestedHeaders != "" {
76+ allowedHeaders := matchingOrigin .Headers .ValueOrFallback (defaultHeaders )
77+
78+ matchingHeaders := []string {}
79+
80+ // echo back allowed and requested headers
81+ for header := range strings .SplitSeq (requestedHeaders , "," ) {
82+ header = strings .TrimSpace (header )
83+
84+ var match string
85+
86+ if slices .ContainsFunc (allowedHeaders , func (allowed string ) bool {
87+ if strings .EqualFold (header , allowed ) {
88+ match = allowed
89+ return true
90+ }
91+
92+ return false
93+ }) {
94+ matchingHeaders = append (matchingHeaders , match )
95+ }
96+ }
97+
98+ if len (matchingHeaders ) != 0 {
99+ // only set if any (matching) headers
100+ w .Header ().Set ("Access-Control-Allow-Headers" , strings .Join (matchingHeaders , "," ))
101+ }
102+ }
61103
62104 w .WriteHeader (http .StatusNoContent )
63105
0 commit comments