Skip to content

[WIP] new listener filter for terminating HTTP/1 CONNECT(#19077)#19346

Closed
liverbirdkte wants to merge 9 commits into
envoyproxy:mainfrom
liverbirdkte:connect_handler
Closed

[WIP] new listener filter for terminating HTTP/1 CONNECT(#19077)#19346
liverbirdkte wants to merge 9 commits into
envoyproxy:mainfrom
liverbirdkte:connect_handler

Conversation

@liverbirdkte
Copy link
Copy Markdown

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 data out of queue

  3. terminate HTTP CONNECT by writing a response to the client

  4. 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:]

@repokitteh-read-only
Copy link
Copy Markdown

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.

🐱

Caused by: #19346 was opened by liverbirdkte.

see: more, trace.

@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to (api/envoy/|docs/root/api-docs/).
envoyproxy/api-shepherds assignee is @adisuissa
CC @envoyproxy/api-watchers: FYI only for changes made to (api/envoy/|docs/root/api-docs/).

🐱

Caused by: #19346 was opened by liverbirdkte.

see: more, trace.

Copy link
Copy Markdown
Member

@rojkov rojkov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I added a few comments.

Also this PR needs docs and tests.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables

Suggested change
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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, will use anonymous namespace instead.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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().

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean adding a default for switch to handle missing cases or to extend ParseState by adding a new status?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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().

Comment thread source/extensions/filters/listener/connect_handler/connect_handler.cc Outdated
Comment thread source/extensions/filters/listener/connect_handler/connect_handler.cc Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need to instantiate a string_view here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it

@rojkov rojkov self-assigned this Dec 23, 2021
@rojkov
Copy link
Copy Markdown
Member

rojkov commented Dec 27, 2021

/wait

Copy link
Copy Markdown
Contributor

@adisuissa adisuissa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this, left an API comment.

Comment on lines 18 to 19
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think such a type exists.
If there is no v2 predecessor, you should remove the annotation.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, will remove this.

@liverbirdkte
Copy link
Copy Markdown
Author

Sorry for the late response, thanks for the comments, I'll submit a new version soon. The patch is for issue #19077.

@liverbirdkte
Copy link
Copy Markdown
Author

start working on tests and docs, will update when code is ready

@rojkov
Copy link
Copy Markdown
Member

rojkov commented Jan 5, 2022

/wait

@liverbirdkte
Copy link
Copy Markdown
Author

Add unittest, looking at how to write fuzz tests..

leizhang added 4 commits January 20, 2022 06:28
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>
@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to (api/envoy[\w/]*/(v1alpha\d?|v1|v2alpha\d?|v2))|(api/envoy/type/(matcher/)?\w+.proto).

🐱

Caused by: #19346 was synchronize by liverbirdkte.

see: more, trace.

@rojkov
Copy link
Copy Markdown
Member

rojkov commented Jan 20, 2022

Please never use git force-push. If the PR is not ready for review you can turn it into a Draft.

@liverbirdkte
Copy link
Copy Markdown
Author

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.

@liverbirdkte liverbirdkte marked this pull request as draft January 20, 2022 09:28
@liverbirdkte
Copy link
Copy Markdown
Author

Thanks, I will convert it back when it's ready.

leizhang added 2 commits January 25, 2022 08:48
Signed-off-by: leizhang <lei.a.zhang@intel.com>
@liverbirdkte liverbirdkte marked this pull request as ready for review January 26, 2022 01:57
Copy link
Copy Markdown
Contributor

@adisuissa adisuissa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm api
left a minor comment.

Comment thread CODEOWNERS Outdated
Comment on lines +220 to +221
# connect handler
/*/extensions/filters/listener/connect_handler @rojkov @alyssawilk
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move up to the extensions part.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Copy Markdown
Member

@rojkov rojkov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it used?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

return ParseState::Error;
}
// terminate CONNECT request
resp_buf_.add(protocol_);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems there's no need to make protocol_ a member of the class.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +28 to +30
http_parser_settings Filter::settings_{
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
};
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be just a compilation unit-wide constexpr?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

thread_local uint8_t Filter::buf_[Config::MAX_INSPECT_SIZE];

namespace {
constexpr absl::string_view response_body = " 200 Connection Established\r\n\r\n";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to STYLE.md this should be

Suggested change
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";

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if (result.return_value_ == 0) {
return ParseState::Error;
}
return parseConnect(absl::string_view(reinterpret_cast<const char*>(buf_), result.return_value_));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to instantiate a temp string_view here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return ParseState::Done;
}

std::vector<absl::string_view> fields = absl::StrSplit(data, absl::ByAnyChar(" :"));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be more efficient to use StringUtil::cropLeft() and StringUtil::cropRight() for server name extraction?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread tools/spelling/spelling_dictionary.txt Outdated
intra
ints
invariance
iov
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably not needed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this because my local checker could not get passed, removing this to see if CI job works well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@rojkov
Copy link
Copy Markdown
Member

rojkov commented Jan 31, 2022

/wait

@liverbirdkte liverbirdkte marked this pull request as draft February 8, 2022 11:01
lei zhang added 2 commits February 8, 2022 22:21
Signed-off-by: leizhang <lei.a.zhang@intel.com>
@liverbirdkte liverbirdkte marked this pull request as ready for review February 8, 2022 14:57
constexpr http_parser_settings Settings{
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
};
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
}
} // namespace

Comment on lines +19 to +20
#TODO(davinci26): The test passes on Windows *but* http inspector
# *used* to rely on Event::FileTriggerType::Edge and we got away with it
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment relevant to connect_handler?

Comment on lines +49 to +57
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",
],
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This target seems to be missing in the PR.

Copy link
Copy Markdown
Contributor

@adisuissa adisuissa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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

@rojkov
Copy link
Copy Markdown
Member

rojkov commented Feb 11, 2022

/wait

@github-actions
Copy link
Copy Markdown

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!

@github-actions github-actions Bot added the stale stalebot believes this issue/PR has not been touched recently label Mar 13, 2022
@github-actions
Copy link
Copy Markdown

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale stalebot believes this issue/PR has not been touched recently v2-freeze waiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants