MEDIUM: filters: Move HTTP headers filtering in its own callback

Instead of calling 'channel_analyze' callback with the flag AN_FLT_HTTP_HDRS,
now we use the new callback 'http_headers'. This change is done because
'channel_analyze' callback will be removed in a next commit.
diff --git a/include/types/filters.h b/include/types/filters.h
index 34818cf..e01e225 100644
--- a/include/types/filters.h
+++ b/include/types/filters.h
@@ -87,6 +87,10 @@
  *                          it needs to wait, any other value otherwise.
  *
  *
+ *  - http_headers        : Called before the body parsing, after all HTTP
+ *                          headers was parsed and analyzed.
+ *                          Returns a negative value if an error occurs, 0 if
+ *                          it needs to wait, any other value otherwise.
  *  - http_data           : Called when unparsed body data are available.
  *                          Returns a negative value if an error occurs, else
  *                          the number of consumed bytes.
@@ -142,6 +146,7 @@
 	/*
 	 * HTTP callbacks
 	 */
+	int  (*http_headers)       (struct stream *s, struct filter *f, struct http_msg *msg);
 	int  (*http_data)          (struct stream *s, struct filter *f, struct http_msg *msg);
 	int  (*http_chunk_trailers)(struct stream *s, struct filter *f, struct http_msg *msg);
 	int  (*http_end)           (struct stream *s, struct filter *f, struct http_msg *msg);
