Skip to content
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
fdd1442
Configure codec library max request header limits
Feb 4, 2019
932eaf0
Add hd to dictionary
Feb 6, 2019
999b247
Undo http1 codec changes
Feb 6, 2019
6e2e092
set http_parser limit in test
Feb 6, 2019
1ba5e19
Remove http2options for nghttp2 check
Feb 7, 2019
51e8fb7
Fix format
Feb 13, 2019
37d6900
add comment
Feb 14, 2019
8c1be4a
Clean up codec tests and bump limit to 96
Feb 14, 2019
d3e146d
Merge remote-tracking branch 'envoy/master' into maxer
Feb 14, 2019
d14f019
Add protocol tests
Feb 15, 2019
7fae643
Revert "Undo http1 codec changes"
Feb 15, 2019
6c6cd5c
Revert "Revert "Undo http1 codec changes""
Feb 20, 2019
87cd65b
set http parser in conn manager config
Feb 20, 2019
12cb34d
Finalize tests
Feb 20, 2019
2370471
Fix format and rmeove dead tests
Feb 20, 2019
7aba9ea
Move http_parser config to compile-time
Feb 22, 2019
dc0b47e
Remove request header rejected tests
Feb 22, 2019
e241e35
Clean comment
Feb 22, 2019
cff066e
bump up nghttp2 huge
Feb 22, 2019
358fd16
Clean test values for large headers
Feb 22, 2019
bbf0df2
matt comments
Feb 26, 2019
c8b006e
word
Feb 26, 2019
8bb762c
Revert "Remove request header rejected tests"
Feb 26, 2019
3bcfbdf
hard coded check w test
Feb 27, 2019
56644a1
Revert "Revert "Undo http1 codec changes""
Feb 27, 2019
7ece1c7
fix compile
Feb 27, 2019
5210dda
fix format
Feb 27, 2019
0f7911c
fix more compile
Feb 27, 2019
9bce125
fix compile more
Feb 27, 2019
7fb8701
fix bork test
Feb 28, 2019
19d10a2
fix format
Feb 28, 2019
b55c483
pr comments
Feb 28, 2019
6473a65
mattfix
Mar 1, 2019
e084dc7
Fix response side client connection
Mar 1, 2019
c7ec56b
fix format
Mar 1, 2019
f520e89
idk
Mar 1, 2019
4a5d64e
pr comments
Mar 4, 2019
9a20bb5
pr comments
Mar 4, 2019
bfbeed4
fix fuzz test
Mar 4, 2019
e28fcdb
update comments
Mar 4, 2019
be85a3f
Merge remote-tracking branch 'envoy/master' into maxer
Mar 4, 2019
b5ba8ef
pr change
Mar 5, 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
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,13 @@ message HttpConnectionManager {
// header in responses. If not set, the default is *envoy*.
string server_name = 10;

// The maximum request headers size for incoming connections. The default max
// is 60K, based on default settings for http codecs. For HTTP1, the current
// limit set by http_parser is 80K. for HTTP2, the default allowed header
// block in nghttp2 is 64K. The max configurable setting is 64K in order to
// stay under both codec limits.
// Requests that exceed this size will receive a 431 response.
// The maximum request headers size for incoming connections.
// If unconfigured, the default max request headers allowed is 60 KiB.
// Requests that exceed this limit will receive a 431 response.
// The max configurable limit is 96 KiB, based on current implementation
// constraints.
google.protobuf.UInt32Value max_request_headers_kb = 29
[(validate.rules).uint32.gt = 0, (validate.rules).uint32.lte = 64];
[(validate.rules).uint32.gt = 0, (validate.rules).uint32.lte = 96];

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.

Worth commenting on the new max?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added a note in the API.

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.

Sorry, worth commenting the reasons behind the max?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Ummmm, a prior version had more detail about the reason behind the max, but I removed the detail because it wasn't really a "public API" reason.

basically 96 kb is the highest I could get it to go without triggering a different nghttp2 bug, but I stopped trying to debug at that point so I don't know what actually breaks.

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 documenting somewhere that we can't go above 96 and have nghttp2 work is worthwhile.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry to come back to this, but can you say something like "The max configurable limit is 96 KiB which is gated by the current implementation details." And then put a comment about whatever nghttp2 issues you had somewhere in the code? I don't think nghttp2 should show up in the docs, it's not relevant to the end user. If you want to put the comment here you can also put in a doc comment (see other examples) which won't get rendered.

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.

+1 - that works for me as a compromise

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 could you please describe a bit why such hard limit has been chosen?
Is there any internal implementation issues with higher limit?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See the comment thread above. IIRC there was some problem getting higher limits to work either in the tests or in prod code which would need debugging to allow raising the limits higher. I agree from a product perspective we should allow higher limits.


// The idle timeout for connections managed by the connection manager. The
// idle timeout is defined as the period in which there are no active
Expand Down
3 changes: 3 additions & 0 deletions bazel/external/http-parser.BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ cc_library(
"http_parser.h",
],
hdrs = ["http_parser.h"],
# This compiler flag effectively disables the http_parser header limit,
# as we do our own checks in the conn manager and codec.
copts = ["-DHTTP_MAX_HEADER_SIZE=0x7fffffff"],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you add a comment on why we set this and why it's safe (we have checks elsewhere, etc.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also, don't you need HTTP/1 codec changes now to check the current header map size on each new header as we do with HTTP/2? I'm not sure how this is safe otherwise?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

done on the comment, working on the http1 codec check

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.

Also as an aside, when this lands please ping the googlers on current and next import duty as this will almost certainly need custom tweaks on import.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

ack

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.

Actually sorry, on second thought I'm having a moment of paranoia. We don't have anywhere else in the Envoy code base where we use http_parser so this is 100% OK today but what do we think of adding a limit just in case? If we added a 200KB limit or some such it'd be very safely above our window such that we should never hit the http_parser limits in the codec, without allowing total infinite memory if someone else uses http parser.
Thoughts?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I changed it to 0xfffffff, i.e. ~2 gb -> ~300 mb.

includes = ["."],
visibility = ["//visibility:public"],
)
8 changes: 4 additions & 4 deletions source/common/http/conn_manager_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ ServerConnectionPtr ConnectionManagerUtility::autoCreateCodec(
ServerConnectionCallbacks& callbacks, Stats::Scope& scope, const Http1Settings& http1_settings,
const Http2Settings& http2_settings, const uint32_t max_request_headers_kb) {
if (determineNextProtocol(connection, data) == Http2::ALPN_STRING) {
return ServerConnectionPtr{new Http2::ServerConnectionImpl(
connection, callbacks, scope, http2_settings, max_request_headers_kb)};
return std::make_unique<Http2::ServerConnectionImpl>(connection, callbacks, scope,
http2_settings, max_request_headers_kb);
} else {
return ServerConnectionPtr{
new Http1::ServerConnectionImpl(connection, callbacks, http1_settings)};
return std::make_unique<Http1::ServerConnectionImpl>(connection, callbacks, http1_settings,
max_request_headers_kb);
}
}

