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

make custom inline headers bootstrap configurable #17330

Merged
merged 9 commits into from
Jul 27, 2021

Conversation

wbpcode
Copy link
Member

@wbpcode wbpcode commented Jul 14, 2021

Signed-off-by: wbpcode [email protected]

Commit Message: make custom inline headers bootstrap configurable
Additional Description:

Make custom inline headers bootstrap configurable. Check #17234 for more background info.

Risk Level: Mid.
Testing: Added.
Docs Changes: N/A.
Release Notes: Wait.

@repokitteh-read-only
Copy link

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

🐱

Caused by: #17330 was opened by wbpcode.

see: more, trace.

Signed-off-by: wbpcode <[email protected]>
Copy link
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.

Left an API comment and some drive-by code comments.

@@ -294,6 +295,46 @@ void loadBootstrap(absl::optional<uint32_t> bootstrap_version,
throw EnvoyException(fmt::format("Unknown bootstrap version {}.", *bootstrap_version));
}
}

bool canBeRegisteredAsInlineHeaderOrNot(const Http::LowerCaseString& header_name) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: canBeRegisteredAsInlineHeader

Copy link
Member Author

Choose a reason for hiding this comment

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

👌

void registerCustomInlineHeadersFromBootstrap(
const envoy::config::bootstrap::v3::Bootstrap& bootstrap) {
for (const auto& inline_header : bootstrap.inline_headers()) {
Http::LowerCaseString lower_case_name(inline_header.inline_header_name());
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: const

Copy link
Member Author

Choose a reason for hiding this comment

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

👌

Comment on lines 354 to 355
// instantiation of InstanceImpl. If InstanceImpl is instantiated again and the inline header is
// registered again, the assertion will be triggered.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a test that covers this scenario? If not, can you please add one.

Copy link
Member Author

Choose a reason for hiding this comment

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

👌

string inline_header_name = 1 [(validate.rules).string = {min_len: 1}];

// The type of the header that is expected to be set as the inline header.
InlineHeaderType inline_header_type = 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that the following PGV constraint (validate.rules).enum.defined_only = true can be added.

Copy link
Member Author

Choose a reason for hiding this comment

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

👌

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

Signed-off-by: wbpcode <[email protected]>
@wbpcode
Copy link
Member Author

wbpcode commented Jul 18, 2021

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #17330 (comment) was created by @wbpcode.

see: more, trace.

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

@wbpcode
Copy link
Member Author

wbpcode commented Jul 20, 2021

@alyssawilk Now the API is ready. When it is convenient for you, can you advance this work? 😄

@alyssawilk alyssawilk self-assigned this Jul 20, 2021
Copy link
Contributor

@alyssawilk alyssawilk 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! this will be a really useful feature going forward :-)

api/envoy/config/bootstrap/v3/bootstrap.proto Show resolved Hide resolved
@@ -292,6 +293,46 @@ void loadBootstrap(absl::optional<uint32_t> bootstrap_version,
throw EnvoyException(fmt::format("Unknown bootstrap version {}.", *bootstrap_version));
}
}

