From: Thomas Holmes Date: Wed, 13 May 2015 10:27:35 +0000 (+0100) Subject: MEDIUM: sample: add fiftyone_degrees converter. X-Git-Tag: v1.6-dev2~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=951d44d24d078b3fa2fdd7ac2f1fcfa3d91ec57a;p=thirdparty%2Fhaproxy.git MEDIUM: sample: add fiftyone_degrees converter. It takes up to 5 string arguments that are to be 51Degrees property names. It will then create a chunk with values detected based on the request header supplied (this should be the User-Agent). --- diff --git a/src/sample.c b/src/sample.c index 47d48c8ba9..6418be83d9 100644 --- a/src/sample.c +++ b/src/sample.c @@ -32,6 +32,10 @@ #include #include +#ifdef USE_51DEGREES +#include <51Degrees.h> +#endif + /* sample type names */ const char *smp_to_type[SMP_TYPES] = { [SMP_T_BOOL] = "bool", @@ -2125,6 +2129,69 @@ static int sample_conv_arith_even(const struct arg *arg_p, return 1; } +#ifdef USE_51DEGREES +static int fiftyone_degrees(const struct arg *args, + struct sample *smp, void *private) +{ + int i, j, found; // used in loops. + fiftyoneDegreesWorkset* ws; // workset for detection. + char no_data[] = "NoData"; // response when no data could be found. + struct _51d_property_names *property; + struct chunk *tmp; + + // use a temporary trash buffer and copy data in it + smp->data.str.str[smp->data.str.len] = '\0'; + + // create workset. this will later contain detection results. + ws = fiftyoneDegreesCreateWorkset(&global._51d_data_set); + if (!ws) + return 0; + + // perform detection. + fiftyoneDegreesMatch(ws, smp->data.str.str); + + i = 0; + tmp = get_trash_chunk(); + chunk_reset(tmp); + // loop through property names passed to the filter and fetch them from the dataset. + while (args[i].data.str.str) { + found = j = 0; + // try to find request property in dataset. + list_for_each_entry(property, &global._51d_property_names, list) { + if (strcmp(property->name, args[i].data.str.str) == 0) { + found = 1; + fiftyoneDegreesSetValues(ws, j); + chunk_appendf(tmp, "%s", fiftyoneDegreesGetValueName(ws->dataSet, *ws->values)); + break; + } + ++j; + } + if (!found) + chunk_appendf(tmp, "%s", no_data); + + // add seperator + if (global._51d_property_seperator) + chunk_appendf(tmp, "%c", global._51d_property_seperator); + else + chunk_appendf(tmp, ","); + ++i; + } + + if (tmp->len) { + --tmp->len; + tmp->str[tmp->len] = '\0'; + } + + smp->data.str.str = tmp->str; + smp->data.str.len = strlen(smp->data.str.str); + + fiftyoneDegreesFreeWorkset(ws); + + return 1; +} +#endif + + /************************************************************************/ /* All supported sample fetch functions must be declared here */ /************************************************************************/ @@ -2278,6 +2345,9 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, { { "div", sample_conv_arith_div, ARG1(1,UINT), NULL, SMP_T_UINT, SMP_T_UINT }, { "mod", sample_conv_arith_mod, ARG1(1,UINT), NULL, SMP_T_UINT, SMP_T_UINT }, { "neg", sample_conv_arith_neg, 0, NULL, SMP_T_UINT, SMP_T_UINT }, +#ifdef USE_51DEGREES + { "51d", fiftyone_degrees, ARG5(1,STR,STR,STR,STR,STR), NULL, SMP_T_STR, SMP_T_STR }, +#endif { NULL, NULL, 0, 0, 0 }, }};