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
gzip: add stats to filter and fix accept-encoding identity bug #3647
Conversation
Signed-off-by: Lita Cho <lcho@lyft.com>
Signed-off-by: Lita Cho <lcho@lyft.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! Generally looks great. Some comments to get started then will take another pass.
that the "gzip" will have a higher weight then "\*". For example, if *accept-encoding* | ||
is "gzip;q=0,\*;q=1", the filter will not compress. But if the header is set to | ||
"\*;q=0,gzip;q=1", the filter will compress. | ||
- A request includes *accept-encoding* header includes "identity". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/includes/whose value is ?
@@ -39,9 +39,14 @@ response and request allow. | |||
By *default* compression will be *skipped* when: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add documentation for all the stats that you added. See other doc examples for how we do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
docs/root/intro/version_history.rst
Outdated
@@ -36,6 +35,7 @@ Version history | |||
* debug: added symbolized stack traces (where supported) | |||
* grpc: support added for the full set of :ref:`Google gRPC call credentials | |||
<envoy_api_msg_core.GrpcService.GoogleGrpc.CallCredentials>`. | |||
* gzip filter: sending accept-encoding header as identity no longer compresses the payload. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: italicize both accept-encoding and identity. Also mention new stats.
bool disable_on_etag_header_; | ||
bool remove_accept_encoding_header_; | ||
const std::string stats_prefix_; | ||
Stats::Scope& scope_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of storing the scope here, you actually want to create the stats object in the config instead of the filter, and the return that on request. See other similar examples in other filters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh got it. didn't see this until now.
@@ -123,16 +128,20 @@ Http::FilterHeadersStatus GzipFilter::encodeHeaders(Http::HeaderMap& headers, bo | |||
headers.insertContentEncoding().value(Http::Headers::get().ContentEncodingValues.Gzip); | |||
compressor_.init(config_->compressionLevel(), config_->compressionStrategy(), | |||
config_->windowBits(), config_->memoryLevel()); | |||
} else { | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: del newline
compressor_.compress(data, end_stream ? Compressor::State::Finish : Compressor::State::Flush); | ||
stats_.total_compressed_bytes_.add(data.length()); | ||
stats_.compressed_.inc(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the compressed stat would be more useful if it were per-request, not per data frame similar to not_compressed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, Jose and I thought that the delta per data frame would be good enough, but happy to change it to per request. if you have a good example of how to do that, that would be awesome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would probably just invert the logic such that when you know that you are not "not compressing" you would increment the compressing stat. Not sure of the best way of doing that since I haven't looked at the filter code in detail, but I'm sure you can sort something out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah nvm, i see what you mean. Yup. will fix to move this into the encodeHeaders
@@ -191,15 +217,23 @@ bool GzipFilter::isContentTypeAllowed(Http::HeaderMap& headers) const { | |||
} | |||
|
|||
bool GzipFilter::isEtagAllowed(Http::HeaderMap& headers) const { | |||
return !(config_->disableOnEtagHeader() && headers.Etag()); | |||
bool isEtagAllowed = !(config_->disableOnEtagHeader() && headers.Etag()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: all variables snake_case. There are other examples in the PR, please audit. Also, this var can be const bool
. Also other similar examples for this, please audit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah. Copy paste fail. Will fix.
Signed-off-by: Lita Cho <lcho@lyft.com>
Signed-off-by: Lita Cho <lcho@lyft.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, some more nits.
@@ -163,19 +170,36 @@ bool GzipFilter::isAcceptEncodingAllowed(Http::HeaderMap& headers) const { | |||
const auto q_value = StringUtil::trim(StringUtil::cropLeft(token, ";")); | |||
// If value is the gzip coding, check the qvalue and return. | |||
if (value == Http::Headers::get().AcceptEncodingValues.Gzip) { | |||
return !StringUtil::caseCompare(q_value, ZeroQvalueString); | |||
bool is_gzip = !StringUtil::caseCompare(q_value, ZeroQvalueString); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: const
@@ -191,15 +215,23 @@ bool GzipFilter::isContentTypeAllowed(Http::HeaderMap& headers) const { | |||
} | |||
|
|||
bool GzipFilter::isEtagAllowed(Http::HeaderMap& headers) const { | |||
return !(config_->disableOnEtagHeader() && headers.Etag()); | |||
bool is_etag_allowed = !(config_->disableOnEtagHeader() && headers.Etag()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: const
} | ||
|
||
bool GzipFilter::isMinimumContentLength(Http::HeaderMap& headers) const { | ||
const Http::HeaderEntry* content_length = headers.ContentLength(); | ||
if (content_length) { | ||
uint64_t length; | ||
return StringUtil::atoul(content_length->value().c_str(), length) && | ||
length >= config_->minimumLength(); | ||
bool is_minimum_content_length = StringUtil::atoul(content_length->value().c_str(), length) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: const
@@ -18,14 +19,43 @@ namespace Extensions { | |||
namespace HttpFilters { | |||
namespace Gzip { | |||
|
|||
/** | |||
* All gzip filter stats. @see stats_macros.h | |||
* Note that the total_bytes is only if the response |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is hard to understand. Rephrase?
@@ -35,6 +65,8 @@ class GzipFilterConfig { | |||
} | |||
|
|||
Runtime::Loader& runtime() { return runtime_; } | |||
GzipStats& stats() { return stats_; } | |||
const std::string stats_prefix() { return stats_prefix_; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed anymore
compressed, Counter, Number of requests compressed. | ||
not_compressed, Counter, Number of requests not compressed. | ||
no_accept_header, Counter, Number of requests with no accept header sent. | ||
header_identity, Counter, Number of requests sent with the "identity" set as the *accept-encoding*. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"with the" -> "with", same elsewhere where applicable
Signed-off-by: Lita Cho <lcho@lyft.com>
@mattklein123 this is ready for another look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, well done
gzip filter: add stats to filter and fix accept-encoding identity bug
Description: This PR adds stats to the gzip filter. In the process of adding stats, I noticed a bug where the filter compresses when the Accept-Encoding is set to identity. I believe that goes against the RFC, as no transformation or encoding should happen to the data when "identity" is set. https://tools.ietf.org/html/rfc7231#section-5.3.4
Risk Level: Low
Testing: unit and integration
Docs Changes: Updated the gzip filter docs to clarify the behavior with identity and added more details with q=0.
Release Notes: Added a change to the release notes as this is user impacting.