From 86a7fb007c109c0a042630a9104fd2a6f4230b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20S=C3=A1gi-Kaz=C3=A1r?= Date: Tue, 9 Jan 2018 12:19:42 +0100 Subject: [PATCH] Add CORS max age annotation (#1888) Add cors-max-age annotation --- docs/annotations.md | 1 + docs/user-guide/annotations.md | 5 +++++ internal/ingress/annotations/cors/main.go | 11 +++++++++++ internal/ingress/annotations/cors/main_test.go | 4 ++++ rootfs/etc/nginx/template/nginx.tmpl | 2 +- 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/annotations.md b/docs/annotations.md index 5e94ed0b9..562fae40e 100644 --- a/docs/annotations.md +++ b/docs/annotations.md @@ -61,6 +61,7 @@ Key: | `cors-allow-headers` | Specifies the Headers allowed in CORS (Access-Control-Allow-Headers) | DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization | nginx | `cors-allow-methods` | Specifies the Methods allowed in CORS (Access-Control-Allow-Methods) | GET, PUT, POST, DELETE, PATCH, OPTIONS | nginx | `cors-allow-credentials` | Specifies the Access-Control-Allow-Credentials | true | nginx +| `cors-max-age` | Specifies the Access-Control-Max-Age | 1728000 | nginx ## Miscellaneous diff --git a/docs/user-guide/annotations.md b/docs/user-guide/annotations.md index ffd49ae21..eb39cc05d 100644 --- a/docs/user-guide/annotations.md +++ b/docs/user-guide/annotations.md @@ -25,6 +25,7 @@ The following annotations are supported: |[nginx.ingress.kubernetes.io/cors-allow-methods](#enable-cors)|string| |[nginx.ingress.kubernetes.io/cors-allow-headers](#enable-cors)|string| |[nginx.ingress.kubernetes.io/cors-allow-credentials](#enable-cors)|true or false| +|[nginx.ingress.kubernetes.io/cors-max-age](#enable-cors)|number| |[nginx.ingress.kubernetes.io/force-ssl-redirect](#server-side-https-enforcement-through-redirect)|true or false| |[nginx.ingress.kubernetes.io/from-to-www-redirect](#redirect-from-to-www)|true or false| |[nginx.ingress.kubernetes.io/limit-connections](#rate-limiting)|number| @@ -208,6 +209,10 @@ Example: `nginx.ingress.kubernetes.io/cors-allow-origin: "https://origin-site.co Example: `nginx.ingress.kubernetes.io/cors-allow-credentials: "true"` +* `nginx.ingress.kubernetes.io/cors-max-age` controls how long preflight requests can be cached. + +Example: `nginx.ingress.kubernetes.io/cors-max-age: 600` + For more information please check https://enable-cors.org/server_nginx.html diff --git a/internal/ingress/annotations/cors/main.go b/internal/ingress/annotations/cors/main.go index a23a1c5be..b882018ae 100644 --- a/internal/ingress/annotations/cors/main.go +++ b/internal/ingress/annotations/cors/main.go @@ -29,6 +29,7 @@ const ( // Default values defaultCorsMethods = "GET, PUT, POST, DELETE, PATCH, OPTIONS" defaultCorsHeaders = "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization" + defaultCorsMaxAge = 1728000 ) var ( @@ -55,6 +56,7 @@ type Config struct { CorsAllowMethods string `json:"corsAllowMethods"` CorsAllowHeaders string `json:"corsAllowHeaders"` CorsAllowCredentials bool `json:"corsAllowCredentials"` + CorsMaxAge int `json:"corsMaxAge"` } // NewParser creates a new CORS annotation parser @@ -70,6 +72,9 @@ func (c1 *Config) Equal(c2 *Config) bool { if c1 == nil || c2 == nil { return false } + if c1.CorsMaxAge != c2.CorsMaxAge { + return false + } if c1.CorsAllowCredentials != c2.CorsAllowCredentials { return false } @@ -117,12 +122,18 @@ func (c cors) Parse(ing *extensions.Ingress) (interface{}, error) { corsallowcredentials = true } + corsmaxage, err := parser.GetIntAnnotation("cors-max-age", ing) + if err != nil { + corsmaxage = defaultCorsMaxAge + } + return &Config{ CorsEnabled: corsenabled, CorsAllowOrigin: corsalloworigin, CorsAllowHeaders: corsallowheaders, CorsAllowMethods: corsallowmethods, CorsAllowCredentials: corsallowcredentials, + CorsMaxAge: corsmaxage, }, nil } diff --git a/internal/ingress/annotations/cors/main_test.go b/internal/ingress/annotations/cors/main_test.go index c8a195294..8f9545429 100644 --- a/internal/ingress/annotations/cors/main_test.go +++ b/internal/ingress/annotations/cors/main_test.go @@ -71,6 +71,7 @@ func TestIngressCorsConfig(t *testing.T) { data[parser.GetAnnotationWithPrefix("cors-allow-credentials")] = "false" data[parser.GetAnnotationWithPrefix("cors-allow-methods")] = "PUT, GET,OPTIONS, PATCH, $nginx_version" data[parser.GetAnnotationWithPrefix("cors-allow-origin")] = "https://origin123.test.com:4443" + data[parser.GetAnnotationWithPrefix("cors-max-age")] = "600" ing.SetAnnotations(data) corst, _ := NewParser(&resolver.Mock{}).Parse(ing) @@ -95,4 +96,7 @@ func TestIngressCorsConfig(t *testing.T) { t.Errorf("expected origin https://origin123.test.com:4443, but got %v", nginxCors.CorsAllowOrigin) } + if nginxCors.CorsMaxAge != 600 { + t.Errorf("expected max age 600, but got %v", nginxCors.CorsMaxAge) + } } diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index 144d3e92b..e8c006598 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -558,7 +558,7 @@ stream { {{ if $cors.CorsAllowCredentials }} add_header 'Access-Control-Allow-Credentials' '{{ $cors.CorsAllowCredentials }}' always; {{ end }} add_header 'Access-Control-Allow-Methods' '{{ $cors.CorsAllowMethods }}' always; add_header 'Access-Control-Allow-Headers' '{{ $cors.CorsAllowHeaders }}' always; - add_header 'Access-Control-Max-Age' 1728000; + add_header 'Access-Control-Max-Age' {{ $cors.CorsMaxAge }}; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 204;