diff --git a/docs/configuration/http_conn_man/route_config/route.rst b/docs/configuration/http_conn_man/route_config/route.rst index c63cb6c30684..161f418f7c0f 100644 --- a/docs/configuration/http_conn_man/route_config/route.rst +++ b/docs/configuration/http_conn_man/route_config/route.rst @@ -18,6 +18,7 @@ next (e.g., redirect, forward, rewrite, etc.). "path_redirect": "...", "prefix_rewrite": "...", "host_rewrite": "...", + "auto_host_rewrite": "...", "case_sensitive": "...", "timeout_ms": "...", "runtime": "{...}", @@ -98,6 +99,15 @@ host_rewrite *(optional, string)* Indicates that during forwarding, the host header will be swapped with this value. +.. _config_http_conn_man_route_table_route_auto_host_rewrite: + +auto_host_rewrite + *(optional, boolean)* Indicates that during forwarding, the host header will be swapped with the + hostname of the upstream host chosen by the cluster manager. This option is applicable only when + the destination cluster for a route is of type *strict_dns* or *logical_dns*. Setting this to true + with other cluster types has no effect. *auto_host_rewrite* and *host_rewrite* are mutually exclusive + options. Only one can be specified. + .. _config_http_conn_man_route_table_route_case_sensitive: case_sensitive diff --git a/docs/intro/arch_overview/http_routing.rst b/docs/intro/arch_overview/http_routing.rst index bcdccf88a98e..b5aabd93009b 100644 --- a/docs/intro/arch_overview/http_routing.rst +++ b/docs/intro/arch_overview/http_routing.rst @@ -22,7 +22,9 @@ request. The router filter supports the following features: level. * :ref:`Path `/:ref:`host ` redirection at the route level. -* :ref:`Host rewriting `. +* :ref:`Explicit host rewriting `. +* :ref:`Automatic host rewriting ` based on + the DNS name of the selected upstream host. * :ref:`Prefix rewriting `. * :ref:`Request retries ` specified either via HTTP header or via route configuration. diff --git a/include/envoy/router/router.h b/include/envoy/router/router.h index 6117ad90455b..5f1d74adb05c 100644 --- a/include/envoy/router/router.h +++ b/include/envoy/router/router.h @@ -220,6 +220,11 @@ class RouteEntry { * @return const VirtualHost& the virtual host that owns the route. */ virtual const VirtualHost& virtualHost() const PURE; + + /** + * @return bool true if the :authority header should be overwritten with the upstream hostname. + */ + virtual bool autoHostRewrite() const PURE; }; /** diff --git a/include/envoy/upstream/host_description.h b/include/envoy/upstream/host_description.h index e21d266c151c..00d73c3d5040 100644 --- a/include/envoy/upstream/host_description.h +++ b/include/envoy/upstream/host_description.h @@ -50,6 +50,12 @@ class HostDescription { */ virtual Outlier::DetectorHostSink& outlierDetector() const PURE; + /** + * @return the hostname associated with the host if any. + * Empty string "" indicates that hostname is not a DNS name. + */ + virtual const std::string& hostname() const PURE; + /** * @return the address used to connect to the host. */ diff --git a/source/common/http/async_client_impl.h b/source/common/http/async_client_impl.h index 54dd21df8e8b..eab69bcaf489 100644 --- a/source/common/http/async_client_impl.h +++ b/source/common/http/async_client_impl.h @@ -129,6 +129,7 @@ class AsyncStreamImpl : public AsyncClient::Stream, return nullptr; } const Router::VirtualHost& virtualHost() const override { return virtual_host_; } + bool autoHostRewrite() const override { return false; } static const NullRateLimitPolicy rate_limit_policy_; static const NullRetryPolicy retry_policy_; diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index 35368a0848ce..85bd0ff050c9 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -488,6 +488,7 @@ const std::string Json::Schema::ROUTE_ENTRY_CONFIGURATION_SCHEMA(R"EOF( "path_redirect" : {"type" : "string"}, "prefix_rewrite" : {"type" : "string"}, "host_rewrite" : {"type" : "string"}, + "auto_host_rewrite" : {"type" : "boolean"}, "case_sensitive" : {"type" : "boolean"}, "timeout_ms" : {"type" : "integer"}, "runtime" : { diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index 050d4214ca9f..8504c8325657 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -94,6 +94,7 @@ RouteEntryImplBase::RouteEntryImplBase(const VirtualHostImpl& vhost, const Json: : case_sensitive_(route.getBoolean("case_sensitive", true)), prefix_rewrite_(route.getString("prefix_rewrite", "")), host_rewrite_(route.getString("host_rewrite", "")), vhost_(vhost), + auto_host_rewrite_(route.getBoolean("auto_host_rewrite", false)), cluster_name_(route.getString("cluster", "")), cluster_header_name_(route.getString("cluster_header", "")), timeout_(route.getInteger("timeout_ms", DEFAULT_ROUTE_TIMEOUT_MS)), @@ -105,6 +106,12 @@ RouteEntryImplBase::RouteEntryImplBase(const VirtualHostImpl& vhost, const Json: route.validateSchema(Json::Schema::ROUTE_ENTRY_CONFIGURATION_SCHEMA); + // Route can either have a host_rewrite with fixed host header or automatic host rewrite + // based on the DNS name of the instance in the backing cluster. + if (auto_host_rewrite_ && !host_rewrite_.empty()) { + throw EnvoyException("routes cannot have both auto_host_rewrite and host_rewrite options set"); + } + bool have_weighted_clusters = route.hasObject("weighted_clusters"); bool have_cluster = !cluster_name_.empty() || !cluster_header_name_.get().empty() || have_weighted_clusters; diff --git a/source/common/router/config_impl.h b/source/common/router/config_impl.h index 77723d85f4ed..2e51dfb00758 100644 --- a/source/common/router/config_impl.h +++ b/source/common/router/config_impl.h @@ -212,6 +212,7 @@ class RouteEntryImplBase : public RouteEntry, } std::chrono::milliseconds timeout() const override { return timeout_; } const VirtualHost& virtualHost() const override { return vhost_; } + bool autoHostRewrite() const override { return auto_host_rewrite_; } // Router::RedirectEntry std::string newPath(const Http::HeaderMap& headers) const override; @@ -258,6 +259,7 @@ class RouteEntryImplBase : public RouteEntry, } const VirtualHost& virtualHost() const override { return parent_->virtualHost(); } + bool autoHostRewrite() const override { return parent_->autoHostRewrite(); } // Router::Route const RedirectEntry* redirectEntry() const override { return nullptr; } @@ -301,6 +303,7 @@ class RouteEntryImplBase : public RouteEntry, static const uint64_t DEFAULT_ROUTE_TIMEOUT_MS = 15000; const VirtualHostImpl& vhost_; + const bool auto_host_rewrite_; const std::string cluster_name_; const Http::LowerCaseString cluster_header_name_; const std::chrono::milliseconds timeout_; diff --git a/source/common/router/router.cc b/source/common/router/router.cc index 3d7607f4d659..f5f448173ae8 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -704,6 +704,10 @@ void Filter::UpstreamRequest::onPoolReady(Http::StreamEncoder& request_encoder, conn_pool_stream_handle_ = nullptr; request_encoder_ = &request_encoder; calling_encode_headers_ = true; + if (parent_.route_entry_->autoHostRewrite() && !host->hostname().empty()) { + parent_.downstream_headers_->Host()->value(host->hostname()); + } + request_encoder.encodeHeaders(*parent_.downstream_headers_, !buffered_request_body_ && encode_complete_ && !encode_trailers_); calling_encode_headers_ = false; diff --git a/source/common/upstream/logical_dns_cluster.cc b/source/common/upstream/logical_dns_cluster.cc index d5d990fb3643..60e85f2461a2 100644 --- a/source/common/upstream/logical_dns_cluster.cc +++ b/source/common/upstream/logical_dns_cluster.cc @@ -21,7 +21,7 @@ LogicalDnsCluster::LogicalDnsCluster(const Json::Object& config, Runtime::Loader } dns_url_ = hosts_json[0]->getString("url"); - Network::Utility::hostFromTcpUrl(dns_url_); + hostname_ = Network::Utility::hostFromTcpUrl(dns_url_); Network::Utility::portFromTcpUrl(dns_url_); // This must come before startResolve(), since the resolve callback relies on @@ -70,8 +70,8 @@ void LogicalDnsCluster::startResolve() { // the friendly DNS name in that output, but currently there is no way to // express a DNS name inside of an Address::Instance. For now this is OK but // we might want to do better again later. - logical_host_.reset( - new LogicalHost(info_, Network::Utility::resolveUrl("tcp://0.0.0.0:0"), *this)); + logical_host_.reset(new LogicalHost( + info_, hostname_, Network::Utility::resolveUrl("tcp://0.0.0.0:0"), *this)); HostVectorPtr new_hosts(new std::vector()); new_hosts->emplace_back(logical_host_); updateHosts(new_hosts, createHealthyHostList(*new_hosts), empty_host_lists_, diff --git a/source/common/upstream/logical_dns_cluster.h b/source/common/upstream/logical_dns_cluster.h index ffb0cdd009f5..ed1a51b7485c 100644 --- a/source/common/upstream/logical_dns_cluster.h +++ b/source/common/upstream/logical_dns_cluster.h @@ -42,9 +42,9 @@ class LogicalDnsCluster : public ClusterImplBase { private: struct LogicalHost : public HostImpl { - LogicalHost(ClusterInfoPtr cluster, Network::Address::InstancePtr address, - LogicalDnsCluster& parent) - : HostImpl(cluster, address, false, 1, ""), parent_(parent) {} + LogicalHost(ClusterInfoPtr cluster, const std::string& hostname, + Network::Address::InstancePtr address, LogicalDnsCluster& parent) + : HostImpl(cluster, hostname, address, false, 1, ""), parent_(parent) {} // Upstream::Host CreateConnectionData createConnection(Event::Dispatcher& dispatcher) const override; @@ -63,6 +63,7 @@ class LogicalDnsCluster : public ClusterImplBase { return logical_host_->outlierDetector(); } const HostStats& stats() const override { return logical_host_->stats(); } + const std::string& hostname() const override { return logical_host_->hostname(); } Network::Address::InstancePtr address() const override { return address_; } const std::string& zone() const override { return EMPTY_STRING; } @@ -88,6 +89,7 @@ class LogicalDnsCluster : public ClusterImplBase { bool initialized_; Event::TimerPtr resolve_timer_; std::string dns_url_; + std::string hostname_; Network::Address::InstancePtr current_resolved_address_; HostPtr logical_host_; Network::ActiveDnsQuery* active_dns_query_{}; diff --git a/source/common/upstream/sds.cc b/source/common/upstream/sds.cc index 3c6882db4e73..86f4bd1c694a 100644 --- a/source/common/upstream/sds.cc +++ b/source/common/upstream/sds.cc @@ -32,8 +32,8 @@ void SdsClusterImpl::parseResponse(const Http::Message& response) { } new_hosts.emplace_back( - new HostImpl(info_, Network::Address::InstancePtr{new Network::Address::Ipv4Instance( - host->getString("ip_address"), host->getInteger("port"))}, + new HostImpl(info_, "", Network::Address::InstancePtr{new Network::Address::Ipv4Instance( + host->getString("ip_address"), host->getInteger("port"))}, canary, weight, zone)); } diff --git a/source/common/upstream/upstream_impl.cc b/source/common/upstream/upstream_impl.cc index 54d53ca94907..58f3058c716c 100644 --- a/source/common/upstream/upstream_impl.cc +++ b/source/common/upstream/upstream_impl.cc @@ -267,8 +267,8 @@ StaticClusterImpl::StaticClusterImpl(const Json::Object& config, Runtime::Loader std::vector hosts_json = config.getObjectArray("hosts"); HostVectorPtr new_hosts(new std::vector()); for (Json::ObjectPtr& host : hosts_json) { - new_hosts->emplace_back(HostPtr{ - new HostImpl(info_, Network::Utility::resolveUrl(host->getString("url")), false, 1, "")}); + new_hosts->emplace_back(HostPtr{new HostImpl( + info_, "", Network::Utility::resolveUrl(host->getString("url")), false, 1, "")}); } updateHosts(new_hosts, createHealthyHostList(*new_hosts), empty_host_lists_, empty_host_lists_, @@ -420,10 +420,11 @@ void StrictDnsClusterImpl::ResolveTarget::startResolve() { // address that has port in it. We need to both support IPv6 as well as potentially // move port handling into the DNS interface itself, which would work better for // SRV. - new_hosts.emplace_back(new HostImpl( - parent_.info_, Network::Address::InstancePtr{new Network::Address::Ipv4Instance( - address->ip()->addressAsString(), port_)}, - false, 1, "")); + new_hosts.emplace_back( + new HostImpl(parent_.info_, dns_address_, + Network::Address::InstancePtr{new Network::Address::Ipv4Instance( + address->ip()->addressAsString(), port_)}, + false, 1, "")); } std::vector hosts_added; diff --git a/source/common/upstream/upstream_impl.h b/source/common/upstream/upstream_impl.h index 954d9beda40a..873c03e05192 100644 --- a/source/common/upstream/upstream_impl.h +++ b/source/common/upstream/upstream_impl.h @@ -25,9 +25,9 @@ namespace Upstream { */ class HostDescriptionImpl : virtual public HostDescription { public: - HostDescriptionImpl(ClusterInfoPtr cluster, Network::Address::InstancePtr address, bool canary, - const std::string& zone) - : cluster_(cluster), address_(address), canary_(canary), zone_(zone), + HostDescriptionImpl(ClusterInfoPtr cluster, const std::string& hostname, + Network::Address::InstancePtr address, bool canary, const std::string& zone) + : cluster_(cluster), hostname_(hostname), address_(address), canary_(canary), zone_(zone), stats_{ALL_HOST_STATS(POOL_COUNTER(stats_store_), POOL_GAUGE(stats_store_))} {} // Upstream::HostDescription @@ -41,11 +41,13 @@ class HostDescriptionImpl : virtual public HostDescription { } } const HostStats& stats() const override { return stats_; } + const std::string& hostname() const override { return hostname_; } Network::Address::InstancePtr address() const override { return address_; } const std::string& zone() const override { return zone_; } protected: ClusterInfoPtr cluster_; + const std::string hostname_; Network::Address::InstancePtr address_; const bool canary_; const std::string zone_; @@ -64,9 +66,10 @@ class HostImpl : public HostDescriptionImpl, public Host, public std::enable_shared_from_this { public: - HostImpl(ClusterInfoPtr cluster, Network::Address::InstancePtr address, bool canary, - uint32_t initial_weight, const std::string& zone) - : HostDescriptionImpl(cluster, address, canary, zone) { + HostImpl(ClusterInfoPtr cluster, const std::string& hostname, + Network::Address::InstancePtr address, bool canary, uint32_t initial_weight, + const std::string& zone) + : HostDescriptionImpl(cluster, hostname, address, canary, zone) { weight(initial_weight); } diff --git a/test/common/filter/tcp_proxy_test.cc b/test/common/filter/tcp_proxy_test.cc index e8a2e40c77e6..85b951d18d35 100644 --- a/test/common/filter/tcp_proxy_test.cc +++ b/test/common/filter/tcp_proxy_test.cc @@ -312,7 +312,7 @@ class TcpProxyTest : public testing::Test { Upstream::MockHost::MockCreateConnectionData conn_info; conn_info.connection_ = upstream_connection_; conn_info.host_.reset( - new Upstream::HostImpl(cluster_manager_.cluster_.info_, + new Upstream::HostImpl(cluster_manager_.cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")); EXPECT_CALL(cluster_manager_, tcpConnForCluster_("fake_cluster")).WillOnce(Return(conn_info)); EXPECT_CALL(*upstream_connection_, addReadFilter(_)) diff --git a/test/common/http/access_log/access_log_impl_test.cc b/test/common/http/access_log/access_log_impl_test.cc index 7fa70b58421b..43a1c7164441 100644 --- a/test/common/http/access_log/access_log_impl_test.cc +++ b/test/common/http/access_log/access_log_impl_test.cc @@ -140,7 +140,7 @@ TEST_F(AccessLogImplTest, NoFilter) { TEST_F(AccessLogImplTest, UpstreamHost) { std::shared_ptr cluster{new Upstream::MockClusterInfo()}; request_info_.upstream_host_ = std::make_shared( - cluster, Network::Utility::resolveUrl("tcp://10.0.0.5:1234"), false, ""); + cluster, "", Network::Utility::resolveUrl("tcp://10.0.0.5:1234"), false, ""); std::string json = R"EOF( { diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index 91ab88fa9cab..47bd2256e27b 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -49,7 +49,7 @@ class CodecClientTest : public testing::Test { Network::ReadFilterPtr filter_; std::shared_ptr cluster_{new NiceMock()}; Upstream::HostDescriptionPtr host_{new Upstream::HostDescriptionImpl( - cluster_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, "")}; + cluster_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, "")}; }; TEST_F(CodecClientTest, BasicHeaderOnlyResponse) { diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index 9474b4f9acff..6a20816f891b 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -30,10 +30,11 @@ namespace Http1 { class ConnPoolImplForTest : public ConnPoolImpl { public: ConnPoolImplForTest(Event::MockDispatcher& dispatcher, Upstream::ClusterInfoPtr cluster) - : ConnPoolImpl(dispatcher, Upstream::HostPtr{new Upstream::HostImpl( - cluster, Network::Utility::resolveUrl("tcp://127.0.0.1:9000"), - false, 1, "")}, - Upstream::ResourcePriority::Default), + : ConnPoolImpl( + dispatcher, + Upstream::HostPtr{new Upstream::HostImpl( + cluster, "", Network::Utility::resolveUrl("tcp://127.0.0.1:9000"), false, 1, "")}, + Upstream::ResourcePriority::Default), mock_dispatcher_(dispatcher) {} ~ConnPoolImplForTest() { diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index b24309a3d82d..e7406dd5ca6a 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -88,7 +88,7 @@ class Http2ConnPoolImplTest : public testing::Test { NiceMock dispatcher_; std::shared_ptr cluster_{new NiceMock()}; Upstream::HostPtr host_{new Upstream::HostImpl( - cluster_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}; + cluster_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}; TestConnPoolImpl pool_; std::vector test_clients_; NiceMock runtime_; diff --git a/test/common/network/filter_manager_impl_test.cc b/test/common/network/filter_manager_impl_test.cc index 089542e65bca..1397c8143eb1 100644 --- a/test/common/network/filter_manager_impl_test.cc +++ b/test/common/network/filter_manager_impl_test.cc @@ -149,7 +149,7 @@ TEST_F(NetworkFilterManagerTest, RateLimitAndTcpProxy) { Upstream::MockHost::MockCreateConnectionData conn_info; conn_info.connection_ = upstream_connection; conn_info.host_.reset(new Upstream::HostImpl( - cm.cluster_.info_, Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")); + cm.cluster_.info_, "", Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")); EXPECT_CALL(cm, tcpConnForCluster_("fake_cluster")).WillOnce(Return(conn_info)); request_callbacks->complete(RateLimit::LimitStatus::OK); diff --git a/test/common/redis/conn_pool_impl_test.cc b/test/common/redis/conn_pool_impl_test.cc index 1969f439eeea..1aa45cca263c 100644 --- a/test/common/redis/conn_pool_impl_test.cc +++ b/test/common/redis/conn_pool_impl_test.cc @@ -30,7 +30,7 @@ class RedisClientImplTest : public testing::Test, public DecoderFactory { Upstream::MockHost::MockCreateConnectionData conn_info; conn_info.connection_ = upstream_connection_; conn_info.host_.reset(new Upstream::HostImpl( - cm_.cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")); + cm_.cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")); EXPECT_CALL(cm_, tcpConnForCluster_("foo")).WillOnce(Return(conn_info)); EXPECT_CALL(*upstream_connection_, addReadFilter(_)) .WillOnce(SaveArg<0>(&upstream_read_filter_)); diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index 6fdafe800f8d..4fc5cfa6d41a 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -412,6 +412,32 @@ TEST(RouteMatcherTest, Priority) { } } +TEST(RouteMatcherTest, NoHostRewriteAndAutoRewrite) { + std::string json = R"EOF( +{ + "virtual_hosts": [ + { + "name": "local_service", + "domains": ["*"], + "routes": [ + { + "prefix": "/", + "cluster": "local_service", + "host_rewrite": "foo", + "auto_host_rewrite" : true + } + ] + } + ] +} + )EOF"; + + Json::ObjectPtr loader = Json::Factory::LoadFromString(json); + NiceMock runtime; + NiceMock cm; + EXPECT_THROW(ConfigImpl(*loader, runtime, cm, true), EnvoyException); +} + TEST(RouteMatcherTest, HeaderMatchedRouting) { std::string json = R"EOF( { diff --git a/test/common/router/router_test.cc b/test/common/router/router_test.cc index 957db091c456..67288dee7976 100644 --- a/test/common/router/router_test.cc +++ b/test/common/router/router_test.cc @@ -951,4 +951,75 @@ TEST_F(RouterTest, CanaryStatusFalse) { EXPECT_EQ(0U, cm_.cluster_.info_->stats_store_.counter("canary.upstream_rq_200").value()); } +TEST_F(RouterTest, AutoHostRewriteEnabled) { + NiceMock encoder; + std::string req_host{"foo.bar.com"}; + + Http::TestHeaderMapImpl incoming_headers; + HttpTestUtility::addDefaultHeaders(incoming_headers); + incoming_headers.Host()->value(req_host); + + cm_.conn_pool_.host_->hostname_ = "scooby.doo"; + Http::TestHeaderMapImpl outgoing_headers; + HttpTestUtility::addDefaultHeaders(outgoing_headers); + outgoing_headers.Host()->value(cm_.conn_pool_.host_->hostname_); + + EXPECT_CALL(callbacks_.route_->route_entry_, timeout()) + .WillOnce(Return(std::chrono::milliseconds(0))); + + EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) + .WillOnce(Invoke([&](Http::StreamDecoder&, Http::ConnectionPool::Callbacks& callbacks) + -> Http::ConnectionPool::Cancellable* { + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_); + return nullptr; + })); + + // :authority header in the outgoing request should match the DNS name of + // the selected upstream host + EXPECT_CALL(encoder, encodeHeaders(HeaderMapEqualRef(&outgoing_headers), true)) + .WillOnce(Invoke([&](const Http::HeaderMap&, bool) -> void { + encoder.stream_.resetStream(Http::StreamResetReason::RemoteReset); + })); + + EXPECT_CALL(callbacks_.request_info_, onUpstreamHostSelected(_)) + .WillOnce(Invoke([&](const Upstream::HostDescriptionPtr host) + -> void { EXPECT_EQ(host_address_, host->address()); })); + EXPECT_CALL(callbacks_.route_->route_entry_, autoHostRewrite()).WillOnce(Return(true)); + router_.decodeHeaders(incoming_headers, true); +} + +TEST_F(RouterTest, AutoHostRewriteDisabled) { + NiceMock encoder; + std::string req_host{"foo.bar.com"}; + + Http::TestHeaderMapImpl incoming_headers; + HttpTestUtility::addDefaultHeaders(incoming_headers); + incoming_headers.Host()->value(req_host); + + cm_.conn_pool_.host_->hostname_ = "scooby.doo"; + + EXPECT_CALL(callbacks_.route_->route_entry_, timeout()) + .WillOnce(Return(std::chrono::milliseconds(0))); + + EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) + .WillOnce(Invoke([&](Http::StreamDecoder&, Http::ConnectionPool::Callbacks& callbacks) + -> Http::ConnectionPool::Cancellable* { + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_); + return nullptr; + })); + + // :authority header in the outgoing request should match the :authority header of + // the incoming request + EXPECT_CALL(encoder, encodeHeaders(HeaderMapEqualRef(&incoming_headers), true)) + .WillOnce(Invoke([&](const Http::HeaderMap&, bool) -> void { + encoder.stream_.resetStream(Http::StreamResetReason::RemoteReset); + })); + + EXPECT_CALL(callbacks_.request_info_, onUpstreamHostSelected(_)) + .WillOnce(Invoke([&](const Upstream::HostDescriptionPtr host) + -> void { EXPECT_EQ(host_address_, host->address()); })); + EXPECT_CALL(callbacks_.route_->route_entry_, autoHostRewrite()).WillOnce(Return(false)); + router_.decodeHeaders(incoming_headers, true); +} + } // Router diff --git a/test/common/stats/statsd_test.cc b/test/common/stats/statsd_test.cc index 6b40109aa0df..97f2bad4879b 100644 --- a/test/common/stats/statsd_test.cc +++ b/test/common/stats/statsd_test.cc @@ -33,7 +33,7 @@ TEST_F(TcpStatsdSinkTest, All) { Upstream::MockHost::MockCreateConnectionData conn_info; conn_info.connection_ = connection; conn_info.host_.reset( - new Upstream::HostImpl(Upstream::ClusterInfoPtr{new Upstream::MockClusterInfo}, + new Upstream::HostImpl(Upstream::ClusterInfoPtr{new Upstream::MockClusterInfo}, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")); EXPECT_CALL(cluster_manager_, tcpConnForCluster_("statsd")).WillOnce(Return(conn_info)); diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index 9f9e281de4d6..cb1d6df09107 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -505,7 +505,7 @@ TEST_F(ClusterManagerImplTest, DynamicAddRemove) { loader_api = Json::Factory::LoadFromString(json_api_3); MockCluster* cluster2 = new NiceMock(); cluster2->hosts_ = {HostPtr{new HostImpl( - cluster2->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster2->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(factory_, clusterFromJson_(_, _, _, _)).WillOnce(Return(cluster2)); EXPECT_CALL(*cluster2, initializePhase()).Times(0); EXPECT_CALL(*cluster2, initialize()); diff --git a/test/common/upstream/health_checker_impl_test.cc b/test/common/upstream/health_checker_impl_test.cc index 965d7d20526f..5a0197b78059 100644 --- a/test/common/upstream/health_checker_impl_test.cc +++ b/test/common/upstream/health_checker_impl_test.cc @@ -162,7 +162,7 @@ TEST_F(HttpHealthCheckerImplTest, Success) { EXPECT_CALL(*this, onHostStatus(_, false)).Times(1); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->info_->stats().upstream_cx_total_.inc(); expectSessionCreate(); expectStreamCreate(0); @@ -184,7 +184,7 @@ TEST_F(HttpHealthCheckerImplTest, SuccessServiceCheck) { EXPECT_CALL(*this, onHostStatus(_, false)).Times(1); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->info_->stats().upstream_cx_total_.inc(); expectSessionCreate(); expectStreamCreate(0); @@ -207,7 +207,7 @@ TEST_F(HttpHealthCheckerImplTest, ServiceDoesNotMatchFail) { EXPECT_CALL(*this, onHostStatus(_, true)).Times(1); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->info_->stats().upstream_cx_total_.inc(); expectSessionCreate(); expectStreamCreate(0); @@ -231,7 +231,7 @@ TEST_F(HttpHealthCheckerImplTest, ServiceNotPresentInResponseFail) { EXPECT_CALL(*this, onHostStatus(_, true)).Times(1); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->info_->stats().upstream_cx_total_.inc(); expectSessionCreate(); expectStreamCreate(0); @@ -254,7 +254,7 @@ TEST_F(HttpHealthCheckerImplTest, ServiceCheckRuntimeOff) { EXPECT_CALL(*this, onHostStatus(_, false)).Times(1); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->info_->stats().upstream_cx_total_.inc(); expectSessionCreate(); expectStreamCreate(0); @@ -274,7 +274,7 @@ TEST_F(HttpHealthCheckerImplTest, SuccessStartFailedFailFirstServiceCheck) { EXPECT_CALL(runtime_.snapshot_, featureEnabled("health_check.verify_cluster", 100)) .WillRepeatedly(Return(true)); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->hosts_[0]->healthFlagSet(Host::HealthFlag::FAILED_ACTIVE_HC); expectSessionCreate(); expectStreamCreate(0); @@ -306,7 +306,7 @@ TEST_F(HttpHealthCheckerImplTest, SuccessNoTraffic) { EXPECT_CALL(*this, onHostStatus(_, false)).Times(1); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; expectSessionCreate(); expectStreamCreate(0); health_checker_->start(); @@ -319,7 +319,7 @@ TEST_F(HttpHealthCheckerImplTest, SuccessNoTraffic) { TEST_F(HttpHealthCheckerImplTest, SuccessStartFailedSuccessFirst) { setupNoServiceValidationHC(); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->hosts_[0]->healthFlagSet(Host::HealthFlag::FAILED_ACTIVE_HC); expectSessionCreate(); expectStreamCreate(0); @@ -337,7 +337,7 @@ TEST_F(HttpHealthCheckerImplTest, SuccessStartFailedSuccessFirst) { TEST_F(HttpHealthCheckerImplTest, SuccessStartFailedFailFirst) { setupNoServiceValidationHC(); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->hosts_[0]->healthFlagSet(Host::HealthFlag::FAILED_ACTIVE_HC); expectSessionCreate(); expectStreamCreate(0); @@ -366,7 +366,7 @@ TEST_F(HttpHealthCheckerImplTest, SuccessStartFailedFailFirst) { TEST_F(HttpHealthCheckerImplTest, HttpFail) { setupNoServiceValidationHC(); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; expectSessionCreate(); expectStreamCreate(0); health_checker_->start(); @@ -395,7 +395,7 @@ TEST_F(HttpHealthCheckerImplTest, Disconnect) { EXPECT_CALL(*this, onHostStatus(_, false)).Times(1); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; expectSessionCreate(); expectStreamCreate(0); health_checker_->start(); @@ -416,7 +416,7 @@ TEST_F(HttpHealthCheckerImplTest, Disconnect) { TEST_F(HttpHealthCheckerImplTest, Timeout) { setupNoServiceValidationHC(); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; expectSessionCreate(); expectStreamCreate(0); health_checker_->start(); @@ -443,7 +443,7 @@ TEST_F(HttpHealthCheckerImplTest, DynamicAddAndRemove) { expectSessionCreate(); expectStreamCreate(0); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->runCallbacks({cluster_->hosts_.back()}, {}); std::vector removed{cluster_->hosts_.back()}; @@ -457,7 +457,7 @@ TEST_F(HttpHealthCheckerImplTest, ConnectionClose) { EXPECT_CALL(*this, onHostStatus(_, false)); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; expectSessionCreate(); expectStreamCreate(0); health_checker_->start(); @@ -476,7 +476,7 @@ TEST_F(HttpHealthCheckerImplTest, RemoteCloseBetweenChecks) { EXPECT_CALL(*this, onHostStatus(_, false)).Times(2); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; expectSessionCreate(); expectStreamCreate(0); health_checker_->start(); @@ -628,7 +628,7 @@ class TcpHealthCheckerImplTest : public testing::Test { TEST_F(TcpHealthCheckerImplTest, Success) { cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; expectSessionCreate(); expectClientCreate(); health_checker_->start(); @@ -646,7 +646,7 @@ TEST_F(TcpHealthCheckerImplTest, Timeout) { expectSessionCreate(); expectClientCreate(); cluster_->hosts_ = {HostPtr{new HostImpl( - cluster_->info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_->info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; cluster_->runCallbacks({cluster_->hosts_.back()}, {}); Buffer::OwnedImpl response; diff --git a/test/common/upstream/host_utility_test.cc b/test/common/upstream/host_utility_test.cc index 29506f67a70e..b8cc48691858 100644 --- a/test/common/upstream/host_utility_test.cc +++ b/test/common/upstream/host_utility_test.cc @@ -8,7 +8,7 @@ namespace Upstream { TEST(HostUtilityTest, All) { ClusterInfoPtr cluster{new MockClusterInfo()}; - HostImpl host(cluster, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, ""); + HostImpl host(cluster, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, ""); EXPECT_EQ("healthy", HostUtility::healthFlagsToString(host)); host.healthFlagSet(Host::HealthFlag::FAILED_ACTIVE_HC); diff --git a/test/common/upstream/load_balancer_impl_test.cc b/test/common/upstream/load_balancer_impl_test.cc index 656c582482d7..9745e98ace79 100644 --- a/test/common/upstream/load_balancer_impl_test.cc +++ b/test/common/upstream/load_balancer_impl_test.cc @@ -12,7 +12,7 @@ namespace Upstream { static HostPtr newTestHost(Upstream::ClusterInfoPtr cluster, const std::string& url, uint32_t weight = 1) { - return HostPtr{new HostImpl(cluster, Network::Utility::resolveUrl(url), false, weight, "")}; + return HostPtr{new HostImpl(cluster, "", Network::Utility::resolveUrl(url), false, weight, "")}; } class RoundRobinLoadBalancerTest : public testing::Test { diff --git a/test/common/upstream/load_balancer_simulation_test.cc b/test/common/upstream/load_balancer_simulation_test.cc index cf4c649451c4..91b3105f0789 100644 --- a/test/common/upstream/load_balancer_simulation_test.cc +++ b/test/common/upstream/load_balancer_simulation_test.cc @@ -13,7 +13,7 @@ namespace Upstream { static HostPtr newTestHost(Upstream::ClusterInfoPtr cluster, const std::string& url, uint32_t weight = 1, const std::string& zone = "") { - return HostPtr{new HostImpl(cluster, Network::Utility::resolveUrl(url), false, weight, zone)}; + return HostPtr{new HostImpl(cluster, "", Network::Utility::resolveUrl(url), false, weight, zone)}; } /** @@ -178,4 +178,4 @@ TEST_F(DISABLED_SimulationTest, unequalZoneDistribution6) { run({3U, 2U, 5U}, {3U, 4U, 5U}, {3U, 4U, 5U}); } -} // Upstream \ No newline at end of file +} // Upstream diff --git a/test/common/upstream/logical_dns_cluster_test.cc b/test/common/upstream/logical_dns_cluster_test.cc index 219375d647b5..a90d62e79364 100644 --- a/test/common/upstream/logical_dns_cluster_test.cc +++ b/test/common/upstream/logical_dns_cluster_test.cc @@ -88,6 +88,7 @@ TEST_F(LogicalDnsClusterTest, ImmediateResolve) { setup(json); EXPECT_EQ(1UL, cluster_->hosts().size()); EXPECT_EQ(1UL, cluster_->healthyHosts().size()); + EXPECT_EQ("foo.bar.com", cluster_->hosts()[0]->hostname()); tls_.shutdownThread(); } diff --git a/test/common/upstream/outlier_detection_impl_test.cc b/test/common/upstream/outlier_detection_impl_test.cc index 16b75ca30524..940bf5b62edf 100644 --- a/test/common/upstream/outlier_detection_impl_test.cc +++ b/test/common/upstream/outlier_detection_impl_test.cc @@ -67,7 +67,7 @@ class OutlierDetectorImplTest : public testing::Test { TEST_F(OutlierDetectorImplTest, DestroyWithActive) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = {HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( DetectorImpl::create(cluster_, dispatcher_, runtime_, time_source_, event_logger_)); @@ -97,7 +97,7 @@ TEST_F(OutlierDetectorImplTest, DestroyWithActive) { TEST_F(OutlierDetectorImplTest, DestroyHostInUse) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = {HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( DetectorImpl::create(cluster_, dispatcher_, runtime_, time_source_, event_logger_)); @@ -115,14 +115,14 @@ TEST_F(OutlierDetectorImplTest, DestroyHostInUse) { TEST_F(OutlierDetectorImplTest, BasicFlow) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = {HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( DetectorImpl::create(cluster_, dispatcher_, runtime_, time_source_, event_logger_)); detector->addChangedStateCb([&](HostPtr host) -> void { checker_.check(host); }); cluster_.hosts_.push_back(HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:81"), false, 1, "")}); + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:81"), false, 1, "")}); cluster_.runCallbacks({cluster_.hosts_[1]}, {}); // Cause a consecutive 5xx error. @@ -172,7 +172,7 @@ TEST_F(OutlierDetectorImplTest, BasicFlow) { TEST_F(OutlierDetectorImplTest, RemoveWhileEjected) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = {HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( DetectorImpl::create(cluster_, dispatcher_, runtime_, time_source_, event_logger_)); @@ -208,9 +208,9 @@ TEST_F(OutlierDetectorImplTest, RemoveWhileEjected) { TEST_F(OutlierDetectorImplTest, Overflow) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = { - HostPtr{new HostImpl(cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), + HostPtr{new HostImpl(cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}, - HostPtr{new HostImpl(cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:81"), + HostPtr{new HostImpl(cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:81"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( @@ -249,7 +249,7 @@ TEST_F(OutlierDetectorImplTest, Overflow) { TEST_F(OutlierDetectorImplTest, NotEnforcing) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = {HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( DetectorImpl::create(cluster_, dispatcher_, runtime_, time_source_, event_logger_)); @@ -274,7 +274,7 @@ TEST_F(OutlierDetectorImplTest, NotEnforcing) { TEST_F(OutlierDetectorImplTest, CrossThreadRemoveRace) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = {HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( DetectorImpl::create(cluster_, dispatcher_, runtime_, time_source_, event_logger_)); @@ -300,7 +300,7 @@ TEST_F(OutlierDetectorImplTest, CrossThreadRemoveRace) { TEST_F(OutlierDetectorImplTest, CrossThreadDestroyRace) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = {HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( DetectorImpl::create(cluster_, dispatcher_, runtime_, time_source_, event_logger_)); @@ -327,7 +327,7 @@ TEST_F(OutlierDetectorImplTest, CrossThreadDestroyRace) { TEST_F(OutlierDetectorImplTest, CrossThreadFailRace) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = {HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( DetectorImpl::create(cluster_, dispatcher_, runtime_, time_source_, event_logger_)); @@ -360,7 +360,7 @@ TEST_F(OutlierDetectorImplTest, CrossThreadFailRace) { TEST_F(OutlierDetectorImplTest, Consecutive5xxAlreadyEjected) { EXPECT_CALL(cluster_, addMemberUpdateCb(_)); cluster_.hosts_ = {HostPtr{new HostImpl( - cluster_.info_, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; + cluster_.info_, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, 1, "")}}; EXPECT_CALL(*interval_timer_, enableTimer(std::chrono::milliseconds(10000))); std::shared_ptr detector( DetectorImpl::create(cluster_, dispatcher_, runtime_, time_source_, event_logger_)); diff --git a/test/common/upstream/ring_hash_lb_test.cc b/test/common/upstream/ring_hash_lb_test.cc index 4add05932eec..7726bd10bf99 100644 --- a/test/common/upstream/ring_hash_lb_test.cc +++ b/test/common/upstream/ring_hash_lb_test.cc @@ -12,7 +12,7 @@ using testing::Return; namespace Upstream { static HostPtr newTestHost(Upstream::ClusterInfoPtr cluster, const std::string& url) { - return HostPtr{new HostImpl(cluster, Network::Utility::resolveUrl(url), false, 1, "")}; + return HostPtr{new HostImpl(cluster, "", Network::Utility::resolveUrl(url), false, 1, "")}; } class TestLoadBalancerContext : public LoadBalancerContext { diff --git a/test/common/upstream/sds_test.cc b/test/common/upstream/sds_test.cc index 4a7197979312..da861bd4738d 100644 --- a/test/common/upstream/sds_test.cc +++ b/test/common/upstream/sds_test.cc @@ -134,6 +134,9 @@ TEST_F(SdsTest, NoHealthChecker) { EXPECT_EQ(5UL, cluster_->healthyHostsPerZone()[1].size()); EXPECT_EQ(4UL, cluster_->healthyHostsPerZone()[2].size()); + // Hosts in SDS and static clusters should have empty hostname + EXPECT_EQ("", cluster_->hosts()[0]->hostname()); + HostPtr canary_host = findHost("10.0.16.43"); EXPECT_TRUE(canary_host->canary()); EXPECT_EQ("us-east-1d", canary_host->zone()); diff --git a/test/common/upstream/upstream_impl_test.cc b/test/common/upstream/upstream_impl_test.cc index b1cfdabade88..56a58baefb82 100644 --- a/test/common/upstream/upstream_impl_test.cc +++ b/test/common/upstream/upstream_impl_test.cc @@ -117,7 +117,7 @@ TEST(StrictDnsClusterImplTest, Basic) { }, "max_requests_per_connection": 3, "http_codec_options": "no_compression", - "hosts": [{"url": "tcp://localhost:11001"}, + "hosts": [{"url": "tcp://localhost1:11001"}, {"url": "tcp://localhost2:11002"}] } )EOF"; @@ -153,6 +153,8 @@ TEST(StrictDnsClusterImplTest, Basic) { resolver1.dns_callback_(TestUtility::makeDnsResponse({"127.0.0.1", "127.0.0.2"})); EXPECT_THAT(std::list({"127.0.0.1:11001", "127.0.0.2:11001"}), ContainerEq(hostListToAddresses(cluster.hosts()))); + EXPECT_EQ("localhost1", cluster.hosts()[0]->hostname()); + EXPECT_EQ("localhost1", cluster.hosts()[1]->hostname()); resolver1.expectResolve(dns_resolver); resolver1.timer_->callback_(); @@ -202,8 +204,10 @@ TEST(StrictDnsClusterImplTest, Basic) { TEST(HostImplTest, HostCluster) { MockCluster cluster; - HostImpl host(cluster.info_, Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), false, 1, ""); + HostImpl host(cluster.info_, "", Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), false, 1, + ""); EXPECT_EQ(cluster.info_.get(), &host.cluster()); + EXPECT_EQ("", host.hostname()); EXPECT_FALSE(host.canary()); EXPECT_EQ("", host.zone()); } @@ -212,18 +216,19 @@ TEST(HostImplTest, Weight) { MockCluster cluster; { - HostImpl host(cluster.info_, Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), false, 0, ""); + HostImpl host(cluster.info_, "", Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), false, 0, + ""); EXPECT_EQ(1U, host.weight()); } { - HostImpl host(cluster.info_, Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), false, 101, - ""); + HostImpl host(cluster.info_, "", Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), false, + 101, ""); EXPECT_EQ(100U, host.weight()); } { - HostImpl host(cluster.info_, Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), false, 50, + HostImpl host(cluster.info_, "", Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), false, 50, ""); EXPECT_EQ(50U, host.weight()); host.weight(51); @@ -235,15 +240,36 @@ TEST(HostImplTest, Weight) { } } -TEST(HostImplTest, CanaryAndZone) { +TEST(HostImplTest, HostameCanaryAndZone) { MockCluster cluster; - HostImpl host(cluster.info_, Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), true, 1, - "hello"); + HostImpl host(cluster.info_, "lyft.com", Network::Utility::resolveUrl("tcp://10.0.0.1:1234"), + true, 1, "hello"); EXPECT_EQ(cluster.info_.get(), &host.cluster()); + EXPECT_EQ("lyft.com", host.hostname()); EXPECT_TRUE(host.canary()); EXPECT_EQ("hello", host.zone()); } +TEST(StaticClusterImplTest, EmptyHostname) { + Stats::IsolatedStoreImpl stats; + Ssl::MockContextManager ssl_context_manager; + NiceMock runtime; + std::string json = R"EOF( + { + "name": "staticcluster", + "connect_timeout_ms": 250, + "type": "static", + "lb_type": "random", + "hosts": [{"url": "tcp://10.0.0.1:11001"}] + } + )EOF"; + + Json::ObjectPtr config = Json::Factory::LoadFromString(json); + StaticClusterImpl cluster(*config, runtime, stats, ssl_context_manager); + EXPECT_EQ(1UL, cluster.healthyHosts().size()); + EXPECT_EQ("", cluster.hosts()[0]->hostname()); +} + TEST(StaticClusterImplTest, OutlierDetector) { Stats::IsolatedStoreImpl stats; Ssl::MockContextManager ssl_context_manager; diff --git a/test/integration/integration.cc b/test/integration/integration.cc index 2e2590e27ee0..e4d8416e8cdd 100644 --- a/test/integration/integration.cc +++ b/test/integration/integration.cc @@ -238,7 +238,7 @@ BaseIntegrationTest::makeHttpConnection(Network::ClientConnectionPtr&& conn, Http::CodecClient::Type type) { std::shared_ptr cluster{new NiceMock()}; Upstream::HostDescriptionPtr host_description{new Upstream::HostDescriptionImpl( - cluster, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, "")}; + cluster, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, "")}; return IntegrationCodecClientPtr{ new IntegrationCodecClient(*dispatcher_, std::move(conn), host_description, type)}; } diff --git a/test/integration/utility.cc b/test/integration/utility.cc index bb11e8c54a2b..fc88eb8a059b 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -49,7 +49,7 @@ IntegrationUtil::makeSingleRequest(uint32_t port, const std::string& method, con Event::DispatcherPtr dispatcher(api.allocateDispatcher()); std::shared_ptr cluster{new NiceMock()}; Upstream::HostDescriptionPtr host_description{new Upstream::HostDescriptionImpl( - cluster, Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, "")}; + cluster, "", Network::Utility::resolveUrl("tcp://127.0.0.1:80"), false, "")}; Http::CodecClientProd client(type, dispatcher->createClientConnection(Network::Utility::resolveUrl( fmt::format("tcp://127.0.0.1:{}", port))), diff --git a/test/mocks/router/mocks.h b/test/mocks/router/mocks.h index de94ee72c6d7..24c61d2b441f 100644 --- a/test/mocks/router/mocks.h +++ b/test/mocks/router/mocks.h @@ -147,6 +147,7 @@ class MockRouteEntry : public RouteEntry { MOCK_CONST_METHOD1(virtualCluster, const VirtualCluster*(const Http::HeaderMap& headers)); MOCK_CONST_METHOD0(virtualHostName, const std::string&()); MOCK_CONST_METHOD0(virtualHost, const VirtualHost&()); + MOCK_CONST_METHOD0(autoHostRewrite, bool()); std::string cluster_name_{"fake_cluster"}; TestVirtualCluster virtual_cluster_; diff --git a/test/mocks/upstream/host.h b/test/mocks/upstream/host.h index ae50367c0723..d43586977d9b 100644 --- a/test/mocks/upstream/host.h +++ b/test/mocks/upstream/host.h @@ -56,10 +56,12 @@ class MockHostDescription : public HostDescription { MOCK_CONST_METHOD0(canary, bool()); MOCK_CONST_METHOD0(cluster, const ClusterInfo&()); MOCK_CONST_METHOD0(outlierDetector, Outlier::DetectorHostSink&()); + MOCK_CONST_METHOD0(hostname, const std::string&()); MOCK_CONST_METHOD0(address, Network::Address::InstancePtr()); MOCK_CONST_METHOD0(stats, HostStats&()); MOCK_CONST_METHOD0(zone, const std::string&()); + std::string hostname_; Network::Address::InstancePtr address_; testing::NiceMock outlier_detector_; testing::NiceMock cluster_; diff --git a/test/mocks/upstream/mocks.cc b/test/mocks/upstream/mocks.cc index 708a019d46bd..773ab7fe70c7 100644 --- a/test/mocks/upstream/mocks.cc +++ b/test/mocks/upstream/mocks.cc @@ -32,6 +32,7 @@ MockDetector::~MockDetector() {} MockHostDescription::MockHostDescription() : address_(Network::Utility::resolveUrl("tcp://10.0.0.1:443")) { + ON_CALL(*this, hostname()).WillByDefault(ReturnRef(hostname_)); ON_CALL(*this, address()).WillByDefault(Return(address_)); ON_CALL(*this, outlierDetector()).WillByDefault(ReturnRef(outlier_detector_)); ON_CALL(*this, stats()).WillByDefault(ReturnRef(stats_));