[WIP] new listener filter for terminating HTTP/1 CONNECT(#19077)#19346
[WIP] new listener filter for terminating HTTP/1 CONNECT(#19077)#19346liverbirdkte wants to merge 9 commits into
Conversation
|
Hi @liverbirdkte, 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 |
rojkov
left a comment
There was a problem hiding this comment.
Nice! I added a few comments.
Also this PR needs docs and tests.
There was a problem hiding this comment.
Per https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
| static absl::string_view response_body = " 200 Connection Established\r\n\r\n"; | |
| static constexpr absl::string_view response_body = " 200 Connection Established\r\n\r\n"; |
And instead of static we prefer anonymous namespaces.
There was a problem hiding this comment.
got it, will use anonymous namespace instead.
There was a problem hiding this comment.
The switch above is meant to be fully exhaustive. We'd better detect a missing case in it if we extend ParseState. Better replace NOT_REACHED_GCOVR_EXCL_LINE with ENVOY_BUG().
There was a problem hiding this comment.
Do you mean adding a default for switch to handle missing cases or to extend ParseState by adding a new status?
There was a problem hiding this comment.
No need to add default as some compilers can generate a warning at compile time about non-exhaustive switch'es.
If ParseState is ever extended with a new value then this switch will become non-exhaustive. So, it'll be possible to reach NOT_REACHED_GCOVR_EXCL_LINE. And that would be a bug most probably. Unfortunately reaching NOT_REACHED_GCOVR_EXCL_LINE doesn't trigger a bug nor prints a warning. Thus it's better to replace it with ENVOY_BUG().
There was a problem hiding this comment.
nit: no need to instantiate a string_view here.
|
/wait |
adisuissa
left a comment
There was a problem hiding this comment.
Thanks for working on this, left an API comment.
There was a problem hiding this comment.
I don't think such a type exists.
If there is no v2 predecessor, you should remove the annotation.
|
Sorry for the late response, thanks for the comments, I'll submit a new version soon. The patch is for issue #19077. |
|
start working on tests and docs, will update when code is ready |
|
/wait |
|
Add unittest, looking at how to write fuzz tests.. |
Add a new listener filter to handle CONNECT request, only HTTP/1.x is supported. 1. inspect if incoming request is HTTP CONNECT 2. drain CONNECT request queue 3. terminate HTTP CONNECT by writing a response to the client 4. set server names using request url in CONNECT request Signed-off-by: leizhang <lei.a.zhang@intel.com>
Signed-off-by: leizhang <lei.a.zhang@intel.com>
Signed-off-by: leizhang <lei.a.zhang@intel.com>
Signed-off-by: leizhang <lei.a.zhang@intel.com>
7ae9503 to
04203ad
Compare
|
Please never use git force-push. If the PR is not ready for review you can turn it into a Draft. |
|
OK, I was fixing some CI failures, saw the DOC issue, so I added sign-off and force push as the instruction on the page told me to. Also didn't mean to modify unrelated jwt_authn proto, but git hook format checker won't get passed unless I apply these changes. |
|
Thanks, I will convert it back when it's ready. |
adisuissa
left a comment
There was a problem hiding this comment.
/lgtm api
left a minor comment.
| # connect handler | ||
| /*/extensions/filters/listener/connect_handler @rojkov @alyssawilk |
There was a problem hiding this comment.
Please move up to the extensions part.
rojkov
left a comment
There was a problem hiding this comment.
Thank you! Looks good. I added a few questions.
| static constexpr absl::string_view HTTP1_CONNECT_PREFACE = "CONNECT"; | ||
| Buffer::OwnedImpl resp_buf_{}; | ||
| absl::string_view protocol_; | ||
| absl::string_view request_url_; |
| return ParseState::Error; | ||
| } | ||
| // terminate CONNECT request | ||
| resp_buf_.add(protocol_); |
There was a problem hiding this comment.
It seems there's no need to make protocol_ a member of the class.
| http_parser_settings Filter::settings_{ | ||
| nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | ||
| }; |
There was a problem hiding this comment.
Can it be just a compilation unit-wide constexpr?
| thread_local uint8_t Filter::buf_[Config::MAX_INSPECT_SIZE]; | ||
|
|
||
| namespace { | ||
| constexpr absl::string_view response_body = " 200 Connection Established\r\n\r\n"; |
There was a problem hiding this comment.
According to STYLE.md this should be
| constexpr absl::string_view response_body = " 200 Connection Established\r\n\r\n"; | |
| constexpr absl::string_view ResponseBody = " 200 Connection Established\r\n\r\n"; |
| if (result.return_value_ == 0) { | ||
| return ParseState::Error; | ||
| } | ||
| return parseConnect(absl::string_view(reinterpret_cast<const char*>(buf_), result.return_value_)); |
There was a problem hiding this comment.
No need to instantiate a temp string_view here.
| return ParseState::Done; | ||
| } | ||
|
|
||
| std::vector<absl::string_view> fields = absl::StrSplit(data, absl::ByAnyChar(" :")); |
There was a problem hiding this comment.
Would it be more efficient to use StringUtil::cropLeft() and StringUtil::cropRight() for server name extraction?
| intra | ||
| ints | ||
| invariance | ||
| iov |
There was a problem hiding this comment.
I added this because my local checker could not get passed, removing this to see if CI job works well.
There was a problem hiding this comment.
Indeed the check fails. This is weird as I used iov in my PRs and everything was ok. And it's all over the code base. Looks like the code is treated as a comment by the spellchecker. @phlax could you please have a look?
|
/wait |
Signed-off-by: leizhang <lei.a.zhang@intel.com>
| constexpr http_parser_settings Settings{ | ||
| nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | ||
| }; | ||
| } |
There was a problem hiding this comment.
nit:
| } | |
| } // namespace |
| #TODO(davinci26): The test passes on Windows *but* http inspector | ||
| # *used* to rely on Event::FileTriggerType::Edge and we got away with it |
There was a problem hiding this comment.
Is this comment relevant to connect_handler?
| envoy_cc_fuzz_test( | ||
| name = "connect_handler_fuzz_test", | ||
| srcs = ["connect_handler_fuzz_test.cc"], | ||
| corpus = "connect_handler_corpus", | ||
| deps = [ | ||
| "//source/extensions/filters/listener/connect_handler:connect_handler_lib", | ||
| "//test/extensions/filters/listener/common/fuzz:listener_filter_fuzzer_lib", | ||
| ], | ||
| ) |
There was a problem hiding this comment.
This target seems to be missing in the PR.
adisuissa
left a comment
There was a problem hiding this comment.
Thanks!
Left a small comment on the doc.
/lgtm api
I suggest adding an integration test.
| Connect Handler | ||
| =============== | ||
|
|
||
| Connect Handler listener filter allows detecting whether the incoming request appears to be HTTP/1.x CONNECT, and if it is CONNECT, it removes the CONNECT by reading data from socket and responding with a 200 status code to indicate a connection to remote server is established. It also extracts remote server url from the CONNECT. This can be used to select a |
There was a problem hiding this comment.
| Connect Handler listener filter allows detecting whether the incoming request appears to be HTTP/1.x CONNECT, and if it is CONNECT, it removes the CONNECT by reading data from socket and responding with a 200 status code to indicate a connection to remote server is established. It also extracts remote server url from the CONNECT. This can be used to select a | |
| Connect Handler listener filter allows detecting whether the incoming request appears to be HTTP/1.x CONNECT, and if it is CONNECT, it removes the CONNECT by reading data from the socket and responding with a 200 status code to indicate a connection to the remote server is established. It also extracts the remote server url from the CONNECT. This can be used to select a |
|
/wait |
|
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
This pull request has been automatically closed because it has not had activity in the last 37 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Add a new listener filter to handle CONNECT request, only HTTP/1.x is supported.
inspect if incoming request is HTTP CONNECT
drain CONNECT request data out of queue
terminate HTTP CONNECT by writing a response to the client
set server names using request url in CONNECT request
It seems the behavior of draining CONNECT data and writing response may have an impact on other listener filters in the loop. Is there any way to exit the listener filter iteration? Or I should put this listener filter as the last one in the config.
Commit Message:
Additional Description:
Risk Level:
Testing:
Docs Changes:
Release Notes:
Platform Specific Features:
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Fixes commit #PR or SHA]
[Optional Deprecated:]
[Optional API Considerations:]