Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fine-granular feature flag for request body compression #38098

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ message Compressor {
// Configuration for filter behavior on the request direction.
message RequestDirectionConfig {
CommonDirectionConfig common_config = 1;

// Allow request body compression enabled by request header flag
// https://github.com/envoyproxy/envoy/issues/38097
// If true, it checks the "X-Request-Compression" header to see whether the request needs to do compression or not
bool enable_on_x_header = 2;
}

// Configuration for filter behavior on the response direction.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ message HttpProtocolOptions {
option (validate.required) = true;

// To explicitly configure either HTTP/1 or HTTP/2 (but not both!) use ``explicit_http_config``.
// If the ``explicit_http_config`` is empty, HTTP/1.1 is used.
ExplicitHttpConfig explicit_http_config = 3;

// This allows switching on protocol based on what protocol the downstream
Expand Down
25 changes: 23 additions & 2 deletions source/extensions/filters/http/compressor/compressor_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ CompressorFilterConfig::RequestDirectionConfig::RequestDirectionConfig(
const std::string& stats_prefix, Stats::Scope& scope, Runtime::Loader& runtime)
: DirectionConfig(proto_config.request_direction_config().common_config(),
stats_prefix + "request.", scope, runtime),
enable_on_x_header_(proto_config.request_direction_config().enable_on_x_header()),
is_set_{proto_config.has_request_direction_config()} {}

CompressorFilterConfig::ResponseDirectionConfig::ResponseDirectionConfig(
Expand Down Expand Up @@ -212,8 +213,8 @@ Http::FilterHeadersStatus CompressorFilter::decodeHeaders(Http::RequestHeaderMap

const auto& request_config = config_->requestDirectionConfig();

if (!end_stream && request_config.compressionEnabled() && !Http::Utility::isUpgrade(headers) &&
request_config.isMinimumContentLength(headers) &&
if (!end_stream && requestCompressionEnabled(request_config, headers) &&
!Http::Utility::isUpgrade(headers) && request_config.isMinimumContentLength(headers) &&
request_config.isContentTypeAllowed(headers) &&
!headers.getInline(request_content_encoding_handle.handle()) &&
isTransferEncodingAllowed(headers)) {
Expand Down Expand Up @@ -648,6 +649,26 @@ bool CompressorFilter::compressionEnabled(
: config.compressionEnabled();
}

// True if request compression is enabled.
bool CompressorFilter::requestCompressionEnabled(
const CompressorFilterConfig::RequestDirectionConfig& config,
const Http::RequestHeaderMap& headers) const {
if (config.compressionEnabled()) {
return config.compressionEnabled();
} else if (config.enableOnXHeader()) {
Envoy::Http::HeaderMap::GetResult header_result =
headers.get(Envoy::Http::LowerCaseString("X-Request-Compression"));
if (header_result.size() > 0) { // Check if the header exists
std::string compressionRequired =
std::string(header_result.operator[](0)->value().getStringView());
if (absl::EqualsIgnoreCase(compressionRequired, "true")) {
return true;
}
}
}
return false;
}

bool CompressorFilter::removeAcceptEncodingHeader(
const CompressorFilterConfig::ResponseDirectionConfig& config,
const CompressorPerRouteFilterConfig* per_route_config) const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ class CompressorFilterConfig {

bool compressionEnabled() const override { return is_set_ && compression_enabled_.enabled(); }

bool enableOnXHeader() const { return enable_on_x_header_; }

private:
const bool enable_on_x_header_;
const bool is_set_;
};

Expand Down Expand Up @@ -200,6 +203,8 @@ class CompressorFilter : public Http::PassThroughFilter {
private:
bool compressionEnabled(const CompressorFilterConfig::ResponseDirectionConfig& config,
const CompressorPerRouteFilterConfig* per_route_config) const;
bool requestCompressionEnabled(const CompressorFilterConfig::RequestDirectionConfig& config,
const Http::RequestHeaderMap& headers) const;
bool removeAcceptEncodingHeader(const CompressorFilterConfig::ResponseDirectionConfig& config,
const CompressorPerRouteFilterConfig* per_route_config) const;
bool hasCacheControlNoTransform(Http::ResponseHeaderMap& headers) const;
Expand Down