diff --git a/apis/v1/httproute_types.go b/apis/v1/httproute_types.go index 6131d70b7b..f5defcc306 100644 --- a/apis/v1/httproute_types.go +++ b/apis/v1/httproute_types.go @@ -612,9 +612,14 @@ type HTTPHeaderMatch struct { Name HTTPHeaderName `json:"name"` // Value is the value of HTTP Header to be matched. + // + // Must consist of printable US-ASCII characters, optionally separated + // by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + // // // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=4096 + // Value string `json:"value"` } @@ -981,9 +986,14 @@ type HTTPHeader struct { Name HTTPHeaderName `json:"name"` // Value is the value of HTTP Header to be matched. + // + // Must consist of printable US-ASCII characters, optionally separated + // by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + // // // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=4096 + // Value string `json:"value"` } diff --git a/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml index 8efb5867b7..3560ceecda 100644 --- a/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml +++ b/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml @@ -544,10 +544,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -619,10 +623,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -827,10 +835,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -902,10 +914,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -1194,10 +1210,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -1268,10 +1288,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -1475,10 +1499,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -1549,10 +1577,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name diff --git a/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml index 050ba3277d..4a13c86176 100644 --- a/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml +++ b/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml @@ -819,10 +819,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -894,10 +898,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -1255,10 +1263,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -1330,10 +1342,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -2045,10 +2061,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -2119,10 +2139,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -2479,10 +2503,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -2553,10 +2581,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -2882,10 +2914,14 @@ spec: - RegularExpression type: string value: - description: Value is the value of HTTP Header to - be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -4445,10 +4481,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -4520,10 +4560,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -4881,10 +4925,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -4956,10 +5004,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP - Header to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -5671,10 +5723,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -5745,10 +5801,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6105,10 +6165,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6179,10 +6243,14 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: Value is the value of HTTP Header - to be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6508,10 +6576,14 @@ spec: - RegularExpression type: string value: - description: Value is the value of HTTP Header to - be matched. + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 maxLength: 4096 minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name diff --git a/examples/experimental/http-response-header.yaml b/examples/experimental/http-response-header.yaml index cbcd28eeb7..25ef470c41 100644 --- a/examples/experimental/http-response-header.yaml +++ b/examples/experimental/http-response-header.yaml @@ -20,6 +20,8 @@ spec: value: header-add-2 - name: X-Header-Add-3 value: header-add-3 + - name: Content-Disposition + value: "attachment; filename=\"example_file.txt\"" backendRefs: - name: echo port: 8080 diff --git a/hack/invalid-examples/experimental/httproute/invalid-header-value.yaml b/hack/invalid-examples/experimental/httproute/invalid-header-value.yaml new file mode 100644 index 0000000000..d2e00a7115 --- /dev/null +++ b/hack/invalid-examples/experimental/httproute/invalid-header-value.yaml @@ -0,0 +1,12 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: invalid-header-value +spec: + rules: + - filters: + - type: ResponseHeaderModifier + responseHeaderModifier: + add: + - name: X-Test-Header + value: "this\nis\rinvalid\r\nvalue" diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 9279b1767a..f69e286430 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -4386,7 +4386,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPHeader(ref common.ReferenceCallbac }, "value": { SchemaProps: spec.SchemaProps{ - Description: "Value is the value of HTTP Header to be matched.", + Description: "Value is the value of HTTP Header to be matched. Must consist of printable US-ASCII characters, optionally separated by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 \n\n", Default: "", Type: []string{"string"}, Format: "", @@ -4502,7 +4502,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPHeaderMatch(ref common.ReferenceCa }, "value": { SchemaProps: spec.SchemaProps{ - Description: "Value is the value of HTTP Header to be matched.", + Description: "Value is the value of HTTP Header to be matched. Must consist of printable US-ASCII characters, optionally separated by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 \n\n", Default: "", Type: []string{"string"}, Format: "", diff --git a/pkg/generator/main.go b/pkg/generator/main.go index dc170b8823..17abed2484 100644 --- a/pkg/generator/main.go +++ b/pkg/generator/main.go @@ -217,6 +217,18 @@ func gatewayTweaks(channel string, name string, jsonProps apiext.JSONSchemaProps Rule: celMatch[2], }) } + + patternRe := regexp.MustCompile(validationPrefix + "Pattern=`([^`]*)`") + patternMatches := patternRe.FindAllStringSubmatch(jsonProps.Description, 64) + if len(patternMatches) == 1 && jsonProps.Pattern == "" { + patternMatch := patternMatches[0] + if len(patternMatch) != 2 { + log.Fatalf("Invalid %s Pattern tag for %s", validationPrefix, name) + } + + numValid++ + jsonProps.Pattern = patternMatch[1] + } } if numValid < numExpressions {