github.com/bosssauce/ponzu@v0.11.1-0.20200102001432-9bc41b703131/system/api/cors.go (about) 1 package api 2 3 import ( 4 "log" 5 "net/http" 6 "net/url" 7 8 "github.com/ponzu-cms/ponzu/system/db" 9 ) 10 11 // sendPreflight is used to respond to a cross-origin "OPTIONS" request 12 func sendPreflight(res http.ResponseWriter) { 13 res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type") 14 res.Header().Set("Access-Control-Allow-Origin", "*") 15 res.WriteHeader(200) 16 return 17 } 18 19 func responseWithCORS(res http.ResponseWriter, req *http.Request) (http.ResponseWriter, bool) { 20 if db.ConfigCache("cors_disabled").(bool) == true { 21 // check origin matches config domain 22 domain := db.ConfigCache("domain").(string) 23 origin := req.Header.Get("Origin") 24 u, err := url.Parse(origin) 25 if err != nil { 26 log.Println("Error parsing URL from request Origin header:", origin) 27 return res, false 28 } 29 30 // hack to get dev environments to bypass cors since u.Host (below) will 31 // be empty, based on Go's url.Parse function 32 if domain == "localhost" { 33 domain = "" 34 } 35 origin = u.Host 36 37 // currently, this will check for exact match. will need feedback to 38 // determine if subdomains should be allowed or allow multiple domains 39 // in config 40 if origin == domain { 41 // apply limited CORS headers and return 42 res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type") 43 res.Header().Set("Access-Control-Allow-Origin", domain) 44 return res, true 45 } 46 47 // disallow request 48 res.WriteHeader(http.StatusForbidden) 49 return res, false 50 } 51 52 // apply full CORS headers and return 53 res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type") 54 res.Header().Set("Access-Control-Allow-Origin", "*") 55 56 return res, true 57 } 58 59 // CORS wraps a HandlerFunc to respond to OPTIONS requests properly 60 func CORS(next http.HandlerFunc) http.HandlerFunc { 61 return db.CacheControl(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { 62 res, cors := responseWithCORS(res, req) 63 if !cors { 64 return 65 } 66 67 if req.Method == http.MethodOptions { 68 sendPreflight(res) 69 return 70 } 71 72 next.ServeHTTP(res, req) 73 })) 74 }