-
Notifications
You must be signed in to change notification settings - Fork 5.5k
filters: add generic compressor filter #7057
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
Changes from 63 commits
321d72e
86d8f82
fd920c4
6a1f90f
207d983
eeb4c4f
054be50
1a8853b
5124466
0405f89
ae31978
c05bcbd
a239574
6a373cd
07b4974
d27b53e
36cd2d3
a71137c
a8c86ef
7cbdadd
19a2cfa
f7960f9
5942a8e
12e6281
bf2710a
bb5b24b
a6c6c46
3164191
ff14601
134187b
a8522dd
decc691
ffbd399
b961274
e7a928f
59db2c2
dec3407
f376068
2a9a12a
9f389b0
ce23b42
676d676
c68e451
1e6f7bf
5f9d88d
e8bab57
edaecd2
96dc9d4
dd64763
1f3aa75
5296095
e7c5fc0
98533ba
b034b87
8693478
0e8656f
93ebd44
41f9843
859bb4c
f408dc6
bed9247
da69508
09d0ca8
afa48c6
54b47e9
8ceb6d8
dbc2e91
adb9ce6
9ea11ca
6b98708
d7bd763
9fe7a41
e99b4c1
8b1ff4e
0b38c92
4cb988e
ad73448
2bbbeb2
ee50131
d414cb8
3d50681
3d6bbb5
0df08ac
3d8d556
68e3a60
1264376
4461a7a
6b3a23e
1f89041
4a70888
50e7300
31324f2
70ef5fc
d2c385d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # DO NOT EDIT. This file is generated by tools/proto_sync.py. | ||
|
|
||
| load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") | ||
|
|
||
| licenses(["notice"]) # Apache 2 | ||
|
|
||
| api_proto_package() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| package envoy.config.filter.http.compressor.v2; | ||
|
|
||
| option java_outer_classname = "CompressorProto"; | ||
| option java_multiple_files = true; | ||
| option java_package = "io.envoyproxy.envoy.config.filter.http.compressor.v2"; | ||
|
|
||
| import "google/protobuf/wrappers.proto"; | ||
|
|
||
| // [#protodoc-title: Compressor] | ||
|
|
||
| message Compressor { | ||
| // Minimum response length, in bytes, which will trigger compression. The default value is 30. | ||
| google.protobuf.UInt32Value content_length = 1; | ||
|
|
||
| // Set of strings that allows specifying which mime-types yield compression; e.g., | ||
| // application/json, text/html, etc. When this field is not defined, compression will be applied | ||
| // to the following mime-types: "application/javascript", "application/json", | ||
|
mattklein123 marked this conversation as resolved.
|
||
| // "application/xhtml+xml", "image/svg+xml", "text/css", "text/html", "text/plain", "text/xml". | ||
| repeated string content_type = 2; | ||
|
|
||
| // If true, disables compression when the response contains an etag header. When it is false, the | ||
| // filter will preserve weak etags and remove the ones that require strong validation. | ||
| bool disable_on_etag_header = 3; | ||
|
|
||
| // If true, removes accept-encoding from the request headers before dispatching it to the upstream | ||
| // so that responses do not get compressed before reaching the filter. | ||
| bool remove_accept_encoding_header = 4; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # DO NOT EDIT. This file is generated by tools/proto_sync.py. | ||
|
|
||
| load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") | ||
|
|
||
| licenses(["notice"]) # Apache 2 | ||
|
|
||
| api_proto_package( | ||
| deps = ["//envoy/config/filter/http/compressor/v2:pkg"], | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| package envoy.config.filter.http.gzip.v3alpha; | ||
|
|
||
| option java_outer_classname = "GzipProto"; | ||
| option java_multiple_files = true; | ||
| option java_package = "io.envoyproxy.envoy.config.filter.http.gzip.v3alpha"; | ||
|
|
||
| import "envoy/config/filter/http/compressor/v2/compressor.proto"; | ||
|
|
||
| import "google/protobuf/wrappers.proto"; | ||
|
|
||
| import "validate/validate.proto"; | ||
|
|
||
| // [#protodoc-title: Gzip] | ||
| // Gzip :ref:`configuration overview <config_http_filters_gzip>`. | ||
|
|
||
| // [#next-free-field: 11] | ||
| message Gzip { | ||
| enum CompressionStrategy { | ||
| DEFAULT = 0; | ||
| FILTERED = 1; | ||
| HUFFMAN = 2; | ||
| RLE = 3; | ||
| } | ||
|
|
||
| message CompressionLevel { | ||
| enum Enum { | ||
| DEFAULT = 0; | ||
| BEST = 1; | ||
| SPEED = 2; | ||
| } | ||
| } | ||
|
|
||
| reserved 2, 6, 7, 8; | ||
|
|
||
| reserved "content_length", "content_type", "disable_on_etag_header", | ||
| "remove_accept_encoding_header"; | ||
|
|
||
| // Value from 1 to 9 that controls the amount of internal memory used by zlib. Higher values | ||
| // use more memory, but are faster and produce better compression results. The default value is 5. | ||
| google.protobuf.UInt32Value memory_level = 1 [(validate.rules).uint32 = {lte: 9 gte: 1}]; | ||
|
|
||
| // A value used for selecting the zlib compression level. This setting will affect speed and | ||
| // amount of compression applied to the content. "BEST" provides higher compression at the cost of | ||
| // higher latency, "SPEED" provides lower compression with minimum impact on response time. | ||
| // "DEFAULT" provides an optimal result between speed and compression. This field will be set to | ||
| // "DEFAULT" if not specified. | ||
| CompressionLevel.Enum compression_level = 3 [(validate.rules).enum = {defined_only: true}]; | ||
|
|
||
| // A value used for selecting the zlib compression strategy which is directly related to the | ||
| // characteristics of the content. Most of the time "DEFAULT" will be the best choice, though | ||
| // there are situations which changing this parameter might produce better results. For example, | ||
| // run-length encoding (RLE) is typically used when the content is known for having sequences | ||
| // which same data occurs many consecutive times. For more information about each strategy, please | ||
| // refer to zlib manual. | ||
| CompressionStrategy compression_strategy = 4 [(validate.rules).enum = {defined_only: true}]; | ||
|
|
||
| // Value from 9 to 15 that represents the base two logarithmic of the compressor's window size. | ||
| // Larger window results in better compression at the expense of memory usage. The default is 12 | ||
| // which will produce a 4096 bytes window. For more details about this parameter, please refer to | ||
| // zlib manual > deflateInit2. | ||
| google.protobuf.UInt32Value window_bits = 9 [(validate.rules).uint32 = {lte: 15 gte: 9}]; | ||
|
|
||
| // Set of configuration parameters common for all compression filters. If this field is set then | ||
| // the fields `content_length`, `content_type`, `disable_on_etag_header` and | ||
| // `remove_accept_encoding_header` are ignored. | ||
| compressor.v2.Compressor compressor = 10; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,7 +45,8 @@ By *default* compression will be *skipped* when: | |
| 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 whose *accept-encoding* header includes "identity". | ||
| - A request whose *accept-encoding* header includes any encoding type with a higher | ||
| weight than "gzip"'s. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what the universe of compression algorithms look like, but I wonder if there's a scenario where several different compression algorithms should be tried, with the results content-dependent. It seems like this semantic imposes a strict ordering on the compressors and you'll only try the highest weighted one; is that right? Or is this a natural limitation of the semantics of the q= fields in the accept-encodings header?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I try the highest weighted one. I' m going to clarify a bit this statement by updating it to
But now I see an issue: let's say the "gzip" filter is configured to compress text only and "brotli" to compress JPEGs only, then a request comes with "Accept-Encoding: gzip;q=1, br;q=.5" and the response contains "Content-Type: image/jpg". In this case no compression would be applied at all with the current implementation. I guess the decision on which filter to use should be delayed until "Content-Type" is known. And it should be done in the scope of this PR, because it will become important when "brotli" is added to Envoy.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jmarantz PTAL. Now the decision which filter to use is delayed until content-type is known. |
||
| - A response contains a *content-encoding* header. | ||
| - A response contains a *cache-control* header whose value includes "no-transform". | ||
| - A response contains a *transfer-encoding* header whose value includes "gzip". | ||
|
|
@@ -80,7 +81,9 @@ Every configured Gzip filter has statistics rooted at <stat_prefix>.gzip.* with | |
| 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 "identity" set as the *accept-encoding*. | ||
| header_gzip, Counter, Number of requests sent with "gzip" set as the *accept-encoding*. | ||
| header_gzip, Counter, Number of requests sent with "gzip" set as the *accept-encoding*. This counter is deprecated in favour of *header_compressor_used*. | ||
| header_compressor_used, Counter, Number of requests sent with "gzip" set as the *accept-encoding*. | ||
| header_compressor_overshadowed, Counter, Number of requests sent with encoding types other than "gzip" and "identity" set as the *accept-encoding*. | ||
| header_wildcard, Counter, Number of requests sent with "\*" set as the *accept-encoding*. | ||
| header_not_valid, Counter, Number of requests sent with a not valid *accept-encoding* header (aka "q=0" or an unsupported encoding type). | ||
| total_uncompressed_bytes, Counter, The total uncompressed bytes of all the requests that were marked for compression. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| licenses(["notice"]) # Apache 2 | ||
|
|
||
| load( | ||
| "//bazel:envoy_build_system.bzl", | ||
| "envoy_cc_library", | ||
| "envoy_package", | ||
| ) | ||
|
|
||
| envoy_package() | ||
|
|
||
| envoy_cc_library( | ||
| name = "compressor_lib", | ||
| srcs = ["compressor.cc"], | ||
| hdrs = ["compressor.h"], | ||
| deps = [ | ||
| "//include/envoy/compressor:compressor_interface", | ||
| "//include/envoy/http:filter_interface", | ||
| "//include/envoy/runtime:runtime_interface", | ||
| "//include/envoy/stats:stats_macros", | ||
| "//include/envoy/stream_info:filter_state_interface", | ||
| "//source/common/buffer:buffer_lib", | ||
| "//source/common/common:lock_guard_lib", | ||
| "//source/common/common:thread_lib", | ||
| "//source/common/http:header_map_lib", | ||
| "//source/common/protobuf", | ||
| "@envoy_api//envoy/config/filter/http/compressor/v2:pkg_cc_proto", | ||
| ], | ||
| ) |
Uh oh!
There was an error while loading. Please reload this page.