bool canBeRegisteredAsInlineHeader(const Http::LowerCaseString& header_name) {
Copy link
Contributor

Choose a reason for hiding this comment

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

call out in API?

Copy link
Member Author

Choose a reason for hiding this comment

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

get it.

string inline_header_name = 1 [(validate.rules).string = {min_len: 1}];

// The type of the header that is expected to be set as the inline header.
InlineHeaderType inline_header_type = 2 [(validate.rules).enum = {defined_only: true}];
Copy link
Contributor

Choose a reason for hiding this comment

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

vadd pgv for well_known_regex: HTTP_HEADER_NAME?

Copy link
Member Author

Choose a reason for hiding this comment

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

get it.

inline_header.inline_header_name()));
}
switch (inline_header.inline_header_type()) {
case envoy::config::bootstrap::v3::CustomInlineHeader::REQUEST_HEADER:
Copy link
Contributor

Choose a reason for hiding this comment

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

Can one add as a custom inline header a header which is already an inline header? I think it's worth a unit test for this.

Copy link
Member Author

@wbpcode wbpcode Jul 21, 2021

Choose a reason for hiding this comment

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

Can one add as a custom inline header a header which is already an inline header?

Yes.

I think it's worth a unit test for this.

I think this scenario has been verified in the test of CustomInlineHeaderRegistry::registerInlineHeader itself. We can register the header with the same name as the inline header repeatedly without any negative effects.

Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::RequestHeaders>
custom_header_1(Http::LowerCaseString{"foo_custom_header"});
Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::RequestHeaders>
custom_header_1_copy(Http::LowerCaseString{"foo_custom_header"});

// Make sure that the same header registered twice points to the same location.
TEST_P(HeaderMapImplTest, CustomRegisteredHeaders) {
TestRequestHeaderMapImpl headers;
EXPECT_EQ(custom_header_1.handle(), custom_header_1_copy.handle());
EXPECT_EQ(nullptr, headers.getInline(custom_header_1.handle()));
EXPECT_EQ(nullptr, headers.getInline(custom_header_1_copy.handle()));
headers.setInline(custom_header_1.handle(), 42);
EXPECT_EQ("42", headers.getInlineValue(custom_header_1_copy.handle()));
EXPECT_EQ("foo_custom_header",
headers.getInline(custom_header_1.handle())->key().getStringView());
}

is_registered = true;
}

EXPECT_TRUE(
Copy link
Contributor

Choose a reason for hiding this comment

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

how about an integration test (protocol integration test?) that the headers / trailers end up elided?

Copy link
Member Author

Choose a reason for hiding this comment

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

get it. I think we can verify this problem with a few simple lines of tests in existing test cases.

Copy link
Contributor

Choose a reason for hiding this comment

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

Where did we land on this? Don't see an integration test

@wbpcode
Copy link
Member Author

wbpcode commented Jul 21, 2021

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #17330 (comment) was created by @wbpcode.

see: more, trace.

alyssawilk
alyssawilk previously approved these changes Jul 21, 2021
Copy link
Contributor

@alyssawilk alyssawilk 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! Throwing over to @snowp for second pass

@alyssawilk
Copy link
Contributor

Also @adisuissa can you do another API stamp?

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

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.

This LGTM, just one question re adding an integration test

@wbpcode wbpcode closed this Jul 24, 2021
@wbpcode wbpcode reopened this Jul 24, 2021
@wbpcode
Copy link
Member Author

wbpcode commented Jul 24, 2021

@snowp Thanks.

@alyssawilk's suggestion is to verify that a header or trailer registered as an inline header can be folded correctly. In practice, integration tests are not necessarily required to verify this problem.
Instead of adding a whole new integration test to verify it, I did the same by adding some extra code to the test case.

https://github.com/wbpcode/envoy/blob/446214acbbce602b8b9a84ad1b0e342c65e47535/test/server/server_test.cc#L390-L427

{
    Http::TestRequestHeaderMapImpl headers{
        {"test1", "test1_value1"},
        {"test1", "test1_value2"},
        {"test3", "test3_value1"},
        {"test3", "test3_value2"},
    };

    // 'test1' is registered as the inline request header.
    auto test1_headers = headers.get(Http::LowerCaseString("test1"));
    EXPECT_EQ(1, test1_headers.size());
    EXPECT_EQ("test1_value1,test1_value2", headers.get_("test1"));

    // 'test3' is not registered as an inline request header.
    auto test3_headers = headers.get(Http::LowerCaseString("test3"));
    EXPECT_EQ(2, test3_headers.size());
    EXPECT_EQ("test3_value1", headers.get_("test3"));
  }

  {
    Http::TestResponseHeaderMapImpl headers{
        {"test1", "test1_value1"},
        {"test1", "test1_value2"},
        {"test3", "test3_value1"},
        {"test3", "test3_value2"},
    };

    // 'test1' is not registered as the inline response header.
    auto test1_headers = headers.get(Http::LowerCaseString("test1"));
    EXPECT_EQ(2, test1_headers.size());
    EXPECT_EQ("test1_value1", headers.get_("test1"));

    // 'test3' is registered as an inline response header.
    auto test3_headers = headers.get(Http::LowerCaseString("test3"));
    EXPECT_EQ(1, test3_headers.size());
    EXPECT_EQ("test3_value1,test3_value2", headers.get_("test3"));
  }
}

