-
Notifications
You must be signed in to change notification settings - Fork 85
test: use TestRequestHeaderMapImpl for building custom headers #2455
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
Changes from 9 commits
0f08b73
bbb24fd
d7f31d3
3ac0389
fe86f65
defc626
a398b4e
fb2276d
9e72e3c
464f0e6
2703f3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,13 @@ | ||
| #include "test/common/integration/base_client_integration_test.h" | ||
|
|
||
| #include <string> | ||
|
|
||
| #include "test/common/http/common.h" | ||
|
|
||
| #include "gtest/gtest.h" | ||
| #include "library/cc/bridge_utility.h" | ||
| #include "library/common/config/internal.h" | ||
| #include "library/common/http/header_utility.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace { | ||
|
|
@@ -89,15 +95,44 @@ void BaseClientIntegrationTest::initialize() { | |
|
|
||
| stream_ = (*stream_prototype_).start(explicit_flow_control_); | ||
| std::string host(fake_upstreams_[0]->localAddress()->asStringView()); | ||
| Platform::RequestHeadersBuilder builder(Platform::RequestMethod::GET, scheme_, host, "/"); | ||
| for (auto& entry : custom_headers_) { | ||
| auto values = {entry.second}; | ||
| builder.set(entry.first, values); | ||
| } | ||
| HttpTestUtility::addDefaultHeaders(default_request_headers_); | ||
| default_request_headers_.setHost(fake_upstreams_[0]->localAddress()->asStringView()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is setHost on
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, thanks for clarifying. The |
||
| } | ||
|
|
||
| std::shared_ptr<Platform::RequestHeaders> BaseClientIntegrationTest::envoyToMobileHeaders( | ||
|
alyssawilk marked this conversation as resolved.
|
||
| const Http::TestRequestHeaderMapImpl& request_headers) { | ||
|
|
||
| envoy_headers envoyHeaders = Http::Utility::toBridgeHeaders(request_headers); | ||
| Platform::RawHeaderMap rawHeaderMap = Platform::envoyHeadersAsRawHeaderMap(envoyHeaders); | ||
|
|
||
| Platform::RequestHeadersBuilder builder( | ||
| Platform::RequestMethod::GET, | ||
| std::string(default_request_headers_.Scheme()->value().getStringView()), | ||
| std::string(default_request_headers_.Host()->value().getStringView()), "/"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's get path from the headers as well? |
||
| if (upstreamProtocol() == Http::CodecType::HTTP2) { | ||
| builder.addUpstreamHttpProtocol(Platform::UpstreamHttpProtocol::HTTP2); | ||
| } | ||
| default_request_headers_ = std::make_shared<Platform::RequestHeaders>(builder.build()); | ||
|
|
||
| request_headers.iterate( | ||
| [&request_headers, &builder](const Http::HeaderEntry& header) -> Http::HeaderMap::Iterate { | ||
| std::string key_val = std::string(header.key().getStringView()); | ||
| if (request_headers.formatter().has_value()) { | ||
| const Envoy::Http::StatefulHeaderKeyFormatter& formatter = | ||
| request_headers.formatter().value(); | ||
| key_val = formatter.format(key_val); | ||
| } | ||
| auto key = std::string(key_val); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isn't key_val already a string? Why do we need the extra one? |
||
| auto value = std::vector<std::string>(); | ||
| value.push_back(std::string(header.value().getStringView())); | ||
| builder.set(key, value); | ||
| return Http::HeaderMap::Iterate::Continue; | ||
| }); | ||
|
|
||
| for (const auto& pair : rawHeaderMap) { | ||
| builder.set(pair.first, pair.second); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I follow L117-133. In L117, we iterate over
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great catch yeah looks like I forgot to delete some code :O |
||
| auto mobile_headers = std::make_shared<Platform::RequestHeaders>(builder.build()); | ||
| return mobile_headers; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: consider skipping the temporary variable and just return the make_shared |
||
| } | ||
|
|
||
| void BaseClientIntegrationTest::threadRoutine(absl::Notification& engine_running) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,11 +4,7 @@ | |
| #include "test/common/integration/base_client_integration_test.h" | ||
| #include "test/integration/autonomous_upstream.h" | ||
|
|
||
| #include "gmock/gmock.h" | ||
| #include "gtest/gtest.h" | ||
| #include "library/common/data/utility.h" | ||
| #include "library/common/engine.h" | ||
| #include "library/common/http/header_utility.h" | ||
| #include "library/common/types/c_types.h" | ||
|
|
||
| using testing::ReturnRef; | ||
|
|
@@ -39,11 +35,12 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, ClientIntegrationTest, | |
| TestUtility::ipTestParamsToString); | ||
|
|
||
| TEST_P(ClientIntegrationTest, Basic) { | ||
| Buffer::OwnedImpl request_data = Buffer::OwnedImpl("request body"); | ||
| custom_headers_.emplace(AutonomousStream::EXPECT_REQUEST_SIZE_BYTES, | ||
| std::to_string(request_data.length())); | ||
| initialize(); | ||
|
|
||
| Buffer::OwnedImpl request_data = Buffer::OwnedImpl("request body"); | ||
| default_request_headers_.addCopy(AutonomousStream::EXPECT_REQUEST_SIZE_BYTES, | ||
| std::to_string(request_data.length())); | ||
|
|
||
| stream_prototype_->setOnData([this](envoy_data c_data, bool end_stream) { | ||
| if (end_stream) { | ||
| EXPECT_EQ(Data::Utility::copyToString(c_data), ""); | ||
|
|
@@ -54,7 +51,7 @@ TEST_P(ClientIntegrationTest, Basic) { | |
| release_envoy_data(c_data); | ||
| }); | ||
|
|
||
| stream_->sendHeaders(default_request_headers_, false); | ||
| stream_->sendHeaders(envoyToMobileHeaders(default_request_headers_), false); | ||
|
|
||
| envoy_data c_data = Data::Utility::toBridgeData(request_data); | ||
| stream_->sendData(c_data); | ||
|
|
@@ -82,7 +79,7 @@ TEST_P(ClientIntegrationTest, BasicNon2xx) { | |
| ->setResponseHeaders(std::make_unique<Http::TestResponseHeaderMapImpl>( | ||
| Http::TestResponseHeaderMapImpl({{":status", "503"}, {"content-length", "0"}}))); | ||
|
|
||
| stream_->sendHeaders(default_request_headers_, true); | ||
| stream_->sendHeaders(envoyToMobileHeaders(default_request_headers_), true); | ||
| terminal_callback_.waitReady(); | ||
|
|
||
| ASSERT_EQ(cc_.on_error_calls, 0); | ||
|
|
@@ -92,10 +89,11 @@ TEST_P(ClientIntegrationTest, BasicNon2xx) { | |
| } | ||
|
|
||
| TEST_P(ClientIntegrationTest, BasicReset) { | ||
| custom_headers_.emplace(AutonomousStream::RESET_AFTER_REQUEST, "yes"); | ||
| initialize(); | ||
|
|
||
| stream_->sendHeaders(default_request_headers_, true); | ||
| default_request_headers_.addCopy(AutonomousStream::RESET_AFTER_REQUEST, "yes"); | ||
|
|
||
| stream_->sendHeaders(envoyToMobileHeaders(default_request_headers_), true); | ||
| terminal_callback_.waitReady(); | ||
|
|
||
| ASSERT_EQ(cc_.on_error_calls, 1); | ||
|
|
@@ -116,7 +114,7 @@ TEST_P(ClientIntegrationTest, BasicCancel) { | |
| return nullptr; | ||
| }); | ||
|
|
||
| stream_->sendHeaders(default_request_headers_, true); | ||
| stream_->sendHeaders(envoyToMobileHeaders(default_request_headers_), true); | ||
|
|
||
| Envoy::FakeRawConnectionPtr upstream_connection; | ||
| ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(upstream_connection)); | ||
|
|
@@ -161,7 +159,7 @@ TEST_P(ClientIntegrationTest, CancelWithPartialStream) { | |
| return nullptr; | ||
| }); | ||
|
|
||
| stream_->sendHeaders(default_request_headers_, true); | ||
| stream_->sendHeaders(envoyToMobileHeaders(default_request_headers_), true); | ||
|
|
||
| Envoy::FakeRawConnectionPtr upstream_connection; | ||
| ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(upstream_connection)); | ||
|
|
@@ -198,10 +196,33 @@ TEST_P(ClientIntegrationTest, CancelWithPartialStream) { | |
|
|
||
| // Test header key case sensitivity. | ||
| TEST_P(ClientIntegrationTest, CaseSensitive) { | ||
| custom_headers_.emplace("FoO", "bar"); | ||
| autonomous_upstream_ = false; | ||
| Envoy::Extensions::Http::HeaderFormatters::PreserveCase:: | ||
| forceRegisterPreserveCaseFormatterFactoryConfig(); | ||
| config_helper_.addConfigModifier([](envoy::config::bootstrap::v3::Bootstrap& bootstrap) { | ||
| ConfigHelper::HttpProtocolOptions protocol_options; | ||
| auto typed_extension_config = protocol_options.mutable_explicit_http_config() | ||
| ->mutable_http_protocol_options() | ||
| ->mutable_header_key_format() | ||
| ->mutable_stateful_formatter(); | ||
| typed_extension_config->set_name("preserve_case"); | ||
| typed_extension_config->mutable_typed_config()->set_type_url( | ||
| "type.googleapis.com/" | ||
| "envoy.extensions.http.header_formatters.preserve_case.v3.PreserveCaseFormatterConfig"); | ||
| ConfigHelper::setProtocolOptions(*bootstrap.mutable_static_resources()->mutable_clusters(0), | ||
| protocol_options); | ||
| }); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we need this? Envoy defaults should include stateful formatter |
||
| initialize(); | ||
|
|
||
| default_request_headers_.header_map_->setFormatter( | ||
| std::make_unique< | ||
| Extensions::Http::HeaderFormatters::PreserveCase::PreserveCaseHeaderFormatter>( | ||
| false, envoy::extensions::http::header_formatters::preserve_case::v3:: | ||
| PreserveCaseFormatterConfig::DEFAULT)); | ||
|
|
||
| default_request_headers_.addCopy("FoO", "bar"); | ||
| default_request_headers_.header_map_->formatter().value().get().processKey("FoO"); | ||
|
|
||
| stream_prototype_->setOnHeaders( | ||
| [this](Platform::ResponseHeadersSharedPtr headers, bool, envoy_stream_intel) { | ||
| cc_.status = absl::StrCat(headers->httpStatus()); | ||
|
|
@@ -210,8 +231,7 @@ TEST_P(ClientIntegrationTest, CaseSensitive) { | |
| EXPECT_TRUE((*headers)["My-ResponsE-Header"][0] == "foo"); | ||
| return nullptr; | ||
| }); | ||
|
|
||
| stream_->sendHeaders(default_request_headers_, true); | ||
| stream_->sendHeaders(envoyToMobileHeaders(default_request_headers_), true); | ||
|
|
||
| Envoy::FakeRawConnectionPtr upstream_connection; | ||
| ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(upstream_connection)); | ||
|
|
@@ -240,7 +260,7 @@ TEST_P(ClientIntegrationTest, TimeoutOnRequestPath) { | |
| autonomous_upstream_ = false; | ||
| initialize(); | ||
|
|
||
| stream_->sendHeaders(default_request_headers_, false); | ||
| stream_->sendHeaders(envoyToMobileHeaders(default_request_headers_), false); | ||
|
|
||
| Envoy::FakeRawConnectionPtr upstream_connection; | ||
| ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(upstream_connection)); | ||
|
|
@@ -261,7 +281,7 @@ TEST_P(ClientIntegrationTest, TimeoutOnResponsePath) { | |
| autonomous_upstream_ = false; | ||
| initialize(); | ||
|
|
||
| stream_->sendHeaders(default_request_headers_, true); | ||
| stream_->sendHeaders(envoyToMobileHeaders(default_request_headers_), true); | ||
|
|
||
| Envoy::FakeRawConnectionPtr upstream_connection; | ||
| ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(upstream_connection)); | ||
|
|
||
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.
The edits to this file aren't strictly part of this diff. I just noticed that the
toEnvoyHeadersfunction has better parameter names in itsheader_utility.hfile, figured I'd fix the mismatch.