]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: 51d/htx: The _51d_fetch method, and the methods it calls are now HTX aware.
authorBen51Degrees <Ben@51Degrees.com>
Wed, 12 Jun 2019 14:19:12 +0000 (15:19 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 12 Jun 2019 16:06:59 +0000 (18:06 +0200)
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.

src/51d.c

index a79b4d7640a16931902037cbb240e7c2153f67c2..bf4065802cd5f4f96a0ab876cc35f911b9056051 100644 (file)
--- 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_retrieve_cache_entry(struct sample *smp, struct lru64 *lru)
  */
 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;
 
-       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,
+       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++) {
+                       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),
-#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++;
+                                                  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++;
+                       }
                }
        }
 }
@@ -266,30 +299,61 @@ static void _51d_init_device_offsets(fiftyoneDegreesDeviceOffsets *offsets) {
 
 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;
 
-       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,
+       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++) {
+                       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 @@ static int _51d_fetch(const struct arg *args, struct sample *smp, const char *kw
 #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*/