-
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
http: make HeaderHashMethod hashing all the header values #15486
Conversation
Previously the HeaderHashMehod only hash the first value of header. This commit aims to hash all the values of header. Signed-off-by: He Jie Xu <hejie.xu@intel.com>
One quick note: I see you force-pushed earlier. Please refrain from doing that for Envoy github reviews; it loses comment threads. Just "merge main". Thank you! |
Thanks for the reminder. I already that from my first PR. Actually, I force update it since it is the first push and no other comments yet. I will keep that in mind in later update. |
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
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.
Code looks much better now, just a minor nit in the test remains.
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
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.
Substantively LGTM. I think @snowp should look at this for its impact on load-balancing polices based on headers.
Also I'm not sure what's up with CI. Can you merge main? Don't force-push. |
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Done |
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
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.
Looks great; just a few comments.
source/common/common/hash.h
Outdated
static uint64_t xxHash64(absl::InlinedVector<absl::string_view, 1>& input, uint64_t seed = 0) { | ||
uint64_t hash = seed; | ||
if (input.size() == 0) { | ||
hash = XXH64(input.data(), input.size(), hash); |
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.
does this case occur?
If so, just use XX64(nullptr, 0, seed)
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.
Or maybe just don't test for that. Remove the if
and let it return seed on an empty array.
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.
We didn't use that case when hashing the header value, special with the check num_headers_to_hash
:
envoy/source/common/http/hash_policy.cc
Line 71 in ce1e9a7
if (check_multiple_values && (num_headers_to_hash > 1)) { |
I just match this behavior with static uint64_t xxHash64(absl::string_view input, uint64_t seed = 0)
.
Then those two methods get the same value for empty string and empty vector, you can see that from the unittest
envoy/test/common/common/hash_test.cc
Lines 6 to 19 in ce1e9a7
TEST(Hash, xxHash) { | |
EXPECT_EQ(3728699739546630719U, HashUtil::xxHash64("foo")); | |
EXPECT_EQ(5234164152756840025U, HashUtil::xxHash64("bar")); | |
EXPECT_EQ(8917841378505826757U, HashUtil::xxHash64("foo\nbar")); | |
EXPECT_EQ(4400747396090729504U, HashUtil::xxHash64("lyft")); | |
EXPECT_EQ(17241709254077376921U, HashUtil::xxHash64("")); | |
} | |
TEST(Hash, xxHashWithVector) { | |
absl::InlinedVector<absl::string_view, 1> v{"foo", "bar"}; | |
EXPECT_EQ(17745830980996999794U, HashUtil::xxHash64(v)); | |
absl::InlinedVector<absl::string_view, 1> empty_vector; | |
EXPECT_EQ(17241709254077376921U, HashUtil::xxHash64(empty_vector)); | |
} |
The upside to handle this empty vector case is in case someone pass the empty vector, then it will get a same behavior just like the empty string one.
But I'm also ok to remove it if you think it needless to a case we didn't use it today.
source/common/common/hash.h
Outdated
hash = XXH64(input.data(), input.size(), hash); | ||
} else { | ||
for (auto& i : input) { | ||
hash = XXH64(i.data(), i.size(), hash); |
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.
Nice I hadn't thought of using the seed arg to XX64 as a carry.
source/common/http/hash_policy.cc
Outdated
} | ||
} | ||
|
||
if (check_multiple_values && (num_headers_to_hash > 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.
I think Matt commented above but you don't need this conditional. num_headers_hash can be set to a value greater than one online if check_multiple_values is true, and the sorting will be a no-op for size==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.
that is what Matt is look for, better to have @mattklein123 check again. also I have comment about the runtime flag above, it may needn't this check anymore.
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.
See my above comment. I think we do need the flag, but we can just set the size to 1 or not above and then we can collapse all of this logic.
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 updated, hope I understand correctly.
source/common/http/hash_policy.cc
Outdated
} | ||
} | ||
|
||
if (check_multiple_values && (num_headers_to_hash > 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.
See my above comment. I think we do need the flag, but we can just set the size to 1 or not above and then we can collapse all of this logic.
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
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.
Looks great, thank you! One tiny comment.
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
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.
Perfect, thanks!
@snowp can do a final pass.
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
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!
Can you merge main to pick up a CI fix?
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.
Thanks LGTM. Will defer to others for merge.
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Thanks for all the review! just merged with main. |
…#15486) Previously the HeaderHashMehod only hash the first value of header. This commit aims to hash all the values of header. Signed-off-by: He Jie Xu <hejie.xu@intel.com>
Commit Message: http: make HeaderHashMethod hashing all the header values
Additional Description:
Previously the HeaderHashMehod only hash the first value of the header.
This PR aims to hash all the values of the header. The new behavior also can be
disabled by the new runtime guard
envoy.reloadable_features.hash_multiple_header_values
.Risk Level: low
Testing: unit-test added
Docs Changes: n/a
Release Notes: add note for new feature
Fixes #15182
Signed-off-by: He Jie Xu hejie.xu@intel.com