@wbpcode
Copy link
Member Author

wbpcode commented Jul 24, 2021

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #17330 (comment) was created by @wbpcode.

see: more, trace.

@wbpcode
Copy link
Member Author

wbpcode commented Jul 24, 2021

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #17330 (comment) was created by @wbpcode.

see: more, trace.

Signed-off-by: wbpcode <[email protected]>
@snowp
Copy link
Contributor

snowp commented Jul 27, 2021

I think normally we encourage adding an integration test even if it's not strictly necessary since they tend to catch unexpected issues (or provide more reliable regression tests). That said it seems like we're okay skipping it in this case, so let's get this merged

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!

@snowp snowp merged commit 6ace04d into envoyproxy:main Jul 27, 2021
baojr added a commit to baojr/envoy that referenced this pull request Jul 29, 2021
…bridge-stream

* upstream/main: (140 commits)
  quiche: remove google quic support (envoyproxy#17465)
  runtime: removing envoy.reloadable_features.check_ocsp_policy (envoyproxy#17524)
  upstream: not trying to do HTTP/3 where not configured (envoyproxy#17454)
  api: Remove confusing line about auto-generation (envoyproxy#17536)
  v2: removing bootstrap (envoyproxy#17523)
  connpool: Fix crash in pool removal if the cluster was already deleted (envoyproxy#17522)
  Enhance the comments clearly (envoyproxy#17517)
  mysql proxy: connection attributes parsing  (envoyproxy#17209)
  [ci] fix false positive CVE scan from node (envoyproxy#17510)
  Fixing Envoy Mobile factory strings (envoyproxy#17509)
  http3: validating codec (envoyproxy#17452)
  quic: add QUIC upstream stream reset error stats (envoyproxy#17496)
  thrift proxy: move UpstreamRequest into its own file (envoyproxy#17498)
  docs: Fixed FaultDelay docs. (envoyproxy#17495)
  updates links to jaegertracing-plugin.tar.gz (envoyproxy#17497)
  http: make custom inline headers bootstrap configurable (envoyproxy#17330)
  deps: update yaml-cpp to latest master (envoyproxy#17489)
  improving tracer coverage (envoyproxy#17493)
  Increase buffer size of `Win32RedirectRecords` (envoyproxy#17471)
  ext_proc: Fix problem with buffered body mode with empty or no body (envoyproxy#17430)
  ...

Signed-off-by: Garrett Bourg <[email protected]>
alyssawilk pushed a commit that referenced this pull request Aug 10, 2021
Commit Message: ensure that the inline cookie header will be folded correctly
Additional Description:

This PR is a supplement to #17330 and #14969 and will finally close #17234. This PR mainly did following works:

update insertByKey to choose suitable delimiter for inline header.
update parseCookie to avoid unnecessary iteration for parsing cookie value.
Risk Level: Low.
Testing: Add.
Docs Changes: N/A.
Release Notes: N/A.
Signed-off-by: wbpcode <[email protected]>
leyao-daily pushed a commit to leyao-daily/envoy that referenced this pull request Sep 30, 2021
leyao-daily pushed a commit to leyao-daily/envoy that referenced this pull request Sep 30, 2021
…roxy#17560)

Commit Message: ensure that the inline cookie header will be folded correctly
Additional Description:

This PR is a supplement to envoyproxy#17330 and envoyproxy#14969 and will finally close envoyproxy#17234. This PR mainly did following works:

update insertByKey to choose suitable delimiter for inline header.
update parseCookie to avoid unnecessary iteration for parsing cookie value.
Risk Level: Low.
Testing: Add.
Docs Changes: N/A.
Release Notes: N/A.
Signed-off-by: wbpcode <[email protected]>
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.

4 participants