diff --git a/src/filters.c b/src/filters.c
index e96af31..051aa48 100644
--- a/src/filters.c
+++ b/src/filters.c
@@ -680,20 +680,21 @@
 }
 
 /*
- * This function do the same that the previsous one, but for the
- * AN_FLT_HTTP_HDRS analyzer. The difference is what is done when all filters
- * have been called. Returns 0 if an error occurs or if it needs to wait, any
- * other value otherwise.
+ * This function is the AN_FLT_HTTP_HDRS analyzer, used to filter HTTP headers
+ * or a request or a response. Returns 0 if an error occurs or if it needs to
+ * wait, any other value otherwise.
  */
 int
 flt_analyze_http_headers(struct stream *s, struct channel *chn, unsigned int an_bit)
 {
-	struct filter *filter;
-	int            ret = 1;
+	struct filter   *filter;
+	struct http_msg *msg;
+	int              ret = 1;
 
+	msg = ((chn->flags & CF_ISRESP) ? &s->txn->rsp : &s->txn->req);
 	RESUME_FILTER_LOOP(s, chn) {
-		if (FLT_OPS(filter)->channel_analyze) {
-			ret = FLT_OPS(filter)->channel_analyze(s, filter, chn, an_bit);
+		if (FLT_OPS(filter)->http_headers) {
+			ret = FLT_OPS(filter)->http_headers(s, filter, msg);
 			if (ret <= 0)
 				BREAK_EXECUTION(s, chn, check_result);
 		}
@@ -707,9 +708,7 @@
 		/* Handle "data" filters only */
 		if (!IS_DATA_FILTER(filter, chn))
 			continue;
-
-		FLT_NXT(filter, chn) = ((chn->flags & CF_ISRESP)
-					? s->txn->rsp.sov : s->txn->req.sov);
+		FLT_NXT(filter, chn) = msg->sov;
 	}
 
  check_result:
diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c
index fb431c1..9ddc858 100644
--- a/src/flt_http_comp.c
+++ b/src/flt_http_comp.c
@@ -103,31 +103,6 @@
 }
 
 static int
-comp_analyze(struct stream *s, struct filter *filter, struct channel *chn,
-	     unsigned int an_bit)
-{
-	struct comp_state *st = filter->ctx;
-
-	if (!strm_fe(s)->comp && !s->be->comp)
-		goto end;
-
-	if (an_bit == AN_FLT_HTTP_HDRS) {
-		if (!(chn->flags & CF_ISRESP))
-			select_compression_request_header(st, s, &s->txn->req);
-		else {
-			select_compression_response_header(st, s, &s->txn->rsp);
-			if (st->comp_algo) {
-				register_data_filter(s, chn, filter);
-				st->hdrs_len = s->txn->rsp.sov;
-			}
-		}
-	}
-
-  end:
-	return 1;
-}
-
-static int
 comp_end_analyze(struct stream *s, struct filter *filter, struct channel *chn)
 {
 	struct comp_state *st = filter->ctx;
@@ -154,6 +129,28 @@
 }
 
 static int
+comp_http_headers(struct stream *s, struct filter *filter, struct http_msg *msg)
+{
+	struct comp_state *st = filter->ctx;
+
+	if (!strm_fe(s)->comp && !s->be->comp)
+		goto end;
+
+	if (!(msg->chn->flags & CF_ISRESP))
+		select_compression_request_header(st, s, msg);
+	else {
+		select_compression_response_header(st, s, msg);
+		if (st->comp_algo) {
+			register_data_filter(s, msg->chn, filter);
+			st->hdrs_len = s->txn->rsp.sov;
+		}
+	}
+
+  end:
+	return 1;
+}
+
+static int
 comp_http_data(struct stream *s, struct filter *filter, struct http_msg *msg)
 {
 	struct comp_state *st = filter->ctx;
@@ -756,9 +753,9 @@
 	.deinit = comp_flt_deinit,
 
 	.channel_start_analyze = comp_start_analyze,
-	.channel_analyze       = comp_analyze,
 	.channel_end_analyze   = comp_end_analyze,
 
+	.http_headers          = comp_http_headers,
 	.http_data             = comp_http_data,
 	.http_chunk_trailers   = comp_http_chunk_trailers,
 	.http_forward_data     = comp_http_forward_data,
diff --git a/src/flt_trace.c b/src/flt_trace.c
index 8b47651..8a9d14d 100644
--- a/src/flt_trace.c
+++ b/src/flt_trace.c
@@ -21,6 +21,7 @@
 #include <types/stream.h>
 
 #include <proto/filters.h>
+#include <proto/hdr_idx.h>
 #include <proto/log.h>
 #include <proto/stream.h>
 
@@ -196,9 +197,6 @@
 		case AN_REQ_HTTP_XFER_BODY:
 			ana = "AN_REQ_HTTP_XFER_BODY";
 			break;
-		case AN_REQ_ALL:
-			ana = "AN_REQ_ALL";
-			break;
 		case AN_RES_INSPECT:
 			ana = "AN_RES_INSPECT";
 			break;
@@ -211,15 +209,9 @@
 		case AN_RES_STORE_RULES:
 			ana = "AN_RES_STORE_RULES";
 			break;
-		case AN_FLT_HTTP_HDRS:
-			ana = "AN_FLT_HTTP_HDRS";
-			break;
 		case AN_RES_HTTP_XFER_BODY:
 			ana = "AN_RES_HTTP_XFER_BODY";
 			break;
-		case AN_FLT_XFER_DATA:
-			ana = "AN_FLT_XFER_DATA";
-			break;
 		default:
 			ana = "unknown";
 	}
@@ -248,6 +240,33 @@
  * Hooks to filter HTTP messages
  *************************************************************************/
 static int
+trace_http_headers(struct stream *s, struct filter *filter,
+		   struct http_msg *msg)
+{
+	struct trace_config *conf = FLT_CONF(filter);
+	struct hdr_idx      *hdr_idx;
+	char                *cur_hdr;
+	int                  cur_idx;
+
+	STRM_TRACE(conf, s, "%-25s: channel=%-10s - mode=%-5s (%s)",
+		   __FUNCTION__,
+		   channel_label(msg->chn), proxy_mode(s), stream_pos(s));
+
+	STRM_TRACE(conf, s, "\t%.*s", MIN(msg->sl.rq.l, 74), msg->chn->buf->p);
+	hdr_idx = &s->txn->hdr_idx;
+	cur_idx = hdr_idx_first_idx(hdr_idx);
+	cur_hdr = msg->chn->buf->p + hdr_idx_first_pos(hdr_idx);
+	while (cur_idx) {
+		STRM_TRACE(conf, s, "\t%.*s",
+			   MIN(hdr_idx->v[cur_idx].len, 74), cur_hdr);
+		cur_hdr += hdr_idx->v[cur_idx].len + hdr_idx->v[cur_idx].cr + 1;
+		cur_idx = hdr_idx->v[cur_idx].next;
+	}
+	register_data_filter(s, msg->chn, filter);
+	return 1;
+}
+
+static int
 trace_http_data(struct stream *s, struct filter *filter,
 		      struct http_msg *msg)
 {
@@ -398,6 +417,7 @@
 	.channel_end_analyze   = trace_chn_end_analyze,
 
 	/* Filter HTTP requests and responses */
+	.http_headers        = trace_http_headers,
 	.http_data           = trace_http_data,
 	.http_chunk_trailers = trace_http_chunk_trailers,
 	.http_end            = trace_http_end,