MEDIUM: WURFL: HTX awareness.

Now wurfl fetch process is fully  HTX aware.
diff --git a/src/wurfl.c b/src/wurfl.c
index ae3d2fc..d187601 100644
--- a/src/wurfl.c
+++ b/src/wurfl.c
@@ -10,6 +10,8 @@
 #include <proto/arg.h>
 #include <proto/log.h>
 #include <proto/proto_http.h>
+#include <proto/http_fetch.h>
+#include <proto/http_htx.h>
 #include <proto/sample.h>
 #include <ebsttree.h>
 #include <ebmbtree.h>
@@ -428,9 +430,27 @@
 	struct buffer *temp;
 	wurfl_information_t *wi;
 	ha_wurfl_header_t wh;
+	struct channel *chn;
 
 	ha_wurfl_log("WURFL: starting ha_wurfl_get_all\n");
+
+	chn = (smp->strm ? &smp->strm->req : NULL);
+
+	if (smp->px->options2 & PR_O2_USE_HTX) {
+		/* HTX version */
+		struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+
+		if (!htx) {
+			return 0;
+		}
+
+	} else {
+		/* Legacy version */
+		CHECK_HTTP_MESSAGE_FIRST(chn);
+	}
+
 	wh.wsmp = smp;
+
 	dHandle = wurfl_lookup(global_wurfl.handle, &ha_wurfl_retrieve_header, &wh);
 
 	temp = get_trash_chunk();
@@ -493,6 +513,7 @@
 		--smp->data.u.str.data;
 	}
 
+	smp->data.type = SMP_T_STR;
 	return 1;
 }
 
@@ -504,9 +525,27 @@
 	struct ebmb_node *node;
 	ha_wurfl_header_t wh;
 	int i = 0;
+	struct channel *chn;
 
 	ha_wurfl_log("WURFL: starting ha_wurfl_get\n");
+
+	chn = (smp->strm ? &smp->strm->req : NULL);
+
+	if (smp->px->options2 & PR_O2_USE_HTX) {
+		/* HTX version */
+		struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+
+		if (!htx) {
+			return 0;
+		}
+
+	} else {
+		/* Legacy version */
+		CHECK_HTTP_MESSAGE_FIRST(chn);
+	}
+
 	wh.wsmp = smp;
+
 	dHandle = wurfl_lookup(global_wurfl.handle, &ha_wurfl_retrieve_header, &wh);
 
 	temp = get_trash_chunk();
@@ -581,6 +620,7 @@
 		--smp->data.u.str.data;
 	}
 
+	smp->data.type = SMP_T_STR;
 	return 1;
 }
 
@@ -700,25 +740,80 @@
 static const char *ha_wurfl_retrieve_header(const char *header_name, const void *wh)
 {
 	struct sample *smp;
-	struct hdr_idx *idx;
-	struct hdr_ctx ctx;
-	const struct http_msg *msg;
+	struct channel *chn;
 	int header_len = HA_WURFL_MAX_HEADER_LENGTH;
 
-	ha_wurfl_log("WURFL: retrieve header request [%s]\n", header_name);
 	smp =  ((ha_wurfl_header_t *)wh)->wsmp;
-	idx = &smp->strm->txn->hdr_idx;
-	msg = &smp->strm->txn->req;
-	ctx.idx = 0;
+	chn = (smp->strm ? &smp->strm->req : NULL);
 
-	if (http_find_full_header2(header_name, strlen(header_name), ci_head(msg->chn), idx, &ctx) == 0)
-		return 0;
+	if (smp->px->options2 & PR_O2_USE_HTX) {
+		/* HTX version */
+		struct htx *htx;
+		struct http_hdr_ctx ctx;
+		struct ist name;
 
-	if (header_len > ctx.vlen)
-		header_len = ctx.vlen;
+		ha_wurfl_log("WURFL: retrieve header (HTX) request [%s]\n", header_name);
 
-	strncpy(((ha_wurfl_header_t *)wh)->header_value, ctx.line + ctx.val, header_len);
+		//the header is searched from the beginning
+		ctx.blk = NULL;
+
+		// We could skip this chek since ha_wurfl_retrieve_header is called from inside
+		// ha_wurfl_get()/ha_wurfl_get_all() that already perform the same check
+		// We choose to keep it in case ha_wurfl_retrieve_header will be called directly
+		htx = smp_prefetch_htx(smp, chn, 1);
+		if (!htx) {
+			return NULL;
+		}
+
+		name.ptr = (char *)header_name;
+		name.len = strlen(header_name);
+
+		// If 4th param is set, it works on full-line headers in whose comma is not a delimiter but is
+		// part of the syntax
+		if (!http_find_header(htx, name, &ctx, 1)) {
+			return NULL;
+		}
+
+		if (header_len > ctx.value.len)
+			header_len = ctx.value.len;
+
+		strncpy(((ha_wurfl_header_t *)wh)->header_value, ctx.value.ptr, header_len);
+
+	} else {
+		/* Legacy version */
+		struct http_txn *txn;
+		struct hdr_idx *idx;
+		struct hdr_ctx ctx;
+		int res;
+
+		ha_wurfl_log("WURFL: retrieve header (legacy) request [%s]\n", header_name);
+
+		// We could skip this chek since ha_wurfl_retrieve_header is called from inside
+		// ha_wurfl_get()/ha_wurfl_get_all() that already perform the same check
+		// We choose to keep it in case ha_wurfl_retrieve_header will be called directly
+		// This is a version of CHECK_HTTP_MESSAGE_FIRST(chn) which returns NULL in case of error
+		res = smp_prefetch_http(smp->px, smp->strm, smp->opt, (chn), smp, 1);
+		if (res <= 0) {
+			return NULL;
+		}
+
+		txn = smp->strm->txn;
+		idx = &txn->hdr_idx;
+
+		ctx.idx = 0;
+
+		if (http_find_full_header2(header_name, strlen(header_name), ci_head(chn), idx, &ctx) == 0)
+			return NULL;
+
+		if (header_len > ctx.vlen)
+			header_len = ctx.vlen;
+
+		strncpy(((ha_wurfl_header_t *)wh)->header_value, ctx.line + ctx.val, header_len);
+
+	}
+
 	((ha_wurfl_header_t *)wh)->header_value[header_len] = '\0';
+
 	ha_wurfl_log("WURFL: retrieve header request returns [%s]\n", ((ha_wurfl_header_t *)wh)->header_value);
 	return ((ha_wurfl_header_t *)wh)->header_value;
 }