From: Ben51Degrees Date: Wed, 12 Jun 2019 14:19:12 +0000 (+0100) Subject: BUG/MINOR: 51d/htx: The _51d_fetch method, and the methods it calls are now HTX aware. X-Git-Tag: v2.0.0~60 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=31a51f25d634ed70f78fb297b8e49265df5230e3;p=thirdparty%2Fhaproxy.git 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 a79b4d7640..bf4065802c 100644 --- a/src/51d.c +++ b/src/51d.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -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*/