BUG/MINOR: 51d/htx: The _51d_fetch method, and the methods it calls are now HTX aware.

The _51d_fetch method, and the two methods it calls to fetch HTTP
headers (_51d_set_device_offsets, and _51d_set_headers), now support
both legacy and HTX operation.

This should be backported to 1.9.
diff --git a/src/51d.c b/src/51d.c
index a79b4d7..bf40658 100644
--- a/src/51d.c
+++ b/src/51d.c
@@ -9,6 +9,7 @@
 #include <types/global.h>
 #include <proto/arg.h>
 #include <proto/http_fetch.h>
+#include <proto/http_htx.h>
 #include <proto/log.h>
 #include <proto/proto_http.h>
 #include <proto/sample.h>
@@ -226,31 +227,63 @@
  */
 static void _51d_set_headers(struct sample *smp, fiftyoneDegreesWorkset *ws)
 {
-	struct hdr_idx *idx;
-	struct hdr_ctx ctx;
-	const struct http_msg *msg;
 	int i;
 
-	idx = &smp->strm->txn->hdr_idx;
-	msg = &smp->strm->txn->req;
-
 	ws->importantHeadersCount = 0;
 
+	if (smp->px->options2 & PR_O2_USE_HTX) {
+		/* HTX version */
+		struct htx *htx;
+		struct http_hdr_ctx ctx;
+		struct ist name;
+		struct channel *chn;
+
+		chn = (smp->strm ? &smp->strm->req : NULL);
+
+		// No need to null check as this has already been carried out in the
+		// calling method
+		htx = smp_prefetch_htx(smp, chn, 1);
+
-	for (i = 0; i < global_51degrees.header_count; i++) {
-		ctx.idx = 0;
-		if (http_find_full_header2((global_51degrees.header_names + i)->area,
-					   (global_51degrees.header_names + i)->data,
+		for (i = 0; i < global_51degrees.header_count; i++) {
+			name.ptr = (global_51degrees.header_names + i)->area;
+			name.len = (global_51degrees.header_names + i)->data;
+			ctx.blk = NULL;
+
+			if (http_find_header(htx, name, &ctx, 1)) {
+				ws->importantHeaders[ws->importantHeadersCount].header = ws->dataSet->httpHeaders + i;
+				ws->importantHeaders[ws->importantHeadersCount].headerValue = ctx.value.ptr;
+				ws->importantHeaders[ws->importantHeadersCount].headerValueLength = ctx.value.len;
+				ws->importantHeadersCount++;
+			}
+		}
+
+	}
+	else {
+		/* Legacy Version */
+		struct hdr_idx *idx;
+		struct hdr_ctx ctx;
+		const struct http_msg *msg;
+
+		idx = &smp->strm->txn->hdr_idx;
+		msg = &smp->strm->txn->req;
+
+
+		for (i = 0; i < global_51degrees.header_count; i++) {
+			ctx.idx = 0;
+			if (http_find_full_header2((global_51degrees.header_names + i)->area,
+			                           (global_51degrees.header_names + i)->data,
 #ifndef BUF_NULL
-		                           msg->chn->buf->p,
+			                           msg->chn->buf->p,
 #else
-		                           ci_head(msg->chn),
+			                           ci_head(msg->chn),
 #endif
-		                           idx,
-		                           &ctx) == 1) {
-			ws->importantHeaders[ws->importantHeadersCount].header = ws->dataSet->httpHeaders + i;
-			ws->importantHeaders[ws->importantHeadersCount].headerValue = ctx.line + ctx.val;
-			ws->importantHeaders[ws->importantHeadersCount].headerValueLength = ctx.vlen;
-			ws->importantHeadersCount++;
+			                           idx,
+			                           &ctx) == 1) {
+				ws->importantHeaders[ws->importantHeadersCount].header = ws->dataSet->httpHeaders + i;
+				ws->importantHeaders[ws->importantHeadersCount].headerValue = ctx.line + ctx.val;
+				ws->importantHeaders[ws->importantHeadersCount].headerValueLength = ctx.vlen;
+				ws->importantHeadersCount++;
+			}
 		}
 	}
 }
@@ -266,30 +299,61 @@
 
 static void _51d_set_device_offsets(struct sample *smp, fiftyoneDegreesDeviceOffsets *offsets)
 {
-	struct hdr_idx *idx;
-	struct hdr_ctx ctx;
-	const struct http_msg *msg;
-	int index;
+	int i;
 
-	idx = &smp->strm->txn->hdr_idx;
-	msg = &smp->strm->txn->req;
 	offsets->size = 0;
 
+	if (smp->px->options2 & PR_O2_USE_HTX) {
+		/* HTX version */
+		struct htx *htx;
+		struct http_hdr_ctx ctx;
+		struct ist name;
+		struct channel *chn;
+
-	for (index = 0; index < global_51degrees.header_count; index++) {
-		ctx.idx = 0;
-		if (http_find_full_header2((global_51degrees.header_names + index)->area,
-					   (global_51degrees.header_names + index)->data,
+		chn = (smp->strm ? &smp->strm->req : NULL);
+
+		// No need to null check as this has already been carried out in the
+		// calling method
+		htx = smp_prefetch_htx(smp, chn, 1);
+
+		for (i = 0; i < global_51degrees.header_count; i++) {
+			name.ptr = (global_51degrees.header_names + i)->area;
+			name.len = (global_51degrees.header_names + i)->data;
+			ctx.blk = NULL;
+
+			if (http_find_header(htx, name, &ctx, 1)) {
+				(offsets->firstOffset + offsets->size)->httpHeaderOffset = *(global_51degrees.header_offsets + i);
+				(offsets->firstOffset + offsets->size)->deviceOffset = fiftyoneDegreesGetDeviceOffset(&global_51degrees.data_set, ctx.value.ptr);
+				offsets->size++;
+			}
+		}
+
+	}
+	else {
+		/* Legacy Version */
+		struct hdr_idx *idx;
+		struct hdr_ctx ctx;
+		const struct http_msg *msg;
+
+		idx = &smp->strm->txn->hdr_idx;
+		msg = &smp->strm->txn->req;
+
+
+		for (i = 0; i < global_51degrees.header_count; i++) {
+			ctx.idx = 0;
+			if (http_find_full_header2((global_51degrees.header_names + i)->area,
+			                          (global_51degrees.header_names + i)->data,
 #ifndef BUF_NULL
-		                           msg->chn->buf->p,
+			                          msg->chn->buf->p,
 #else
-		                           ci_head(msg->chn),
+			                          ci_head(msg->chn),
 #endif
-		                           idx,
-		                           &ctx) == 1) {
-
-			(offsets->firstOffset + offsets->size)->httpHeaderOffset = *(global_51degrees.header_offsets + index);
-			(offsets->firstOffset + offsets->size)->deviceOffset = fiftyoneDegreesGetDeviceOffset(&global_51degrees.data_set, ctx.line + ctx.val);
-			offsets->size++;
+			                          idx,
+			                          &ctx) == 1) {
+				(offsets->firstOffset + offsets->size)->httpHeaderOffset = *(global_51degrees.header_offsets + i);
+				(offsets->firstOffset + offsets->size)->deviceOffset = fiftyoneDegreesGetDeviceOffset(&global_51degrees.data_set, ctx.line + ctx.val);
+				offsets->size++;
+			}
 		}
 	}
 }
@@ -405,14 +469,25 @@
 #endif
 #ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED
 	fiftyoneDegreesDeviceOffsets *offsets; /* Offsets for detection */
+
 #endif
+	struct channel *chn;
+	chn = (smp->strm ? &smp->strm->req : NULL);
 
-	/* Needed to ensure that the HTTP message has been fully received when
-	 * used with TCP operation. Not required for HTTP operation.
+	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);
+	}
+	/*
 	 * Data type has to be reset to ensure the string output is processed
 	 * correctly.
 	 */
-	CHECK_HTTP_MESSAGE_FIRST((smp->strm ? &smp->strm->req : NULL));
 	smp->data.type = SMP_T_STR;
 
 	/* Flags the sample to show it uses constant memory*/