Skip to content
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: fixing up CONNECT to be RFC compliant #21440

Merged
merged 6 commits into from
Jun 8, 2022

Conversation

alyssawilk
Copy link
Contributor

@alyssawilk alyssawilk commented May 25, 2022

Risk Level: Medium (data plane changes)
Testing: updated tests
Docs Changes: n/a
Release Notes: inline
Runtime guard: envoy.reloadable_features.use_rfc_connect
Fixes #20378

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
@repokitteh-read-only
Copy link

As a reminder, PRs marked as draft will not be automatically assigned reviewers,
or be handled by maintainer-oncall triage.

Please mark your PR as ready when you want it to be reviewed!

🐱

Caused by: #21440 was opened by alyssawilk.

see: more, trace.

@alyssawilk
Copy link
Contributor Author

cc @howardjohn

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
std::unique_ptr<Http::RequestHeaderMapImpl> expected_headers;
expected_headers = Http::createHeaderMap<Http::RequestHeaderMapImpl>({
{Http::Headers::get().Method, "CONNECT"},
{Http::Headers::get().Host, this->config_->hostname()},
Copy link
Contributor

Choose a reason for hiding this comment

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

This is great, thanks for the fix!

One possibly concern is that in the current code we are using a header to replace Host, which allows dynamic metadata (

TunnelingConfig: &tcp.TcpProxy_TunnelingConfig{
    Hostname: "ignored",
    HeadersToAdd: []*core.HeaderValueOption{
        {Header: &core.HeaderValue{Key: "x-destination", Value: "%DYNAMIC_METADATA([\"tunnel\", \"address\"])%"}},
    },
},

).

Now we would want to use Hostname to follow the spec, but that is only a static string.

Seems like something that could be expanded in a followup though @lambdai

Copy link
Contributor

@kyessenov kyessenov May 25, 2022

Choose a reason for hiding this comment

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

@jewertow This is an instance when we need metadata for hostname. Not sure if you still want to complete #21067, but we'll probably add metadata support.

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Copy link
Contributor

@RyanTheOptimist RyanTheOptimist left a comment

Choose a reason for hiding this comment

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

Looks great. A couple of minor comments.

modified_headers->setProtocol(Headers::get().ProtocolValues.Bytestream);
if (!headers.Path()) {
modified_headers->setPath("/");
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.use_rfc_connect")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we consider moving the comment from line 296 down into the if blocks and editing it accordingly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -43,7 +43,8 @@ Http::Status EnvoyQuicClientStream::encodeHeaders(const Http::RequestHeaderMap&
SendBufferMonitor::ScopedWatermarkBufferUpdater updater(this, this);
auto spdy_headers = envoyHeadersToSpdyHeaderBlock(headers);
if (headers.Method()) {
if (headers.Method()->value() == "CONNECT") {
if (headers.Method()->value() == "CONNECT" &&
!Runtime::runtimeFeatureEnabled("envoy.reloadable_features.use_rfc_connect")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm slightly surprised not to see an else for the case where the runtime flag is enabled to be parallel with the logic in the h2 code. Is that not required?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah it turns out we essentially had no testing of the HTTP/2 and HTTP/3 paths. Fixed.

@@ -3639,6 +3640,32 @@ TEST_P(Http2CodecImplTest, ConnectTest) {
driveToCompletion();
}

// CONNECT without upgrade type gets tagged with "bytestream"
Copy link
Contributor

Choose a reason for hiding this comment

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

Given that the codec strips the :protocol = bytestream header, I'm not sure I understand this comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it was a bad copy paste :-P

ASSERT_TRUE(codec_client_->waitForDisconnect());
}
// Because CONNECT requests do not include a path, they will fail
// to find a route match and return a 404.
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like this is a change in behavior that is visible to this filter. Presumably that's ok (and expected). Is there any need to call this out in release notes, or anything? Probably not, since they already mention the flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah that's my thought

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
RyanTheOptimist
RyanTheOptimist previously approved these changes Jun 6, 2022
@alyssawilk
Copy link
Contributor Author

also @moderation if you have thoughts please feel encouraged to do a pass as well

@alyssawilk
Copy link
Contributor Author

@snowp ping?

Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

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

One small nit but otherwise this LGTM

if (!config_.usePost()) {
headers->addReference(Http::Headers::get().Protocol,
Http::Headers::get().ProtocolValues.Bytestream);
if (!Runtime::runtimeFeatureEnabled("envoy.reloadable_features.use_rfc_connect")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

super nit but it might be nice to have all these checks have the feature enabled path first, just to make it easier to follow along the two branches when reading

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

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

Thanks!

@alyssawilk alyssawilk merged commit ac02715 into envoyproxy:main Jun 8, 2022
tyxia pushed a commit to tyxia/envoy that referenced this pull request Jun 14, 2022
Risk Level: Medium (data plane changes)
Testing: updated tests
Docs Changes: n/a
Release Notes: inline
Runtime guard: envoy.reloadable_features.use_rfc_connect
Fixes envoyproxy#20378

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Tianyu Xia <tyxia@google.com>
Amila-Rukshan pushed a commit to Amila-Rukshan/envoy that referenced this pull request Jun 28, 2022
Risk Level: Medium (data plane changes)
Testing: updated tests
Docs Changes: n/a
Release Notes: inline
Runtime guard: envoy.reloadable_features.use_rfc_connect
Fixes envoyproxy#20378

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Amila Senadheera <amila.15@cse.mrt.ac.lk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TcpProxy improperly sets :protocol=bytestream for HTTP2
6 participants