diff --git a/api/envoy/config/rbac/v3/rbac.proto b/api/envoy/config/rbac/v3/rbac.proto index 3b7f79d605df..44b3cf7cee6e 100644 --- a/api/envoy/config/rbac/v3/rbac.proto +++ b/api/envoy/config/rbac/v3/rbac.proto @@ -60,7 +60,10 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // permissions: // - and_rules: // rules: -// - header: { name: ":method", exact_match: "GET" } +// - header: +// name: ":method" +// string_match: +// exact: "GET" // - url_path: // path: { prefix: "/products" } // - or_rules: diff --git a/api/envoy/config/rbac/v4alpha/rbac.proto b/api/envoy/config/rbac/v4alpha/rbac.proto index 59c4ba111d1d..bd56c0c3dc32 100644 --- a/api/envoy/config/rbac/v4alpha/rbac.proto +++ b/api/envoy/config/rbac/v4alpha/rbac.proto @@ -58,7 +58,10 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // permissions: // - and_rules: // rules: -// - header: { name: ":method", exact_match: "GET" } +// - header: +// name: ":method" +// string_match: +// exact: "GET" // - url_path: // path: { prefix: "/products" } // - or_rules: diff --git a/api/envoy/config/route/v3/route_components.proto b/api/envoy/config/route/v3/route_components.proto index 06a71c7858b1..dfb8b8ed1a15 100644 --- a/api/envoy/config/route/v3/route_components.proto +++ b/api/envoy/config/route/v3/route_components.proto @@ -1865,7 +1865,7 @@ message RateLimit { // value. // // [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] -// [#next-free-field: 13] +// [#next-free-field: 14] message HeaderMatcher { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.HeaderMatcher"; @@ -1880,12 +1880,16 @@ message HeaderMatcher { // Specifies how the header match will be performed to route the request. oneof header_match_specifier { // If specified, header match will be performed based on the value of the header. - string exact_match = 4; + // This field is deprecated. Please use :ref:`string_match `. + string exact_match = 4 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // If specified, this regex string is a regular expression rule which implies the entire request // header value must match the regex. The rule will not match if only a subsequence of the // request header value matches the regex. - type.matcher.v3.RegexMatcher safe_regex_match = 11; + // This field is deprecated. Please use :ref:`string_match `. + type.matcher.v3.RegexMatcher safe_regex_match = 11 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // If specified, header match will be performed based on range. // The rule will match if the request header value is within this range. @@ -1906,28 +1910,46 @@ message HeaderMatcher { // If specified, header match will be performed based on the prefix of the header value. // Note: empty prefix is not allowed, please use present_match instead. + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // // * The prefix *abcd* matches the value *abcdxyz*, but not for *abcxyz*. - string prefix_match = 9 [(validate.rules).string = {min_len: 1}]; + string prefix_match = 9 [ + deprecated = true, + (validate.rules).string = {min_len: 1}, + (envoy.annotations.deprecated_at_minor_version) = "3.0" + ]; // If specified, header match will be performed based on the suffix of the header value. // Note: empty suffix is not allowed, please use present_match instead. + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // // * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*. - string suffix_match = 10 [(validate.rules).string = {min_len: 1}]; + string suffix_match = 10 [ + deprecated = true, + (validate.rules).string = {min_len: 1}, + (envoy.annotations.deprecated_at_minor_version) = "3.0" + ]; // If specified, header match will be performed based on whether the header value contains // the given value or not. // Note: empty contains match is not allowed, please use present_match instead. + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // // * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. - string contains_match = 12 [(validate.rules).string = {min_len: 1}]; + string contains_match = 12 [ + deprecated = true, + (validate.rules).string = {min_len: 1}, + (envoy.annotations.deprecated_at_minor_version) = "3.0" + ]; + + // If specified, header match will be performed based on the string match of the header value. + type.matcher.v3.StringMatcher string_match = 13; } // If specified, the match result will be inverted before checking. Defaults to false. diff --git a/api/envoy/config/route/v4alpha/route_components.proto b/api/envoy/config/route/v4alpha/route_components.proto index eab4b76fd6c0..9c0cc8f57d35 100644 --- a/api/envoy/config/route/v4alpha/route_components.proto +++ b/api/envoy/config/route/v4alpha/route_components.proto @@ -1816,14 +1816,15 @@ message RateLimit { // value. // // [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] -// [#next-free-field: 13] +// [#next-free-field: 14] message HeaderMatcher { option (udpa.annotations.versioning).previous_message_type = "envoy.config.route.v3.HeaderMatcher"; - reserved 2, 3, 5; + reserved 2, 3, 5, 4, 11, 9, 10, 12; - reserved "regex_match"; + reserved "regex_match", "exact_match", "safe_regex_match", "prefix_match", "suffix_match", + "contains_match"; // Specifies the name of the header in the request. string name = 1 @@ -1831,14 +1832,6 @@ message HeaderMatcher { // Specifies how the header match will be performed to route the request. oneof header_match_specifier { - // If specified, header match will be performed based on the value of the header. - string exact_match = 4; - - // If specified, this regex string is a regular expression rule which implies the entire request - // header value must match the regex. The rule will not match if only a subsequence of the - // request header value matches the regex. - type.matcher.v4alpha.RegexMatcher safe_regex_match = 11; - // If specified, header match will be performed based on range. // The rule will match if the request header value is within this range. // The entire request header value must represent an integer in base 10 notation: consisting of @@ -1856,30 +1849,8 @@ message HeaderMatcher { // request. If specified as false, header match will be performed based on whether the header is absent. bool present_match = 7; - // If specified, header match will be performed based on the prefix of the header value. - // Note: empty prefix is not allowed, please use present_match instead. - // - // Examples: - // - // * The prefix *abcd* matches the value *abcdxyz*, but not for *abcxyz*. - string prefix_match = 9 [(validate.rules).string = {min_len: 1}]; - - // If specified, header match will be performed based on the suffix of the header value. - // Note: empty suffix is not allowed, please use present_match instead. - // - // Examples: - // - // * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*. - string suffix_match = 10 [(validate.rules).string = {min_len: 1}]; - - // If specified, header match will be performed based on whether the header value contains - // the given value or not. - // Note: empty contains match is not allowed, please use present_match instead. - // - // Examples: - // - // * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. - string contains_match = 12 [(validate.rules).string = {min_len: 1}]; + // If specified, header match will be performed based on the string match of the header value. + type.matcher.v4alpha.StringMatcher string_match = 13; } // If specified, the match result will be inverted before checking. Defaults to false. diff --git a/api/envoy/type/matcher/v3/string.proto b/api/envoy/type/matcher/v3/string.proto index 78e1572bf8cf..c64edde142ff 100644 --- a/api/envoy/type/matcher/v3/string.proto +++ b/api/envoy/type/matcher/v3/string.proto @@ -62,8 +62,8 @@ message StringMatcher { string contains = 7 [(validate.rules).string = {min_len: 1}]; } - // If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no - // effect for the safe_regex match. + // If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. This + // has no effect for the safe_regex match. // For example, the matcher *data* will match both input string *Data* and *data* if set to true. bool ignore_case = 6; } diff --git a/api/envoy/type/matcher/v4alpha/string.proto b/api/envoy/type/matcher/v4alpha/string.proto index 14098fac4d41..f9fa48cd3195 100644 --- a/api/envoy/type/matcher/v4alpha/string.proto +++ b/api/envoy/type/matcher/v4alpha/string.proto @@ -63,8 +63,8 @@ message StringMatcher { string contains = 7 [(validate.rules).string = {min_len: 1}]; } - // If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no - // effect for the safe_regex match. + // If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. This + // has no effect for the safe_regex match. // For example, the matcher *data* will match both input string *Data* and *data* if set to true. bool ignore_case = 6; } diff --git a/configs/envoy_double_proxy.template.yaml b/configs/envoy_double_proxy.template.yaml index 7e922bfd7542..e620b9024f09 100644 --- a/configs/envoy_double_proxy.template.yaml +++ b/configs/envoy_double_proxy.template.yaml @@ -53,7 +53,8 @@ "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck pass_through_mode: false headers: - - exact_match: /healthcheck + - string_match: + exact: /healthcheck name: :path - name: envoy.filters.http.buffer typed_config: diff --git a/configs/envoy_front_proxy.template.yaml b/configs/envoy_front_proxy.template.yaml index 22f6fc2de3b3..047390d8ef67 100644 --- a/configs/envoy_front_proxy.template.yaml +++ b/configs/envoy_front_proxy.template.yaml @@ -54,7 +54,8 @@ pass_through_mode: false headers: - name: ":path" - exact_match: "/healthcheck" + string_match: + exact: "/healthcheck" - name: envoy.filters.http.buffer typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.buffer.v3.Buffer diff --git a/configs/envoy_service_to_service.template.yaml b/configs/envoy_service_to_service.template.yaml index f55fe4dd0b55..6ec2f0bde905 100644 --- a/configs/envoy_service_to_service.template.yaml +++ b/configs/envoy_service_to_service.template.yaml @@ -25,7 +25,8 @@ prefix: "/" headers: - name: content-type - exact_match: application/grpc + string_match: + exact: application/grpc route: cluster: local_service_grpc - match: @@ -39,7 +40,8 @@ pass_through_mode: true headers: - name: ":path" - exact_match: "/healthcheck" + string_match: + exact: "/healthcheck" cache_time: 2.5s - name: envoy.filters.http.buffer typed_config: diff --git a/configs/terminate_http2_post.yaml b/configs/terminate_http2_post.yaml index 4c76f72313e2..d2ede127da35 100644 --- a/configs/terminate_http2_post.yaml +++ b/configs/terminate_http2_post.yaml @@ -32,7 +32,8 @@ static_resources: prefix: "/" headers: - name: ":method" - exact_match: "POST" + string_match: + exact: "POST" route: cluster: service_google upgrade_configs: diff --git a/docs/root/configuration/http/http_filters/tap_filter.rst b/docs/root/configuration/http/http_filters/tap_filter.rst index 97fe68e984d6..049eeaca9f43 100644 --- a/docs/root/configuration/http/http_filters/tap_filter.rst +++ b/docs/root/configuration/http/http_filters/tap_filter.rst @@ -78,11 +78,13 @@ An example POST body: - http_request_headers_match: headers: - name: foo - exact_match: bar + string_match: + exact: bar - http_response_headers_match: headers: - name: bar - exact_match: baz + string_match: + exact: baz output_config: sinks: - streaming_admin: {} @@ -103,11 +105,13 @@ Another example POST body: - http_request_headers_match: headers: - name: foo - exact_match: bar + string_match: + exact: bar - http_response_headers_match: headers: - name: bar - exact_match: baz + string_match: + exact: baz output_config: sinks: - streaming_admin: {} @@ -143,7 +147,8 @@ Another example POST body: - http_request_headers_match: headers: - name: foo - exact_match: bar + string_match: + exact: bar - http_request_generic_body_match: patterns: - string_match: test @@ -242,7 +247,8 @@ An static filter configuration to enable streaming output looks like: http_response_headers_match: headers: - name: bar - exact_match: baz + string_match: + exact: baz output_config: streaming: true sinks: diff --git a/docs/root/configuration/operations/tools/router_check.rst b/docs/root/configuration/operations/tools/router_check.rst index e60ef9e737a5..9fff1cb28469 100644 --- a/docs/root/configuration/operations/tools/router_check.rst +++ b/docs/root/configuration/operations/tools/router_check.rst @@ -69,10 +69,12 @@ expects a cluster name match of "instant-server".:: path_redirect: ..., request_header_matches: - name: ..., - exact_match: ... + string_match: + exact: ... response_header_matches: - name: ..., - exact_match: ... + string_match: + exact: ... - name: ..., presence_match: ... diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 20d5236f703d..792dcbe2f1d4 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -27,6 +27,10 @@ Removed Config or Runtime New Features ------------ +* http: added :ref:`string_match ` in the header matcher. Deprecated ---------- +* http: the HeaderMatcher fields :ref:`exact_match `, :ref:`safe_regex_match `, + :ref:`prefix_match `, :ref:`suffix_match ` and + :ref:`contains_match ` are deprecated by :ref:`string_match `. diff --git a/generated_api_shadow/envoy/config/rbac/v3/rbac.proto b/generated_api_shadow/envoy/config/rbac/v3/rbac.proto index 3b7f79d605df..44b3cf7cee6e 100644 --- a/generated_api_shadow/envoy/config/rbac/v3/rbac.proto +++ b/generated_api_shadow/envoy/config/rbac/v3/rbac.proto @@ -60,7 +60,10 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // permissions: // - and_rules: // rules: -// - header: { name: ":method", exact_match: "GET" } +// - header: +// name: ":method" +// string_match: +// exact: "GET" // - url_path: // path: { prefix: "/products" } // - or_rules: diff --git a/generated_api_shadow/envoy/config/rbac/v4alpha/rbac.proto b/generated_api_shadow/envoy/config/rbac/v4alpha/rbac.proto index 7006099d4169..3b27e68bba1d 100644 --- a/generated_api_shadow/envoy/config/rbac/v4alpha/rbac.proto +++ b/generated_api_shadow/envoy/config/rbac/v4alpha/rbac.proto @@ -59,7 +59,10 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // permissions: // - and_rules: // rules: -// - header: { name: ":method", exact_match: "GET" } +// - header: +// name: ":method" +// string_match: +// exact: "GET" // - url_path: // path: { prefix: "/products" } // - or_rules: diff --git a/generated_api_shadow/envoy/config/route/v3/route_components.proto b/generated_api_shadow/envoy/config/route/v3/route_components.proto index 5a55b4d60ac0..93ae347ace73 100644 --- a/generated_api_shadow/envoy/config/route/v3/route_components.proto +++ b/generated_api_shadow/envoy/config/route/v3/route_components.proto @@ -1898,7 +1898,7 @@ message RateLimit { // value. // // [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] -// [#next-free-field: 13] +// [#next-free-field: 14] message HeaderMatcher { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.HeaderMatcher"; @@ -1911,12 +1911,16 @@ message HeaderMatcher { // Specifies how the header match will be performed to route the request. oneof header_match_specifier { // If specified, header match will be performed based on the value of the header. - string exact_match = 4; + // This field is deprecated. Please use :ref:`string_match `. + string exact_match = 4 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // If specified, this regex string is a regular expression rule which implies the entire request // header value must match the regex. The rule will not match if only a subsequence of the // request header value matches the regex. - type.matcher.v3.RegexMatcher safe_regex_match = 11; + // This field is deprecated. Please use :ref:`string_match `. + type.matcher.v3.RegexMatcher safe_regex_match = 11 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // If specified, header match will be performed based on range. // The rule will match if the request header value is within this range. @@ -1937,28 +1941,46 @@ message HeaderMatcher { // If specified, header match will be performed based on the prefix of the header value. // Note: empty prefix is not allowed, please use present_match instead. + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // // * The prefix *abcd* matches the value *abcdxyz*, but not for *abcxyz*. - string prefix_match = 9 [(validate.rules).string = {min_len: 1}]; + string prefix_match = 9 [ + deprecated = true, + (validate.rules).string = {min_len: 1}, + (envoy.annotations.deprecated_at_minor_version) = "3.0" + ]; // If specified, header match will be performed based on the suffix of the header value. // Note: empty suffix is not allowed, please use present_match instead. + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // // * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*. - string suffix_match = 10 [(validate.rules).string = {min_len: 1}]; + string suffix_match = 10 [ + deprecated = true, + (validate.rules).string = {min_len: 1}, + (envoy.annotations.deprecated_at_minor_version) = "3.0" + ]; // If specified, header match will be performed based on whether the header value contains // the given value or not. // Note: empty contains match is not allowed, please use present_match instead. + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // // * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. - string contains_match = 12 [(validate.rules).string = {min_len: 1}]; + string contains_match = 12 [ + deprecated = true, + (validate.rules).string = {min_len: 1}, + (envoy.annotations.deprecated_at_minor_version) = "3.0" + ]; + + // If specified, header match will be performed based on the string match of the header value. + type.matcher.v3.StringMatcher string_match = 13; string hidden_envoy_deprecated_regex_match = 5 [ deprecated = true, diff --git a/generated_api_shadow/envoy/config/route/v4alpha/route_components.proto b/generated_api_shadow/envoy/config/route/v4alpha/route_components.proto index 3bcfa659ac13..f72806788245 100644 --- a/generated_api_shadow/envoy/config/route/v4alpha/route_components.proto +++ b/generated_api_shadow/envoy/config/route/v4alpha/route_components.proto @@ -1894,7 +1894,7 @@ message RateLimit { // value. // // [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] -// [#next-free-field: 13] +// [#next-free-field: 14] message HeaderMatcher { option (udpa.annotations.versioning).previous_message_type = "envoy.config.route.v3.HeaderMatcher"; @@ -1910,12 +1910,16 @@ message HeaderMatcher { // Specifies how the header match will be performed to route the request. oneof header_match_specifier { // If specified, header match will be performed based on the value of the header. - string exact_match = 4; + // This field is deprecated. Please use :ref:`string_match `. + string hidden_envoy_deprecated_exact_match = 4 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // If specified, this regex string is a regular expression rule which implies the entire request // header value must match the regex. The rule will not match if only a subsequence of the // request header value matches the regex. - type.matcher.v4alpha.RegexMatcher safe_regex_match = 11; + // This field is deprecated. Please use :ref:`string_match `. + type.matcher.v4alpha.RegexMatcher hidden_envoy_deprecated_safe_regex_match = 11 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // If specified, header match will be performed based on range. // The rule will match if the request header value is within this range. @@ -1936,28 +1940,46 @@ message HeaderMatcher { // If specified, header match will be performed based on the prefix of the header value. // Note: empty prefix is not allowed, please use present_match instead. + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // // * The prefix *abcd* matches the value *abcdxyz*, but not for *abcxyz*. - string prefix_match = 9 [(validate.rules).string = {min_len: 1}]; + string hidden_envoy_deprecated_prefix_match = 9 [ + deprecated = true, + (validate.rules).string = {min_len: 1}, + (envoy.annotations.deprecated_at_minor_version) = "3.0" + ]; // If specified, header match will be performed based on the suffix of the header value. // Note: empty suffix is not allowed, please use present_match instead. + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // // * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*. - string suffix_match = 10 [(validate.rules).string = {min_len: 1}]; + string hidden_envoy_deprecated_suffix_match = 10 [ + deprecated = true, + (validate.rules).string = {min_len: 1}, + (envoy.annotations.deprecated_at_minor_version) = "3.0" + ]; // If specified, header match will be performed based on whether the header value contains // the given value or not. // Note: empty contains match is not allowed, please use present_match instead. + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // // * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. - string contains_match = 12 [(validate.rules).string = {min_len: 1}]; + string hidden_envoy_deprecated_contains_match = 12 [ + deprecated = true, + (validate.rules).string = {min_len: 1}, + (envoy.annotations.deprecated_at_minor_version) = "3.0" + ]; + + // If specified, header match will be performed based on the string match of the header value. + type.matcher.v4alpha.StringMatcher string_match = 13; } // If specified, the match result will be inverted before checking. Defaults to false. diff --git a/generated_api_shadow/envoy/type/matcher/v3/string.proto b/generated_api_shadow/envoy/type/matcher/v3/string.proto index 934b19d71cc1..4dc7cacffae6 100644 --- a/generated_api_shadow/envoy/type/matcher/v3/string.proto +++ b/generated_api_shadow/envoy/type/matcher/v3/string.proto @@ -66,8 +66,8 @@ message StringMatcher { ]; } - // If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no - // effect for the safe_regex match. + // If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. This + // has no effect for the safe_regex match. // For example, the matcher *data* will match both input string *Data* and *data* if set to true. bool ignore_case = 6; } diff --git a/generated_api_shadow/envoy/type/matcher/v4alpha/string.proto b/generated_api_shadow/envoy/type/matcher/v4alpha/string.proto index 14098fac4d41..f9fa48cd3195 100644 --- a/generated_api_shadow/envoy/type/matcher/v4alpha/string.proto +++ b/generated_api_shadow/envoy/type/matcher/v4alpha/string.proto @@ -63,8 +63,8 @@ message StringMatcher { string contains = 7 [(validate.rules).string = {min_len: 1}]; } - // If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no - // effect for the safe_regex match. + // If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. This + // has no effect for the safe_regex match. // For example, the matcher *data* will match both input string *Data* and *data* if set to true. bool ignore_case = 6; } diff --git a/source/common/http/BUILD b/source/common/http/BUILD index 55c15b06a3f3..db231bbd66b0 100644 --- a/source/common/http/BUILD +++ b/source/common/http/BUILD @@ -467,8 +467,10 @@ envoy_cc_library( ":header_map_lib", ":status_lib", ":utility_lib", + "//envoy/common:matchers_interface", "//envoy/common:regex_interface", "//envoy/http:header_map_interface", + "//source/common/common:matchers_lib", "//source/common/common:regex_lib", "//source/common/common:utility_lib", "//source/common/protobuf:utility_lib", diff --git a/source/common/http/header_utility.cc b/source/common/http/header_utility.cc index a25d62cc83a3..b0fc8d02fe5e 100644 --- a/source/common/http/header_utility.cc +++ b/source/common/http/header_utility.cc @@ -2,6 +2,7 @@ #include "envoy/config/route/v3/route_components.pb.h" +#include "source/common/common/matchers.h" #include "source/common/common/regex.h" #include "source/common/common/utility.h" #include "source/common/http/header_map_impl.h" @@ -66,6 +67,10 @@ HeaderUtility::HeaderData::HeaderData(const envoy::config::route::v3::HeaderMatc header_match_type_ = HeaderMatchType::Contains; value_ = config.contains_match(); break; + case envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase::kStringMatch: + header_match_type_ = HeaderMatchType::StringMatch; + string_match_ = std::make_unique(config.string_match()); + break; case envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase:: HEADER_MATCH_SPECIFIER_NOT_SET: FALLTHRU; @@ -138,17 +143,18 @@ bool HeaderUtility::matchHeaders(const HeaderMap& request_headers, const HeaderD } } + const auto value = header_value.result().value(); bool match; switch (header_data.header_match_type_) { case HeaderMatchType::Value: - match = header_data.value_.empty() || header_value.result().value() == header_data.value_; + match = header_data.value_.empty() || value == header_data.value_; break; case HeaderMatchType::Regex: - match = header_data.regex_->match(header_value.result().value()); + match = header_data.regex_->match(value); break; case HeaderMatchType::Range: { int64_t header_int_value = 0; - match = absl::SimpleAtoi(header_value.result().value(), &header_int_value) && + match = absl::SimpleAtoi(value, &header_int_value) && header_int_value >= header_data.range_.start() && header_int_value < header_data.range_.end(); break; @@ -157,13 +163,16 @@ bool HeaderUtility::matchHeaders(const HeaderMap& request_headers, const HeaderD match = header_data.present_; break; case HeaderMatchType::Prefix: - match = absl::StartsWith(header_value.result().value(), header_data.value_); + match = absl::StartsWith(value, header_data.value_); break; case HeaderMatchType::Suffix: - match = absl::EndsWith(header_value.result().value(), header_data.value_); + match = absl::EndsWith(value, header_data.value_); break; case HeaderMatchType::Contains: - match = absl::StrContains(header_value.result().value(), header_data.value_); + match = absl::StrContains(value, header_data.value_); + break; + case HeaderMatchType::StringMatch: + match = header_data.string_match_->match(value); break; default: NOT_REACHED_GCOVR_EXCL_LINE; diff --git a/source/common/http/header_utility.h b/source/common/http/header_utility.h index c3b8a2088ea9..50b1d571f60e 100644 --- a/source/common/http/header_utility.h +++ b/source/common/http/header_utility.h @@ -2,6 +2,7 @@ #include +#include "envoy/common/matchers.h" #include "envoy/common/regex.h" #include "envoy/config/core/v3/protocol.pb.h" #include "envoy/config/route/v3/route_components.pb.h" @@ -20,7 +21,16 @@ namespace Http { */ class HeaderUtility { public: - enum class HeaderMatchType { Value, Regex, Range, Present, Prefix, Suffix, Contains }; + enum class HeaderMatchType { + Value, + Regex, + Range, + Present, + Prefix, + Suffix, + Contains, + StringMatch + }; /** * Get all header values as a single string. Multiple headers are concatenated with ','. @@ -65,6 +75,7 @@ class HeaderUtility { std::string value_; Regex::CompiledMatcherPtr regex_; envoy::type::v3::Int64Range range_; + Matchers::StringMatcherPtr string_match_; const bool invert_match_; bool present_; diff --git a/test/common/access_log/access_log_impl_test.cc b/test/common/access_log/access_log_impl_test.cc index 427392a2df98..b52e2d038057 100644 --- a/test/common/access_log/access_log_impl_test.cc +++ b/test/common/access_log/access_log_impl_test.cc @@ -783,7 +783,8 @@ name: accesslog header_filter: header: name: test-header - exact_match: exact-match-value + string_match: + exact: exact-match-value typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog @@ -812,9 +813,10 @@ name: accesslog header_filter: header: name: test-header - safe_regex_match: - google_re2: {} - regex: "\\d{3}" + string_match: + safe_regex: + google_re2: {} + regex: "\\d{3}" typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog path: /dev/null diff --git a/test/common/http/header_utility_test.cc b/test/common/http/header_utility_test.cc index 59a52bd5c3ae..7e9ed68e23df 100644 --- a/test/common/http/header_utility_test.cc +++ b/test/common/http/header_utility_test.cc @@ -201,7 +201,7 @@ name: test-header EXPECT_EQ(HeaderUtility::HeaderMatchType::Present, header_data.header_match_type_); } -TEST(HeaderDataConstructorTest, ExactMatchSpecifier) { +TEST(HeaderDataConstructorTest, DEPRECATED_FEATURE_TEST(ExactMatchSpecifier)) { const std::string yaml = R"EOF( name: test-header exact_match: value @@ -247,7 +247,7 @@ present_match: true EXPECT_EQ("", header_data.value_); } -TEST(HeaderDataConstructorTest, PrefixMatchSpecifier) { +TEST(HeaderDataConstructorTest, DEPRECATED_FEATURE_TEST(PrefixMatchSpecifier)) { const std::string yaml = R"EOF( name: test-header prefix_match: value @@ -261,7 +261,7 @@ prefix_match: value EXPECT_EQ("value", header_data.value_); } -TEST(HeaderDataConstructorTest, SuffixMatchSpecifier) { +TEST(HeaderDataConstructorTest, DEPRECATED_FEATURE_TEST(SuffixMatchSpecifier)) { const std::string yaml = R"EOF( name: test-header suffix_match: value @@ -275,7 +275,7 @@ suffix_match: value EXPECT_EQ("value", header_data.value_); } -TEST(HeaderDataConstructorTest, ContainsMatchSpecifier) { +TEST(HeaderDataConstructorTest, DEPRECATED_FEATURE_TEST(ContainsMatchSpecifier)) { const std::string yaml = R"EOF( name: test-header contains_match: somevalueinside @@ -289,10 +289,26 @@ contains_match: somevalueinside EXPECT_EQ("somevalueinside", header_data.value_); } +TEST(HeaderDataConstructorTest, StringMatchSpecifier) { + const std::string yaml = R"EOF( +name: test-header +string_match: + exact: value + )EOF"; + + HeaderUtility::HeaderData header_data = + HeaderUtility::HeaderData(parseHeaderMatcherFromYaml(yaml)); + + EXPECT_EQ("test-header", header_data.name_.get()); + EXPECT_EQ(HeaderUtility::HeaderMatchType::StringMatch, header_data.header_match_type_); + EXPECT_TRUE(header_data.string_match_->match("value")); +} + TEST(HeaderDataConstructorTest, InvertMatchSpecifier) { const std::string yaml = R"EOF( name: test-header -exact_match: value +string_match: + exact: value invert_match: true )EOF"; @@ -300,8 +316,8 @@ invert_match: true HeaderUtility::HeaderData(parseHeaderMatcherFromYaml(yaml)); EXPECT_EQ("test-header", header_data.name_.get()); - EXPECT_EQ(HeaderUtility::HeaderMatchType::Value, header_data.header_match_type_); - EXPECT_EQ("value", header_data.value_); + EXPECT_EQ(HeaderUtility::HeaderMatchType::StringMatch, header_data.header_match_type_); + EXPECT_TRUE(header_data.string_match_->match("value")); EXPECT_EQ(true, header_data.invert_match_); } @@ -310,9 +326,10 @@ TEST(MatchHeadersTest, MayMatchOneOrMoreRequestHeader) { const std::string yaml = R"EOF( name: match-header -safe_regex_match: - google_re2: {} - regex: (a|b) +string_match: + safe_regex: + google_re2: {} + regex: (a|b) )EOF"; std::vector header_data; @@ -330,7 +347,8 @@ name: match-header header_data[0] = std::make_unique(parseHeaderMatcherFromYaml(R"EOF( name: match-header -exact_match: a,b +string_match: + exact: a,b )EOF")); // Make sure that an exact match on "a,b" does in fact work. EXPECT_TRUE(HeaderUtility::matchHeaders(headers, header_data)); @@ -380,7 +398,7 @@ name: match-header EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderExactMatch) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderExactMatch)) { TestRequestHeaderMapImpl matching_headers{{"match-header", "match-value"}}; TestRequestHeaderMapImpl unmatching_headers{{"match-header", "other-value"}, {"other-header", "match-value"}}; @@ -396,7 +414,7 @@ exact_match: match-value EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderExactMatchInverse) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderExactMatchInverse)) { TestRequestHeaderMapImpl matching_headers{{"match-header", "other-value"}, {"other-header", "match-value"}}; TestRequestHeaderMapImpl unmatching_headers{{"match-header", "match-value"}}; @@ -414,7 +432,7 @@ invert_match: true EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderSafeRegexMatch) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderSafeRegexMatch)) { TestRequestHeaderMapImpl matching_headers{{"match-header", "123"}}; TestRequestHeaderMapImpl unmatching_headers{{"match-header", "1234"}, {"match-header", "123.456"}}; @@ -432,7 +450,7 @@ name: match-header EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderSafeRegexInverseMatch) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderSafeRegexInverseMatch)) { TestDeprecatedV2Api _deprecated_v2_api; TestRequestHeaderMapImpl matching_headers{{"match-header", "1234"}, {"match-header", "123.456"}}; TestRequestHeaderMapImpl unmatching_headers{{"match-header", "123"}}; @@ -572,7 +590,7 @@ invert_match: true EXPECT_TRUE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderPrefixMatch) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderPrefixMatch)) { TestRequestHeaderMapImpl matching_headers{{"match-header", "value123"}}; TestRequestHeaderMapImpl unmatching_headers{{"match-header", "123value"}}; @@ -588,7 +606,7 @@ prefix_match: value EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderPrefixInverseMatch) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderPrefixInverseMatch)) { TestRequestHeaderMapImpl unmatching_headers{{"match-header", "value123"}}; TestRequestHeaderMapImpl matching_headers{{"match-header", "123value"}}; @@ -605,7 +623,7 @@ invert_match: true EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderSuffixMatch) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderSuffixMatch)) { TestRequestHeaderMapImpl matching_headers{{"match-header", "123value"}}; TestRequestHeaderMapImpl unmatching_headers{{"match-header", "value123"}}; @@ -621,7 +639,7 @@ suffix_match: value EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderSuffixInverseMatch) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderSuffixInverseMatch)) { TestRequestHeaderMapImpl unmatching_headers{{"match-header", "123value"}}; TestRequestHeaderMapImpl matching_headers{{"match-header", "value123"}}; @@ -638,7 +656,7 @@ invert_match: true EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderContainsMatch) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderContainsMatch)) { TestRequestHeaderMapImpl matching_headers{{"match-header", "123onevalue456"}}; TestRequestHeaderMapImpl unmatching_headers{{"match-header", "123anothervalue456"}}; @@ -654,7 +672,7 @@ contains_match: onevalue EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); } -TEST(MatchHeadersTest, HeaderContainsInverseMatch) { +TEST(MatchHeadersTest, DEPRECATED_FEATURE_TEST(HeaderContainsInverseMatch)) { TestRequestHeaderMapImpl matching_headers{{"match-header", "123onevalue456"}}; TestRequestHeaderMapImpl unmatching_headers{{"match-header", "123anothervalue456"}}; @@ -671,6 +689,62 @@ invert_match: true EXPECT_FALSE(HeaderUtility::matchHeaders(matching_headers, header_data)); } +TEST(MatchHeadersTest, HeaderStringMatch) { + TestRequestHeaderMapImpl matching_headers{{"match-header", "match-value"}}; + TestRequestHeaderMapImpl unmatching_headers{{"match-header", "other-value"}, + {"other-header", "match-value"}}; + const std::string yaml = R"EOF( +name: match-header +string_match: + exact: match-value + )EOF"; + + std::vector header_data; + header_data.push_back( + std::make_unique(parseHeaderMatcherFromYaml(yaml))); + EXPECT_TRUE(HeaderUtility::matchHeaders(matching_headers, header_data)); + EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); +} + +TEST(MatchHeadersTest, HeaderStringMatchIgnoreCase) { + TestRequestHeaderMapImpl matching_headers_1{{"match-header", "123onevalue456"}}; + TestRequestHeaderMapImpl matching_headers_2{{"match-header", "123OneValue456"}}; + TestRequestHeaderMapImpl unmatching_headers{{"match-header", "123anothervalue456"}}; + + const std::string yaml = R"EOF( +name: match-header +string_match: + contains: onevalue + ignore_case: true + )EOF"; + + std::vector header_data; + header_data.push_back( + std::make_unique(parseHeaderMatcherFromYaml(yaml))); + EXPECT_TRUE(HeaderUtility::matchHeaders(matching_headers_1, header_data)); + EXPECT_TRUE(HeaderUtility::matchHeaders(matching_headers_2, header_data)); + EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); +} + +TEST(MatchHeadersTest, HeaderStringMatchInverse) { + TestRequestHeaderMapImpl matching_headers{{"match-header", "other-value"}, + {"other-header", "match-value"}}; + TestRequestHeaderMapImpl unmatching_headers{{"match-header", "match-value"}}; + + const std::string yaml = R"EOF( +name: match-header +string_match: + exact: match-value +invert_match: true + )EOF"; + + std::vector header_data; + header_data.push_back( + std::make_unique(parseHeaderMatcherFromYaml(yaml))); + EXPECT_TRUE(HeaderUtility::matchHeaders(matching_headers, header_data)); + EXPECT_FALSE(HeaderUtility::matchHeaders(unmatching_headers, header_data)); +} + TEST(HeaderIsValidTest, InvalidHeaderValuesAreRejected) { // ASCII values 1-31 are control characters (with the exception of ASCII // values 9, 10, and 13 which are a horizontal tab, line feed, and carriage diff --git a/test/common/router/config_impl_headermap_benchmark_test.cc b/test/common/router/config_impl_headermap_benchmark_test.cc index 755f858c8837..b30332475c85 100644 --- a/test/common/router/config_impl_headermap_benchmark_test.cc +++ b/test/common/router/config_impl_headermap_benchmark_test.cc @@ -45,7 +45,7 @@ static void manyCountryRoutesLongHeaders(benchmark::State& state) { new_routes->mutable_route()->set_cluster(country_name); auto headers_matcher = new_routes->mutable_match()->mutable_headers()->Add(); headers_matcher->set_name(country_header_name.get()); - headers_matcher->set_exact_match(country_name); + headers_matcher->mutable_string_match()->set_exact(country_name); } // Add the default route. auto new_routes = main_virtual_host->mutable_routes()->Add(); diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index a403b857474a..edec06438223 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -373,7 +373,8 @@ TEST_F(RouteMatcherTest, TestConnectRoutes) { {} headers: - name: x-safe - exact_match: "safe" + string_match: + exact: "safe" route: cluster: connect_header_match - name: default @@ -388,11 +389,13 @@ TEST_F(RouteMatcherTest, TestConnectRoutes) { virtual_clusters: - headers: - name: ":path" - safe_regex_match: - google_re2: {} - regex: "^/users/\\d+/location$" + string_match: + safe_regex: + google_re2: {} + regex: "^/users/\\d+/location$" - name: ":method" - exact_match: POST + string_match: + exact: POST name: ulu )EOF"; NiceMock stream_info; @@ -677,51 +680,63 @@ TEST_F(RouteMatcherTest, TestRoutes) { virtual_clusters: - headers: - name: ":path" - safe_regex_match: - google_re2: {} - regex: "^/rides$" + string_match: + safe_regex: + google_re2: {} + regex: "^/rides$" - name: ":method" - exact_match: POST + string_match: + exact: POST name: ride_request - headers: - name: ":path" - safe_regex_match: - google_re2: {} - regex: "^/rides/\\d+$" + string_match: + safe_regex: + google_re2: {} + regex: "^/rides/\\d+$" - name: ":method" - exact_match: PUT + string_match: + exact: PUT name: update_ride - headers: - name: ":path" - safe_regex_match: - google_re2: {} - regex: "^/users/\\d+/chargeaccounts$" + string_match: + safe_regex: + google_re2: {} + regex: "^/users/\\d+/chargeaccounts$" - name: ":method" - exact_match: POST + string_match: + exact: POST name: cc_add - headers: - name: ":path" - safe_regex_match: - google_re2: {} - regex: "^/users$" + string_match: + safe_regex: + google_re2: {} + regex: "^/users$" - name: ":method" - exact_match: POST + string_match: + exact: POST name: create_user_login - headers: - name: ":path" - safe_regex_match: - google_re2: {} - regex: "^/users/\\d+$" + string_match: + safe_regex: + google_re2: {} + regex: "^/users/\\d+$" - name: ":method" - exact_match: PUT + string_match: + exact: PUT name: update_user - headers: - name: ":path" - safe_regex_match: - google_re2: {} - regex: "^/users/\\d+/location$" + string_match: + safe_regex: + google_re2: {} + regex: "^/users/\\d+/location$" - name: ":method" - exact_match: POST + string_match: + exact: POST name: ulu )EOF"; NiceMock stream_info; @@ -1173,9 +1188,10 @@ TEST_F(RouteMatcherTest, TestRoutesWithInvalidRegex) { name: "invalid" headers: name: "invalid" - safe_regex_match: - google_re2: {} - regex: "^/(+invalid)" + string_match: + safe_regex: + google_re2: {} + regex: "^/(+invalid)" )EOF"; NiceMock stream_info; @@ -1845,16 +1861,19 @@ TEST_F(RouteMatcherTest, HeaderMatchedRouting) { prefix: "/" headers: - name: test_header - exact_match: test + string_match: + exact: test route: cluster: local_service_with_headers - match: prefix: "/" headers: - name: test_header_multiple1 - exact_match: test1 + string_match: + exact: test1 - name: test_header_multiple2 - exact_match: test2 + string_match: + exact: test2 route: cluster: local_service_with_multiple_headers - match: @@ -1868,16 +1887,18 @@ TEST_F(RouteMatcherTest, HeaderMatchedRouting) { prefix: "/" headers: - name: test_header_pattern - safe_regex_match: - google_re2: {} - regex: "^user=test-\\d+$" + string_match: + safe_regex: + google_re2: {} + regex: "^user=test-\\d+$" route: cluster: local_service_with_header_pattern_set_regex - match: prefix: "/" headers: - name: test_header_pattern - exact_match: "^customer=test-\\d+$" + string_match: + exact: "^customer=test-\\d+$" route: cluster: local_service_with_header_pattern_unset_regex - match: @@ -1976,7 +1997,8 @@ TEST_F(RouteMatcherTest, InvalidHeaderMatchedRoutingConfig) { prefix: "/" headers: - name: test_header - exact_match: "(+not a regex)" + string_match: + exact: "(+not a regex)" route: { cluster: "local_service" } )EOF"; @@ -1989,9 +2011,10 @@ TEST_F(RouteMatcherTest, InvalidHeaderMatchedRoutingConfig) { prefix: "/" headers: - name: test_header - safe_regex_match: - google_re2: {} - regex: "(+invalid regex)" + string_match: + safe_regex: + google_re2: {} + regex: "(+invalid regex)" route: { cluster: "local_service" } )EOF"; @@ -2808,7 +2831,8 @@ TEST_F(RouteMatcherTest, ContentType) { prefix: "/" headers: - name: content-type - exact_match: application/grpc + string_match: + exact: application/grpc route: cluster: local_service_grpc - match: @@ -6692,16 +6716,19 @@ TEST_F(RouteMatcherTest, HeaderMatchedRoutingV2) { prefix: "/" headers: - name: test_header - exact_match: test + string_match: + exact: test route: cluster: local_service_with_headers - match: prefix: "/" headers: - name: test_header_multiple1 - exact_match: test1 + string_match: + exact: test1 - name: test_header_multiple2 - exact_match: test2 + string_match: + exact: test2 route: cluster: local_service_with_multiple_headers - match: @@ -6714,16 +6741,18 @@ TEST_F(RouteMatcherTest, HeaderMatchedRoutingV2) { prefix: "/" headers: - name: test_header_pattern - safe_regex_match: - google_re2: {} - regex: "^user=test-\\d+$" + string_match: + safe_regex: + google_re2: {} + regex: "^user=test-\\d+$" route: cluster: local_service_with_header_pattern_set_regex - match: prefix: "/" headers: - name: test_header_pattern - exact_match: "^customer=test-\\d+$" + string_match: + exact: "^customer=test-\\d+$" route: cluster: local_service_with_header_pattern_unset_regex - match: @@ -6743,7 +6772,8 @@ TEST_F(RouteMatcherTest, HeaderMatchedRoutingV2) { start: -10 end: 1 - name: test_header_multiple_exact - exact_match: test + string_match: + exact: test route: cluster: local_service_with_header_range_test2 - match: @@ -6768,7 +6798,8 @@ TEST_F(RouteMatcherTest, HeaderMatchedRoutingV2) { prefix: "/" headers: - name: test_header_range - exact_match: "9223372036854775807" + string_match: + exact: "9223372036854775807" route: cluster: local_service_with_header_range_test5 - match: @@ -7172,7 +7203,8 @@ TEST_F(RouteConfigurationV2, RetriableHeaders) { retry_policy: retriable_headers: - name: ":status" - exact_match: "500" + string_match: + exact: "500" - name: X-Upstream-Pushback )EOF"; diff --git a/test/common/router/retry_state_impl_test.cc b/test/common/router/retry_state_impl_test.cc index fd0ed209c656..1640683d81c9 100644 --- a/test/common/router/retry_state_impl_test.cc +++ b/test/common/router/retry_state_impl_test.cc @@ -477,11 +477,11 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersPolicyViaRetryPolicyConfigurati auto* matcher2 = matchers.Add(); matcher2->set_name("should-retry"); - matcher2->set_exact_match("yes"); + matcher2->mutable_string_match()->set_exact("yes"); auto* matcher3 = matchers.Add(); matcher3->set_name("X-Verdict"); - matcher3->set_prefix_match("retry"); + matcher3->mutable_string_match()->set_prefix("retry"); auto* matcher4 = matchers.Add(); matcher4->set_name(":status"); @@ -623,7 +623,7 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersMergedConfigAndRequestHeaders) // Config says: retry if response is not 200. auto* matcher = matchers.Add(); matcher->set_name(":status"); - matcher->set_exact_match("200"); + matcher->mutable_string_match()->set_exact("200"); matcher->set_invert_match(true); policy_.retriable_headers_ = Http::HeaderUtility::buildHeaderMatcherVector(matchers); @@ -674,11 +674,11 @@ TEST_F(RouterRetryStateImplTest, PolicyLimitedByRequestHeaders) { Protobuf::RepeatedPtrField matchers; auto* matcher = matchers.Add(); matcher->set_name(":method"); - matcher->set_exact_match("GET"); + matcher->mutable_string_match()->set_exact("GET"); auto* matcher2 = matchers.Add(); matcher2->set_name(":method"); - matcher2->set_exact_match("HEAD"); + matcher2->mutable_string_match()->set_exact("HEAD"); policy_.retriable_request_headers_ = Http::HeaderUtility::buildHeaderMatcherVector(matchers); diff --git a/test/common/router/router_ratelimit_test.cc b/test/common/router/router_ratelimit_test.cc index 01127c1a0797..358c9513f5cd 100644 --- a/test/common/router/router_ratelimit_test.cc +++ b/test/common/router/router_ratelimit_test.cc @@ -827,7 +827,8 @@ TEST_F(RateLimitPolicyEntryTest, HeaderValueMatch) { descriptor_value: fake_value headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; setupTest(yaml); @@ -848,7 +849,8 @@ TEST_F(RateLimitPolicyEntryTest, HeaderValueMatchNoMatch) { descriptor_value: fake_value headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; setupTest(yaml); @@ -868,7 +870,8 @@ TEST_F(RateLimitPolicyEntryTest, HeaderValueMatchHeadersNotPresent) { expect_match: false headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; setupTest(yaml); @@ -890,7 +893,8 @@ TEST_F(RateLimitPolicyEntryTest, HeaderValueMatchHeadersPresent) { expect_match: false headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; setupTest(yaml); @@ -932,7 +936,8 @@ TEST_F(RateLimitPolicyEntryTest, CompoundActionsNoDescriptor) { descriptor_value: fake_value headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; setupTest(yaml); diff --git a/test/config/utility.cc b/test/config/utility.cc index 820f2c60d82a..70a398663251 100644 --- a/test/config/utility.cc +++ b/test/config/utility.cc @@ -668,7 +668,7 @@ void ConfigHelper::setConnectConfig( auto* header = match->add_headers(); header->set_name(":method"); - header->set_exact_match("POST"); + header->mutable_string_match()->set_exact("POST"); } else { match->mutable_connect_matcher(); } diff --git a/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc b/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc index ee2c03595080..be22190b31f4 100644 --- a/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc +++ b/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc @@ -55,7 +55,8 @@ class AwsMetadataIntegrationTestBase : public ::testing::Test, public BaseIntegr prefix: "/" headers: - name: Authorization - exact_match: AUTH_TOKEN + string_match: + exact: AUTH_TOKEN - name: no_auth_route direct_response: status: {} diff --git a/test/extensions/common/matcher/matcher_test.cc b/test/extensions/common/matcher/matcher_test.cc index 6531884fe830..cad6e76b8dc9 100644 --- a/test/extensions/common/matcher/matcher_test.cc +++ b/test/extensions/common/matcher/matcher_test.cc @@ -98,7 +98,8 @@ TEST_F(TapMatcherTest, AndMightChangeStatus) { - http_response_headers_match: headers: - name: bar - exact_match: baz + string_match: + exact: baz )EOF"; TestUtility::loadFromYaml(matcher_yaml, config_); diff --git a/test/extensions/filters/common/rbac/matchers_test.cc b/test/extensions/filters/common/rbac/matchers_test.cc index ed39ff132283..87d22517dd42 100644 --- a/test/extensions/filters/common/rbac/matchers_test.cc +++ b/test/extensions/filters/common/rbac/matchers_test.cc @@ -146,7 +146,7 @@ TEST(NotMatcher, Principal) { TEST(HeaderMatcher, HeaderMatcher) { envoy::config::route::v3::HeaderMatcher config; config.set_name("foo"); - config.set_exact_match("bar"); + config.mutable_string_match()->set_exact("bar"); Envoy::Http::TestRequestHeaderMapImpl headers; Envoy::Http::LowerCaseString key("foo"); diff --git a/test/extensions/filters/http/fault/fault_filter_test.cc b/test/extensions/filters/http/fault/fault_filter_test.cc index f09372a74c38..b4add362fb60 100644 --- a/test/extensions/filters/http/fault/fault_filter_test.cc +++ b/test/extensions/filters/http/fault/fault_filter_test.cc @@ -114,7 +114,8 @@ class FaultFilterTest : public testing::Test { http_status: 503 headers: - name: X-Foo1 - exact_match: Bar + string_match: + exact: Bar - name: X-Foo2 )EOF"; diff --git a/test/extensions/filters/http/health_check/config_test.cc b/test/extensions/filters/http/health_check/config_test.cc index d3e697276fb2..4faa78c630af 100644 --- a/test/extensions/filters/http/health_check/config_test.cc +++ b/test/extensions/filters/http/health_check/config_test.cc @@ -26,7 +26,8 @@ TEST(HealthCheckFilterConfig, HealthCheckFilter) { pass_through_mode: true headers: - name: ":path" - exact_match: "/hc" + string_match: + exact: "/hc" )EOF"; envoy::extensions::filters::http::health_check::v3::HealthCheck proto_config; @@ -44,7 +45,8 @@ TEST(HealthCheckFilterConfig, BadHealthCheckFilterConfig) { pass_through_mode: true headers: - name: ":path" - exact_match: "/hc" + string_match: + exact: "/hc" status: 500 )EOF"; @@ -59,7 +61,8 @@ TEST(HealthCheckFilterConfig, FailsWhenNotPassThroughButTimeoutSetYaml) { cache_time: 0.234s headers: - name: ":path" - exact_match: "/foo" + string_match: + exact: "/foo" )EOF"; envoy::extensions::filters::http::health_check::v3::HealthCheck proto_config; @@ -78,7 +81,8 @@ TEST(HealthCheckFilterConfig, NotFailingWhenNotPassThroughAndTimeoutNotSetYaml) cache_time: 0.234s headers: - name: ":path" - exact_match: "/foo" + string_match: + exact: "/foo" )EOF"; envoy::extensions::filters::http::health_check::v3::HealthCheck proto_config; @@ -100,7 +104,7 @@ TEST(HealthCheckFilterConfig, FailsWhenNotPassThroughButTimeoutSetProto) { config.mutable_cache_time()->set_seconds(10); envoy::config::route::v3::HeaderMatcher& header = *config.add_headers(); header.set_name(":path"); - header.set_exact_match("foo"); + header.mutable_string_match()->set_exact("foo"); EXPECT_THROW( healthCheckFilterConfig.createFilterFactoryFromProto(config, "dummy_stats_prefix", context), @@ -115,7 +119,7 @@ TEST(HealthCheckFilterConfig, NotFailingWhenNotPassThroughAndTimeoutNotSetProto) config.mutable_pass_through_mode()->set_value(false); envoy::config::route::v3::HeaderMatcher& header = *config.add_headers(); header.set_name(":path"); - header.set_exact_match("foo"); + header.mutable_string_match()->set_exact("foo"); healthCheckFilterConfig.createFilterFactoryFromProto(config, "dummy_stats_prefix", context); } @@ -129,7 +133,7 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterWithEmptyProto) { config.mutable_pass_through_mode()->set_value(false); envoy::config::route::v3::HeaderMatcher& header = *config.add_headers(); header.set_name(":path"); - header.set_exact_match("foo"); + header.mutable_string_match()->set_exact("foo"); healthCheckFilterConfig.createFilterFactoryFromProto(config, "dummy_stats_prefix", context); } @@ -184,7 +188,7 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterHeaderMatch) { envoy::config::route::v3::HeaderMatcher& yheader = *config.add_headers(); yheader.set_name("y-healthcheck"); - yheader.set_exact_match("foo"); + yheader.mutable_string_match()->set_exact("foo"); Http::TestRequestHeaderMapImpl headers{{"x-healthcheck", "arbitrary_value"}, {"y-healthcheck", "foo"}}; @@ -203,7 +207,7 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterHeaderMatchWrongValue) { envoy::config::route::v3::HeaderMatcher& yheader = *config.add_headers(); yheader.set_name("y-healthcheck"); - yheader.set_exact_match("foo"); + yheader.mutable_string_match()->set_exact("foo"); Http::TestRequestHeaderMapImpl headers{{"x-healthcheck", "arbitrary_value"}, {"y-healthcheck", "bar"}}; @@ -222,7 +226,7 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterHeaderMatchMissingHeader) { envoy::config::route::v3::HeaderMatcher& yheader = *config.add_headers(); yheader.set_name("y-healthcheck"); - yheader.set_exact_match("foo"); + yheader.mutable_string_match()->set_exact("foo"); Http::TestRequestHeaderMapImpl headers{{"y-healthcheck", "foo"}}; @@ -237,7 +241,7 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterDuplicateMatch) { envoy::config::route::v3::HeaderMatcher& header = *config.add_headers(); header.set_name("x-healthcheck"); - header.set_exact_match("foo"); + header.mutable_string_match()->set_exact("foo"); envoy::config::route::v3::HeaderMatcher& dup_header = *config.add_headers(); dup_header.set_name("x-healthcheck"); @@ -255,11 +259,11 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterDuplicateNoMatch) { envoy::config::route::v3::HeaderMatcher& header = *config.add_headers(); header.set_name("x-healthcheck"); - header.set_exact_match("foo"); + header.mutable_string_match()->set_exact("foo"); envoy::config::route::v3::HeaderMatcher& dup_header = *config.add_headers(); dup_header.set_name("x-healthcheck"); - dup_header.set_exact_match("bar"); + dup_header.mutable_string_match()->set_exact("bar"); Http::TestRequestHeaderMapImpl headers{{"x-healthcheck", "foo"}}; diff --git a/test/extensions/filters/http/health_check/health_check_test.cc b/test/extensions/filters/http/health_check/health_check_test.cc index b61685e8d677..d2715efa89c6 100644 --- a/test/extensions/filters/http/health_check/health_check_test.cc +++ b/test/extensions/filters/http/health_check/health_check_test.cc @@ -50,7 +50,7 @@ class HealthCheckFilterTest : public testing::Test { header_data_ = std::make_shared>(); envoy::config::route::v3::HeaderMatcher matcher; matcher.set_name(":path"); - matcher.set_exact_match("/healthcheck"); + matcher.mutable_string_match()->set_exact("/healthcheck"); header_data_->emplace_back(std::make_unique(matcher)); filter_ = std::make_unique(context_, pass_through, cache_manager_, header_data_, cluster_min_healthy_percentages); diff --git a/test/extensions/filters/http/oauth2/filter_test.cc b/test/extensions/filters/http/oauth2/filter_test.cc index 9179db9d6686..db54e404a7ed 100644 --- a/test/extensions/filters/http/oauth2/filter_test.cc +++ b/test/extensions/filters/http/oauth2/filter_test.cc @@ -114,7 +114,7 @@ class OAuth2Test : public testing::Test { p.add_resources("https://example.com"); auto* matcher = p.add_pass_through_matcher(); matcher->set_name(":method"); - matcher->set_exact_match("OPTIONS"); + matcher->mutable_string_match()->set_exact("OPTIONS"); auto credentials = p.mutable_credentials(); credentials->set_client_id(TEST_CLIENT_ID); credentials->mutable_token_secret()->set_name("secret"); @@ -257,7 +257,7 @@ TEST_F(OAuth2Test, DefaultAuthScope) { p.set_forward_bearer_token(true); auto* matcher = p.add_pass_through_matcher(); matcher->set_name(":method"); - matcher->set_exact_match("OPTIONS"); + matcher->mutable_string_match()->set_exact("OPTIONS"); auto credentials = p.mutable_credentials(); credentials->set_client_id(TEST_CLIENT_ID); diff --git a/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc b/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc index 4874d30d0778..265fc0e05f2f 100644 --- a/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc +++ b/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc @@ -16,7 +16,10 @@ name: rbac policies: foo: permissions: - - header: { name: ":method", exact_match: "GET" } + - header: + name: ":method" + string_match: + exact: "GET" principals: - any: true )EOF"; @@ -30,7 +33,10 @@ name: rbac policies: "deny policy": permissions: - - header: { name: ":method", exact_match: "GET" } + - header: + name: ":method" + string_match: + exact: "GET" principals: - any: true )EOF"; @@ -43,7 +49,10 @@ name: rbac policies: foo: permissions: - - header: { name: ":path", prefix_match: "/foo" } + - header: + name: ":path" + string_match: + prefix: "/foo" principals: - any: true )EOF"; @@ -85,7 +94,10 @@ name: rbac policies: foo: permissions: - - header: { name: ":method", exact_match: "GET" } + - header: + name: ":method" + string_match: + exact: "GET" principals: - any: true )EOF"; diff --git a/test/extensions/filters/http/tap/tap_filter_integration_test.cc b/test/extensions/filters/http/tap/tap_filter_integration_test.cc index 2806dd7bc4a7..403c5ca02384 100644 --- a/test/extensions/filters/http/tap/tap_filter_integration_test.cc +++ b/test/extensions/filters/http/tap/tap_filter_integration_test.cc @@ -239,11 +239,13 @@ config_id: test_config_id - http_request_headers_match: headers: - name: foo - exact_match: bar + string_match: + exact: bar - http_response_headers_match: headers: - name: bar - exact_match: baz + string_match: + exact: baz output_config: sinks: - streaming_admin: {} @@ -305,11 +307,13 @@ config_id: test_config_id - http_request_headers_match: headers: - name: foo - exact_match: bar + string_match: + exact: bar - http_response_headers_match: headers: - name: bar - exact_match: baz + string_match: + exact: baz output_config: sinks: - streaming_admin: {} @@ -349,11 +353,13 @@ config_id: test_config_id - http_request_trailers_match: headers: - name: foo_trailer - exact_match: bar + string_match: + exact: bar - http_response_trailers_match: headers: - name: bar_trailer - exact_match: baz + string_match: + exact: baz output_config: sinks: - streaming_admin: {} @@ -398,11 +404,13 @@ config_id: test_config_id - http_request_trailers_match: headers: - name: foo_trailer - exact_match: bar + string_match: + exact: bar - http_response_trailers_match: headers: - name: bar_trailer - exact_match: baz + string_match: + exact: baz output_config: sinks: - streaming_admin: {} @@ -535,7 +543,8 @@ name: tap http_request_headers_match: headers: - name: foo - exact_match: bar + string_match: + exact: bar output_config: streaming: true sinks: @@ -581,7 +590,8 @@ name: tap http_response_headers_match: headers: - name: bar - exact_match: baz + string_match: + exact: baz output_config: streaming: true sinks: diff --git a/test/extensions/filters/network/dubbo_proxy/route_matcher_test.cc b/test/extensions/filters/network/dubbo_proxy/route_matcher_test.cc index a523468d69a2..efd8ca25294d 100644 --- a/test/extensions/filters/network/dubbo_proxy/route_matcher_test.cc +++ b/test/extensions/filters/network/dubbo_proxy/route_matcher_test.cc @@ -679,9 +679,11 @@ interface: org.apache.dubbo.demo.DemoService exact: "add" headers: - name: custom - exact_match: "123" + string_match: + exact: "123" - name: custom1 - exact_match: "123" + string_match: + exact: "123" invert_match: true route: cluster: user_service_dubbo_server diff --git a/test/extensions/filters/network/rocketmq_proxy/route_matcher_test.cc b/test/extensions/filters/network/rocketmq_proxy/route_matcher_test.cc index 620fb5432124..5153bc13729d 100644 --- a/test/extensions/filters/network/rocketmq_proxy/route_matcher_test.cc +++ b/test/extensions/filters/network/rocketmq_proxy/route_matcher_test.cc @@ -36,7 +36,8 @@ name: default_route exact: test_topic headers: - name: code - exact_match: '310' + string_match: + exact: '310' route: cluster: fake_cluster metadata_match: diff --git a/test/extensions/filters/network/thrift_proxy/integration_test.cc b/test/extensions/filters/network/thrift_proxy/integration_test.cc index 5f7cb2c41b15..d13f9ddd2975 100644 --- a/test/extensions/filters/network/thrift_proxy/integration_test.cc +++ b/test/extensions/filters/network/thrift_proxy/integration_test.cc @@ -41,19 +41,23 @@ class ThriftConnManagerIntegrationTest method_name: "execute" headers: - name: "x-header-1" - exact_match: "x-value-1" + string_match: + exact: "x-value-1" - name: "x-header-2" - safe_regex_match: - google_re2: {} - regex: "0.[5-9]" + string_match: + safe_regex: + google_re2: {} + regex: "0.[5-9]" - name: "x-header-3" range_match: start: 100 end: 200 - name: "x-header-4" - prefix_match: "user_id:" + string_match: + prefix: "user_id:" - name: "x-header-5" - suffix_match: "asdf" + string_match: + suffix: "asdf" route: cluster: "cluster_1" - match: diff --git a/test/extensions/filters/network/thrift_proxy/route_matcher_test.cc b/test/extensions/filters/network/thrift_proxy/route_matcher_test.cc index d7623f2418d2..8e19060b27e7 100644 --- a/test/extensions/filters/network/thrift_proxy/route_matcher_test.cc +++ b/test/extensions/filters/network/thrift_proxy/route_matcher_test.cc @@ -309,7 +309,8 @@ name: config method_name: "method1" headers: - name: "x-header-1" - exact_match: "x-value-1" + string_match: + exact: "x-value-1" route: cluster: "cluster1" )EOF"; @@ -340,9 +341,10 @@ name: config method_name: "method1" headers: - name: "x-version" - safe_regex_match: - google_re2: {} - regex: "0.[5-9]" + string_match: + safe_regex: + google_re2: {} + regex: "0.[5-9]" route: cluster: "cluster1" )EOF"; @@ -453,7 +455,8 @@ name: config method_name: "method1" headers: - name: "x-header-1" - prefix_match: "user_id:" + string_match: + prefix: "user_id:" route: cluster: "cluster1" )EOF"; @@ -489,7 +492,8 @@ name: config method_name: "method1" headers: - name: "x-header-1" - suffix_match: "asdf" + string_match: + suffix: "asdf" route: cluster: "cluster1" )EOF"; diff --git a/test/extensions/filters/network/thrift_proxy/router_ratelimit_test.cc b/test/extensions/filters/network/thrift_proxy/router_ratelimit_test.cc index 9e5c6a1bcb01..15c19bd2be7b 100644 --- a/test/extensions/filters/network/thrift_proxy/router_ratelimit_test.cc +++ b/test/extensions/filters/network/thrift_proxy/router_ratelimit_test.cc @@ -468,7 +468,8 @@ TEST_F(ThriftRateLimitPolicyEntryTest, HeaderValueActionMatch) { descriptor_value: fake_value headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; initialize(yaml); @@ -487,7 +488,8 @@ TEST_F(ThriftRateLimitPolicyEntryTest, HeaderValueActionValueMismatch) { descriptor_value: fake_value headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; initialize(yaml); @@ -506,7 +508,8 @@ TEST_F(ThriftRateLimitPolicyEntryTest, HeaderValueActionNegateMatch) { expect_match: false headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; initialize(yaml); @@ -525,7 +528,8 @@ TEST_F(ThriftRateLimitPolicyEntryTest, HeaderValueActionNegatedMatchProducesDesc expect_match: false headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; initialize(yaml); @@ -562,7 +566,8 @@ TEST_F(ThriftRateLimitPolicyEntryTest, CompoundActionNoDescriptor) { descriptor_value: fake_value headers: - name: x-header-name - exact_match: test_value + string_match: + exact: test_value )EOF"; initialize(yaml); diff --git a/test/integration/http_subset_lb_integration_test.cc b/test/integration/http_subset_lb_integration_test.cc index e78db3278b62..6d9b1d96e363 100644 --- a/test/integration/http_subset_lb_integration_test.cc +++ b/test/integration/http_subset_lb_integration_test.cc @@ -120,7 +120,7 @@ class HttpSubsetLbIntegrationTest // Match the x-type header against the given host_type (a/b). auto* match_header = match->add_headers(); match_header->set_name(type_header_); - match_header->set_exact_match(host_type); + match_header->mutable_string_match()->set_exact(host_type); // Route to cluster_0, selecting metadata type=a or type=b. auto* action = route->mutable_route(); diff --git a/test/integration/local_reply_integration_test.cc b/test/integration/local_reply_integration_test.cc index fb9225a88bad..3e8f7af5338a 100644 --- a/test/integration/local_reply_integration_test.cc +++ b/test/integration/local_reply_integration_test.cc @@ -26,7 +26,8 @@ TEST_P(LocalReplyIntegrationTest, MapStatusCodeAndFormatToJson) { header_filter: header: name: test-header - exact_match: exact-match-value + string_match: + exact: exact-match-value status_code: 550 headers_to_add: - header: @@ -92,7 +93,8 @@ TEST_P(LocalReplyIntegrationTest, EmptyStructFormatter) { header_filter: header: name: test-header - exact_match: exact-match-value + string_match: + exact: exact-match-value status_code: 550 body_format: json_format: @@ -203,13 +205,15 @@ TEST_P(LocalReplyIntegrationTest, MapStatusCodeAndFormatToJsonForFirstMatchingFi header_filter: header: name: test-header - exact_match: exact-match-value-1 + string_match: + exact: exact-match-value-1 status_code: 550 - filter: header_filter: header: name: test-header - exact_match: exact-match-value + string_match: + exact: exact-match-value status_code: 551 headers_to_add: - header: @@ -225,7 +229,8 @@ TEST_P(LocalReplyIntegrationTest, MapStatusCodeAndFormatToJsonForFirstMatchingFi header_filter: header: name: test-header - exact_match: exact-match-value + string_match: + exact: exact-match-value status_code: 552 body_format: json_format: @@ -283,19 +288,22 @@ TEST_P(LocalReplyIntegrationTest, ShouldNotMatchAnyFilter) { header_filter: header: name: test-header - exact_match: exact-match-value-1 + string_match: + exact: exact-match-value-1 status_code: 550 - filter: header_filter: header: name: test-header - exact_match: exact-match-value-2 + string_match: + exact: exact-match-value-2 status_code: 551 - filter: header_filter: header: name: test-header - exact_match: exact-match-value-3 + string_match: + exact: exact-match-value-3 status_code: 552 body_format: json_format: @@ -355,19 +363,22 @@ TEST_P(LocalReplyIntegrationTest, ShouldMapResponseCodeAndMapToDefaultTextRespon header_filter: header: name: test-header - exact_match: exact-match-value-1 + string_match: + exact: exact-match-value-1 status_code: 550 - filter: header_filter: header: name: test-header - exact_match: exact-match-value-2 + string_match: + exact: exact-match-value-2 status_code: 551 - filter: header_filter: header: name: test-header - exact_match: exact-match-value-3 + string_match: + exact: exact-match-value-3 status_code: 552 )EOF"; setLocalReplyConfig(yaml); diff --git a/test/integration/transport_socket_match_integration_test.cc b/test/integration/transport_socket_match_integration_test.cc index fe5fe47026df..6b97546e038b 100644 --- a/test/integration/transport_socket_match_integration_test.cc +++ b/test/integration/transport_socket_match_integration_test.cc @@ -101,7 +101,7 @@ name: "tls_socket" // Match the x-type header against the given host_type (a/b). auto* match_header = match->add_headers(); match_header->set_name(type_header_); - match_header->set_exact_match(host_type); + match_header->mutable_string_match()->set_exact(host_type); // Route to cluster_0, selecting metadata type=a or type=b. auto* action = route->mutable_route(); diff --git a/test/tools/router_check/router.cc b/test/tools/router_check/router.cc index 7da0acffffa7..65ee00c42884 100644 --- a/test/tools/router_check/router.cc +++ b/test/tools/router_check/router.cc @@ -8,6 +8,7 @@ #include "envoy/config/route/v3/route.pb.h" #include "envoy/type/v3/percent.pb.h" +#include "source/common/common/macros.h" #include "source/common/common/random_generator.h" #include "source/common/network/socket_impl.h" #include "source/common/network/utility.h" @@ -18,9 +19,29 @@ #include "test/test_common/printers.h" namespace { -const std::string -toString(envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase specifier) { - switch (specifier) { + +const std::string toString(envoy::type::matcher::v3::StringMatcher::MatchPatternCase pattern) { + switch (pattern) { + case envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kExact: + return "exact"; + case envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kPrefix: + return "prefix"; + case envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kSuffix: + return "suffix"; + case envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kSafeRegex: + return "safe_regex"; + case envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kHiddenEnvoyDeprecatedRegex: + return "deprecated_regex"; + case envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kContains: + return "contains"; + case envoy::type::matcher::v3::StringMatcher::MatchPatternCase::MATCH_PATTERN_NOT_SET: + return "match_pattern_not_set"; + } + NOT_REACHED_GCOVR_EXCL_LINE; +} + +const std::string toString(const envoy::config::route::v3::HeaderMatcher& header) { + switch (header.header_match_specifier_case()) { case envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase::kExactMatch: return "exact_match"; break; @@ -48,6 +69,9 @@ toString(envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase speci case envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase::kContainsMatch: return "contains_match"; break; + case envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase::kStringMatch: + return "string_match." + ::toString(header.string_match().match_pattern_case()); + break; } NOT_REACHED_GCOVR_EXCL_LINE; } @@ -463,14 +487,8 @@ bool RouterCheckTool::matchHeaderField(const HeaderMap& header_map, // Test failed. Decide on what to log. std::string actual, expected; - std::string match_test_type{test_type + "." + ::toString(header.header_match_specifier_case())}; + std::string match_test_type{test_type + "." + ::toString(header)}; switch (header.header_match_specifier_case()) { - case envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase::kExactMatch: - actual = - header.name() + ": " + ::toString(header_map.get(Http::LowerCaseString(header.name()))); - expected = header.name() + ": " + header.exact_match(); - reportFailure(actual, expected, match_test_type, !header.invert_match()); - break; case envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase::kPresentMatch: case envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase:: HEADER_MATCH_SPECIFIER_NOT_SET: @@ -478,6 +496,16 @@ bool RouterCheckTool::matchHeaderField(const HeaderMap& header_map, expected = "has(" + header.name() + "):" + (header.invert_match() ? "false" : "true"); reportFailure(actual, expected, match_test_type); break; + case envoy::config::route::v3::HeaderMatcher::HeaderMatchSpecifierCase::kStringMatch: + if (header.string_match().match_pattern_case() == + envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kExact) { + actual = + header.name() + ": " + ::toString(header_map.get(Http::LowerCaseString(header.name()))); + expected = header.name() + ": " + header.string_match().exact(); + reportFailure(actual, expected, match_test_type, !header.invert_match()); + break; + } + FALLTHRU; default: actual = header.name() + ": " + ::toString(header_map.get(Http::LowerCaseString(header.name()))); diff --git a/test/tools/router_check/test/config/ComprehensiveRoutes.yaml b/test/tools/router_check/test/config/ComprehensiveRoutes.yaml index a477fbe0a7a8..fef2ba6cf16a 100644 --- a/test/tools/router_check/test/config/ComprehensiveRoutes.yaml +++ b/test/tools/router_check/test/config/ComprehensiveRoutes.yaml @@ -19,9 +19,11 @@ virtual_hosts: virtual_clusters: - headers: - name: :path - safe_regex_match: - google_re2: {} - regex: ^/users/\d+$ + string_match: + safe_regex: + google_re2: {} + regex: ^/users/\d+$ - name: :method - exact_match: PUT + string_match: + exact: PUT name: update_user diff --git a/test/tools/router_check/test/config/ContentType.yaml b/test/tools/router_check/test/config/ContentType.yaml index 17f1d551755e..0d7ea6557241 100644 --- a/test/tools/router_check/test/config/ContentType.yaml +++ b/test/tools/router_check/test/config/ContentType.yaml @@ -7,7 +7,8 @@ virtual_hosts: prefix: "/" headers: - name: "content-type" - exact_match: "application/grpc" + string_match: + exact: "application/grpc" route: cluster: local_service_grpc - match: diff --git a/test/tools/router_check/test/config/DirectResponse.golden.proto.json b/test/tools/router_check/test/config/DirectResponse.golden.proto.json index 729dd11788ce..f516ba133bfc 100644 --- a/test/tools/router_check/test/config/DirectResponse.golden.proto.json +++ b/test/tools/router_check/test/config/DirectResponse.golden.proto.json @@ -17,11 +17,15 @@ "response_header_matches": [ { "name": "content-type", - "exact_match": "text/plain" + "string_match": { + "exact": "text/plain" + } }, { "name": "content-length", - "exact_match": "8" + "string_match": { + "exact": "8" + } } ] } @@ -43,11 +47,15 @@ "response_header_matches": [ { "name": "content-type", - "exact_match": "application/json" + "string_match": { + "exact": "application/json" + } }, { "name": "content-length", - "exact_match": "25" + "string_match": { + "exact": "25" + } } ] } @@ -69,7 +77,9 @@ "response_header_matches": [ { "name": "content-type", - "exact_match": "text/plain,application/json" + "string_match": { + "exact": "text/plain,application/json" + } } ] } diff --git a/test/tools/router_check/test/config/HeaderMatchedRouting.yaml b/test/tools/router_check/test/config/HeaderMatchedRouting.yaml index 5f891bea08d5..0a58891d7ed2 100644 --- a/test/tools/router_check/test/config/HeaderMatchedRouting.yaml +++ b/test/tools/router_check/test/config/HeaderMatchedRouting.yaml @@ -7,16 +7,19 @@ virtual_hosts: prefix: / headers: - name: test_header - exact_match: test + string_match: + exact: test route: cluster: local_service_with_headers - match: prefix: / headers: - name: test_header_multiple1 - exact_match: test1 + string_match: + exact: test1 - name: test_header_multiple2 - exact_match: test2 + string_match: + exact: test2 route: cluster: local_service_with_multiple_headers @@ -30,16 +33,18 @@ virtual_hosts: prefix: / headers: - name: test_header_pattern - safe_regex_match: - google_re2: {} - regex: ^user=test-\d+$ + string_match: + safe_regex: + google_re2: {} + regex: ^user=test-\d+$ route: cluster: local_service_with_header_pattern_set_regex - match: prefix: / headers: - name: test_header_pattern - exact_match: ^customer=test-\d+$ + string_match: + exact: ^customer=test-\d+$ route: cluster: local_service_with_header_pattern_unset_regex - match: @@ -47,7 +52,8 @@ virtual_hosts: grpc: {} headers: - name: test_header - exact_match: some_value + string_match: + exact: some_value route: cluster: local_service_with_grpc_and_other_header - match: diff --git a/test/tools/router_check/test/config/TestRoutes.golden.proto.json b/test/tools/router_check/test/config/TestRoutes.golden.proto.json index 25c2ed007523..69b33e95c788 100644 --- a/test/tools/router_check/test/config/TestRoutes.golden.proto.json +++ b/test/tools/router_check/test/config/TestRoutes.golden.proto.json @@ -292,15 +292,21 @@ "request_header_matches": [ { "name": ":authority", - "exact_match": "new_host" + "string_match": { + "exact": "new_host" + } }, { "name": ":path", - "exact_match": "/host/rewrite/me" + "string_match": { + "exact": "/host/rewrite/me" + } }, { "name": ":method", - "exact_match": "GET" + "string_match": { + "exact": "GET" + } }, { "name": ":cookie", @@ -320,7 +326,9 @@ "request_header_matches": [ { "name": "X-Client-IP", - "exact_match": "127.0.0.1" + "string_match": { + "exact": "127.0.0.1" + } } ] } @@ -342,7 +350,9 @@ "response_header_matches": [ { "name": "content-type", - "exact_match": "text/plain" + "string_match": { + "exact": "text/plain" + } }, { "name": "content-length", @@ -354,7 +364,9 @@ }, { "name": "x-ping-response", - "exact_match": "yes" + "string_match": { + "exact": "yes" + } }, { "name": "x-ping-response", diff --git a/test/tools/router_check/test/config/TestRoutes.yaml b/test/tools/router_check/test/config/TestRoutes.yaml index a047ce0f89bc..929a415b9768 100644 --- a/test/tools/router_check/test/config/TestRoutes.yaml +++ b/test/tools/router_check/test/config/TestRoutes.yaml @@ -61,12 +61,12 @@ virtual_hosts: prefix: /host/rewrite/me route: cluster: ats - host_rewrite: new_host + host_rewrite_literal: new_host - match: prefix: /oldhost/rewrite/me route: cluster: ats - host_rewrite: new_oldhost + host_rewrite_literal: new_oldhost - match: path: /foo case_sensitive: true @@ -84,7 +84,7 @@ virtual_hosts: case_sensitive: false route: cluster: ats - host_rewrite: new_host + host_rewrite_literal: new_host - match: path: /FOOD case_sensitive: false @@ -101,7 +101,7 @@ virtual_hosts: prefix: /customheaders route: cluster: ats - host_rewrite: new_host + host_rewrite_literal: new_host request_headers_to_add: - header: key: X-Client-IP @@ -115,59 +115,73 @@ virtual_hosts: virtual_clusters: - headers: - name: :path - safe_regex_match: - google_re2: {} - regex: ^/rides$ + string_match: + safe_regex: + google_re2: {} + regex: ^/rides$ - name: :method - exact_match: POST + string_match: + exact: POST name: ride_request - headers: - name: :path - safe_regex_match: - google_re2: {} - regex: ^/rides/\d+$ + string_match: + safe_regex: + google_re2: {} + regex: ^/rides/\d+$ - name: :method - exact_match: PUT + string_match: + exact: PUT name: update_ride - headers: - name: :path - safe_regex_match: - google_re2: {} - regex: ^/users/\d+/chargeaccounts$ + string_match: + safe_regex: + google_re2: {} + regex: ^/users/\d+/chargeaccounts$ - name: :method - exact_match: POST + string_match: + exact: POST name: cc_add - headers: - name: :path - safe_regex_match: - google_re2: {} - regex: ^/users/\d+/chargeaccounts/[^validate]\w+$ + string_match: + safe_regex: + google_re2: {} + regex: ^/users/\d+/chargeaccounts/[^validate]\w+$ - name: :method - exact_match: PUT + string_match: + exact: PUT name: cc_add - headers: - name: :path - safe_regex_match: - google_re2: {} - regex: ^/users$ + string_match: + safe_regex: + google_re2: {} + regex: ^/users$ - name: :method - exact_match: POST + string_match: + exact: POST name: create_user_login - headers: - name: :path - safe_regex_match: - google_re2: {} - regex: ^/users/\d+$ + string_match: + safe_regex: + google_re2: {} + regex: ^/users/\d+$ - name: :method - exact_match: PUT + string_match: + exact: PUT name: update_user - headers: - name: :path - safe_regex_match: - google_re2: {} - regex: ^/users/\d+/location$ + string_match: + safe_regex: + google_re2: {} + regex: ^/users/\d+/location$ - name: :method - exact_match: POST + string_match: + exact: POST name: ulu internal_only_headers: - x-lyft-user-id diff --git a/test/tools/router_check/test/config/TestRoutesFailures.golden.proto.json b/test/tools/router_check/test/config/TestRoutesFailures.golden.proto.json index 498f155a4d5c..80d1df05fd30 100644 --- a/test/tools/router_check/test/config/TestRoutesFailures.golden.proto.json +++ b/test/tools/router_check/test/config/TestRoutesFailures.golden.proto.json @@ -17,7 +17,9 @@ "response_header_matches": [ { "name": "content-type", - "exact_match": "text/plain", + "string_match": { + "exact": "text/plain" + }, "invert_match": true }, { @@ -30,7 +32,9 @@ }, { "name": "x-ping-response", - "exact_match": "pong" + "string_match": { + "exact": "pong" + } }, { "name": "x-ping-response", diff --git a/test/tools/router_check/test/config/Weighted.yaml b/test/tools/router_check/test/config/Weighted.yaml index a7f6f3b6667a..655e72a944a8 100644 --- a/test/tools/router_check/test/config/Weighted.yaml +++ b/test/tools/router_check/test/config/Weighted.yaml @@ -17,11 +17,13 @@ virtual_hosts: virtual_clusters: - headers: - name: :path - safe_regex_match: - google_re2: {} - regex: ^/test/\d+$ + string_match: + safe_regex: + google_re2: {} + regex: ^/test/\d+$ - name: :method - exact_match: GET + string_match: + exact: GET name: test_virtual_cluster - name: www2 domains: diff --git a/test/tools/router_check/test/route_tests.sh b/test/tools/router_check/test/route_tests.sh index 7d7e6bdb55f6..ea785de8b36a 100755 --- a/test/tools/router_check/test/route_tests.sh +++ b/test/tools/router_check/test/route_tests.sh @@ -88,13 +88,13 @@ fi echo "testing error strings" FAILURE_OUTPUT=$("${PATH_BIN}" "-c" "${PATH_CONFIG}/TestRoutes.yaml" "-t" "${PATH_CONFIG}/TestRoutesFailures.golden.proto.json" "--only-show-failures" 2>&1) || echo "${FAILURE_OUTPUT:-no-output}" -if ! echo "${FAILURE_OUTPUT}" | grep -Fxq "expected: [content-type: text/plain], actual: NOT [content-type: text/plain], test type: response_header_matches.exact_match"; then +if ! echo "${FAILURE_OUTPUT}" | grep -Fxq "expected: [content-type: text/plain], actual: NOT [content-type: text/plain], test type: response_header_matches.string_match.exact"; then exit 1 fi if ! echo "${FAILURE_OUTPUT}" | grep -Fxq "actual: [content-length: 25], test type: response_header_matches.range_match"; then exit 1 fi -if ! echo "${FAILURE_OUTPUT}" | grep -Fxq "expected: [x-ping-response: pong], actual: [x-ping-response: yes], test type: response_header_matches.exact_match"; then +if ! echo "${FAILURE_OUTPUT}" | grep -Fxq "expected: [x-ping-response: pong], actual: [x-ping-response: yes], test type: response_header_matches.string_match.exact"; then exit 1 fi if ! echo "${FAILURE_OUTPUT}" | grep -Fxq "expected: [has(x-ping-response):false], actual: [has(x-ping-response):true], test type: response_header_matches.present_match"; then