diff options
author | Steve <nilslice@gmail.com> | 2017-02-13 11:06:14 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-13 11:06:14 -0800 |
commit | 4222b04d45b2932022c71eecf909e0e43f5f9d9d (patch) | |
tree | df0a0cc191834d9220fe5a9f952ad61c9527a43e /system/api/cors.go | |
parent | 7a85b284dec2bbb462969fb7e9e949b1a2ae720a (diff) | |
parent | 46d7c021d8de124be803b5c10f157c132343ab4e (diff) |
Merge pull request #73 from ponzu-cms/ponzu-dev
[core] Adding support to omit fields from json response, minor code reorganization
Diffstat (limited to 'system/api/cors.go')
-rw-r--r-- | system/api/cors.go | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/system/api/cors.go b/system/api/cors.go new file mode 100644 index 0000000..249a378 --- /dev/null +++ b/system/api/cors.go @@ -0,0 +1,74 @@ +package api + +import ( + "log" + "net/http" + "net/url" + + "github.com/ponzu-cms/ponzu/system/db" +) + +// sendPreflight is used to respond to a cross-origin "OPTIONS" request +func sendPreflight(res http.ResponseWriter) { + res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type") + res.Header().Set("Access-Control-Allow-Origin", "*") + res.WriteHeader(200) + return +} + +func responseWithCORS(res http.ResponseWriter, req *http.Request) (http.ResponseWriter, bool) { + if db.ConfigCache("cors_disabled").(bool) == true { + // check origin matches config domain + domain := db.ConfigCache("domain").(string) + origin := req.Header.Get("Origin") + u, err := url.Parse(origin) + if err != nil { + log.Println("Error parsing URL from request Origin header:", origin) + return res, false + } + + // hack to get dev environments to bypass cors since u.Host (below) will + // be empty, based on Go's url.Parse function + if domain == "localhost" { + domain = "" + } + origin = u.Host + + // currently, this will check for exact match. will need feedback to + // determine if subdomains should be allowed or allow multiple domains + // in config + if origin == domain { + // apply limited CORS headers and return + res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type") + res.Header().Set("Access-Control-Allow-Origin", domain) + return res, true + } + + // disallow request + res.WriteHeader(http.StatusForbidden) + return res, false + } + + // apply full CORS headers and return + res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type") + res.Header().Set("Access-Control-Allow-Origin", "*") + + return res, true +} + +// CORS wraps a HandlerFunc to respond to OPTIONS requests properly +func CORS(next http.HandlerFunc) http.HandlerFunc { + return db.CacheControl(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + res, cors := responseWithCORS(res, req) + if !cors { + return + } + + if req.Method == http.MethodOptions { + sendPreflight(res) + return + } + + next.ServeHTTP(res, req) + })) +} |