Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ bug_fixes:
change: |
Fix a bug where Lua filters may result in Envoy crashes when setting response body to a
larger payload (greater than the body buffer limit).
- area: bootstrap
change: |
Fixed an issue where the custom
:ref:`header_prefix <envoy_v3_api_field_config.bootstrap.v3.Bootstrap.header_prefix>`
will result in crash at startup.
- area: connection pool
change: |
Fix a crash in the TCP connection pool that occurs during downstream connection teardown when large requests
Expand Down
2 changes: 1 addition & 1 deletion envoy/http/header_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ template <CustomInlineHeaderRegistry::Type type> class RegisterCustomInlineHeade
RegisterCustomInlineHeader(const LowerCaseString& header)
: handle_(CustomInlineHeaderRegistry::registerInlineHeader<type>(header)) {}

typename CustomInlineHeaderRegistry::Handle<type> handle() { return handle_; }
typename CustomInlineHeaderRegistry::Handle<type> handle() const { return handle_; }

private:
const typename CustomInlineHeaderRegistry::Handle<type> handle_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::Respons
etag_handle(Http::CustomHeaders::get().Etag);
Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::ResponseHeaders>
vary_handle(Http::CustomHeaders::get().Vary);
Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::ResponseHeaders>
compression_status_handle(Http::Headers::get().EnvoyCompressionStatus);

Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::RequestHeaders>
request_content_encoding_handle(Http::CustomHeaders::get().ContentEncoding);
Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::ResponseHeaders>
Expand Down Expand Up @@ -795,8 +792,7 @@ void CompressorFilter::insertEnvoyCompressionStatusHeader(
absl::string_view status_to_set, absl::optional<absl::string_view> original_length) {
std::string status_value =
createEnvoyCompressionStatusHeaderValue(encoding_type, status_to_set, original_length);
headers.appendInline(compression_status_handle.handle(), status_value,
Http::Headers::get().EnvoyCompressionStatusValues.ValueSeparator);
headers.addReferenceKey(Http::Headers::get().EnvoyCompressionStatus, status_value);
}

