Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0e55b36
Makes the http connection manager reject requests w/ invalid header v…
dcarney Jun 11, 2019
aabe8ea
Fixes tests; making them use new absl::string_view type
dcarney Jun 18, 2019
42f264b
Fixes test to use absl::string_view
dcarney Jun 18, 2019
5f50baa
Makes HTTP header validation opt-in behavior
dcarney Jun 18, 2019
1515e9e
Eliminates the creation of a temporary std::string obj
dcarney Jun 18, 2019
e3d03fe
Uses plain boolean over proto-wrapped boolean type for config property
dcarney Jun 18, 2019
ab06539
Fixes reference in doc string for HTTP connection manager proto.
dcarney Jun 18, 2019
b9015ef
Fixes mock obj for HTTP conn manager utility tests
dcarney Jun 18, 2019
e073771
Adds overrides for new validateHeaders() method in fuzz test
dcarney Jun 18, 2019
dad83f1
http conn manager: reverts HTTP header checking changes, based on PR …
dcarney Jun 25, 2019
a989177
header utility: replaces header validation func with one that operate…
dcarney Jun 25, 2019
73f0d7d
HTTP 1.1 codec: adds runtime-guarded header value validation
dcarney Jun 25, 2019
c2cb387
Adds test coverage for HTTP 1.1 codec header validation
dcarney Jun 25, 2019
52bb48c
Updates version history from latest master, mentions runtime guard st…
dcarney Jun 25, 2019
ba0bc86
Updates version history to show only the diff for this PR
dcarney Jun 25, 2019
393a161
Removes response code const
dcarney Jun 25, 2019
88b3d22
Adds HTTP/1.1 codec c-tor overloads that take header validation as an…
dcarney Jun 26, 2019
0718d58
Incorporates latest upstream changes to the runtime loader
dcarney Jul 9, 2019
16bcc99
Incorporates PR feedback
dcarney Jul 9, 2019
65c35df
Fixes version_history after latest master rebase
dcarney Jul 10, 2019
ce5982b
Fixes CI test failure, for codec test that passes locally
dcarney Jul 10, 2019
2873206
s/validate_header_values/strict_header_validation/
dcarney Jul 11, 2019
c0126ea
Moves release note to 1.12.0
dcarney Jul 11, 2019
2b3bb2c
Adds a TODO for @alyssawilk, per our Envoy Slack convo
dcarney Jul 11, 2019
8cd3776
Moves runtime value check to the proper codec creation block
dcarney Jul 15, 2019
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
1 change: 1 addition & 0 deletions docs/root/intro/version_history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Version history

1.12.0 (pending)
================
* http: added the ability to reject HTTP/1.1 requests with invalid HTTP header values, using the runtime feature `envoy.reloadable_features.strict_header_validation`.

