Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7c0674d
Remove trailing host dot from host/authority header.
maheshkurund Mar 19, 2021
d2e05b7
Fixed formatting.
maheshkurund Mar 19, 2021
595157c
Added missing variable entry.
maheshkurund Mar 19, 2021
4945289
Added unit test to check dot striping after RequestDecoder::decodeHea…
maheshkurund Mar 22, 2021
74f247f
Fixed test failure caused because of missing cleanup.
maheshkurund Mar 22, 2021
bb62fda
Merge branch 'main' into remove_trailing_host_dot
maheshkurund Apr 8, 2021
c3d1057
Fixed proto field number
maheshkurund Apr 8, 2021
4b9c804
Merge remote-tracking branch 'upstream/main' into remove_trailing_hos…
maheshkurund Apr 22, 2021
468ce45
Fixed tests.
maheshkurund Apr 22, 2021
3a4f449
Fixed tests.
maheshkurund Apr 23, 2021
40a1a44
Fixed test cleanup.
maheshkurund Apr 23, 2021
8995b52
Merge upstream/main
maheshkurund Apr 30, 2021
baed449
Addressed review comment.
maheshkurund Apr 30, 2021
58b3759
Merge branch 'main' into remove_trailing_host_dot
maheshkurund May 10, 2021
e910496
Fixed docs.
maheshkurund May 11, 2021
dca8659
Merge main into remove_trailing_host_dot
maheshkurund May 12, 2021
fffc458
Merge main branch into remove_trailing_host_dot
maheshkurund May 18, 2021
d3cd808
Addressed review comments.
maheshkurund May 18, 2021
ef66621
Merge branch 'main' into remove_trailing_host_dot
maheshkurund May 20, 2021
c744100
Addressed review comments.
maheshkurund May 20, 2021
ec186fd
Merge branch 'main' into remove_trailing_host_dot
maheshkurund May 20, 2021
c94357b
Merge branch 'main' into remove_trailing_host_dot
maheshkurund May 21, 2021
d117486
Addressed review comments.
maheshkurund May 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// HTTP connection manager :ref:`configuration overview <config_http_conn_man>`.
// [#extension: envoy.filters.network.http_connection_manager]

