summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rr.yaml9
-rw-r--r--service/http/config.go13
-rw-r--r--service/http/service.go45
3 files changed, 65 insertions, 2 deletions
diff --git a/.rr.yaml b/.rr.yaml
index c04daaff..b1886909 100644
--- a/.rr.yaml
+++ b/.rr.yaml
@@ -30,13 +30,18 @@ http:
# HTTP service provides built-in middlewares
middlewares:
+ # Middleware to handle CORS requests
+ cors:
+ AllowedOrigin: "*"
+ allowedHeaders: "*"
+ allowedMethods: "GET,POST,PUT,DELETE"
+ allowCredentials: true
+ maxAge: 600
# Middleware that adding Headers to the Request / Response
headers:
customRequestHeaders:
"Example-Request-Header": "Value"
customResponseHeaders:
- "Access-Control-Allow-Origin": "*"
- "Access-Control-Allow-Headers": "GET,POST,PUT,DELETE"
"X-Powered-By": "RoadRunner"
# HTTP service provides FastCGI as frontend
diff --git a/service/http/config.go b/service/http/config.go
index 2b8cf049..2897d1f7 100644
--- a/service/http/config.go
+++ b/service/http/config.go
@@ -42,6 +42,15 @@ type Config struct {
type MiddlewaresConfig struct {
Headers *HeaderMiddlewareConfig
+ CORS *CORSMiddlewareConfig
+}
+
+type CORSMiddlewareConfig struct {
+ AllowedOrigin string
+ AllowedMethods string
+ AllowedHeaders string
+ AllowCredentials *bool
+ MaxAge int
}
type HeaderMiddlewareConfig struct {
@@ -49,6 +58,10 @@ type HeaderMiddlewareConfig struct {
CustomResponseHeaders map[string]string
}
+func (c *MiddlewaresConfig) EnableCORS() bool {
+ return c.CORS != nil
+}
+
func (c *MiddlewaresConfig) EnableHeaders() bool {
return c.Headers.CustomRequestHeaders != nil || c.Headers.CustomResponseHeaders != nil
}
diff --git a/service/http/service.go b/service/http/service.go
index 59e7dd5a..3d9f196e 100644
--- a/service/http/service.go
+++ b/service/http/service.go
@@ -12,6 +12,7 @@ import (
"net/http"
"net/http/fcgi"
"net/url"
+ "strconv"
"strings"
"sync"
)
@@ -271,10 +272,54 @@ func (s *Service) headersMiddleware(f http.HandlerFunc) http.HandlerFunc {
}
}
+func handlePreflight(w http.ResponseWriter, r *http.Request, options *CORSMiddlewareConfig) {
+ headers := w.Header()
+
+ headers.Add("Vary", "Origin")
+ headers.Add("Vary", "Access-Control-Request-Method")
+ headers.Add("Vary", "Access-Control-Request-Headers")
+
+ if options.AllowedOrigin != "" {
+ headers.Set("Access-Control-Allow-Origin", options.AllowedOrigin)
+ }
+
+ if options.AllowedHeaders != "" {
+ headers.Set("Access-Control-Allow-Headers", options.AllowedHeaders)
+ }
+
+ if options.AllowedMethods != "" {
+ headers.Set("Access-Control-Allow-Methods", options.AllowedMethods)
+ }
+
+ if options.AllowCredentials != nil {
+ headers.Set("Access-Control-Allow-Credentials", strconv.FormatBool(*options.AllowCredentials))
+ }
+
+ if options.MaxAge > 0 {
+ headers.Set("Access-Control-Max-Age", strconv.Itoa(options.MaxAge))
+ }
+}
+
+func (s *Service) corsMiddleware(f http.HandlerFunc) http.HandlerFunc {
+ // Define the http.HandlerFunc
+ return func(w http.ResponseWriter, r *http.Request) {
+ if r.Method == http.MethodOptions {
+ handlePreflight(w, r, s.cfg.Middlewares.CORS)
+ w.WriteHeader(http.StatusOK);
+ } else {
+ f(w, r)
+ }
+ }
+}
+
func (s *Service) initMiddlewares() error {
if s.cfg.Middlewares.EnableHeaders() {
s.AddMiddleware(s.headersMiddleware)
}
+ if s.cfg.Middlewares.EnableCORS() {
+ s.AddMiddleware(s.corsMiddleware)
+ }
+
return nil
}