Skip to content

Commit 678d786

Browse files
authored
[compress] Add an option to do not compress partial object (#12121)
1 parent 4d12805 commit 678d786

8 files changed

Lines changed: 127 additions & 34 deletions

File tree

doc/admin-guide/plugins/compress.en.rst

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,26 @@ range-request
108108

109109
This config controls behavior of this plugin when a client send ``Range`` header and ``Accept-Encoding`` header in the same time.
110110

111-
============== =================================================================
112-
Value Description
113-
============== =================================================================
114-
ignore-range Remove ``Range`` header if the request has both headers (Default)
115-
false Same as ``ignore-range`` for compatiblity
116-
no-compression Remove ``Accept-Encoding`` header if the request has both headers
117-
none Do nothing
118-
true Same as ``none`` for compatibility
119-
============== =================================================================
111+
====================== =================================================================
112+
Value Description
113+
====================== =================================================================
114+
none Do nothing
115+
true Same as ``none`` for compatibility
116+
remove-range Remove ``Range`` header if the request has both headers
117+
remove-accept-encoding Remove ``Accept-Encoding`` header if the request has both headers
118+
no-compression Do NOT compress Partial Content (default)
119+
false Same as ``no-compression`` for compatiblity
120+
====================== =================================================================
120121

121122
.. important::
122123

123124
Do NOT set this to ``none`` (or ``true``) if the cache config is set to ``false``. This combination will deliver corrupted content.
124125

126+
127+
.. important::
128+
129+
Some plugins (like cache_range_request) remove ``Range`` header. If you set ``remove-range`` or ``remove-accept-encoding``, be careful with the order of plugins.
130+
125131
compressible-content-type
126132
-------------------------
127133

plugins/compress/compress.cc

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ handle_range_request(TSMBuffer req_buf, TSMLoc req_loc, HostConfiguration *hc)
103103
debug("Both of Accept-Encoding and Range header are found in the request");
104104

105105
switch (hc->range_request_ctl()) {
106-
case RangeRequestCtrl::IGNORE_RANGE: {
107-
debug("Remove the Range header by ignore-range config");
106+
case RangeRequestCtrl::REMOVE_RANGE: {
107+
debug("Remove the Range header by remove-range config");
108108
while (range_hdr_field) {
109109
TSMLoc next_dup = TSMimeHdrFieldNextDup(req_buf, req_loc, range_hdr_field);
110110
TSMimeHdrFieldDestroy(req_buf, req_loc, range_hdr_field);
@@ -113,8 +113,8 @@ handle_range_request(TSMBuffer req_buf, TSMLoc req_loc, HostConfiguration *hc)
113113
}
114114
break;
115115
}
116-
case RangeRequestCtrl::NO_COMPRESSION: {
117-
debug("Remove the Accept-Encoding header by no-compression config");
116+
case RangeRequestCtrl::REMOVE_ACCEPT_ENCODING: {
117+
debug("Remove the Accept-Encoding header by remove-accept-encoding config");
118118
while (accept_encoding_hdr_field) {
119119
TSMLoc next_dup = TSMimeHdrFieldNextDup(req_buf, req_loc, accept_encoding_hdr_field);
120120
TSMimeHdrFieldDestroy(req_buf, req_loc, accept_encoding_hdr_field);
@@ -123,6 +123,10 @@ handle_range_request(TSMBuffer req_buf, TSMLoc req_loc, HostConfiguration *hc)
123123
}
124124
break;
125125
}
126+
case RangeRequestCtrl::NO_COMPRESSION:
127+
// Do NOT touch header - this config is referred by `transformable()` function
128+
debug("no header modification by no-compression config");
129+
break;
126130
case RangeRequestCtrl::NONE:
127131
[[fallthrough]];
128132
default:
@@ -733,6 +737,33 @@ transformable(TSHttpTxn txnp, bool server, HostConfiguration *host_configuration
733737
return 0;
734738
}
735739

740+
// check Partial Object is transformable
741+
if (host_configuration->range_request_ctl() == RangeRequestCtrl::NO_COMPRESSION) {
742+
// check Range header in client request
743+
// CAVETE: some plugin (- e.g. cache_range_request) tweaks client headers
744+
TSMLoc range_hdr_field = TSMimeHdrFieldFind(cbuf, chdr, TS_MIME_FIELD_RANGE, TS_MIME_LEN_RANGE);
745+
if (range_hdr_field != TS_NULL_MLOC) {
746+
debug("Range header found in the request and range_request is configured as no_compression");
747+
TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
748+
TSHandleMLocRelease(cbuf, chdr, range_hdr_field);
749+
TSHandleMLocRelease(cbuf, TS_NULL_MLOC, chdr);
750+
return 0;
751+
}
752+
753+
// check Content-Range header in (cached) server response
754+
TSMLoc content_range_hdr_field = TSMimeHdrFieldFind(bufp, hdr_loc, TS_MIME_FIELD_CONTENT_RANGE, TS_MIME_LEN_CONTENT_RANGE);
755+
if (content_range_hdr_field != TS_NULL_MLOC) {
756+
debug("Content-Range header found in the response and range_request is configured as no_compression");
757+
TSHandleMLocRelease(bufp, hdr_loc, content_range_hdr_field);
758+
TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
759+
TSHandleMLocRelease(cbuf, TS_NULL_MLOC, chdr);
760+
return 0;
761+
}
762+
763+
TSHandleMLocRelease(bufp, hdr_loc, content_range_hdr_field);
764+
TSHandleMLocRelease(cbuf, chdr, range_hdr_field);
765+
}
766+
736767
// the only compressible method is currently GET.
737768
int method_length;
738769
const char *method = TSHttpHdrMethodGet(cbuf, chdr, &method_length);
@@ -966,8 +997,8 @@ transform_plugin(TSCont contp, TSEvent event, void *edata)
966997
* 1. Reads the client request header
967998
* 2. For global plugin, get host configuration from global config
968999
* For remap plugin, get host configuration from configs populated through remap
969-
* 3. Check for Accept encoding
970-
* 4. Remove Range header
1000+
* 3. Check for Accept-Encoding header
1001+
* 4. Check for Range header
9711002
* 5. Schedules TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK and TS_HTTP_TXN_CLOSE_HOOK for
9721003
* further processing
9731004
*/

plugins/compress/configuration.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,16 +272,22 @@ HostConfiguration::compression_algorithms()
272272
return compression_algorithms_;
273273
}
274274

275+
/**
276+
"true" and "false" are compatibility with old version, will be removed
277+
*/
275278
void
276279
HostConfiguration::set_range_request(const std::string &token)
277280
{
278-
// "true" and "false" are compatibility with old version, will be removed
279-
if (token == "false" || token == "ignore-range") {
280-
range_request_ctl_ = RangeRequestCtrl::IGNORE_RANGE;
281-
} else if (token == "true" || token == "none") {
281+
if (token == "true" || token == "none") {
282282
range_request_ctl_ = RangeRequestCtrl::NONE;
283-
} else if (token == "no-compression") {
283+
} else if (token == "false" || token == "no-compression") {
284284
range_request_ctl_ = RangeRequestCtrl::NO_COMPRESSION;
285+
} else if (token == "remove-range") {
286+
range_request_ctl_ = RangeRequestCtrl::REMOVE_RANGE;
287+
} else if (token == "remove-accept-encoding") {
288+
range_request_ctl_ = RangeRequestCtrl::REMOVE_ACCEPT_ENCODING;
289+
} else {
290+
error("invalid token for range_request: %s", token.c_str());
285291
}
286292
}
287293

plugins/compress/configuration.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ enum CompressionAlgorithm {
4242
};
4343

4444
enum class RangeRequestCtrl : int {
45-
IGNORE_RANGE = 0, ///< Ignore Range Header (default)
46-
NO_COMPRESSION = 1, ///< Do NOT compress if it's a range request
47-
NONE = 2, ///< Do nothing
45+
NONE = 0, ///< Do nothing
46+
NO_COMPRESSION = 1, ///< Do NOT compress Partial Content (default)
47+
REMOVE_RANGE = 2, ///< Remove Range Header
48+
REMOVE_ACCEPT_ENCODING = 3, ///< Remove Accept-Encoding Header
4849
};
4950

5051
class HostConfiguration : private atscppapi::noncopyable
@@ -148,7 +149,7 @@ class HostConfiguration : private atscppapi::noncopyable
148149
int compression_algorithms_;
149150
unsigned int minimum_content_length_;
150151

151-
RangeRequestCtrl range_request_ctl_{RangeRequestCtrl::IGNORE_RANGE};
152+
RangeRequestCtrl range_request_ctl_ = RangeRequestCtrl::NO_COMPRESSION;
152153
StringContainer compressible_content_types_;
153154
StringContainer allows_;
154155
// maintain backwards compatibility/usability out of the box

tests/gold_tests/pluginTest/compress/compress-range.test.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,23 @@ def setupTS(self):
4242
"proxy.config.http.insert_response_via_str": 2,
4343
})
4444

45-
self.ts.Setup.Copy("etc/cache-true-ignore-range.config")
45+
self.ts.Setup.Copy("etc/cache-true-remove-range.config")
46+
self.ts.Setup.Copy("etc/cache-true-remove-accept-encoding.config")
4647
self.ts.Setup.Copy("etc/cache-true-no-compression.config")
4748

4849
self.ts.Disk.remap_config.AddLines(
4950
{
50-
f"map /cache-true-ignore-range/ http://127.0.0.1:{self.server.Variables.http_port}/ @plugin=compress.so @pparam={Test.RunDirectory}/cache-true-ignore-range.config",
51-
f"map /cache-true-no-compression/ http://127.0.0.1:{self.server.Variables.http_port}/ @plugin=compress.so @pparam={Test.RunDirectory}/cache-true-no-compression.config",
51+
f"""
52+
map /cache-true-remove-range/ http://127.0.0.1:{self.server.Variables.http_port}/ \
53+
@plugin=compress.so \
54+
@pparam={Test.RunDirectory}/cache-true-remove-range.config
55+
map /cache-true-remove-accept-encoding/ http://127.0.0.1:{self.server.Variables.http_port}/ \
56+
@plugin=compress.so \
57+
@pparam={Test.RunDirectory}/cache-true-remove-accept-encoding.config
58+
map /cache-true-no-compression/ http://127.0.0.1:{self.server.Variables.http_port}/ \
59+
@plugin=compress.so \
60+
@pparam={Test.RunDirectory}/cache-true-no-compression.config
61+
"""
5262
})
5363

5464
def run(self):
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cache true
2+
range-request remove-accept-encoding
3+
compressible-content-type application/json
4+
supported-algorithms gzip
5+
minimum-content-length 0

tests/gold_tests/pluginTest/compress/etc/cache-true-ignore-range.config renamed to tests/gold_tests/pluginTest/compress/etc/cache-true-remove-range.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cache true
2-
range-request ignore-range
2+
range-request remove-range
33
compressible-content-type application/json
44
supported-algorithms gzip
55
minimum-content-length 0

tests/gold_tests/pluginTest/compress/replay/compress-and-range.replay.yaml

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ sessions:
4545
#
4646
# ```
4747
# cache true
48-
# range-request ignore-range
48+
# range-request remove-range
4949
#```
5050
#
5151
# 1-1: Accept-Encoding only
5252
- client-request:
5353
method: "GET"
5454
version: "1.1"
55-
url: /cache-true-ignore-range/
55+
url: /cache-true-remove-range/
5656
headers:
5757
fields:
5858
- [ uuid, 1-1]
@@ -73,7 +73,7 @@ sessions:
7373
- client-request:
7474
method: "GET"
7575
version: "1.1"
76-
url: /cache-true-ignore-range/
76+
url: /cache-true-remove-range/
7777
headers:
7878
fields:
7979
- [ uuid, 1-2]
@@ -98,7 +98,7 @@ sessions:
9898
- client-request:
9999
method: "GET"
100100
version: "1.1"
101-
url: /cache-true-ignore-range/
101+
url: /cache-true-remove-range/
102102
headers:
103103
fields:
104104
- [ uuid, 1-3]
@@ -125,14 +125,14 @@ sessions:
125125
#
126126
# ```
127127
# cache true
128-
# range-request no-compression
128+
# range-request remove-accept-encoding
129129
#```
130130
#
131131
# 2-1: Range and Accept-Encoding
132132
- client-request:
133133
method: "GET"
134134
version: "1.1"
135-
url: /cache-true-no-compression/
135+
url: /cache-true-remove-accept-encoding/
136136
headers:
137137
fields:
138138
- [ uuid, 2-1]
@@ -154,3 +154,37 @@ sessions:
154154
fields:
155155
- [ Content-Length, { value: 10, as: equal } ]
156156

157+
# Test Case 3
158+
#
159+
# ```
160+
# cache true
161+
# range-request no-compression
162+
#```
163+
#
164+
# 3-1: Range and Accept-Encoding
165+
- client-request:
166+
method: "GET"
167+
version: "1.1"
168+
url: /cache-true-no-compression/
169+
headers:
170+
fields:
171+
- [ uuid, 3-1]
172+
- [ Host, example.com ]
173+
- [ Range, 0-9 ]
174+
- [ Accept-Encoding, gzip ]
175+
176+
proxy-request:
177+
headers:
178+
fields:
179+
- [ Range, { as: present } ]
180+
- [ Accept-Encoding, { as: present } ]
181+
182+
server-response:
183+
<<: *origin-server-response-206
184+
185+
proxy-response:
186+
status: 206
187+
headers:
188+
fields:
189+
- [ Content-Length, { value: 10, as: equal } ]
190+

0 commit comments

Comments
 (0)