void CompressorFilter::insertVaryHeader(Http::ResponseHeaderMap& headers) {
Expand Down
61 changes: 49 additions & 12 deletions test/extensions/filters/http/compressor/compressor_filter_test.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <sys/types.h>

#include "source/common/http/header_utility.h"
#include "source/extensions/filters/http/compressor/compressor_filter.h"

#include "test/extensions/filters/http/compressor/compressor_filter_testing_peer.h"
Expand Down Expand Up @@ -183,7 +184,7 @@ class CompressorFilterTest : public testing::Test {
std::unique_ptr<CompressorFilter> filter_;
Buffer::OwnedImpl data_;
std::string expected_str_;
std::string response_stats_prefix_{};
std::string response_stats_prefix_;
Stats::TestUtil::TestStore stats_;
NiceMock<Runtime::MockLoader> runtime_;
NiceMock<Http::MockStreamDecoderFilterCallbacks> decoder_callbacks_;
Expand Down Expand Up @@ -1373,7 +1374,11 @@ TEST_F(CompressorFilterTest, EnvoyCompressionStatusHeaderContentLength) {
doRequestNoCompression({{":method", "get"}, {"accept-encoding", "test, deflate"}});
Http::TestResponseHeaderMapImpl headers{{":method", "get"}, {"content-length", "10"}};
doResponse(headers, false, false);
EXPECT_EQ(headers.get_("x-envoy-compression-status"), "test;ContentLengthTooSmall");
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test;ContentLengthTooSmall");
}

TEST_F(CompressorFilterTest, EnvoyCompressionStatusHeaderContentType) {
Expand All @@ -1397,7 +1402,11 @@ TEST_F(CompressorFilterTest, EnvoyCompressionStatusHeaderContentType) {
Http::TestResponseHeaderMapImpl headers{
{":method", "get"}, {"content-length", "256"}, {"content-type", "image/jpeg"}};
doResponse(headers, false, false);
EXPECT_EQ(headers.get_("x-envoy-compression-status"), "test;ContentTypeNotAllowed");
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test;ContentTypeNotAllowed");
}

TEST_F(CompressorFilterTest, EnvoyCompressionStatusHeaderEtag) {
Expand All @@ -1421,7 +1430,11 @@ TEST_F(CompressorFilterTest, EnvoyCompressionStatusHeaderEtag) {
Http::TestResponseHeaderMapImpl headers{
{":method", "get"}, {"content-length", "256"}, {"etag", "12345"}};
doResponse(headers, false, false);
EXPECT_EQ(headers.get_("x-envoy-compression-status"), "test;EtagNotAllowed");
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test;EtagNotAllowed");
}

TEST_F(CompressorFilterTest, EnvoyCompressionStatusHeaderStatusCode) {
Expand All @@ -1447,7 +1460,11 @@ TEST_F(CompressorFilterTest, EnvoyCompressionStatusHeaderStatusCode) {
Http::TestResponseHeaderMapImpl headers{
{":method", "get"}, {"content-length", "256"}, {":status", "206"}};
doResponse(headers, false, false);
EXPECT_EQ(headers.get_("x-envoy-compression-status"), "test;StatusCodeNotAllowed");
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test;StatusCodeNotAllowed");
}

TEST_F(CompressorFilterTest, EnvoyCompressionStatusHeaderCompressed) {
Expand All @@ -1469,7 +1486,11 @@ TEST_F(CompressorFilterTest, EnvoyCompressionStatusHeaderCompressed) {
doRequestNoCompression({{":method", "get"}, {"accept-encoding", "test, deflate"}});
Http::TestResponseHeaderMapImpl headers{{":method", "get"}, {"content-length", "256"}};
doResponse(headers, true, false);
EXPECT_EQ(headers.get_("x-envoy-compression-status"), "test;Compressed;OriginalLength=256");
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test;Compressed;OriginalLength=256");
}

class IsMinimumContentLengthTest
Expand Down Expand Up @@ -1888,7 +1909,10 @@ TEST_F(MultipleFiltersTest, BothFiltersFail) {
Http::TestResponseHeaderMapImpl headers{{":method", "get"}, {"content-length", "10"}};
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter1_->encodeHeaders(headers, false));
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter2_->encodeHeaders(headers, false));
EXPECT_EQ(headers.get_("x-envoy-compression-status"),
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test1;ContentLengthTooSmall,test2;ContentLengthTooSmall");
}

Expand Down Expand Up @@ -1938,7 +1962,10 @@ TEST_F(MultipleFiltersTest, OneFilterFailsOneSucceeds) {
{":method", "get"}, {"content-length", "256"}, {"content-type", "text/plain"}};
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter1_->encodeHeaders(headers, false));
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter2_->encodeHeaders(headers, false));
EXPECT_EQ(headers.get_("x-envoy-compression-status"),
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test1;ContentTypeNotAllowed,test2;Compressed;OriginalLength=256");
}

Expand All @@ -1958,7 +1985,11 @@ TEST_F(MultipleFiltersTest, FirstFilterSucceedsSecondSkips) {
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter1_->encodeHeaders(headers, false));
// The second filter should not compress because the content-encoding header is already set.
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter2_->encodeHeaders(headers, false));
EXPECT_EQ(headers.get_("x-envoy-compression-status"), "test1;Compressed;OriginalLength=256");
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test1;Compressed;OriginalLength=256");
EXPECT_EQ(headers.get_("content-encoding"), "test1");
}

Expand Down Expand Up @@ -2011,7 +2042,10 @@ TEST_F(MultipleFiltersTest, BothFiltersFailDifferentReasons) {
{":method", "get"}, {"content-length", "256"}, {"content-type", "text/plain"}};
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter1_->encodeHeaders(headers, false));
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter2_->encodeHeaders(headers, false));
EXPECT_EQ(headers.get_("x-envoy-compression-status"),
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test1;ContentLengthTooSmall,test2;ContentTypeNotAllowed");
}

Expand Down Expand Up @@ -2060,7 +2094,10 @@ TEST_F(MultipleFiltersTest, BothFiltersFailEtagAndStatusCode) {
{":method", "get"}, {"content-length", "256"}, {"etag", "12345"}, {":status", "206"}};
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter1_->encodeHeaders(headers, false));
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter2_->encodeHeaders(headers, false));
EXPECT_EQ(headers.get_("x-envoy-compression-status"),
EXPECT_EQ(Http::HeaderUtility::getAllOfHeaderAsString(
headers.get(Http::Headers::get().EnvoyCompressionStatus))
.result()
.value(),
"test1;EtagNotAllowed,test2;StatusCodeNotAllowed");
}

Expand Down Expand Up @@ -2175,7 +2212,7 @@ class ChooseFirstTest : public MultipleFiltersTest,

Buffer::OwnedImpl data_;
std::string expected_str_;
std::string response_stats_prefix_{};
std::string response_stats_prefix_;
NiceMock<Http::MockStreamEncoderFilterCallbacks> encoder_callbacks_;
};

Expand Down