diff --git a/api/v1alpha1/cors_types.go b/api/v1alpha1/cors_types.go
index c70e18886bd..328a4fe186b 100644
--- a/api/v1alpha1/cors_types.go
+++ b/api/v1alpha1/cors_types.go
@@ -5,10 +5,8 @@
package v1alpha1
-import (
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
-)
+import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
// Origin is defined by the scheme (protocol), hostname (domain), and port of
// the URL used to access it. The hostname can be "precise" which is just the
@@ -32,26 +30,34 @@ type Origin string
// CORS defines the configuration for Cross-Origin Resource Sharing (CORS).
type CORS struct {
// AllowOrigins defines the origins that are allowed to make requests.
+ // It specifies the allowed origins in the Access-Control-Allow-Origin header.
+ // The value "*" allows any origin to make requests.
//
// +optional
AllowOrigins []Origin `json:"allowOrigins,omitempty"`
// AllowMethods defines the methods that are allowed to make requests.
+ // It specifies the allowed methods in the Access-Control-Allow-Methods header.
+ // The value "*" allows any method to be used.
//
// +optional
- AllowMethods []gwapiv1.HTTPMethod `json:"allowMethods,omitempty"`
+ AllowMethods []string `json:"allowMethods,omitempty"`
// AllowHeaders defines the headers that are allowed to be sent with requests.
+ // It specifies the allowed headers in the Access-Control-Allow-Headers header.
+ // The value "*" allows any header to be sent.
//
// +optional
- AllowHeaders []gwapiv1.HTTPHeaderName `json:"allowHeaders,omitempty"`
+ AllowHeaders []string `json:"allowHeaders,omitempty"`
// ExposeHeaders defines the headers that can be exposed in the responses.
+ // It specifies the headers in the Access-Control-Expose-Headers header.
//
// +optional
- ExposeHeaders []gwapiv1.HTTPHeaderName `json:"exposeHeaders,omitempty"`
+ ExposeHeaders []string `json:"exposeHeaders,omitempty"`
// MaxAge defines how long the results of a preflight request can be cached.
+ // It specifies the value in the Access-Control-Max-Age header.
//
// +optional
MaxAge *metav1.Duration `json:"maxAge,omitempty"`
@@ -61,4 +67,10 @@ type CORS struct {
//
// +optional
AllowCredentials *bool `json:"allowCredentials,omitempty"`
+
+ //TODO zhaohuabing
+ // According to the CORS specification, the following rules should be enforced:
+ // - ExposeHeaders should also allow "*" to expose all headers.
+ // - If AllowCredentials is true, then the "*" shold be treated as a literal.
+ // Blocked by this Envoy issue: https://github.com/envoyproxy/envoy/issues/36066
}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 12542e7aff7..cde4e3b90d7 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -599,17 +599,17 @@ func (in *CORS) DeepCopyInto(out *CORS) {
}
if in.AllowMethods != nil {
in, out := &in.AllowMethods, &out.AllowMethods
- *out = make([]apisv1.HTTPMethod, len(*in))
+ *out = make([]string, len(*in))
copy(*out, *in)
}
if in.AllowHeaders != nil {
in, out := &in.AllowHeaders, &out.AllowHeaders
- *out = make([]apisv1.HTTPHeaderName, len(*in))
+ *out = make([]string, len(*in))
copy(*out, *in)
}
if in.ExposeHeaders != nil {
in, out := &in.ExposeHeaders, &out.ExposeHeaders
- *out = make([]apisv1.HTTPHeaderName, len(*in))
+ *out = make([]string, len(*in))
copy(*out, *in)
}
if in.MaxAge != nil {
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
index a484a80a0c4..0043432dd57 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -254,59 +254,26 @@ spec:
like cookies, authentication headers, or TLS client certificates.
type: boolean
allowHeaders:
- description: AllowHeaders defines the headers that are allowed
- to be sent with requests.
+ description: |-
+ AllowHeaders defines the headers that are allowed to be sent with requests.
+ It specifies the allowed headers in the Access-Control-Allow-Headers header.
+ The value "*" allows any header to be sent.
items:
- description: |-
- HTTPHeaderName is the name of an HTTP header.
-
- Valid values include:
-
- * "Authorization"
- * "Set-Cookie"
-
- Invalid values include:
-
- - ":method" - ":" is an invalid character. This means that HTTP/2 pseudo
- headers are not currently supported by this type.
- - "/invalid" - "/ " is an invalid character
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
type: array
allowMethods:
- description: AllowMethods defines the methods that are allowed
- to make requests.
+ description: |-
+ AllowMethods defines the methods that are allowed to make requests.
+ It specifies the allowed methods in the Access-Control-Allow-Methods header.
+ The value "*" allows any method to be used.
items:
- description: |-
- HTTPMethod describes how to select a HTTP route by matching the HTTP
- method as defined by
- [RFC 7231](https://datatracker.ietf.org/doc/html/rfc7231#section-4) and
- [RFC 5789](https://datatracker.ietf.org/doc/html/rfc5789#section-2).
- The value is expected in upper case.
-
- Note that values may be added to this enum, implementations
- must ensure that unknown values will not cause a crash.
-
- Unknown values here must result in the implementation setting the
- Accepted Condition for the Route to `status: False`, with a
- Reason of `UnsupportedValue`.
- enum:
- - GET
- - HEAD
- - POST
- - PUT
- - DELETE
- - CONNECT
- - OPTIONS
- - TRACE
- - PATCH
type: string
type: array
allowOrigins:
- description: AllowOrigins defines the origins that are allowed
- to make requests.
+ description: |-
+ AllowOrigins defines the origins that are allowed to make requests.
+ It specifies the allowed origins in the Access-Control-Allow-Origin header.
+ The value "*" allows any origin to make requests.
items:
description: |-
Origin is defined by the scheme (protocol), hostname (domain), and port of
@@ -328,30 +295,16 @@ spec:
type: string
type: array
exposeHeaders:
- description: ExposeHeaders defines the headers that can be exposed
- in the responses.
+ description: |-
+ ExposeHeaders defines the headers that can be exposed in the responses.
+ It specifies the headers in the Access-Control-Expose-Headers header.
items:
- description: |-
- HTTPHeaderName is the name of an HTTP header.
-
- Valid values include:
-
- * "Authorization"
- * "Set-Cookie"
-
- Invalid values include:
-
- - ":method" - ":" is an invalid character. This means that HTTP/2 pseudo
- headers are not currently supported by this type.
- - "/invalid" - "/ " is an invalid character
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
type: array
maxAge:
- description: MaxAge defines how long the results of a preflight
- request can be cached.
+ description: |-
+ MaxAge defines how long the results of a preflight request can be cached.
+ It specifies the value in the Access-Control-Max-Age header.
type: string
type: object
extAuth:
diff --git a/internal/xds/translator/cors.go b/internal/xds/translator/cors.go
index cda5ae8a40a..542b9aa680c 100644
--- a/internal/xds/translator/cors.go
+++ b/internal/xds/translator/cors.go
@@ -134,8 +134,18 @@ func (*cors) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
allowOrigins = append(allowOrigins, buildXdsStringMatcher(origin))
}
- allowMethods = strings.Join(c.AllowMethods, ", ")
- allowHeaders = strings.Join(c.AllowHeaders, ", ")
+ // Envoy only supports a single "*" for matching all, and treats the "*" in "*, GET" as a literal.
+ // https://github.com/envoyproxy/envoy/blob/eb61f368690cae173502f80549b7e2169ec24766/source/extensions/filters/http/cors/cors_filter.cc#L140-L159
+ if hasWildcard(c.AllowMethods) {
+ allowMethods = "*"
+ } else {
+ allowMethods = strings.Join(c.AllowMethods, ", ")
+ }
+ if hasWildcard(c.AllowHeaders) {
+ allowHeaders = "*"
+ } else {
+ allowHeaders = strings.Join(c.AllowHeaders, ", ")
+ }
exposeHeaders = strings.Join(c.ExposeHeaders, ", ")
if c.MaxAge != nil {
maxAge = strconv.Itoa(int(c.MaxAge.Seconds()))
@@ -166,6 +176,15 @@ func (*cors) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
return nil
}
+func hasWildcard(array []string) bool {
+ for _, s := range array {
+ if s == "*" {
+ return true
+ }
+ }
+ return false
+}
+
func (c *cors) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error {
return nil
}
diff --git a/internal/xds/translator/testdata/in/xds-ir/cors.yaml b/internal/xds/translator/testdata/in/xds-ir/cors.yaml
index dd9eff3418f..0e046110a00 100644
--- a/internal/xds/translator/testdata/in/xds-ir/cors.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/cors.yaml
@@ -30,6 +30,7 @@ http:
allowMethods:
- GET
- POST
+ - "*"
allowHeaders:
- "x-header-1"
- "x-header-2"
diff --git a/internal/xds/translator/testdata/out/xds-ir/cors.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/cors.routes.yaml
index 93bfb4d3c15..12c4fce7778 100644
--- a/internal/xds/translator/testdata/out/xds-ir/cors.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/cors.routes.yaml
@@ -17,7 +17,7 @@
'@type': type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy
allowCredentials: true
allowHeaders: x-header-1, x-header-2
- allowMethods: GET, POST
+ allowMethods: '*'
allowOriginStringMatch:
- safeRegex:
regex: '*.example.com'
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index 16fd6de412e..ffb388a142d 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -533,11 +533,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `allowOrigins` | _[Origin](#origin) array_ | false | AllowOrigins defines the origins that are allowed to make requests. |
-| `allowMethods` | _HTTPMethod array_ | false | AllowMethods defines the methods that are allowed to make requests. |
-| `allowHeaders` | _[HTTPHeaderName](#httpheadername) array_ | false | AllowHeaders defines the headers that are allowed to be sent with requests. |
-| `exposeHeaders` | _[HTTPHeaderName](#httpheadername) array_ | false | ExposeHeaders defines the headers that can be exposed in the responses. |
-| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxAge defines how long the results of a preflight request can be cached. |
+| `allowOrigins` | _[Origin](#origin) array_ | false | AllowOrigins defines the origins that are allowed to make requests.
It specifies the allowed origins in the Access-Control-Allow-Origin header.
The value "*" allows any origin to make requests. |
+| `allowMethods` | _string array_ | false | AllowMethods defines the methods that are allowed to make requests.
It specifies the allowed methods in the Access-Control-Allow-Methods header.
The value "*" allows any method to be used. |
+| `allowHeaders` | _string array_ | false | AllowHeaders defines the headers that are allowed to be sent with requests.
It specifies the allowed headers in the Access-Control-Allow-Headers header.
The value "*" allows any header to be sent. |
+| `exposeHeaders` | _string array_ | false | ExposeHeaders defines the headers that can be exposed in the responses.
It specifies the headers in the Access-Control-Expose-Headers header. |
+| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxAge defines how long the results of a preflight request can be cached.
It specifies the value in the Access-Control-Max-Age header. |
| `allowCredentials` | _boolean_ | false | AllowCredentials indicates whether a request can include user credentials
like cookies, authentication headers, or TLS client certificates. |
diff --git a/site/content/zh/latest/api/extension_types.md b/site/content/zh/latest/api/extension_types.md
index 16fd6de412e..ffb388a142d 100644
--- a/site/content/zh/latest/api/extension_types.md
+++ b/site/content/zh/latest/api/extension_types.md
@@ -533,11 +533,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `allowOrigins` | _[Origin](#origin) array_ | false | AllowOrigins defines the origins that are allowed to make requests. |
-| `allowMethods` | _HTTPMethod array_ | false | AllowMethods defines the methods that are allowed to make requests. |
-| `allowHeaders` | _[HTTPHeaderName](#httpheadername) array_ | false | AllowHeaders defines the headers that are allowed to be sent with requests. |
-| `exposeHeaders` | _[HTTPHeaderName](#httpheadername) array_ | false | ExposeHeaders defines the headers that can be exposed in the responses. |
-| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxAge defines how long the results of a preflight request can be cached. |
+| `allowOrigins` | _[Origin](#origin) array_ | false | AllowOrigins defines the origins that are allowed to make requests.
It specifies the allowed origins in the Access-Control-Allow-Origin header.
The value "*" allows any origin to make requests. |
+| `allowMethods` | _string array_ | false | AllowMethods defines the methods that are allowed to make requests.
It specifies the allowed methods in the Access-Control-Allow-Methods header.
The value "*" allows any method to be used. |
+| `allowHeaders` | _string array_ | false | AllowHeaders defines the headers that are allowed to be sent with requests.
It specifies the allowed headers in the Access-Control-Allow-Headers header.
The value "*" allows any header to be sent. |
+| `exposeHeaders` | _string array_ | false | ExposeHeaders defines the headers that can be exposed in the responses.
It specifies the headers in the Access-Control-Expose-Headers header. |
+| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxAge defines how long the results of a preflight request can be cached.
It specifies the value in the Access-Control-Max-Age header. |
| `allowCredentials` | _boolean_ | false | AllowCredentials indicates whether a request can include user credentials
like cookies, authentication headers, or TLS client certificates. |