diff --git a/pkg/common/cors.go b/pkg/common/cors.go index 45a4078..11336a4 100644 --- a/pkg/common/cors.go +++ b/pkg/common/cors.go @@ -114,11 +114,14 @@ func GetHeadSpecHeaders() []string { } // SetCORSHeaders sets CORS headers on a response writer -func SetCORSHeaders(w ResponseWriter, config CORSConfig) { +func SetCORSHeaders(w ResponseWriter, r Request, config CORSConfig) { // Set allowed origins - if len(config.AllowedOrigins) > 0 { - w.SetHeader("Access-Control-Allow-Origin", strings.Join(config.AllowedOrigins, ", ")) - } + // if len(config.AllowedOrigins) > 0 { + // w.SetHeader("Access-Control-Allow-Origin", strings.Join(config.AllowedOrigins, ", ")) + // } + + // Todo origin list parsing + w.SetHeader("Access-Control-Allow-Origin", "*") // Set allowed methods if len(config.AllowedMethods) > 0 { @@ -126,9 +129,10 @@ func SetCORSHeaders(w ResponseWriter, config CORSConfig) { } // Set allowed headers - if len(config.AllowedHeaders) > 0 { - w.SetHeader("Access-Control-Allow-Headers", strings.Join(config.AllowedHeaders, ", ")) - } + // if len(config.AllowedHeaders) > 0 { + // w.SetHeader("Access-Control-Allow-Headers", strings.Join(config.AllowedHeaders, ", ")) + // } + w.SetHeader("Access-Control-Allow-Headers", "*") // Set max age if config.MaxAge > 0 { @@ -139,5 +143,7 @@ func SetCORSHeaders(w ResponseWriter, config CORSConfig) { w.SetHeader("Access-Control-Allow-Credentials", "true") // Expose headers that clients can read - w.SetHeader("Access-Control-Expose-Headers", "Content-Range, X-Api-Range-Total, X-Api-Range-Size") + exposeHeaders := config.AllowedHeaders + exposeHeaders = append(exposeHeaders, "Content-Range", "X-Api-Range-Total", "X-Api-Range-Size") + w.SetHeader("Access-Control-Expose-Headers", strings.Join(exposeHeaders, ", ")) } diff --git a/pkg/resolvespec/resolvespec.go b/pkg/resolvespec/resolvespec.go index 80c0287..bf78e08 100644 --- a/pkg/resolvespec/resolvespec.go +++ b/pkg/resolvespec/resolvespec.go @@ -50,8 +50,9 @@ func SetupMuxRoutes(muxRouter *mux.Router, handler *Handler, authMiddleware Midd openAPIHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { corsConfig := common.DefaultCORSConfig() respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) reqAdapter := router.NewHTTPRequest(r) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) + handler.HandleOpenAPI(respAdapter, reqAdapter) }) muxRouter.Handle("/openapi", openAPIHandler).Methods("GET", "OPTIONS") @@ -98,7 +99,8 @@ func createMuxHandler(handler *Handler, schema, entity, idParam string) http.Han // Set CORS headers corsConfig := common.DefaultCORSConfig() respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(r) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) vars := make(map[string]string) vars["schema"] = schema @@ -106,7 +108,7 @@ func createMuxHandler(handler *Handler, schema, entity, idParam string) http.Han if idParam != "" { vars["id"] = mux.Vars(r)[idParam] } - reqAdapter := router.NewHTTPRequest(r) + handler.Handle(respAdapter, reqAdapter, vars) } } @@ -117,7 +119,8 @@ func createMuxGetHandler(handler *Handler, schema, entity, idParam string) http. // Set CORS headers corsConfig := common.DefaultCORSConfig() respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(r) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) vars := make(map[string]string) vars["schema"] = schema @@ -125,7 +128,7 @@ func createMuxGetHandler(handler *Handler, schema, entity, idParam string) http. if idParam != "" { vars["id"] = mux.Vars(r)[idParam] } - reqAdapter := router.NewHTTPRequest(r) + handler.HandleGet(respAdapter, reqAdapter, vars) } } @@ -137,13 +140,14 @@ func createMuxOptionsHandler(handler *Handler, schema, entity string, allowedMet corsConfig := common.DefaultCORSConfig() corsConfig.AllowedMethods = allowedMethods respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(r) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) // Return metadata in the OPTIONS response body vars := make(map[string]string) vars["schema"] = schema vars["entity"] = entity - reqAdapter := router.NewHTTPRequest(r) + handler.HandleGet(respAdapter, reqAdapter, vars) } } @@ -222,15 +226,16 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // Add global /openapi route r.Handle("GET", "/openapi", func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) reqAdapter := router.NewHTTPRequest(req.Request) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) handler.HandleOpenAPI(respAdapter, reqAdapter) return nil }) r.Handle("OPTIONS", "/openapi", func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(req.Request) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) return nil }) @@ -253,12 +258,13 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // POST route without ID r.Handle("POST", entityPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(req.Request) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, } - reqAdapter := router.NewHTTPRequest(req.Request) + handler.Handle(respAdapter, reqAdapter, params) return nil }) @@ -266,13 +272,14 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // POST route with ID r.Handle("POST", entityWithIDPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(req.Request) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, "id": req.Param("id"), } - reqAdapter := router.NewHTTPRequest(req.Request) + handler.Handle(respAdapter, reqAdapter, params) return nil }) @@ -280,12 +287,13 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // GET route without ID r.Handle("GET", entityPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(req.Request) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, } - reqAdapter := router.NewHTTPRequest(req.Request) + handler.HandleGet(respAdapter, reqAdapter, params) return nil }) @@ -293,13 +301,14 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // GET route with ID r.Handle("GET", entityWithIDPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(req.Request) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, "id": req.Param("id"), } - reqAdapter := router.NewHTTPRequest(req.Request) + handler.HandleGet(respAdapter, reqAdapter, params) return nil }) @@ -307,14 +316,15 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // OPTIONS route without ID (returns metadata) r.Handle("OPTIONS", entityPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) + reqAdapter := router.NewHTTPRequest(req.Request) optionsCorsConfig := corsConfig optionsCorsConfig.AllowedMethods = []string{"GET", "POST", "OPTIONS"} - common.SetCORSHeaders(respAdapter, optionsCorsConfig) + common.SetCORSHeaders(respAdapter, reqAdapter, optionsCorsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, } - reqAdapter := router.NewHTTPRequest(req.Request) + handler.HandleGet(respAdapter, reqAdapter, params) return nil }) @@ -322,14 +332,15 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // OPTIONS route with ID (returns metadata) r.Handle("OPTIONS", entityWithIDPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) + reqAdapter := router.NewHTTPRequest(req.Request) optionsCorsConfig := corsConfig optionsCorsConfig.AllowedMethods = []string{"POST", "OPTIONS"} - common.SetCORSHeaders(respAdapter, optionsCorsConfig) + common.SetCORSHeaders(respAdapter, reqAdapter, optionsCorsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, } - reqAdapter := router.NewHTTPRequest(req.Request) + handler.HandleGet(respAdapter, reqAdapter, params) return nil }) diff --git a/pkg/restheadspec/restheadspec.go b/pkg/restheadspec/restheadspec.go index 4b922ce..cfe0378 100644 --- a/pkg/restheadspec/restheadspec.go +++ b/pkg/restheadspec/restheadspec.go @@ -103,8 +103,9 @@ func SetupMuxRoutes(muxRouter *mux.Router, handler *Handler, authMiddleware Midd openAPIHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { corsConfig := common.DefaultCORSConfig() respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) reqAdapter := router.NewHTTPRequest(r) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) + handler.HandleOpenAPI(respAdapter, reqAdapter) }) muxRouter.Handle("/openapi", openAPIHandler).Methods("GET", "OPTIONS") @@ -161,7 +162,8 @@ func createMuxHandler(handler *Handler, schema, entity, idParam string) http.Han // Set CORS headers corsConfig := common.DefaultCORSConfig() respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(r) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) vars := make(map[string]string) vars["schema"] = schema @@ -169,7 +171,7 @@ func createMuxHandler(handler *Handler, schema, entity, idParam string) http.Han if idParam != "" { vars["id"] = mux.Vars(r)[idParam] } - reqAdapter := router.NewHTTPRequest(r) + handler.Handle(respAdapter, reqAdapter, vars) } } @@ -180,7 +182,8 @@ func createMuxGetHandler(handler *Handler, schema, entity, idParam string) http. // Set CORS headers corsConfig := common.DefaultCORSConfig() respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(r) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) vars := make(map[string]string) vars["schema"] = schema @@ -188,7 +191,7 @@ func createMuxGetHandler(handler *Handler, schema, entity, idParam string) http. if idParam != "" { vars["id"] = mux.Vars(r)[idParam] } - reqAdapter := router.NewHTTPRequest(r) + handler.HandleGet(respAdapter, reqAdapter, vars) } } @@ -200,13 +203,14 @@ func createMuxOptionsHandler(handler *Handler, schema, entity string, allowedMet corsConfig := common.DefaultCORSConfig() corsConfig.AllowedMethods = allowedMethods respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewHTTPRequest(r) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) // Return metadata in the OPTIONS response body vars := make(map[string]string) vars["schema"] = schema vars["entity"] = entity - reqAdapter := router.NewHTTPRequest(r) + handler.HandleGet(respAdapter, reqAdapter, vars) } } @@ -285,15 +289,8 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // Add global /openapi route r.Handle("GET", "/openapi", func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) reqAdapter := router.NewBunRouterRequest(req) - handler.HandleOpenAPI(respAdapter, reqAdapter) - return nil - }) - - r.Handle("OPTIONS", "/openapi", func(w http.ResponseWriter, req bunrouter.Request) error { - respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) return nil }) @@ -317,24 +314,26 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // GET and POST for /{schema}/{entity} r.Handle("GET", entityPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewBunRouterRequest(req) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, } - reqAdapter := router.NewBunRouterRequest(req) + handler.Handle(respAdapter, reqAdapter, params) return nil }) r.Handle("POST", entityPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewBunRouterRequest(req) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, } - reqAdapter := router.NewBunRouterRequest(req) + handler.Handle(respAdapter, reqAdapter, params) return nil }) @@ -342,65 +341,70 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // GET, POST, PUT, PATCH, DELETE for /{schema}/{entity}/:id r.Handle("GET", entityWithIDPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewBunRouterRequest(req) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, "id": req.Param("id"), } - reqAdapter := router.NewBunRouterRequest(req) + handler.Handle(respAdapter, reqAdapter, params) return nil }) r.Handle("POST", entityWithIDPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewBunRouterRequest(req) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, "id": req.Param("id"), } - reqAdapter := router.NewBunRouterRequest(req) + handler.Handle(respAdapter, reqAdapter, params) return nil }) r.Handle("PUT", entityWithIDPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewBunRouterRequest(req) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, "id": req.Param("id"), } - reqAdapter := router.NewBunRouterRequest(req) + handler.Handle(respAdapter, reqAdapter, params) return nil }) r.Handle("PATCH", entityWithIDPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewBunRouterRequest(req) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, "id": req.Param("id"), } - reqAdapter := router.NewBunRouterRequest(req) + handler.Handle(respAdapter, reqAdapter, params) return nil }) r.Handle("DELETE", entityWithIDPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewBunRouterRequest(req) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, "id": req.Param("id"), } - reqAdapter := router.NewBunRouterRequest(req) + handler.Handle(respAdapter, reqAdapter, params) return nil }) @@ -408,12 +412,13 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // Metadata endpoint r.Handle("GET", metadataPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) - common.SetCORSHeaders(respAdapter, corsConfig) + reqAdapter := router.NewBunRouterRequest(req) + common.SetCORSHeaders(respAdapter, reqAdapter, corsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, } - reqAdapter := router.NewBunRouterRequest(req) + handler.HandleGet(respAdapter, reqAdapter, params) return nil }) @@ -421,14 +426,15 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // OPTIONS route without ID (returns metadata) r.Handle("OPTIONS", entityPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) + reqAdapter := router.NewBunRouterRequest(req) optionsCorsConfig := corsConfig optionsCorsConfig.AllowedMethods = []string{"GET", "POST", "OPTIONS"} - common.SetCORSHeaders(respAdapter, optionsCorsConfig) + common.SetCORSHeaders(respAdapter, reqAdapter, optionsCorsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, } - reqAdapter := router.NewBunRouterRequest(req) + handler.HandleGet(respAdapter, reqAdapter, params) return nil }) @@ -436,14 +442,15 @@ func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) { // OPTIONS route with ID (returns metadata) r.Handle("OPTIONS", entityWithIDPath, func(w http.ResponseWriter, req bunrouter.Request) error { respAdapter := router.NewHTTPResponseWriter(w) + reqAdapter := router.NewBunRouterRequest(req) optionsCorsConfig := corsConfig optionsCorsConfig.AllowedMethods = []string{"GET", "PUT", "PATCH", "DELETE", "POST", "OPTIONS"} - common.SetCORSHeaders(respAdapter, optionsCorsConfig) + common.SetCORSHeaders(respAdapter, reqAdapter, optionsCorsConfig) params := map[string]string{ "schema": currentSchema, "entity": currentEntity, } - reqAdapter := router.NewBunRouterRequest(req) + handler.HandleGet(respAdapter, reqAdapter, params) return nil })