Add CORS headers to all responses including errors
MODIFY
src/github.com/matrix-org/dendrite/cmd/dendrite-client-api-server/main.go
src/github.com/matrix-org/dendrite/cmd/dendrite-client-api-server/main.go
@@ -121,7 +121,7 @@ func main() {
queryAPI, aliasAPI, accountDB, deviceDB, federation, keyRing,
userUpdateProducer, syncProducer,
)
- common.SetupHTTPAPI(http.DefaultServeMux, api)
+ common.SetupHTTPAPI(http.DefaultServeMux, common.WrapHandlerInCORS(api))
log.Fatal(http.ListenAndServe(string(cfg.Listen.ClientAPI), nil))
}

MODIFY
src/github.com/matrix-org/dendrite/cmd/dendrite-media-api-server/main.go
src/github.com/matrix-org/dendrite/cmd/dendrite-media-api-server/main.go
@@ -70,7 +70,7 @@ func main() {
api := mux.NewRouter()
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))
}

MODIFY
src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go
src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go
@@ -103,7 +103,7 @@ func main() {
// Expose the matrix APIs directly rather than putting them under a /api path.
go func() {
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
go func() {

MODIFY
src/github.com/matrix-org/dendrite/cmd/dendrite-public-rooms-api-server/main.go
src/github.com/matrix-org/dendrite/cmd/dendrite-public-rooms-api-server/main.go
@@ -85,7 +85,7 @@ func main() {
api := mux.NewRouter()
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))
}

MODIFY
src/github.com/matrix-org/dendrite/cmd/dendrite-sync-api-server/main.go
src/github.com/matrix-org/dendrite/cmd/dendrite-sync-api-server/main.go
@@ -105,7 +105,7 @@ func main() {
api := mux.NewRouter()
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))
}

MODIFY
src/github.com/matrix-org/dendrite/common/httpapi.go
src/github.com/matrix-org/dendrite/common/httpapi.go
@@ -4,7 +4,6 @@ import (
"net/http"
"time"
- "github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/auth"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/gomatrixserverlib"
@@ -87,8 +86,29 @@ func MakeFedAPI(
// SetupHTTPAPI registers an HTTP API mux under /api and sets up a metrics
// listener.
-func SetupHTTPAPI(servMux *http.ServeMux, apiMux *mux.Router) {
+func SetupHTTPAPI(servMux *http.ServeMux, apiMux http.Handler) {
// This is deprecated.
servMux.Handle("/metrics", prometheus.Handler()) // nolint: megacheck, staticcheck
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)
+ }
+ })
+}

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