-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Extend StatefulHeaderFormatter to allow forwarding HTTP1 reason phrase #18997
Conversation
Hi @syhpoon, welcome and thank you for your contribution. We will try to review your Pull Request as quickly as possible. In the meantime, please take a look at the contribution guidelines if you have not done so already. |
CC @envoyproxy/api-shepherds: Your approval is needed for changes made to |
Thank you for the contribution. I'm not sure if you are the same person that I was discussing this on Slack with (https://envoyproxy.slack.com/archives/C78HA81DH/p1634828677000900), but I think we decided that the best and least intrusive way of supporting this is to add this into the stateful header formatter system that allows remembering the case of H1 headers during proxy. I think adding remembering the reason phrase to this would be pretty simple and avoid polluting the header map with H1 specific concepts. Can we try to implement it that way? Thank you. /wait |
Yes, that was me discussing this issue on Slack.
Current implementation make this an HTTP1-specific option. If the option is not set (default), there's no performance penalty as the parser callback is not even called. The only addition is one new class member field, and yes, I agree, it's not ideal to have a http1-specific concept in generic class, but I was kind hoping that folks much more familiar with the codebase could advise on a better way to achieve this, if this is considered a major concern. |
This feature is a very niche ask, similar to preserving the case of H1 headers. I personally would not overthink this. I think it would be fine to just add an option to https://github.com/envoyproxy/envoy/blob/main/api/envoy/extensions/http/header_formatters/preserve_case/v3/preserve_case.proto about whether to preserve the reason phrase, or, I think it woud probably be fine to just do it always when using this formatter. Then I think it's fine to extend the interface to set/get the reason phrase. |
Okay, then a follow-up question: would you expect for Basically this is my main concern, but if you're saying it's okay to go this way, I can definitely tweak my implementation accordingly. |
I don't think it's really that messy. The interface methods could be a nop in a different implementation. As long as we clearly document that the PreserveCaseFormatter does this, I think it's fine. I agree the name is now not great, but so it goes. I just don't think it's worth leaking the implementation details of this very niche feature into the rest of the codebase.
Let's get another opinion from @alyssawilk on this. @alyssawilk for preserving the H1 reason phrase, do you think we should bolt it on to the stateful header formatter code or build it more directly in? |
I'm less familiar with the stateful header formatters so largely inclined to trust you on this, but naming aside the formatters largely exist to handle "metadata" for how we want to serialize HTTP/1.1 requests to the wire, so I'm totally fine jamming the reason phrase in there too. |
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 generally on the right track, some comments to get you started, thanks.
/wait
@@ -16,4 +16,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; | |||
// See the :ref:`header casing <config_http_conn_man_header_casing>` configuration guide for more | |||
// information. | |||
message PreserveCaseFormatterConfig { | |||
// Allows forwarding reason phrase text. |
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.
Add a release note for this please
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.
Added.
envoy/http/header_formatter.h
Outdated
/** | ||
* Called to save received reason phrase | ||
*/ | ||
virtual void setReasonPhrase(const char* data, uint32_t length) PURE; |
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.
Pass absl::string_view
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.
Done.
@@ -38,7 +38,7 @@ class LegacyHttpParserImpl::Impl { | |||
parser_.allow_chunked_length = 1; | |||
} | |||
|
|||
Impl(http_parser_type type, void* data) : Impl(type) { | |||
Impl(http_parser_type type, void* data, bool parse_status) : Impl(type) { |
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 would just always parse status, the cost is low.
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 the flag.
|
||
private: | ||
StringUtil::CaseUnorderedSet original_header_keys_; | ||
bool forward_reason_phrase_{false}; | ||
absl::string_view reason_phrase_; |
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 needs to be std::string or you will be referencing data that is gone.
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.
Fixed.
@syhpoon please avoid force-pushing in Envoy Github as it disrupts the comment-flow. Just do normal merges and pushes. |
@mattklein123 all the comments should have been addressed, would appreciate another 👀 |
Apologies for delay but Matt's out this week and where normally we'd reassign, over half the maintainers are out as well so thanks for your patience on unusual review lag :-) |
No worries! Thanks, Alyssa for letting me know! |
Signed-off-by: Max Kuznetsov <[email protected]>
@syhpoon friendly request to please not force push. It makes reviews much harder. Thank you! |
Sure, but there were no new comments and previous CI run failed, it didn't look the force-push would mess anything. |
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, looks awesome. Just 2 small test comments then we can ship!
/wait
@@ -9,7 +9,7 @@ namespace HeaderFormatters { | |||
namespace PreserveCase { | |||
|
|||
TEST(PreserveCaseFormatterTest, All) { | |||
PreserveCaseHeaderFormatter formatter; | |||
PreserveCaseHeaderFormatter formatter(false); |
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 you verify that when this is false, and you set a reason phrase, you don't get a reason phrase back?
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.
Added another test case for this.
testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), | ||
TestUtility::ipTestParamsToString); | ||
|
||
TEST_P(PreserveCaseFormatterReasonPhraseIntegrationTest, VerifyReasonPhrase) { |
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 you add an off test also where when explicitly disabled you get back the stock phrase?
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.
Done!
Signed-off-by: Max Kuznetsov <[email protected]>
Signed-off-by: Max Kuznetsov <[email protected]>
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 needs format fix, thanks.
/wait
Signed-off-by: Max Kuznetsov <[email protected]>
Thanks @mattklein123, should be good to go! |
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, nice work!
Thanks, Matt! |
Commit Message: http: extend StatefulHeaderFormatter to allow forwarding HTTP1 reason phrase
Additional Description: In some cases the upstream can produce a non-default reason phrase when using HTTP1. For example AWS S3 can return
503 Slow Down
in certain cases. StatefuleHeaderFormatter can now take an optional flag to enable forwarding non-default HTTP1 reason phrases.Risk Level: Medium
Testing: unit testing, integration testing
Docs Changes: release notes
Release Notes: http: added support for forwarding HTTP1 reason phrase
Platform Specific Features: N/A