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;
 				}
 			}