]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: sample: add fiftyone_degrees converter.
authorThomas Holmes <tom@51degrees.com>
Wed, 13 May 2015 10:27:35 +0000 (11:27 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 2 Jun 2015 12:00:25 +0000 (14:00 +0200)
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).

src/sample.c

index 47d48c8ba9e526bc1f605b3f2d5b1b61e2d07e01..6418be83d992727012365ca46af2d190c8fe827b 100644 (file)
 #include <proto/sample.h>
 #include <proto/stick_table.h>
 
+#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 },
 }};