// [#next-free-field: 44]
// [#next-free-field: 45]
message HttpConnectionManager {
option (udpa.annotations.versioning).previous_message_type =
"envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager";
Expand Down Expand Up @@ -630,6 +630,13 @@ message HttpConnectionManager {
// <envoy_api_msg_extensions.filters.network.http_connection_manager.v3.PathNormalizationOptions>`
// for details.
PathNormalizationOptions path_normalization_options = 43;

// Determines if trailing dot of the host should be removed from host/authority header before any
// processing of request by HTTP filters or routing.
// This affects the upstream host header.
// Without setting this option, incoming requests with host `example.com.` will not match against
// route with :ref:`domains<envoy_api_field_config.route.v3.VirtualHost.domains>` match set to `example.com`. Defaults to `false`.
bool strip_trailing_host_dot = 44;

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.

Drive by question for mdroth, do we think it's worth moving this and strip_matching_host_port together in a host mutation proto or just and wait and see if we get more?

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.

At this point, there are a whole bunch of options here related to URI normalization, not just the host ones but also the path ones. I'd be open to moving all of those options to a separate UriNormalizationOptions message, but I'd also be okay with keeping them here, since they're unlikely to ever be used anywhere else.

}

// The configuration to customize local reply returned by Envoy.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ New Features
* http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 and HTTP/2 dispatching. Crashes while inside the dispatching loop should dump debug information. Furthermore, HTTP/1 and HTTP/2 clients now dumps the originating request whose response from the upstream caused Envoy to crash.
* http: added support for :ref:`preconnecting <envoy_v3_api_msg_config.cluster.v3.Cluster.PreconnectPolicy>`. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1.
* http: added new runtime config `envoy.reloadable_features.check_unsupported_typed_per_filter_config`, the default value is true. When the value is true, envoy will reject virtual host-specific typed per filter config when the filter doesn't support it.
* http: added :ref:`stripping trailing host dot from host header <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.strip_trailing_host_dot>` support.
* http: change frame flood and abuse checks to the upstream HTTP/2 codec to ON by default. It can be disabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to false.
* json: introduced new JSON parser (https://github.com/nlohmann/json) to replace RapidJSON. The new parser is disabled by default. To test the new RapidJSON parser, enable the runtime feature `envoy.reloadable_features.remove_legacy_json`.
* kill_request: :ref:`Kill Request <config_http_filters_kill_request>` Now supports bidirection killing.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions source/common/http/conn_manager_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,12 @@ class ConnectionManagerConfig {
*/
virtual bool shouldMergeSlashes() const PURE;

/**
* @return if the HttpConnectionManager should remove trailing host dot from host/authority
* header.
*/
virtual bool shouldStripTrailingHostDot() const PURE;

/**
* @return port strip type from host/authority header.
*/
Expand Down
3 changes: 3 additions & 0 deletions source/common/http/conn_manager_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,9 @@ void ConnectionManagerUtility::maybeNormalizeHost(RequestHeaderMap& request_head
} else if (config.stripPortType() == Http::StripPortType::MatchingHost) {
HeaderUtility::stripPortFromHost(request_headers, port);
}
if (config.shouldStripTrailingHostDot()) {
HeaderUtility::stripTrailingHostDot(request_headers);
}
}

} // namespace Http
Expand Down
23 changes: 23 additions & 0 deletions source/common/http/header_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,29 @@ bool HeaderUtility::isEnvoyInternalRequest(const RequestHeaderMap& headers) {
internal_request_header->value() == Headers::get().EnvoyInternalRequestValues.True;
}

void HeaderUtility::stripTrailingHostDot(RequestHeaderMap& headers) {
auto host = headers.getHostValue();
// Find last dot and return if not found or take off end if last

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.

Maybe just // If the host ends in a period, remove it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes fits well here, will update.

auto dot_index = host.rfind('.');
if (dot_index == std::string::npos) {
return;
} else if (dot_index == (host.size() - 1)) {
host.remove_suffix(1);
headers.setHost(host);
return;
}
// Check if the dot is just before a colon, which means it must be the port

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.

If the dot is just before a colon, it must be preceding the port number.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will change.

// because although the host may contain a colon via an IPv6 bracketed
// address, and although that IPv6 address may also contain dots when
// embedding an address per RFC 4291 2.2.3, the dot will never directly
// precede the colon like it would in foo.com.:123

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.

Maybe split this sentence up? It's very long

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yah, will fix it.

if (host[dot_index + 1] == ':') {
// Does a memcpy internally, but since we only have access to a string_view

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.

What does a memcpy? If you're talking about it copying data to a new string we do that on L238 as well, so this call out seems to be a bit unnecessary

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will remove it.

// anyways, this is acceptable compared to a string::erase of a copy

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.

nit: end comments with period

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will change.

headers.setHost(absl::StrCat(host.substr(0, dot_index), host.substr(dot_index + 1)));
}
}

void HeaderUtility::stripPortFromHost(RequestHeaderMap& headers,
absl::optional<uint32_t> listener_port) {

Expand Down
5 changes: 5 additions & 0 deletions source/common/http/header_utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ class HeaderUtility {
static bool shouldCloseConnection(Http::Protocol protocol,
const RequestOrResponseHeaderMap& headers);

/**
* @brief Remove the trailing host dot from host/authority header.
*/
static void stripTrailingHostDot(RequestHeaderMap& headers);

/**
* @brief Remove the port part from host/authority header if it is equal to provided port.
* If port is not passed, port part from host/authority header is removed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig(
merge_slashes_(config.merge_slashes()),
headers_with_underscores_action_(
config.common_http_protocol_options().headers_with_underscores_action()),
local_reply_(LocalReply::Factory::create(config.local_reply_config(), context)) {
local_reply_(LocalReply::Factory::create(config.local_reply_config(), context)),
strip_trailing_host_dot_(config.strip_trailing_host_dot()) {
// If idle_timeout_ was not configured in common_http_protocol_options, use value in deprecated
// idle_timeout field.
// TODO(asraa): Remove when idle_timeout is removed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class HttpConnectionManagerConfig : Logger::Loggable<Logger::Id::config>,
const Http::Http1Settings& http1Settings() const override { return http1_settings_; }
bool shouldNormalizePath() const override { return normalize_path_; }
bool shouldMergeSlashes() const override { return merge_slashes_; }
bool shouldStripTrailingHostDot() const override { return strip_trailing_host_dot_; }
Http::StripPortType stripPortType() const override { return strip_port_type_; }
envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
headersWithUnderscoresAction() const override {
Expand Down Expand Up @@ -257,6 +258,7 @@ class HttpConnectionManagerConfig : Logger::Loggable<Logger::Id::config>,
const envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
headers_with_underscores_action_;
const LocalReply::LocalReplyPtr local_reply_;
const bool strip_trailing_host_dot_;

// Default idle timeout is 5 minutes if nothing is specified in the HCM config.
static const uint64_t StreamIdleTimeoutMs = 5 * 60 * 1000;
Expand Down
1 change: 1 addition & 0 deletions source/server/admin/admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class AdminImpl : public Admin,
const Http::Http1Settings& http1Settings() const override { return http1_settings_; }
bool shouldNormalizePath() const override { return true; }
bool shouldMergeSlashes() const override { return true; }
bool shouldStripTrailingHostDot() const override { return false; }
Http::StripPortType stripPortType() const override { return Http::StripPortType::None; }
envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
headersWithUnderscoresAction() const override {
Expand Down
1 change: 1 addition & 0 deletions test/common/http/conn_manager_impl_fuzz_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class FuzzConfig : public ConnectionManagerConfig {
const Http::Http1Settings& http1Settings() const override { return http1_settings_; }
bool shouldNormalizePath() const override { return false; }
bool shouldMergeSlashes() const override { return false; }
bool shouldStripTrailingHostDot() const override { return false; }
Http::StripPortType stripPortType() const override { return Http::StripPortType::None; }
envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
headersWithUnderscoresAction() const override {
Expand Down
83 changes: 83 additions & 0 deletions test/common/http/conn_manager_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,89 @@ TEST_F(HttpConnectionManagerImplTest, RouteShouldUseNormalizedHost) {
filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose);
}

// Filters observe host header w/o trailing dot in host when trailing dot removal is configured

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.

Do you think dot stripping could be tested more directly? Instantiate ConnectionManagerImpl, create a RequestDecoder by invoking ConnectionManagerImpl::newStream(), then invoke RequestDecoder::decodeHeaders() and verify the contents of the "host" header. WDYT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yes, added test for this, please check and let me know. Thank you.

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.

Ultimately, I'm not sure why three tests that very closely resemble each other are needed (they all verify that a) header map is updated, and b) that filters in the filter chain see that change. Perhaps just RemoveTrailingHostDot or FilterShouldUseHostWithoutTrailingDot is sufficient?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agree, will remove RemoveTrailingHostDot test and add check to verify host header after RequestDecoder::decodeHeaders() in FilterShouldUseHostWithoutTrailingDot and RouteShouldUseHostWithoutTrailingDot.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed.

TEST_F(HttpConnectionManagerImplTest, FilterShouldUseHostWithoutTrailingDot) {
setup(false, "");
// Enable removal of host's trailing dot
strip_trailing_host_dot_ = true;
const std::string original_host = "host.";
const std::string updated_host = "host";

auto* filter = new MockStreamFilter();

EXPECT_CALL(filter_factory_, createFilterChain(_))
.WillOnce(Invoke([&](FilterChainFactoryCallbacks& callbacks) -> void {
callbacks.addStreamDecoderFilter(StreamDecoderFilterSharedPtr{filter});
}));

EXPECT_CALL(*filter, decodeHeaders(_, true))
.WillRepeatedly(Invoke([&](RequestHeaderMap& header_map, bool) -> FilterHeadersStatus {
EXPECT_EQ(updated_host, header_map.getHostValue());
return FilterHeadersStatus::StopIteration;
}));

EXPECT_CALL(*filter, setDecoderFilterCallbacks(_));

EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> Http::Status {
decoder_ = &conn_manager_->newStream(response_encoder_);

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.

Couldn't you reduce the test to setup and lines 854-857? Then verify the contents of authority in headers...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Is it ok to verify host header after RequestDecoder::decodeHeaders() in existing tests? Or should I keep only single test which just verifies host header after RequestDecoder::decodeHeaders() as you mentioned above?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed.

RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{
{":authority", original_host}, {":path", "/"}, {":method", "GET"}}};
decoder_->decodeHeaders(std::move(headers), true);
return Http::okStatus();
}));

// Kick off the incoming data.
Buffer::OwnedImpl fake_input("1234");
conn_manager_->onData(fake_input, false);

// Clean up.
EXPECT_CALL(*filter, onStreamComplete());
EXPECT_CALL(*filter, onDestroy());
filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose);
}

// The router observes host header w/o trailing dot, not the original host, when
// remove_trailing_hot_dot is configured
TEST_F(HttpConnectionManagerImplTest, RouteShouldUseHostWithoutTrailingDot) {
setup(false, "");
// Enable removal of host's trailing dot
strip_trailing_host_dot_ = true;
strip_port_type_ = Http::StripPortType::MatchingHost;
const std::string original_host = "host.";
const std::string updated_host = "host";

EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> Http::Status {
decoder_ = &conn_manager_->newStream(response_encoder_);
RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{
{":authority", original_host}, {":path", "/"}, {":method", "GET"}}};
decoder_->decodeHeaders(std::move(headers), true);
return Http::okStatus();
}));

const std::string fake_cluster_name = "fake_cluster";

std::shared_ptr<Upstream::MockThreadLocalCluster> fake_cluster =
std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
std::shared_ptr<Router::MockRoute> route = std::make_shared<NiceMock<Router::MockRoute>>();
EXPECT_CALL(route->route_entry_, clusterName()).WillRepeatedly(ReturnRef(fake_cluster_name));

EXPECT_CALL(*route_config_provider_.route_config_, route(_, _, _, _))
.WillOnce(Invoke([&](const Router::RouteCallback&, const Http::RequestHeaderMap& header_map,
const StreamInfo::StreamInfo&, uint64_t) {
EXPECT_EQ(updated_host, header_map.getHostValue());
return route;
}));
EXPECT_CALL(filter_factory_, createFilterChain(_))
.WillOnce(Invoke([&](FilterChainFactoryCallbacks&) -> void {}));

// Kick off the incoming data.
Buffer::OwnedImpl fake_input("1234");
conn_manager_->onData(fake_input, false);

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 you need to call onData callback (and set the expectation above), instead you should be able to do

conn_manager_->createCodec(fake_input);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thank you. Updated the code with suggestion.


// Clean up.
filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose);
}

TEST_F(HttpConnectionManagerImplTest, DateHeaderNotPresent) {
setup(false, "");
setUpEncoderAndDecoder(false, false);
Expand Down
2 changes: 2 additions & 0 deletions test/common/http/conn_manager_impl_test_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan
const Http::Http1Settings& http1Settings() const override { return http1_settings_; }
bool shouldNormalizePath() const override { return normalize_path_; }
bool shouldMergeSlashes() const override { return merge_slashes_; }
bool shouldStripTrailingHostDot() const override { return strip_trailing_host_dot_; }
Http::StripPortType stripPortType() const override { return strip_port_type_; }
const RequestIDExtensionSharedPtr& requestIDExtension() override { return request_id_extension_; }
envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
Expand Down Expand Up @@ -206,6 +207,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan
NiceMock<Tcp::ConnectionPool::MockInstance> conn_pool_; // for websocket tests
RequestIDExtensionSharedPtr request_id_extension_;
const LocalReply::LocalReplyPtr local_reply_;
bool strip_trailing_host_dot_ = false;

// TODO(mattklein123): Not all tests have been converted over to better setup. Convert the rest.
NiceMock<MockResponseEncoder> response_encoder_;
Expand Down
45 changes: 45 additions & 0 deletions test/common/http/conn_manager_utility_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1480,6 +1480,51 @@ TEST_F(ConnectionManagerUtilityTest, RemovePort) {
EXPECT_EQ(header_map_none.getHostValue(), "host:9999");
}

// maybeNormalizeHost() removes trailing dot of host from host header.
TEST_F(ConnectionManagerUtilityTest, RemoveTrailingDot) {
ON_CALL(config_, shouldStripTrailingHostDot()).WillByDefault(Return(true));
TestRequestHeaderMapImpl original_headers;
original_headers.setHost("host.");

TestRequestHeaderMapImpl header_map(original_headers);
ConnectionManagerUtility::maybeNormalizeHost(header_map, config_, 0);
EXPECT_EQ(header_map.getHostValue(), "host");

ON_CALL(config_, stripPortType()).WillByDefault(Return(Http::StripPortType::None));
ON_CALL(config_, shouldStripTrailingHostDot()).WillByDefault(Return(true));
TestRequestHeaderMapImpl original_headers_with_port;
original_headers_with_port.setHost("host.:443");

TestRequestHeaderMapImpl header_map_with_port(original_headers_with_port);
ConnectionManagerUtility::maybeNormalizeHost(header_map_with_port, config_, 443);
EXPECT_EQ(header_map_with_port.getHostValue(), "host:443");

ON_CALL(config_, stripPortType()).WillByDefault(Return(Http::StripPortType::MatchingHost));
ON_CALL(config_, shouldStripTrailingHostDot()).WillByDefault(Return(true));
TestRequestHeaderMapImpl original_headers_strip_port;
original_headers_strip_port.setHost("host.:443");

TestRequestHeaderMapImpl header_map_strip_port(original_headers_strip_port);
ConnectionManagerUtility::maybeNormalizeHost(header_map_strip_port, config_, 443);
EXPECT_EQ(header_map_strip_port.getHostValue(), "host");

ON_CALL(config_, shouldStripTrailingHostDot()).WillByDefault(Return(true));
TestRequestHeaderMapImpl original_headers_no_dot;
original_headers_no_dot.setHost("host");

TestRequestHeaderMapImpl header_map_no_dot(original_headers_no_dot);
ConnectionManagerUtility::maybeNormalizeHost(header_map_no_dot, config_, 0);
EXPECT_EQ(header_map_no_dot.getHostValue(), "host");

ON_CALL(config_, shouldStripTrailingHostDot()).WillByDefault(Return(false));
TestRequestHeaderMapImpl original_headers_none;
original_headers_none.setHost("host.");

TestRequestHeaderMapImpl header_map_none(original_headers_none);
ConnectionManagerUtility::maybeNormalizeHost(header_map_none, config_, 0);
EXPECT_EQ(header_map_none.getHostValue(), "host.");
}

// test preserve_external_request_id true does not reset the passed requestId if passed
TEST_F(ConnectionManagerUtilityTest, PreserveExternalRequestId) {
connection_.stream_info_.downstream_address_provider_->setRemoteAddress(
Expand Down
Loading