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

compression: add generic decompressor filter #11172

Merged
merged 65 commits into from
May 26, 2020
Merged

compression: add generic decompressor filter #11172

merged 65 commits into from
May 26, 2020

Conversation

junr03
Copy link
Member

@junr03 junr03 commented May 12, 2020

Commit Message: add generic decompressor filter
Additional Description: this PR takes the design of the compressor filter, and uses the decompressor extension point to build a generic decompressor http filter. This filter can be used to decompress compressed payloads both on the request and response direction.
Risk Level: low - low as it is an extension, med - for users as this is a brand new filter.
Testing: unit tests, integration tests
Docs Changes: added docs
Release Notes: added release notes

Jose Nino added 30 commits April 10, 2020 11:44
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
…atted

Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
fmt
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
wip
Signed-off-by: Jose Nino <jnino@lyft.com>
wip
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
fmt
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
fmt
Signed-off-by: Jose Nino <jnino@lyft.com>
Copy link
Member

@rojkov rojkov left a comment

Choose a reason for hiding this comment

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

Yes, it definitely makes sense to buffer streams in a dedicated filter. I missed there's such filter.

// A decompressor library to use for decompression. Currently only
// :ref:`envoy.compression.gzip.compressor<envoy_api_msg_extensions.compression.gzip.decompressor.v3.Gzip>`
// is included in Envoy.
config.core.v3.TypedExtensionConfig decompressor_library = 1
Copy link
Member

Choose a reason for hiding this comment

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

That was my concern too: that might surprise if some options are configured separately and some are not. I'd probably prefer to configure two separate decompressor filters configured differently for different directions. But now with bufferization moved out it looks much better. I like it.

Perhaps the message's hierarchy could be flatter with request_direction_config.common_config.advertise_accept_encoding changed to just request_advertise_accept_encoding. Though I don't have strong opinion.

Copy link
Contributor

@rebello95 rebello95 left a comment

Choose a reason for hiding this comment

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

A few comments, but LGTM overall!

Jose Nino added 4 commits May 18, 2020 17:13
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
@junr03
Copy link
Member Author

junr03 commented May 19, 2020

@rojkov, @rebello95 updated if you can take a look

rebello95
rebello95 previously approved these changes May 19, 2020
Copy link
Contributor

@rebello95 rebello95 left a comment

Choose a reason for hiding this comment

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

LGTM

Jose Nino added 2 commits May 20, 2020 08:06
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
@junr03
Copy link
Member Author

junr03 commented May 20, 2020

@mattklein123 this is now ready for you! Thanks

@mattklein123 mattklein123 marked this pull request as ready for review May 20, 2020 20:56
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Nice work! Just a few high level comments/questions. Thank you!

/wait

Comment on lines 52 to 54
RequestDirectionConfig request_direction_config = 2;

ResponseDirectionConfig response_direction_config = 3;
Copy link
Member

Choose a reason for hiding this comment

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

Can you add docs here to explain what this config does and what happens if it is not set? Presumably if empty it doesn't decompress in the given direction?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, bears repeating here what I wrote in the runtime field.

The default is actually to decompress if empty. Do you prefer to not decompress if empty?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's fine either way I would just clearly document it as it wasn't clear to me on first read through.

// A decompressor library to use for decompression. Currently only
// :ref:`envoy.compression.gzip.compressor<envoy_api_msg_extensions.compression.gzip.decompressor.v3.Gzip>`
// is included in Envoy.
config.core.v3.TypedExtensionConfig decompressor_library = 1
Copy link
Member

Choose a reason for hiding this comment

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

FWIW it seemed odd to me that we don't allow this to be configured differently in each direction? Can you at least clarify this applies to both the request and response configuration depending on whether they are configured or not?


When decompression is *applied*:

- The *content-length* is removed from headers.
Copy link
Member

Choose a reason for hiding this comment

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

Is this going to break some uses cases? Is it a future work item that we might want to buffer the decompressed data and rewrite content-length?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, sorry @mattklein123 , this context got dropped because github didn't allow me to move my original PR over.

We discussed here: https://github.com/junr03/envoy/pull/1#discussion_r411669576

And then I had this idea: #11172 (comment)

tl;dr: I originally implemented buffering here. But then decided to remove (and depend on the buffer filter) to keep this filter simpler. wdyt?

Copy link
Member

Choose a reason for hiding this comment

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

Does the buffer filter reset content length? Anyway I think that's fine but I might make that clear in the documentation that the user might want to couple this with the buffer filter.

Copy link
Member Author

Choose a reason for hiding this comment

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

Does the buffer filter reset content length?

Yep, it sets it if not present, which made it ideal for this arrangement.

void BufferFilter::maybeAddContentLength() {

Yeah I can add a section in the docs about it 👌

Copy link
Member Author

Choose a reason for hiding this comment

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

Ultimately the issue is that the setup would still be a bit kludgy because of filter ordering, and the fact that the buffer filter can't be disabled independently for requests and responses. For Lyft's use case it'll be fine because we don't need to preserve content-length on responses.

So at the end of the day it might make sense to have this filter pay the price and do buffering itself. My proposal is to leave as is (with the new docs I added) to get this PR in, and then I can open an issue with a link to the commit that had buffering, it would just need to be updated a bit, and integration tests written (which shouldn't be hard at all). I can get to it as a low-pri.

Copy link
Member

Choose a reason for hiding this comment

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

I think it's fine to document the limitation and we can revisit later.

@@ -9,11 +9,15 @@ namespace Decompressor {
namespace {
const uint32_t DefaultWindowBits = 12;
const uint32_t DefaultChunkSize = 4096;
// When summed to window bits, this tells zlib library to decompress gzip data per:
Copy link
Member

Choose a reason for hiding this comment

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

nit: s/summed/logical ORd or something like that (even though sum is technically correct I think this is more clear)

Jose Nino added 2 commits May 21, 2020 15:30
Signed-off-by: Jose Nino <jnino@lyft.com>
fmt
Signed-off-by: Jose Nino <jnino@lyft.com>
@junr03 junr03 requested a review from dio as a code owner May 21, 2020 22:37
mattklein123
mattklein123 previously approved these changes May 21, 2020
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

LGTM modulo the comment about the compression config. Not sure if you are still planning on fixing that or not.

Signed-off-by: Jose Nino <jnino@lyft.com>
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

I think this is fine to ship and we can reevaluate the config later depending on feedback. Thank you!

@junr03 junr03 merged commit 48a5b21 into envoyproxy:master May 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants