]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: compression: add an offload option to remove the Accept-Encoding header
authorWilly Tarreau <w@1wt.eu>
Fri, 26 Oct 2012 22:34:28 +0000 (00:34 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 26 Oct 2012 23:13:24 +0000 (01:13 +0200)
This is used when it is desired that backend servers don't compress
(eg: because of buggy implementations).

doc/configuration.txt
include/types/compression.h
src/cfgparse.c
src/proto_http.c

index 2c427f3aa7ae498caf6cb780ef8079ea19185b00..acf3099de83e7d78de893766423568f25009729e 100644 (file)
@@ -1780,12 +1780,24 @@ clitimeout <timeout> (deprecated)
 
 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
index 96dd10772398e1203958f29ee17f865606c29fd2..10ac4b1159768f0304d5b738c2b6828760353766 100644 (file)
@@ -28,6 +28,7 @@
 struct comp {
        struct comp_algo *algos;
        struct comp_type *types;
+       unsigned int offload;
 };
 
 struct comp_algo {
index 971371d18a05d44d2605357f1a2736eabb6d5513..ef3be08fd6fd2994f43cf1814814c13d255b830c 100644 (file)
@@ -5273,6 +5273,9 @@ stats_error_parsing:
                                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 @@ stats_error_parsing:
                        }
                }
                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;
index 31d49f9997f1eb2da78a492ba4ab02db2a192624..6167f1f175929c48cab5215e356f1e8711e63e1c 100644 (file)
@@ -1974,6 +1974,7 @@ static inline int http_skip_chunk_crlf(struct http_msg *msg)
 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 @@ int select_compression_request_header(struct session *s, struct buffer *req)
                        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;
                                }
                        }