MEDIUM: WURFL: HTX awareness.
Now wurfl fetch process is fully HTX aware.
diff --git a/src/wurfl.c b/src/wurfl.c
index ae3d2fc..d187601 100644
--- a/src/wurfl.c
+++ b/src/wurfl.c
@@ -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 @@
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 @@
--smp->data.u.str.data;
}
+ smp->data.type = SMP_T_STR;
return 1;
}
@@ -504,9 +525,27 @@
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 @@
--smp->data.u.str.data;
}
+ smp->data.type = SMP_T_STR;
return 1;
}
@@ -700,25 +740,80 @@
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);
- strncpy(((ha_wurfl_header_t *)wh)->header_value, ctx.line + ctx.val, header_len);
+ //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);
+
+ }
+
((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;
}