MEDIUM: da: HTX mode support.

The DeviceAtlas module now can support both the legacy
mode and the new HTX's with the known set of support headers
for the latter.
This commit is contained in:
David CARLIER 2019-04-24 20:41:53 +01:00 committed by Willy Tarreau
parent 0470d704a7
commit 4de0eba848
1 changed files with 147 additions and 65 deletions

View File

@ -7,6 +7,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>
@ -285,20 +286,101 @@ static int da_haproxy_conv(const struct arg *args, struct sample *smp, void *pri
static int da_haproxy_fetch(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct hdr_idx *hidx;
struct hdr_ctx hctx;
const struct http_msg *hmsg;
da_evidence_t ev[DA_MAX_HEADERS];
da_deviceinfo_t devinfo;
da_status_t status;
struct channel *chn;
char vbuf[DA_MAX_HEADERS][1024] = {{ 0 }};
int i, nbh = 0;
if (global_deviceatlas.daset == 0) {
return 1;
return 0;
}
CHECK_HTTP_MESSAGE_FIRST((smp->strm ? &smp->strm->req : NULL));
chn = (smp->strm ? &smp->strm->req : NULL);
/* HTX Mode check */
if (smp->px->options2 & PR_O2_USE_HTX) {
struct htx_blk *blk;
struct htx *htx = smp_prefetch_htx(smp, chn, 1);
if (!htx) {
return 0;
}
i = 0;
for (blk = htx_get_head_blk(htx); nbh < DA_MAX_HEADERS && blk; blk = htx_get_next_blk(htx, blk)) {
size_t vlen;
char *pval;
da_evidence_id_t evid;
enum htx_blk_type type;
struct ist n, v;
char hbuf[24] = { 0 };
char tval[1024] = { 0 };
type = htx_get_blk_type(blk);
if (type == HTX_BLK_HDR) {
n = htx_get_blk_name(htx, blk);
v = htx_get_blk_value(htx, blk);
} else if (type == HTX_BLK_EOH) {
break;
} else {
continue;
}
/* The HTTP headers used by the DeviceAtlas API are not longer */
if (n.len >= sizeof(hbuf)) {
continue;
}
memcpy(hbuf, n.ptr, n.len);
hbuf[n.len] = 0;
pval = v.ptr;
vlen = v.len;
evid = -1;
i = v.len > sizeof(tval) - 1 ? sizeof(tval) - 1 : v.len;
memcpy(tval, v.ptr, i);
tval[i] = 0;
pval = tval;
if (strcasecmp(hbuf, "Accept-Language") == 0) {
evid = da_atlas_accept_language_evidence_id(&global_deviceatlas.atlas);
} else if (strcasecmp(hbuf, "Cookie") == 0) {
char *p, *eval;
size_t pl;
eval = pval + vlen;
/**
* The cookie value, if it exists, is located between the current header's
* value position and the next one
*/
if (http_extract_cookie_value(pval, eval, global_deviceatlas.cookiename,
global_deviceatlas.cookienamelen, 1, &p, &pl) == NULL) {
continue;
}
vlen -= global_deviceatlas.cookienamelen - 1;
pval = p;
evid = da_atlas_clientprop_evidence_id(&global_deviceatlas.atlas);
} else {
evid = da_atlas_header_evidence_id(&global_deviceatlas.atlas, hbuf);
}
if (evid == -1) {
continue;
}
i = vlen > sizeof(vbuf[nbh]) - 1 ? sizeof(vbuf[nbh]) - 1 : vlen;
memcpy(vbuf[nbh], pval, i);
vbuf[nbh][i] = 0;
ev[nbh].key = evid;
ev[nbh].value = vbuf[nbh];
++ nbh;
}
} else {
struct hdr_idx *hidx;
struct hdr_ctx hctx;
const struct http_msg *hmsg;
CHECK_HTTP_MESSAGE_FIRST(chn);
smp->data.type = SMP_T_STR;
/**
@ -360,9 +442,9 @@ static int da_haproxy_fetch(const struct arg *args, struct sample *smp, const ch
vbuf[nbh][i - 1] = 0;
ev[nbh].key = evid;
ev[nbh].value = vbuf[nbh];
ev[nbh].value[vlen] = 0;
++ nbh;
}
}
status = da_searchv(&global_deviceatlas.atlas, &devinfo,
ev, nbh);