-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
header: New HeaderMatcher and StringMatcher type - Contains #12623
Conversation
CC @envoyproxy/api-shepherds: Your approval is needed for changes made to |
Tests passing in local
|
|
||
// 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_bytes: 1}]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v2 is deprecated and freezed, no change is allowed in v2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed v2 api changes.
@@ -1568,6 +1568,15 @@ message HeaderMatcher { | |||
// | |||
// * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*. | |||
string suffix_match = 10 [(validate.rules).string = {min_bytes: 1}]; | |||
|
|||
// If specified, header match will be performed based on whether the header value contains |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we just want to add support general globs, rather than special casing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@htuch This is being added for issue opened here: #12590
This is no more a special case than suffix-match
or present-match
. @htuch and @mattklein123 Later today I will add the same matcher for StringMatcher as well. Please let me know if we want to proceed this way.
Is there another PR or design doc available for wildcard based matches? Regex matching with std::regex
can cause catastrophic backtracking and occasional crashes. Is there such a possibility with glob/wildcard matching too? Substring matches are O(n) as they are based on KMP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@htuch I did a little more digging. I see that the Xray
tracer extension has a wildcard match:
https://github.com/envoyproxy/envoy/pull/8526/files#diff-620892d553c2be71cf26761d0c9db408R26
I am still breaking it down but right now it looks like it supports ?
and *
which is good enough for our case.
Do you want just these two wildcards or a full set? If you're okay with this I can refactor the code a little to reuse the same matcher.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we would want a syntax more like #7763. Maybe we should go with a simple contains for now.
@shivanshu21 one other question, do you get catastophic backtracing with RE2 for this case? Do you know what the performance penalty of using RE2 vs. a strcontains operation is here? |
@htuch We haven't tried with Safe Regex as the definition says this:
The rule will not match if only a subsequence of the header matches the regex. So looks like strContains() case won't be handled here. We have however tried comparing |
Matchers test passing in local
|
RE2 should work, as long as you glob at the start and end, e.g. |
LGTM, but just want to check with other @envoyproxy/api-shepherds that this makes sense. I think that RE2 is not the right answer for performance here, but do we want to essentially open up arbitrary string predicates as first class API elements? |
Thanks! I will wait for API shepherds to respond before merging. |
@lizan PTAL |
@envoyproxy/api-shepherds , @lizan This PR has been awaiting review. Please take a look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API LGTM
source/common/common/matchers.cc
Outdated
@@ -100,6 +100,10 @@ bool StringMatcherImpl::match(const absl::string_view value) const { | |||
case envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kSuffix: | |||
return matcher_.ignore_case() ? absl::EndsWithIgnoreCase(value, matcher_.suffix()) | |||
: absl::EndsWith(value, matcher_.suffix()); | |||
case envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kContains: | |||
return matcher_.ignore_case() ? absl::StrContains(absl::AsciiStrToLower(value), | |||
absl::AsciiStrToLower(matcher_.contains())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we cache the lowered matcher_.contains somewhere for this case?
Fixes: 12590 Signed-off-by: Shivanshu Goswami <[email protected]>
Signed-off-by: Shivanshu Goswami <[email protected]>
Signed-off-by: Shivanshu Goswami <[email protected]>
Signed-off-by: Shivanshu Goswami <[email protected]>
…string Signed-off-by: Shivanshu Goswami <[email protected]>
Matchers and Header utility tests passing
@lizan I have added the lowercase string to the class so that it is only computed once. PTAL. |
/retest |
Retrying Azure Pipelines, to retry CircleCI checks, use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but can you also add release notes? Thanks.
@@ -13,6 +13,7 @@ Minor Behavior Changes | |||
|
|||
* compressor: always insert `Vary` headers for compressible resources even if it's decided not to compress a response due to incompatible `Accept-Encoding` value. The `Vary` header needs to be inserted to let a caching proxy in front of Envoy know that the requested resource still can be served with compression applied. | |||
* decompressor: headers-only requests were incorrectly not advertising accept-encoding when configured to do so. This is now fixed. | |||
* http: added a new header matcher type called ``contains`` which matches if the value of the header has the substring mentioned in contains matcher. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually, we link the added field here. In this case, probably:
* matcher: added :ref:`contains <envoy_v3_api_field_type.matcher.v3.StringMatcher.contains>` to ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And, it seems like you have another one for route
as well.
Signed-off-by: Shivanshu Goswami <[email protected]>
@mattklein123 How do we remove the @lizan and Htuch have both LGTMed and Lizan has LGTMed for API changes as well. I have addressed all the comments including adding release notes with proper links. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with small comment, thanks!
/wait
api/envoy/type/matcher/string.proto
Outdated
@@ -16,7 +16,7 @@ option (udpa.annotations.file_status).package_version_status = FROZEN; | |||
// [#protodoc-title: String matcher] | |||
|
|||
// Specifies the way to match a string. | |||
// [#next-free-field: 7] | |||
// [#next-free-field: 8] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still modifying a v2 API. Please revert this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! I thought all the v2 apis are in api/envoy/api/v2
folder. Reverting.
Signed-off-by: Shivanshu Goswami <[email protected]>
Addressed the comment. Please take a look and suggest ways to unblock the merge. |
Thanks Lizan! The API shepherds hold is removed. I cannot merge till @mattklein123 clicks this: |
* envoy/master: (90 commits) cleanup: use structured binding (envoyproxy#12791) docs: fix header name for retries in gRPC services (envoyproxy#12790) docs: clarify meaning of HeaderValueOption.append (envoyproxy#12792) doc: clarify handling of duplicate xDS resource names (envoyproxy#12756) Dependencies: build updates. (envoyproxy#12786) Ratelimit: Add optional descriptor key to generic_key action (envoyproxy#12734) test: refactor header inclusion to speed up building (for test/mocks/upstream:upstream_mocks) (envoyproxy#12407) docs: Fix omitted word (envoyproxy#12782) ci: avoid uploading dwp as separate artifact (envoyproxy#12777) doc: Fix small typos (envoyproxy#12769) fix cache factory category (envoyproxy#12765) docs: fix typo v1.15.0.rst (envoyproxy#12680) Add clang-cl RBE toolchain for Windows (envoyproxy#12776) fuzz: add router fuzz proto (envoyproxy#12727) header: New HeaderMatcher and StringMatcher type - Contains (envoyproxy#12623) tcp_proxy: use dynamicMetadata() from StreamInfo for load balancing (envoyproxy#12595) network: add io handle recv function for http inspector (envoyproxy#12736) jwt_authn: supports jwt payload without "iss" field (envoyproxy#12744) Add support for nested JSON format in json logging mode (envoyproxy#12602) http: fixing a fuzz flake by setting details on connection teardown (envoyproxy#12737) ... Signed-off-by: Scott LaVigne <[email protected]>
Fixes: 12590
Signed-off-by: Shivanshu Goswami [email protected]
For an explanation of how to fill out the fields, please see the relevant section
in PULL_REQUESTS.md
Commit Message: header: New HeaderMatcher type - Contains
Additional Description: For matching values in the header that might be somewhere in the middle of the header, the present option is to use Regex in the form .Search-Pattern.. This can cause catastrophic backtracking as described in #7728
As a solution, I have introduced another header match type called
contains
which is based on absl::StrContains().Risk Level: Low
Testing: Unit tests are included and manual testing was performed.
Docs Changes:
Release Notes:
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Deprecated:]