MINOR: compression: add an offload option to remove the Accept-Encoding header
This is used when it is desired that backend servers don't compress
(eg: because of buggy implementations).
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 2c427f3..acf3099 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1780,12 +1780,24 @@
compression algo [ gzip ] ...
compression type ...
+compression offload
Enable HTTP compression.
May be used in sections : defaults | frontend | listen | backend
yes | yes | yes | yes
Arguments :
algo is followed by the list of supported compression algorithms.
type is followed by the list of MIME types that will be compressed.
+ offload makes haproxy work as a compression offloader only (see notes).
+
+ The "offload" setting makes haproxy remove the Accept-Encoding header to
+ prevent backend servers from compressing responses. It is strongly
+ recommended not to do this because this means that all the compression work
+ will be done on the single point where haproxy is located. However in some
+ deployment scenarios, haproxy may be installed in front of a buggy gateway
+ and need to prevent it from emitting invalid payloads. In this case, simply
+ removing the header in the configuration does not work because it applies
+ before the header is parsed, so that prevents haproxy from compressing. The
+ "offload" setting should then be used for such scenarios.
Examples :
compression algo gzip
diff --git a/include/types/compression.h b/include/types/compression.h
index 96dd107..10ac4b1 100644
--- a/include/types/compression.h
+++ b/include/types/compression.h
@@ -28,6 +28,7 @@
struct comp {
struct comp_algo *algos;
struct comp_type *types;
+ unsigned int offload;
};
struct comp_algo {
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 971371d..ef3be08 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -5273,6 +5273,9 @@
continue;
}
}
+ else if (!strcmp(args[1], "offload")) {
+ comp->offload = 1;
+ }
else if (!strcmp(args[1], "type")) {
int cur_arg;
cur_arg = 2;
@@ -5289,7 +5292,7 @@
}
}
else {
- Alert("parsing [%s:%d] : '%s' expects algo or type\n",
+ Alert("parsing [%s:%d] : '%s' expects 'algo', 'type' or 'offload'\n",
file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
diff --git a/src/proto_http.c b/src/proto_http.c
index 31d49f9..6167f1f 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -1974,6 +1974,7 @@
int select_compression_request_header(struct session *s, struct buffer *req)
{
struct http_txn *txn = &s->txn;
+ struct http_msg *msg = &txn->req;
struct hdr_ctx ctx;
struct comp_algo *comp_algo = NULL;
struct comp_algo *comp_algo_back = NULL;
@@ -2006,6 +2007,17 @@
for (comp_algo = comp_algo_back; comp_algo; comp_algo = comp_algo->next) {
if (word_match(ctx.line + ctx.val, ctx.vlen, comp_algo->name, comp_algo->name_len)) {
s->comp_algo = comp_algo;
+
+ /* remove all occurrences of the header when "compression offload" is set */
+
+ if ((s->be->comp && s->be->comp->offload) ||
+ (s->fe->comp && s->fe->comp->offload)) {
+ http_remove_header2(msg, &txn->hdr_idx, &ctx);
+ ctx.idx = 0;
+ while (http_find_header2("Accept-Encoding", 15, req->p, &txn->hdr_idx, &ctx)) {
+ http_remove_header2(msg, &txn->hdr_idx, &ctx);
+ }
+ }
return 1;
}
}