From bae26ec268aef4e85d5055f1b83c6b3992bf178f Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Thu, 26 Jul 2018 08:31:22 -0700 Subject: MM-11160 Adding proper CORS support. (#9152) * Adding proper CORS support. * Better CORS tests. --- app/server.go | 55 ++++++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) (limited to 'app/server.go') diff --git a/app/server.go b/app/server.go index 769690295..6b2e244d8 100644 --- a/app/server.go +++ b/app/server.go @@ -18,6 +18,7 @@ import ( "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/pkg/errors" + "github.com/rs/cors" "golang.org/x/crypto/acme/autocert" "github.com/mattermost/mattermost-server/mlog" @@ -44,7 +45,7 @@ type Server struct { didFinishListen chan struct{} } -var allowedMethods []string = []string{ +var corsAllowedMethods []string = []string{ "POST", "GET", "OPTIONS", @@ -61,35 +62,6 @@ func (rl *RecoveryLogger) Println(i ...interface{}) { mlog.Error(fmt.Sprint(i)) } -type CorsWrapper struct { - config model.ConfigFunc - router *mux.Router -} - -func (cw *CorsWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if allowed := *cw.config().ServiceSettings.AllowCorsFrom; allowed != "" { - if utils.CheckOrigin(r, allowed) { - w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) - - if r.Method == "OPTIONS" { - w.Header().Set( - "Access-Control-Allow-Methods", - strings.Join(allowedMethods, ", ")) - - w.Header().Set( - "Access-Control-Allow-Headers", - r.Header.Get("Access-Control-Request-Headers")) - } - } - } - - if r.Method == "OPTIONS" { - return - } - - cw.router.ServeHTTP(w, r) -} - const TIME_TO_WAIT_FOR_CONNECTIONS_TO_CLOSE_ON_SERVER_SHUTDOWN = time.Second // golang.org/x/crypto/acme/autocert/autocert.go @@ -114,7 +86,28 @@ func stripPort(hostport string) string { func (a *App) StartServer() error { mlog.Info("Starting Server...") - var handler http.Handler = &CorsWrapper{a.Config, a.Srv.RootRouter} + var handler http.Handler = a.Srv.RootRouter + if allowedOrigins := *a.Config().ServiceSettings.AllowCorsFrom; allowedOrigins != "" { + exposedCorsHeaders := *a.Config().ServiceSettings.CorsExposedHeaders + allowCredentials := *a.Config().ServiceSettings.CorsAllowCredentials + debug := *a.Config().ServiceSettings.CorsDebug + corsWrapper := cors.New(cors.Options{ + AllowedOrigins: strings.Fields(allowedOrigins), + AllowedMethods: corsAllowedMethods, + AllowedHeaders: []string{"*"}, + ExposedHeaders: strings.Fields(exposedCorsHeaders), + MaxAge: 86400, + AllowCredentials: allowCredentials, + Debug: debug, + }) + + // If we have debugging of CORS turned on then forward messages to logs + if debug { + corsWrapper.Log = a.Log.StdLog(mlog.String("source", "cors")) + } + + handler = corsWrapper.Handler(handler) + } if *a.Config().RateLimitSettings.Enable { mlog.Info("RateLimiter is enabled") -- cgit v1.2.3-1-g7c22