Add CORS headers to all responses including errors (#364)

This commit is contained in:
Erik Johnston 2017-12-06 09:36:50 +00:00 committed by GitHub
parent bc3dd821f9
commit 578d8cf492
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 7 deletions

View File

@ -121,7 +121,7 @@ func main() {
queryAPI, aliasAPI, accountDB, deviceDB, federation, keyRing, queryAPI, aliasAPI, accountDB, deviceDB, federation, keyRing,
userUpdateProducer, syncProducer, userUpdateProducer, syncProducer,
) )
common.SetupHTTPAPI(http.DefaultServeMux, api) common.SetupHTTPAPI(http.DefaultServeMux, common.WrapHandlerInCORS(api))
log.Fatal(http.ListenAndServe(string(cfg.Listen.ClientAPI), nil)) log.Fatal(http.ListenAndServe(string(cfg.Listen.ClientAPI), nil))
} }

View File

@ -70,7 +70,7 @@ func main() {
api := mux.NewRouter() api := mux.NewRouter()
routing.Setup(api, cfg, db, deviceDB, client) routing.Setup(api, cfg, db, deviceDB, client)
common.SetupHTTPAPI(http.DefaultServeMux, api) common.SetupHTTPAPI(http.DefaultServeMux, common.WrapHandlerInCORS(api))
log.Fatal(http.ListenAndServe(string(cfg.Listen.MediaAPI), nil)) log.Fatal(http.ListenAndServe(string(cfg.Listen.MediaAPI), nil))
} }

View File

@ -103,7 +103,7 @@ func main() {
// Expose the matrix APIs directly rather than putting them under a /api path. // Expose the matrix APIs directly rather than putting them under a /api path.
go func() { go func() {
log.Info("Listening on ", *httpBindAddr) log.Info("Listening on ", *httpBindAddr)
log.Fatal(http.ListenAndServe(*httpBindAddr, m.api)) log.Fatal(http.ListenAndServe(*httpBindAddr, common.WrapHandlerInCORS(m.api)))
}() }()
// Handle HTTPS if certificate and key are provided // Handle HTTPS if certificate and key are provided
go func() { go func() {

View File

@ -85,7 +85,7 @@ func main() {
api := mux.NewRouter() api := mux.NewRouter()
routing.Setup(api, deviceDB, db) routing.Setup(api, deviceDB, db)
common.SetupHTTPAPI(http.DefaultServeMux, api) common.SetupHTTPAPI(http.DefaultServeMux, common.WrapHandlerInCORS(api))
log.Fatal(http.ListenAndServe(string(cfg.Listen.PublicRoomsAPI), nil)) log.Fatal(http.ListenAndServe(string(cfg.Listen.PublicRoomsAPI), nil))
} }

View File

@ -105,7 +105,7 @@ func main() {
api := mux.NewRouter() api := mux.NewRouter()
routing.Setup(api, sync.NewRequestPool(db, n, adb), db, deviceDB) routing.Setup(api, sync.NewRequestPool(db, n, adb), db, deviceDB)
common.SetupHTTPAPI(http.DefaultServeMux, api) common.SetupHTTPAPI(http.DefaultServeMux, common.WrapHandlerInCORS(api))
log.Fatal(http.ListenAndServe(string(cfg.Listen.SyncAPI), nil)) log.Fatal(http.ListenAndServe(string(cfg.Listen.SyncAPI), nil))
} }

View File

@ -4,7 +4,6 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/auth" "github.com/matrix-org/dendrite/clientapi/auth"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
@ -87,8 +86,29 @@ func MakeFedAPI(
// SetupHTTPAPI registers an HTTP API mux under /api and sets up a metrics // SetupHTTPAPI registers an HTTP API mux under /api and sets up a metrics
// listener. // listener.
func SetupHTTPAPI(servMux *http.ServeMux, apiMux *mux.Router) { func SetupHTTPAPI(servMux *http.ServeMux, apiMux http.Handler) {
// This is deprecated. // This is deprecated.
servMux.Handle("/metrics", prometheus.Handler()) // nolint: megacheck, staticcheck servMux.Handle("/metrics", prometheus.Handler()) // nolint: megacheck, staticcheck
servMux.Handle("/api/", http.StripPrefix("/api", apiMux)) servMux.Handle("/api/", http.StripPrefix("/api", apiMux))
} }
// WrapHandlerInCORS adds CORS headers to all responses, including all error
// responses.
// Handles OPTIONS requests directly.
func WrapHandlerInCORS(h http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
if r.Method == "OPTIONS" && r.Header.Get("Access-Control-Request-Method") != "" {
// Its easiest just to always return a 200 OK for everything. Whether
// this is technically correct or not is a question, but in the end this
// is what a lot of other people do (including synapse) and the clients
// are perfectly happy with it.
w.WriteHeader(http.StatusOK)
} else {
h.ServeHTTP(w, r)
}
})
}