Expand Down
21 changes: 16 additions & 5 deletions source/common/http/http1/codec_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,11 @@ const ToLowerTable& ConnectionImpl::toLowerTable() {
return *table;
}

ConnectionImpl::ConnectionImpl(Network::Connection& connection, http_parser_type type)
ConnectionImpl::ConnectionImpl(Network::Connection& connection, http_parser_type type,
uint32_t max_headers_kb)
: connection_(connection), output_buffer_([&]() -> void { this->onBelowLowWatermark(); },
[&]() -> void { this->onAboveHighWatermark(); }) {
[&]() -> void { this->onAboveHighWatermark(); }),
max_headers_kb_(max_headers_kb) {
output_buffer_.setWatermarks(connection.bufferLimit());
http_parser_init(&parser_, type);
parser_.data = this;
Expand Down Expand Up @@ -419,6 +421,14 @@ void ConnectionImpl::onHeaderValue(const char* data, size_t length) {

header_parsing_state_ = HeaderParsingState::Value;
current_header_value_.append(data, length);

uint32_t total =

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.

const uint32_t?

current_header_field_.size() + current_header_value_.size() + current_header_map_->byteSize();
if (total > (max_headers_kb_ * 1024)) {
error_code_ = Http::Code::RequestHeaderFieldsTooLarge;
sendProtocolError();
throw CodecProtocolException("headers size exceeds limit");
}
}

int ConnectionImpl::onHeadersCompleteBase() {
Expand Down Expand Up @@ -471,8 +481,9 @@ void ConnectionImpl::onResetStreamBase(StreamResetReason reason) {

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

void ServerConnectionImpl::onEncodeComplete() {
ASSERT(active_request_);
Expand Down Expand Up @@ -643,7 +654,7 @@ void ServerConnectionImpl::onBelowLowWatermark() {
}

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

bool ClientConnectionImpl::cannotHaveBody() {
if ((!pending_responses_.empty() && pending_responses_.front().head_request_) ||
Expand Down
9 changes: 7 additions & 2 deletions source/common/http/http1/codec_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable<Log
bool maybeDirectDispatch(Buffer::Instance& data);

protected:
ConnectionImpl(Network::Connection& connection, http_parser_type type);
ConnectionImpl(Network::Connection& connection, http_parser_type type,
uint32_t max_request_headers_kb);

bool resetStreamCalled() { return reset_stream_called_; }

Expand Down Expand Up @@ -273,6 +274,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable<Log
Buffer::RawSlice reserved_iovec_;
char* reserved_current_{};
Protocol protocol_{Protocol::Http11};
const uint32_t max_headers_kb_;
};

/**
Expand All @@ -281,7 +283,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable<Log
class ServerConnectionImpl : public ServerConnection, public ConnectionImpl {
public:
ServerConnectionImpl(Network::Connection& connection, ServerConnectionCallbacks& callbacks,
Http1Settings settings);
Http1Settings settings, uint32_t max_request_headers_kb);

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

Expand Down Expand Up @@ -363,6 +365,9 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl {
std::list<PendingResponse> pending_responses_;
// Set true between receiving 100-Continue headers and receiving the spurious onMessageComplete.
bool ignore_message_complete_for_100_continue_{};

// The default limit of 80 KiB is the vanilla http_parser behaviour.

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.

The default limit is 80Kb (Kilobytes) not KiB (Kibibytes), no?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Wow, I forgot kibibytes were a thing. In any case, I checked http_parser.h:63, looks like it's indeed KiB.

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.

Oh jeez, trusted the http_parser issue which was incorrect - looks like they were saying KB when they meant KiB. You can ignore this one.

static constexpr uint32_t MAX_RESPONSE_HEADERS_KB = 80;
};

} // namespace Http1
Expand Down
4 changes: 4 additions & 0 deletions source/common/http/http2/codec_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,10 @@ ConnectionImpl::Http2Options::Http2Options(const Http2Settings& http2_settings)
nghttp2_option_set_no_closed_streams(options_, 1);
nghttp2_option_set_no_auto_window_update(options_, 1);

// The max send header block length is configured to an arbitrarily high number so as to never
// trigger the check within nghttp2, as we check request headers length in codec_impl::saveHeader.
nghttp2_option_set_max_send_header_block_length(options_, 0x7fffffff);

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 on limits


if (http2_settings.hpack_table_size_ != NGHTTP2_DEFAULT_HEADER_TABLE_SIZE) {
nghttp2_option_set_max_deflate_dynamic_table_size(options_, http2_settings.hpack_table_size_);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,11 @@ HttpConnectionManagerConfig::createCodec(Network::Connection& connection,
Http::ServerConnectionCallbacks& callbacks) {
switch (codec_type_) {
case CodecType::HTTP1:
return Http::ServerConnectionPtr{
new Http::Http1::ServerConnectionImpl(connection, callbacks, http1_settings_)};
return std::make_unique<Http::Http1::ServerConnectionImpl>(
connection, callbacks, http1_settings_, maxRequestHeadersKb());
case CodecType::HTTP2:
return Http::ServerConnectionPtr{new Http::Http2::ServerConnectionImpl(
connection, callbacks, context_.scope(), http2_settings_, maxRequestHeadersKb())};
return std::make_unique<Http::Http2::ServerConnectionImpl>(
connection, callbacks, context_.scope(), http2_settings_, maxRequestHeadersKb());
case CodecType::AUTO:
return Http::ConnectionManagerUtility::autoCreateCodec(connection, data, callbacks,
context_.scope(), http1_settings_,
Expand Down
4 changes: 2 additions & 2 deletions test/common/http/codec_impl_fuzz_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@ void codecFuzz(const test::common::http::CodecImplFuzzTestCase& input, HttpVersi
max_request_headers_kb);
} else {
const Http1Settings server_http1settings{fromHttp1Settings(input.h1_settings().server())};
server = absl::make_unique<Http1::ServerConnectionImpl>(server_connection, server_callbacks,
server_http1settings);
server = absl::make_unique<Http1::ServerConnectionImpl>(
server_connection, server_callbacks, server_http1settings, max_request_headers_kb);
}

ReorderBuffer client_write_buf{*server};
Expand Down
115 changes: 104 additions & 11 deletions test/common/http/http1/codec_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ namespace Http1 {
class Http1ServerConnectionImplTest : public TestBase {
public:
void initialize() {
codec_ = std::make_unique<ServerConnectionImpl>(connection_, callbacks_, codec_settings_);
codec_ = std::make_unique<ServerConnectionImpl>(connection_, callbacks_, codec_settings_,
max_request_headers_kb_);
}

NiceMock<Network::MockConnection> connection_;
Expand All @@ -42,6 +43,9 @@ class Http1ServerConnectionImplTest : public TestBase {
void expectHeadersTest(Protocol p, bool allow_absolute_url, Buffer::OwnedImpl& buffer,
TestHeaderMapImpl& expected_headers);
void expect400(Protocol p, bool allow_absolute_url, Buffer::OwnedImpl& buffer);

protected:
uint32_t max_request_headers_kb_{Http::DEFAULT_MAX_REQUEST_HEADERS_KB};
};

void Http1ServerConnectionImplTest::expect400(Protocol p, bool allow_absolute_url,
Expand All @@ -53,7 +57,8 @@ void Http1ServerConnectionImplTest::expect400(Protocol p, bool allow_absolute_ur

if (allow_absolute_url) {
codec_settings_.allow_absolute_url_ = allow_absolute_url;
codec_ = std::make_unique<ServerConnectionImpl>(connection_, callbacks_, codec_settings_);
codec_ = std::make_unique<ServerConnectionImpl>(connection_, callbacks_, codec_settings_,
max_request_headers_kb_);
}

Http::MockStreamDecoder decoder;
Expand All @@ -72,7 +77,8 @@ void Http1ServerConnectionImplTest::expectHeadersTest(Protocol p, bool allow_abs
// Make a new 'codec' with the right settings
if (allow_absolute_url) {
codec_settings_.allow_absolute_url_ = allow_absolute_url;
codec_ = std::make_unique<ServerConnectionImpl>(connection_, callbacks_, codec_settings_);
codec_ = std::make_unique<ServerConnectionImpl>(connection_, callbacks_, codec_settings_,
max_request_headers_kb_);
}

Http::MockStreamDecoder decoder;
Expand Down Expand Up @@ -1006,9 +1012,8 @@ TEST_F(Http1ClientConnectionImplTest, HighwatermarkMultipleResponses) {
static_cast<ClientConnection*>(codec_.get())
->onUnderlyingConnectionBelowWriteBufferLowWatermark();
}

// For issue #1421 regression test that Envoy's HTTP parser applies header limits early.
TEST_F(Http1ServerConnectionImplTest, TestCodecHeaderLimits) {
TEST_F(Http1ServerConnectionImplTest, TestLargeRequestHeadersRejected) {
// Default limit of 60 KiB
initialize();

std::string exception_reason;
Expand All @@ -1022,14 +1027,102 @@ TEST_F(Http1ServerConnectionImplTest, TestCodecHeaderLimits) {

Buffer::OwnedImpl buffer("GET / HTTP/1.1\r\n");
codec_->dispatch(buffer);
std::string long_string = "foo: " + std::string(1024, 'q') + "\r\n";
for (int i = 0; i < 79; ++i) {
buffer = Buffer::OwnedImpl(long_string);
std::string long_string = "big: " + std::string(60 * 1024, 'q') + "\r\n";
buffer = Buffer::OwnedImpl(long_string);
EXPECT_THROW_WITH_MESSAGE(codec_->dispatch(buffer), EnvoyException, "headers size exceeds limit");
}

TEST_F(Http1ServerConnectionImplTest, TestLargeRequestHeadersSplitRejected) {
// Default limit of 60 KiB
initialize();

std::string exception_reason;
NiceMock<Http::MockStreamDecoder> decoder;
Http::StreamEncoder* response_encoder = nullptr;
EXPECT_CALL(callbacks_, newStream(_, _))
.WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& {
response_encoder = &encoder;
return decoder;
}));
Buffer::OwnedImpl buffer("GET / HTTP/1.1\r\n");
codec_->dispatch(buffer);

std::string long_string = std::string(1024, 'q');
for (int i = 0; i < 59; i++) {
buffer = Buffer::OwnedImpl(fmt::format("big: {}\r\n", long_string));
codec_->dispatch(buffer);
}
// the 60th 1kb header should induce overflow
buffer = Buffer::OwnedImpl(fmt::format("big: {}\r\n", long_string));
EXPECT_THROW_WITH_MESSAGE(codec_->dispatch(buffer), EnvoyException, "headers size exceeds limit");
}

TEST_F(Http1ServerConnectionImplTest, TestLargeRequestHeadersAccepted) {
max_request_headers_kb_ = 65;
initialize();

NiceMock<Http::MockStreamDecoder> decoder;
Http::StreamEncoder* response_encoder = nullptr;
EXPECT_CALL(callbacks_, newStream(_, _))
.WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& {
response_encoder = &encoder;
return decoder;
}));

Buffer::OwnedImpl buffer("GET / HTTP/1.1\r\n");
codec_->dispatch(buffer);
std::string long_string = "big: " + std::string(64 * 1024, 'q') + "\r\n";
buffer = Buffer::OwnedImpl(long_string);
codec_->dispatch(buffer);
}

TEST_F(Http1ServerConnectionImplTest, TestLargeRequestHeadersAcceptedMaxConfigurable) {
max_request_headers_kb_ = 96;
Comment thread
aunu53 marked this conversation as resolved.
initialize();

NiceMock<Http::MockStreamDecoder> decoder;
Http::StreamEncoder* response_encoder = nullptr;
EXPECT_CALL(callbacks_, newStream(_, _))
.WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& {
response_encoder = &encoder;
return decoder;
}));

Buffer::OwnedImpl buffer("GET / HTTP/1.1\r\n");
codec_->dispatch(buffer);
std::string long_string = "big: " + std::string(95 * 1024, 'q') + "\r\n";
buffer = Buffer::OwnedImpl(long_string);
EXPECT_THROW_WITH_MESSAGE(codec_->dispatch(buffer), EnvoyException,
"http/1.1 protocol error: HPE_HEADER_OVERFLOW");
codec_->dispatch(buffer);
}

TEST_F(Http1ClientConnectionImplTest, TestLargeResponseHeadersRejected) {
initialize();

NiceMock<Http::MockStreamDecoder> response_decoder;
Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder);
TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}};
request_encoder.encodeHeaders(headers, true);

Buffer::OwnedImpl buffer("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n");
codec_->dispatch(buffer);
std::string long_header = "big: " + std::string(80 * 1024, 'q') + "\r\n";
buffer = Buffer::OwnedImpl(long_header);
EXPECT_THROW_WITH_MESSAGE(codec_->dispatch(buffer), EnvoyException, "headers size exceeds limit");
}

TEST_F(Http1ClientConnectionImplTest, TestLargeResponseHeadersAccepted) {
initialize();

NiceMock<Http::MockStreamDecoder> response_decoder;
Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder);
TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}};
request_encoder.encodeHeaders(headers, true);

Buffer::OwnedImpl buffer("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n");
codec_->dispatch(buffer);
std::string long_header = "big: " + std::string(79 * 1024, 'q') + "\r\n";
buffer = Buffer::OwnedImpl(long_header);
codec_->dispatch(buffer);
}

} // namespace Http1
Expand Down
Loading