MEDIUM: WURFL: HTX awareness.

Now wurfl fetch process is fully  HTX aware.
This commit is contained in:
mbellomi 2019-05-21 17:15:07 +02:00 committed by Willy Tarreau
parent 9896981675
commit 2c07700098
1 changed files with 107 additions and 12 deletions

View File

@ -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 @@ static int ha_wurfl_get_all(const struct arg *args, struct sample *smp, const ch
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 @@ static int ha_wurfl_get_all(const struct arg *args, struct sample *smp, const ch
--smp->data.u.str.data;
}
smp->data.type = SMP_T_STR;
return 1;
}
@ -504,9 +525,27 @@ static int ha_wurfl_get(const struct arg *args, struct sample *smp, const char *
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 @@ static int ha_wurfl_get(const struct arg *args, struct sample *smp, const char *
--smp->data.u.str.data;
}
smp->data.type = SMP_T_STR;
return 1;
}
@ -700,25 +740,80 @@ static const char *(*ha_wurfl_get_property_callback(char *name)) (wurfl_handle w
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);
//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);
}
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;
}