1.11.0 (July 11, 2019)
======================
Expand Down
4 changes: 4 additions & 0 deletions source/common/http/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ envoy_cc_library(
":conn_manager_config_interface",
":exception_lib",
":header_map_lib",
":header_utility_lib",
":headers_lib",
":path_utility_lib",
":user_agent_lib",
Expand Down Expand Up @@ -313,6 +314,9 @@ envoy_cc_library(
name = "header_utility_lib",
srcs = ["header_utility.cc"],
hdrs = ["header_utility.h"],
external_deps = [
"nghttp2",
],
deps = [
"//include/envoy/http:header_map_interface",
"//include/envoy/json:json_object_interface",
Expand Down
5 changes: 3 additions & 2 deletions source/common/http/codec_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,12 @@ void CodecClient::onData(Buffer::Instance& data) {

CodecClientProd::CodecClientProd(Type type, Network::ClientConnectionPtr&& connection,
Upstream::HostDescriptionConstSharedPtr host,
Event::Dispatcher& dispatcher)
Event::Dispatcher& dispatcher, bool strict_header_validation)
: CodecClient(type, std::move(connection), host, dispatcher) {
switch (type) {
case Type::HTTP1: {
codec_ = std::make_unique<Http1::ClientConnectionImpl>(*connection_, *this);
codec_ = std::make_unique<Http1::ClientConnectionImpl>(*connection_, *this,
strict_header_validation);
break;
}
case Type::HTTP2: {
Expand Down
3 changes: 2 additions & 1 deletion source/common/http/codec_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ using CodecClientPtr = std::unique_ptr<CodecClient>;
class CodecClientProd : public CodecClient {
public:
CodecClientProd(Type type, Network::ClientConnectionPtr&& connection,
Upstream::HostDescriptionConstSharedPtr host, Event::Dispatcher& dispatcher);
Upstream::HostDescriptionConstSharedPtr host, Event::Dispatcher& dispatcher,
bool strict_header_validation);
};

} // namespace Http
Expand Down
6 changes: 5 additions & 1 deletion source/common/http/conn_manager_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,15 @@ class ConnectionManagerConfig {
* @param connection supplies the owning connection.
* @param data supplies the currently available read data.
* @param callbacks supplies the callbacks to install into the codec.
* @param strict_header_validation indicates whether or not the codec should validate the values
* of each HTTP header (NOTE: this argument only affects the H/1.1 codec; the H/2 codec always
* does this)
* @return a codec or nullptr if no codec can be created.
*/
virtual ServerConnectionPtr createCodec(Network::Connection& connection,
const Buffer::Instance& data,
ServerConnectionCallbacks& callbacks) PURE;
ServerConnectionCallbacks& callbacks,
const bool strict_header_validation) PURE;

/**
* @return DateProvider& the date provider to use for
Expand Down
7 changes: 5 additions & 2 deletions source/common/http/conn_manager_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "common/http/path_utility.h"
#include "common/http/utility.h"
#include "common/network/utility.h"
#include "common/runtime/runtime_impl.h"

#include "absl/strings/escaping.h"
#include "absl/strings/match.h"
Expand Down Expand Up @@ -111,7 +112,8 @@ ConnectionManagerImpl::ConnectionManagerImpl(ConnectionManagerConfig& config,
overload_manager ? overload_manager->getThreadLocalOverloadState().getState(
Server::OverloadActionNames::get().DisableHttpKeepAlive)
: Server::OverloadManager::getInactiveState()),
time_source_(time_source) {}
time_source_(time_source), strict_header_validation_(Runtime::runtimeFeatureEnabled(
"envoy.reloadable_features.strict_header_validation")) {}

const HeaderMapImpl& ConnectionManagerImpl::continueHeader() {
CONSTRUCT_ON_FIRST_USE(HeaderMapImpl,
Expand Down Expand Up @@ -259,7 +261,8 @@ StreamDecoder& ConnectionManagerImpl::newStream(StreamEncoder& response_encoder,

Network::FilterStatus ConnectionManagerImpl::onData(Buffer::Instance& data, bool) {
if (!codec_) {
codec_ = config_.createCodec(read_callbacks_->connection(), data, *this);
codec_ =
config_.createCodec(read_callbacks_->connection(), data, *this, strict_header_validation_);
if (codec_->protocol() == Protocol::Http2) {
stats_.named_.downstream_cx_http2_total_.inc();
stats_.named_.downstream_cx_http2_active_.inc();
Expand Down
2 changes: 2 additions & 0 deletions source/common/http/conn_manager_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,8 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
const Server::OverloadActionState& overload_stop_accepting_requests_ref_;
const Server::OverloadActionState& overload_disable_keepalive_ref_;
TimeSource& time_source_;

const bool strict_header_validation_;
};

} // namespace Http
Expand Down
7 changes: 4 additions & 3 deletions source/common/http/conn_manager_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ std::string ConnectionManagerUtility::determineNextProtocol(Network::Connection&
ServerConnectionPtr ConnectionManagerUtility::autoCreateCodec(
Network::Connection& connection, const Buffer::Instance& data,
ServerConnectionCallbacks& callbacks, Stats::Scope& scope, const Http1Settings& http1_settings,
const Http2Settings& http2_settings, const uint32_t max_request_headers_kb) {
const Http2Settings& http2_settings, const uint32_t max_request_headers_kb,
bool strict_header_validation) {
if (determineNextProtocol(connection, data) == Http2::ALPN_STRING) {
return std::make_unique<Http2::ServerConnectionImpl>(connection, callbacks, scope,
http2_settings, max_request_headers_kb);
} else {
return std::make_unique<Http1::ServerConnectionImpl>(connection, callbacks, http1_settings,
max_request_headers_kb);
return std::make_unique<Http1::ServerConnectionImpl>(
connection, callbacks, http1_settings, max_request_headers_kb, strict_header_validation);
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/common/http/conn_manager_utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ConnectionManagerUtility {
autoCreateCodec(Network::Connection& connection, const Buffer::Instance& data,
ServerConnectionCallbacks& callbacks, Stats::Scope& scope,
const Http1Settings& http1_settings, const Http2Settings& http2_settings,
const uint32_t max_request_headers_kb);
const uint32_t max_request_headers_kb, bool strict_header_validation);

/**
* Mutates request headers in various ways. This functionality is broken out because of its
Expand Down
6 changes: 6 additions & 0 deletions source/common/http/header_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "common/protobuf/utility.h"

#include "absl/strings/match.h"
#include "nghttp2/nghttp2.h"

namespace Envoy {
namespace Http {
Expand Down Expand Up @@ -117,6 +118,11 @@ bool HeaderUtility::matchHeaders(const Http::HeaderMap& request_headers,
return match != header_data.invert_match_;
}

bool HeaderUtility::headerIsValid(const absl::string_view header_value) {
return (nghttp2_check_header_value(reinterpret_cast<const uint8_t*>(header_value.data()),
header_value.size()) != 0);
}

void HeaderUtility::addHeaders(Http::HeaderMap& headers, const Http::HeaderMap& headers_to_add) {
headers_to_add.iterate(
[](const Http::HeaderEntry& header, void* context) -> Http::HeaderMap::Iterate {
Expand Down
7 changes: 7 additions & 0 deletions source/common/http/header_utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ class HeaderUtility {

static bool matchHeaders(const Http::HeaderMap& request_headers, const HeaderData& config_header);

/**
* Validates that a header value is valid, according to RFC 7230, section 3.2.
* http://tools.ietf.org/html/rfc7230#section-3.2
* @return bool true if the header values are valid, according to the aforementioned RFC.
*/
static bool headerIsValid(const absl::string_view header_value);

/**
* Add headers from one HeaderMap to another
* @param headers target where headers will be added
Expand Down
2 changes: 2 additions & 0 deletions source/common/http/http1/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ envoy_cc_library(
"//source/common/http:codes_lib",
"//source/common/http:exception_lib",
"//source/common/http:header_map_lib",
"//source/common/http:header_utility_lib",
"//source/common/http:headers_lib",
"//source/common/http:utility_lib",
],
Expand Down Expand Up @@ -55,6 +56,7 @@ envoy_cc_library(
"//source/common/http:conn_pool_base_lib",
"//source/common/http:headers_lib",
"//source/common/network:utility_lib",
"//source/common/runtime:runtime_lib",
"//source/common/upstream:upstream_lib",
],
)
53 changes: 43 additions & 10 deletions source/common/http/http1/codec_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "common/common/stack_array.h"
#include "common/common/utility.h"
#include "common/http/exception.h"
#include "common/http/header_utility.h"
#include "common/http/headers.h"
#include "common/http/utility.h"

Expand Down Expand Up @@ -319,11 +320,20 @@ const ToLowerTable& ConnectionImpl::toLowerTable() {
return *table;
}

// TODO(alyssawilk) The overloaded constructors here and on {Client,Server}ConnectionImpl
// can be cleaned up once "strict_header_validation" becomes the default behavior, rather
// than a runtime-guarded one. The overloads were a workaround for the fact that Runtime
// doesn't work from integration test call sites in scenarios where the required
// thread-local storage is not available.
ConnectionImpl::ConnectionImpl(Network::Connection& connection, http_parser_type type,
uint32_t max_headers_kb)
: ConnectionImpl::ConnectionImpl(connection, type, max_headers_kb, false) {}

ConnectionImpl::ConnectionImpl(Network::Connection& connection, http_parser_type type,
uint32_t max_headers_kb, bool strict_header_validation)
: connection_(connection), output_buffer_([&]() -> void { this->onBelowLowWatermark(); },
[&]() -> void { this->onAboveHighWatermark(); }),
max_headers_kb_(max_headers_kb) {
max_headers_kb_(max_headers_kb), strict_header_validation_(strict_header_validation) {
output_buffer_.setWatermarks(connection.bufferLimit());
http_parser_init(&parser_, type);
parser_.data = this;
Expand Down Expand Up @@ -421,11 +431,21 @@ void ConnectionImpl::onHeaderValue(const char* data, size_t length) {
// Ignore trailers.
return;
}
// http-parser should filter for this
// (https://tools.ietf.org/html/rfc7230#section-3.2.6), but it doesn't today. HeaderStrings
// have an invariant that they must not contain embedded zero characters
// (NUL, ASCII 0x0).
if (absl::string_view(data, length).find('\0') != absl::string_view::npos) {

const absl::string_view header_value = absl::string_view(data, length);

if (strict_header_validation_) {
if (!Http::HeaderUtility::headerIsValid(header_value)) {
ENVOY_CONN_LOG(debug, "invalid header value: {}", connection_, header_value);
error_code_ = Http::Code::BadRequest;
sendProtocolError();
throw CodecProtocolException("http/1.1 protocol error: header value contains invalid chars");
}
} else if (header_value.find('\0') != absl::string_view::npos) {
// http-parser should filter for this
// (https://tools.ietf.org/html/rfc7230#section-3.2.6), but it doesn't today. HeaderStrings
// have an invariant that they must not contain embedded zero characters
// (NUL, ASCII 0x0).
throw CodecProtocolException("http/1.1 protocol error: header value contains NUL");
}

Expand Down Expand Up @@ -496,8 +516,15 @@ void ConnectionImpl::onResetStreamBase(StreamResetReason reason) {
ServerConnectionImpl::ServerConnectionImpl(Network::Connection& connection,
ServerConnectionCallbacks& callbacks,
Http1Settings settings, uint32_t max_request_headers_kb)
: ConnectionImpl(connection, HTTP_REQUEST, max_request_headers_kb), callbacks_(callbacks),
codec_settings_(settings) {}
: ServerConnectionImpl::ServerConnectionImpl(connection, callbacks, settings,
max_request_headers_kb, false) {}

ServerConnectionImpl::ServerConnectionImpl(Network::Connection& connection,
ServerConnectionCallbacks& callbacks,
Http1Settings settings, uint32_t max_request_headers_kb,
bool strict_header_validation)
: ConnectionImpl(connection, HTTP_REQUEST, max_request_headers_kb, strict_header_validation),
callbacks_(callbacks), codec_settings_(settings) {}

void ServerConnectionImpl::onEncodeComplete() {
ASSERT(active_request_);
Expand Down Expand Up @@ -668,8 +695,14 @@ void ServerConnectionImpl::onBelowLowWatermark() {
}
}

ClientConnectionImpl::ClientConnectionImpl(Network::Connection& connection, ConnectionCallbacks&)
: ConnectionImpl(connection, HTTP_RESPONSE, MAX_RESPONSE_HEADERS_KB) {}
ClientConnectionImpl::ClientConnectionImpl(Network::Connection& connection,
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.

Any reason to not just remove the old constructor and default validate_header_values to false?

Though now that I think about it, I think we'd be better off only having the new constructor and not having a default value. If we force all callers to pick a boolean we won't miss any code sites using the new code path.

It will probably mean tweaking a bunch of unit tests (you can set them all true) but hopefully you can search and replace there

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.

The main reason I hadn't done that was the pervasiveness of the change: it involves a bunch of find/replace that really blew up the diff for the PR. (Due to the fact that it involves changing ServerConnectionImpl, ClientConnectionImpl, CodecClient/CodecClientProd, ConnectionManagerConfig, and associated mocks, unit tests, and call sites.

If you think that much code churn is warranted though, I can certainly do that, and make all the callers default to false (and default the unit test callers to true). I know originally we had talked about an overloaded constructor like the one included here, which didn't lead to nearly as much churn.

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.

Yeah, that's actually a fair point about code churn given we'd want to go back to the single argument once we flip this to true and deprecate.

Do you feel confident from grepping around that you have all the call sites under source/...? If not, how about a hacked local version with a RELEASE_ASSERT in the old constructors to make sure we didn't miss any, and we'll call it a day?

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.

Yep, I added RELEASE_ASSERT(false, ""); to the {Client,Server}ConnectionImpl constructors and ran Envoy to perform the steps outlined in the PR description (in the "testing" section). Worked great.

ConnectionCallbacks& callbacks)
: ClientConnectionImpl::ClientConnectionImpl(connection, callbacks, false) {}

ClientConnectionImpl::ClientConnectionImpl(Network::Connection& connection, ConnectionCallbacks&,
bool strict_header_validation)
: ConnectionImpl(connection, HTTP_RESPONSE, MAX_RESPONSE_HEADERS_KB, strict_header_validation) {
}

bool ClientConnectionImpl::cannotHaveBody() {
if ((!pending_responses_.empty() && pending_responses_.front().head_request_) ||
Expand Down
11 changes: 11 additions & 0 deletions source/common/http/http1/codec_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable<Log
protected:
ConnectionImpl(Network::Connection& connection, http_parser_type type,
uint32_t max_request_headers_kb);
ConnectionImpl(Network::Connection& connection, http_parser_type type,
uint32_t max_request_headers_kb, bool strict_header_validation);

bool resetStreamCalled() { return reset_stream_called_; }

Expand Down Expand Up @@ -282,6 +284,8 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable<Log
char* reserved_current_{};
Protocol protocol_{Protocol::Http11};
const uint32_t max_headers_kb_;

bool strict_header_validation_;
};

/**
Expand All @@ -292,6 +296,10 @@ class ServerConnectionImpl : public ServerConnection, public ConnectionImpl {
ServerConnectionImpl(Network::Connection& connection, ServerConnectionCallbacks& callbacks,
Http1Settings settings, uint32_t max_request_headers_kb);

ServerConnectionImpl(Network::Connection& connection, ServerConnectionCallbacks& callbacks,
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.

Ditto here, regarding the new constructor

Http1Settings settings, uint32_t max_request_headers_kb,
bool strict_header_validation);

virtual bool supports_http_10() override { return codec_settings_.accept_http_10_; }

private:
Expand Down Expand Up @@ -342,6 +350,9 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl {
public:
ClientConnectionImpl(Network::Connection& connection, ConnectionCallbacks& callbacks);

ClientConnectionImpl(Network::Connection& connection, ConnectionCallbacks& callbacks,
bool strict_header_validation);

// Http::ClientConnection
StreamEncoder& newStream(StreamDecoder& response_decoder) override;

Expand Down
8 changes: 7 additions & 1 deletion source/common/http/http1/conn_pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "common/http/codes.h"
#include "common/http/headers.h"
#include "common/network/utility.h"
#include "common/runtime/runtime_impl.h"
#include "common/upstream/upstream_impl.h"

#include "absl/strings/match.h"
Expand Down Expand Up @@ -341,8 +342,13 @@ void ConnPoolImpl::ActiveClient::onConnectTimeout() {
}

CodecClientPtr ProdConnPoolImpl::createCodecClient(Upstream::Host::CreateConnectionData& data) {

const bool strict_header_validation =
Runtime::runtimeFeatureEnabled("envoy.reloadable_features.strict_header_validation");

CodecClientPtr codec{new CodecClientProd(CodecClient::Type::HTTP1, std::move(data.connection_),
data.host_description_, dispatcher_)};
data.host_description_, dispatcher_,
strict_header_validation)};
return codec;
}

Expand Down
2 changes: 1 addition & 1 deletion source/common/http/http2/conn_pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ ConnPoolImpl::ActiveClient::~ActiveClient() {

CodecClientPtr ProdConnPoolImpl::createCodecClient(Upstream::Host::CreateConnectionData& data) {
CodecClientPtr codec{new CodecClientProd(CodecClient::Type::HTTP2, std::move(data.connection_),
data.host_description_, dispatcher_)};
data.host_description_, dispatcher_, false)};
return codec;
}

Expand Down
7 changes: 5 additions & 2 deletions source/common/upstream/health_checker_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "common/http/header_map_impl.h"
#include "common/network/address_impl.h"
#include "common/router/router.h"
#include "common/runtime/runtime_impl.h"
#include "common/upstream/host_utility.h"

// TODO(dio): Remove dependency to extension health checkers when redis_health_check is removed.
Expand Down Expand Up @@ -335,8 +336,10 @@ Http::CodecClient::Type HttpHealthCheckerImpl::codecClientType(bool use_http2) {

Http::CodecClient*
ProdHttpHealthCheckerImpl::createCodecClient(Upstream::Host::CreateConnectionData& data) {
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'd be inclined to snag the runtime value here too, so when we've flipped the default we can remove the old code path and always do full sanitization

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 think you did this in the wrong block, for the gRPC health checker (always H2) rather than than here where it can be 1/1

Other than that, LGTM.
@snowp any other thoughts on your end?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@alyssawilk Good catch! Just fixed that.

const bool strict_header_validation =
Runtime::runtimeFeatureEnabled("envoy.reloadable_features.strict_header_validation");
return new Http::CodecClientProd(codec_client_type_, std::move(data.connection_),
data.host_description_, dispatcher_);
data.host_description_, dispatcher_, strict_header_validation);
}

TcpHealthCheckMatcher::MatchSegments TcpHealthCheckMatcher::loadProtoBytes(
Expand Down Expand Up @@ -744,7 +747,7 @@ Http::CodecClientPtr
ProdGrpcHealthCheckerImpl::createCodecClient(Upstream::Host::CreateConnectionData& data) {
return std::make_unique<Http::CodecClientProd>(Http::CodecClient::Type::HTTP2,
std::move(data.connection_),
data.host_description_, dispatcher_);
data.host_description_, dispatcher_, false);
}

std::ostream& operator<<(std::ostream& out, HealthState state) {
Expand Down
Loading