MAJOR: filters/http: Rewrite the HTTP compression as a filter

HTTP compression has been rewritten to use the filter API. This is more a PoC
than other thing for now. It allocates memory to work. So, if only for that, it
should be rewritten.

In the mean time, the implementation has been refactored to allow its use with
other filters. However, there are limitations that should be respected:

  - No filter placed after the compression one is allowed to change input data
    (in 'http_data' callback).
  - No filter placed before the compression one is allowed to change forwarded
    data (in 'http_forward_data' callback).

For now, these limitations are informal, so you should be careful when you use
several filters.

About the configuration, 'compression' keywords are still supported and must be
used to configure the HTTP compression behavior. In absence of a 'filter' line
for the compression filter, it is added in the filter chain when the first
compression' line is parsed. This is an easy way to do when you do not use other
filters. But another filter exists, an error is reported so that the user must
explicitly declare the filter.

For example:

  listen tst
      ...
      compression algo gzip
      compression offload
      ...
      filter flt_1
      filter compression
      filter flt_2
      ...
diff --git a/src/proto_http.c b/src/proto_http.c
index 3cb3b41..48d12f0 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -69,8 +69,6 @@
 #include <proto/pattern.h>
 #include <proto/vars.h>
 
-#include <proto/flt_http_comp.h> /* NOTE: temporary include, will be removed very soon */
-
 const char HTTP_100[] =
 	"HTTP/1.1 100 Continue\r\n\r\n";
 
@@ -4193,10 +4191,6 @@
 		if (!(s->flags & SF_FINST_MASK))
 			s->flags |= SF_FINST_R;
 
-		/* we may want to compress the stats page */
-		if (sess->fe->comp || s->be->comp)
-			select_compression_request_header(s, req->buf);
-
 		/* enable the minimally required analyzers to handle keep-alive and compression on the HTTP response */
 		req->analysers &= (AN_REQ_HTTP_BODY | AN_FLT_END);
 		req->analysers &= ~AN_FLT_XFER_DATA;
@@ -4335,9 +4329,6 @@
 		req->buf->i,
 		req->analysers);
 
-	if (sess->fe->comp || s->be->comp)
-		select_compression_request_header(s, req->buf);
-
 	/*
 	 * Right now, we know that we have processed the entire headers
 	 * and that unwanted requests have been filtered out. We can do
@@ -4942,15 +4933,11 @@
 
 		if (fe->mode == PR_MODE_HTTP) {
 			fe->fe_counters.p.http.rsp[n]++;
-			if (s->comp_algo && (s->flags & SF_COMP_READY))
-				fe->fe_counters.p.http.comp_rsp++;
 		}
 		if ((s->flags & SF_BE_ASSIGNED) &&
 		    (be->mode == PR_MODE_HTTP)) {
 			be->be_counters.p.http.rsp[n]++;
 			be->be_counters.p.http.cum_req++;
-			if (s->comp_algo && (s->flags & SF_COMP_READY))
-				be->be_counters.p.http.comp_rsp++;
 		}
 	}
 
@@ -6289,7 +6276,6 @@
 	    (txn->status >= 100 && txn->status < 200) ||
 	    txn->status == 204 || txn->status == 304) {
 		msg->flags |= HTTP_MSGF_XFER_LEN;
-		s->comp_algo = NULL;
 		goto skip_content_length;
 	}
 
@@ -6339,9 +6325,6 @@
 		msg->body_len = msg->chunk_len = cl;
 	}
 
-	if (sess->fe->comp || s->be->comp)
-		select_compression_response_header(s, rep->buf);
-
 skip_content_length:
 	/* Now we have to check if we need to modify the Connection header.
 	 * This is more difficult on the response than it is on the request,
@@ -7038,8 +7021,7 @@
 	if (msg->sov > 0)
 		msg->sov -= ret;
 
-	if ((s->comp_algo == NULL || msg->msg_state >= HTTP_MSG_TRAILERS) &&
-	    LIST_ISEMPTY(&s->strm_flt.filters))
+	if (LIST_ISEMPTY(&s->strm_flt.filters))
 		msg->chunk_len -= channel_forward(res, msg->chunk_len);
 
 	if (res->flags & CF_SHUTW)
@@ -7073,7 +7055,8 @@
 	 * Similarly, with keep-alive on the client side, we don't want to forward a
 	 * close.
 	 */
-	if ((msg->flags & HTTP_MSGF_TE_CHNK) || s->comp_algo || !msg->body_len ||
+	if ((msg->flags & HTTP_MSGF_TE_CHNK) || !msg->body_len ||
+	    (msg->flags & HTTP_MSGF_COMPRESSING) ||
 	    (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
 	    (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL)
 		channel_dont_close(res);
@@ -7086,7 +7069,7 @@
 	 * flag with the last block of forwarded data, which would cause an
 	 * additional delay to be observed by the receiver.
 	 */
-	if ((msg->flags & HTTP_MSGF_TE_CHNK) || s->comp_algo)
+	if ((msg->flags & HTTP_MSGF_TE_CHNK) || (msg->flags & HTTP_MSGF_COMPRESSING))
 		res->flags |= CF_EXPECT_MORE;
 
 	/* the stream handler will take care of timeouts and errors */
@@ -8810,12 +8793,6 @@
 	struct http_txn *txn = s->txn;
 	struct proxy *fe = strm_fe(s);
 
-	/* release any possible compression context */
-	if (s->flags & SF_COMP_READY)
-		s->comp_algo->end(&s->comp_ctx);
-	s->comp_algo = NULL;
-	s->flags &= ~SF_COMP_READY;
-
 	/* these ones will have been dynamically allocated */
 	pool_free2(pool2_requri, txn->uri);
 	pool_free2(pool2_capture, txn->cli_cookie);