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.
This commit is contained in:
Ben51Degrees 2019-06-12 15:19:12 +01:00 committed by Willy Tarreau
parent 3381022d88
commit 31a51f25d6

159
src/51d.c
View File

@ -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),
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_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,
#ifndef BUF_NULL
msg->chn->buf->p,
#else
ci_head(msg->chn),
#endif
idx,
&ctx) == 1) {
if (smp->px->options2 & PR_O2_USE_HTX) {
/* HTX version */
struct htx *htx;
struct http_hdr_ctx ctx;
struct ist name;
struct channel *chn;
(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++;
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,
#else
ci_head(msg->chn),
#endif
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
/* Needed to ensure that the HTTP message has been fully received when
* used with TCP operation. Not required for HTTP operation.
#endif
struct channel *chn;
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);
}
/*
* 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*/