BUG/MAJOR: http: use a static storage for sample fetch context

Baptiste Assmann reported that the cook*() ACLs do not work anymore.

The reason is the way we store the hdr_ctx between subsequent calls
to smp_fetch_cookie() since commit 3740635b (1.5-dev10).

The smp->ctx.a[] storage holds up to 8 pointers. It is not meant for
generic storage. We used to store hdr_ctx in the ctx, but while it used
to just fit for smp_fetch_hdr(), it does not for smp_fetch_cookie()
since we stored it at offset 2.

The correct solution is to use this storage to store a pointer to the
current hdr_ctx struct which is statically allocated.
diff --git a/src/proto_http.c b/src/proto_http.c
index 087cd47..e7d84ce 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -220,6 +220,9 @@
  */
 struct chunk http_err_chunks[HTTP_ERR_SIZE];
 
+/* this struct is used between calls to smp_fetch_hdr() or smp_fetch_cookie() */
+static struct hdr_ctx static_hdr_ctx;
+
 #define FD_SETS_ARE_BITFIELDS
 #ifdef FD_SETS_ARE_BITFIELDS
 /*
@@ -8660,12 +8663,19 @@
 {
 	struct http_txn *txn = l7;
 	struct hdr_idx *idx = &txn->hdr_idx;
-	struct hdr_ctx *ctx = (struct hdr_ctx *)smp->ctx.a;
+	struct hdr_ctx *ctx = smp->ctx.a[0];
 	const struct http_msg *msg = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) ? &txn->req : &txn->rsp;
 	int occ = 0;
 	const char *name_str = NULL;
 	int name_len = 0;
 
+	if (!ctx) {
+		/* first call */
+		ctx = &static_hdr_ctx;
+		ctx->idx = 0;
+		smp->ctx.a[2] = ctx;
+	}
+
 	if (args) {
 		if (args[0].type != ARGT_STR)
 			return 0;
@@ -9116,7 +9126,7 @@
 
 /* Iterate over all cookies present in a message. The context is stored in
  * smp->ctx.a[0] for the in-header position, smp->ctx.a[1] for the
- * end-of-header-value, and smp->ctx.a[2] for the hdr_idx. Depending on
+ * end-of-header-value, and smp->ctx.a[2] for the hdr_ctx. Depending on
  * the direction, multiple cookies may be parsed on the same line or not.
  * The cookie name is in args and the name length in args->data.str.len.
  * Accepts exactly 1 argument of type string. If the input options indicate
@@ -9128,7 +9138,7 @@
 {
 	struct http_txn *txn = l7;
 	struct hdr_idx *idx = &txn->hdr_idx;
-	struct hdr_ctx *ctx = (struct hdr_ctx *)&smp->ctx.a[2];
+	struct hdr_ctx *ctx = smp->ctx.a[2];
 	const struct http_msg *msg;
 	const char *hdr_name;
 	int hdr_name_len;
@@ -9139,6 +9149,13 @@
 	if (!args || args->type != ARGT_STR)
 		return 0;
 
+	if (!ctx) {
+		/* first call */
+		ctx = &static_hdr_ctx;
+		ctx->idx = 0;
+		smp->ctx.a[2] = ctx;
+	}
+
 	CHECK_HTTP_MESSAGE_FIRST();
 
 	if ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) {