From: Dragan Dosen Date: Mon, 29 Jun 2015 14:43:25 +0000 (+0200) Subject: MEDIUM: 51Degrees code refactoring and cleanup X-Git-Tag: v1.6-dev3~44 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=93b38d9191a2f03d623cd697b509d00cd9b9d00f;p=thirdparty%2Fhaproxy.git MEDIUM: 51Degrees code refactoring and cleanup Moved 51Degrees code from src/haproxy.c, src/sample.c and src/cfgparse.c into a separate files src/51d.c and include/import/51d.h. Added two new functions init_51degrees() and deinit_51degrees(), updated Makefile and other code reorganizations related to 51Degrees. --- diff --git a/Makefile b/Makefile index 3438ab4af2..9389e22be1 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ # USE_NS : enable network namespace support. Supported on Linux >= 2.6.24. # USE_DL : enable it if your system requires -ldl. Automatic on Linux. # USE_DEVICEATLAS : enable DeviceAtlas api. -# USE_51DEGREES : enable third party device detection library from 51degrees +# USE_51DEGREES : enable third party device detection library from 51Degrees # # Options can be forced by specifying "USE_xxx=1" or can be disabled by using # "USE_xxx=" (empty string). @@ -604,7 +604,7 @@ endif ifneq ($(USE_DEVICEATLAS),) # Use DEVICEATLAS_SRC and possibly DEVICEATLAS_INC and DEVICEATLAS_LIB to force path -# to 51degrees headers and libraries if needed. +# to DeviceAtlas headers and libraries if needed. DEVICEATLAS_SRC = DEVICEATLAS_INC = $(DEVICEATLAS_SRC) DEVICEATLAS_LIB = $(DEVICEATLAS_SRC) @@ -621,6 +621,8 @@ ifneq ($(USE_51DEGREES),) 51DEGREES_SRC = 51DEGREES_INC = $(51DEGREES_SRC) 51DEGREES_LIB = $(51DEGREES_SRC) +OPTIONS_OBJS += $(51DEGREES_LIB)/51Degrees.o +OPTIONS_OBJS += src/51d.o OPTIONS_CFLAGS += -DUSE_51DEGREES $(if $(51DEGREES_INC),-I$(51DEGREES_INC)) BUILD_OPTIONS += $(call ignore_implicit,USE_51DEGREES) OPTIONS_LDFLAGS += $(if $(51DEGREES_LIB),-L$(51DEGREES_LIB)) -lz @@ -744,10 +746,6 @@ ifneq ($(TRACE),) OBJS += src/trace.o endif -ifneq ($(USE_51DEGREES),) -OBJS += $(51DEGREES_SRC)/51Degrees.o -endif - WRAPPER_OBJS = src/haproxy-systemd-wrapper.o # Not used right now diff --git a/README b/README index cda6fd910a..701207fa83 100644 --- a/README +++ b/README @@ -282,13 +282,13 @@ The configuration file needs to set the following parameters: 51degrees-data-file path to the pattern or trie data file 51degrees-property-name-list list of 51Degrees properties to detect - 51degrees-property-seperator seperator to use between values + 51degrees-property-separator separator to use between values The following is an example of the settings for Pattern. 51degrees-data-file '51D_REPO_PATH'/data/51Degrees-Lite.dat 51degrees-property-name-list IsTablet DeviceType IsMobile - 51degrees-property-seperator , + 51degrees-property-separator , HAProxy needs a way to pass device information to the backend servers. This is done by using the 51d converter, which intercepts the User-Agent header and @@ -307,7 +307,7 @@ and X-51D-Tablet. Any number of headers can be created this way and can be named anything. The User-Agent header is passed to the converter in req.fhdr(User-Agent). 51d( ) invokes the 51degrees converter. It can be passed up to five property names of values to return. Values will be returned in the -same order, seperated by the 51-degrees-property-seperator configured earlier. +same order, seperated by the 51-degrees-property-separator configured earlier. If a property name can't be found the value 'NoData' is returned instead. The free Lite data file contains information about screen size in pixels and diff --git a/doc/configuration.txt b/doc/configuration.txt index af71d09c40..c4c3d23ad8 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -542,7 +542,7 @@ The following keywords are supported in the "global" section : - unix-bind - 51degrees-data-file - 51degrees-property-name-list - - 51degrees-property-seperator + - 51degrees-property-separator * Performance tuning - max-spread-checks @@ -886,7 +886,7 @@ description Please note that this options is only available when haproxy has been compiled with USE_51DEGREES. -51degrees-property-seperator +51degrees-property-separator A char that will be appended to every property value in a response header containing 51Degrees results. If not set that will be set as ','. diff --git a/include/import/51d.h b/include/import/51d.h new file mode 100644 index 0000000000..2335c3535f --- /dev/null +++ b/include/import/51d.h @@ -0,0 +1,9 @@ +#ifndef _IMPORT_51D_H +#define _IMPORT_51D_H + +#include <51Degrees.h> + +int init_51degrees(void); +void deinit_51degrees(void); + +#endif diff --git a/include/types/global.h b/include/types/global.h index 921ef83d11..72024f8cfc 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -33,7 +33,7 @@ #include #ifdef USE_51DEGREES -#include <51Degrees.h> +#include #endif #ifndef UNIX_MAX_PATH @@ -185,25 +185,18 @@ struct global { char separator; } deviceatlas; #endif - #ifdef USE_51DEGREES - char _51d_property_seperator; /* the seperator to use in the response for the values. this is taken from 51degrees-property-seperator from config. */ - struct list _51d_property_names; /* list of properties to load into the data set. this is taken from 51degrees-property-name-list from config. */ - char * _51d_data_file_path; + struct { + char property_separator; /* the separator to use in the response for the values. this is taken from 51degrees-property-separator from config. */ + struct list property_names; /* list of properties to load into the data set. this is taken from 51degrees-property-name-list from config. */ + char *data_file_path; #ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED - fiftyoneDegreesDataSet _51d_data_set; /* data set used with the pattern detection method. */ + fiftyoneDegreesDataSet data_set; /* data set used with the pattern detection method. */ #endif - + } _51degrees; #endif }; -#ifdef USE_51DEGREES -struct _51d_property_names { - struct list list; - char *name; -}; -#endif - extern struct global global; extern int pid; /* current process id */ extern int relative_pid; /* process id starting at 1 */ diff --git a/src/51d.c b/src/51d.c new file mode 100644 index 0000000000..03cf742c85 --- /dev/null +++ b/src/51d.c @@ -0,0 +1,271 @@ +#include + +#include +#include +#include +#include +#include +#include + +#include + +struct _51d_property_names { + struct list list; + char *name; +}; + +static int _51d_data_file(char **args, int section_type, struct proxy *curpx, + struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, + "'%s' expects a filepath to a 51Degrees trie or pattern data file.", + args[0]); + return -1; + } + + if (global._51degrees.data_file_path) + free(global._51degrees.data_file_path); + global._51degrees.data_file_path = strdup(args[1]); + + return 0; +} + +static int _51d_property_name_list(char **args, int section_type, struct proxy *curpx, + struct proxy *defpx, const char *file, int line, + char **err) +{ + int cur_arg = 1; + struct _51d_property_names *name; + + if (*(args[cur_arg]) == 0) { + memprintf(err, + "'%s' expects at least one 51Degrees property name.", + args[0]); + return -1; + } + + while (*(args[cur_arg])) { + name = calloc(1, sizeof(struct _51d_property_names)); + name->name = strdup(args[cur_arg]); + LIST_ADDQ(&global._51degrees.property_names, &name->list); + ++cur_arg; + } + + return 0; +} + +static int _51d_property_separator(char **args, int section_type, struct proxy *curpx, + struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, + "'%s' expects a single character.", + args[0]); + return -1; + } + if (strlen(args[1]) > 1) { + memprintf(err, + "'%s' expects a single character, got '%s'.", + args[0], args[1]); + return -1; + } + + global._51degrees.property_separator = *args[1]; + + return 0; +} + +static int _51d_conv(const struct arg *args, struct sample *smp, void *private) +{ + int i; + char no_data[] = "NoData"; /* response when no data could be found */ + struct chunk *temp; +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + int j, found; + const char* property_name; + fiftyoneDegreesWorkset* ws; /* workset for detection */ +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + int device_offset; + int property_index; +#endif + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + /* Create workset. This will later contain detection results. */ + ws = fiftyoneDegreesCreateWorkset(&global._51degrees.data_set); + if (!ws) + return 0; +#endif + + smp->data.str.str[smp->data.str.len] = '\0'; + + /* Perform detection. */ +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesMatch(ws, smp->data.str.str); +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + device_offset = fiftyoneDegreesGetDeviceOffset(smp->data.str.str); +#endif + + i = 0; + temp = get_trash_chunk(); + chunk_reset(temp); + + /* Loop through property names passed to the filter and fetch them from the dataset. */ + while (args[i].data.str.str) { + /* Try to find request property in dataset. */ +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + found = 0; + for (j = 0; j < ws->dataSet->requiredPropertyCount; j++) { + property_name = fiftyoneDegreesGetPropertyName(ws->dataSet, ws->dataSet->requiredProperties[j]); + if (strcmp(property_name, args[i].data.str.str) == 0) { + found = 1; + fiftyoneDegreesSetValues(ws, j); + chunk_appendf(temp, "%s", fiftyoneDegreesGetValueName(ws->dataSet, *ws->values)); + break; + } + } + if (!found) { + chunk_appendf(temp, "%s", no_data); + } +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + property_index = fiftyoneDegreesGetPropertyIndex(args[i].data.str.str); + if (property_index > 0) { + chunk_appendf(temp, "%s", fiftyoneDegreesGetValue(device_offset, property_index)); + } + else { + chunk_appendf(temp, "%s", no_data); + } +#endif + /* Add separator. */ + chunk_appendf(temp, "%c", global._51degrees.property_separator); + ++i; + } + + if (temp->len) { + --temp->len; + temp->str[temp->len] = '\0'; + } + + smp->data.str.str = temp->str; + smp->data.str.len = strlen(smp->data.str.str); + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesFreeWorkset(ws); +#endif + + return 1; +} + +int init_51degrees(void) +{ + int i = 0; + struct chunk *temp; + struct _51d_property_names *name; + char **_51d_property_list = NULL; + fiftyoneDegreesDataSetInitStatus _51d_dataset_status = DATA_SET_INIT_STATUS_NOT_SET; + + if (!LIST_ISEMPTY(&global._51degrees.property_names)) { + i = 0; + list_for_each_entry(name, &global._51degrees.property_names, list) + ++i; + _51d_property_list = calloc(i, sizeof(char *)); + + i = 0; + list_for_each_entry(name, &global._51degrees.property_names, list) + _51d_property_list[i++] = name->name; + } + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + _51d_dataset_status = fiftyoneDegreesInitWithPropertyArray(global._51degrees.data_file_path, &global._51degrees.data_set, _51d_property_list, i); +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + _51d_dataset_status = fiftyoneDegreesInitWithPropertyArray(global._51degrees.data_file_path, _51d_property_list, i); +#endif + + temp = get_trash_chunk(); + chunk_reset(temp); + + switch (_51d_dataset_status) { + case DATA_SET_INIT_STATUS_SUCCESS: + break; + case DATA_SET_INIT_STATUS_INSUFFICIENT_MEMORY: + chunk_printf(temp, "Insufficient memory."); + break; + case DATA_SET_INIT_STATUS_CORRUPT_DATA: +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + chunk_printf(temp, "Corrupt data file. Check that the data file provided is uncompressed and Pattern data format."); +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + chunk_printf(temp, "Corrupt data file. Check that the data file provided is uncompressed and Trie data format."); +#endif + break; + case DATA_SET_INIT_STATUS_INCORRECT_VERSION: +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + chunk_printf(temp, "Incorrect version. Check that the data file provided is uncompressed and Pattern data format."); +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + chunk_printf(temp, "Incorrect version. Check that the data file provided is uncompressed and Trie data format."); +#endif + break; + case DATA_SET_INIT_STATUS_FILE_NOT_FOUND: + chunk_printf(temp, "File not found."); + break; + case DATA_SET_INIT_STATUS_NOT_SET: + chunk_printf(temp, "Data set not initialised."); + break; + } + if (_51d_dataset_status != DATA_SET_INIT_STATUS_SUCCESS) { + if (temp->len) + Alert("51Degrees Setup - Error reading 51Degrees data file. %s\n", temp->str); + else + Alert("51Degrees Setup - Error reading 51Degrees data file.\n"); + exit(1); + } + free(_51d_property_list); + + return 0; +} + +void deinit_51degrees(void) +{ + struct _51d_property_names *_51d_prop_name, *_51d_prop_nameb; + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesDestroy(&global._51degrees.data_set); +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + fiftyoneDegreesDestroy(); +#endif + + free(global._51degrees.data_file_path); global._51degrees.data_file_path = NULL; + list_for_each_entry_safe(_51d_prop_name, _51d_prop_nameb, &global._51degrees.property_names, list) { + LIST_DEL(&_51d_prop_name->list); + free(_51d_prop_name); + } +} + +static struct cfg_kw_list _51dcfg_kws = {{ }, { + { CFG_GLOBAL, "51degrees-data-file", _51d_data_file }, + { CFG_GLOBAL, "51degrees-property-name-list", _51d_property_name_list }, + { CFG_GLOBAL, "51degrees-property-separator", _51d_property_separator }, + { 0, NULL, NULL }, +}}; + +/* Note: must not be declared as its list will be overwritten */ +static struct sample_conv_kw_list conv_kws = {ILH, { + { "51d", _51d_conv, ARG5(1,STR,STR,STR,STR,STR), NULL, SMP_T_STR, SMP_T_STR }, + { NULL, NULL, 0, 0, 0 }, +}}; + +__attribute__((constructor)) +static void __51d_init(void) +{ + /* register sample fetch and format conversion keywords */ + sample_register_convs(&conv_kws); + cfg_register_keywords(&_51dcfg_kws); +} diff --git a/src/cfgparse.c b/src/cfgparse.c index 129cf17dc9..031fbbfde4 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -1766,48 +1766,6 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) goto out; #endif } -#ifdef USE_51DEGREES - else if (strcmp(args[0], "51degrees-data-file") == 0) { - if(!*(args[1])) { - Alert("parsing [%s:%d]: '%s' expects a filepath to a 51Degrees trie or pattern data file.\n", file, linenum, args[0]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - global._51d_data_file_path = strdup(args[1]); - } - else if (strcmp(args[0], "51degrees-property-seperator") == 0) { - if(!*(args[1])) { - Alert("parsing [%s:%d]: '%s' expects a single character.\n", file, linenum, args[0]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - if (strlen(args[1]) > 1) { - Alert("parsing [%s:%d]: '%s' expects a single character, got '%s'.\n", file, linenum, args[0], args[1]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - global._51d_property_seperator = *args[1]; - } - else if (strcmp(args[0], "51degrees-property-name-list") == 0) { - int arg; - struct _51d_property_names *name; - - arg = 1; - if (!*args[arg]) { - Alert("parsing [%s:%d]: '%s' expects at least one 51Degrees property name.\n", file, linenum, args[0]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - - LIST_INIT(&global._51d_property_names); - while (*args[arg]) { - name = calloc(1, sizeof(struct _51d_property_names)); - name->name = strdup(args[arg]); - LIST_ADDQ(&global._51d_property_names, &name->list); - ++arg; - } - } -#endif else { struct cfg_kw_list *kwl; int index; diff --git a/src/haproxy.c b/src/haproxy.c index 69a23275ff..f93502a4bf 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -117,7 +117,7 @@ #endif #ifdef USE_51DEGREES -#include <51Degrees.h> +#include #endif /*********************************************************************/ @@ -189,7 +189,14 @@ struct global global = { }, #endif #ifdef USE_51DEGREES - ._51d_property_names = LIST_HEAD_INIT(global._51d_property_names), + ._51degrees = { + .property_separator = ',', + .property_names = LIST_HEAD_INIT(global._51degrees.property_names), + .data_file_path = NULL, +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + .data_set = { }, +#endif + }, #endif /* others NULL OK */ }; @@ -550,12 +557,6 @@ void init(int argc, char **argv) char *progname; char *change_dir = NULL; struct tm curtime; -#ifdef USE_51DEGREES - int i = 0; - struct _51d_property_names *name; - char **_51d_property_list = NULL; - fiftyoneDegreesDataSetInitStatus _51d_dataset_status = DATA_SET_INIT_STATUS_NOT_SET; -#endif chunk_init(&trash, malloc(global.tune.bufsize), global.tune.bufsize); alloc_trash_buffers(global.tune.bufsize); @@ -819,6 +820,9 @@ void init(int argc, char **argv) #if defined(USE_DEVICEATLAS) init_deviceatlas(); #endif +#ifdef USE_51DEGREES + init_51degrees(); +#endif if (have_appsession) appsession_init(); @@ -1106,65 +1110,6 @@ void init(int argc, char **argv) /* initialize structures for name resolution */ if (!dns_init_resolvers()) exit(1); - -#ifdef USE_51DEGREES - if (!LIST_ISEMPTY(&global._51d_property_names)) { - i = 0; - list_for_each_entry(name, &global._51d_property_names, list) - ++i; - _51d_property_list = calloc(i, sizeof(char *)); - - i = 0; - list_for_each_entry(name, &global._51d_property_names, list) - _51d_property_list[i++] = name->name; - } - -#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED - _51d_dataset_status = fiftyoneDegreesInitWithPropertyArray(global._51d_data_file_path, _51d_property_list, i); -#endif -#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED - _51d_dataset_status = fiftyoneDegreesInitWithPropertyArray(global._51d_data_file_path, &global._51d_data_set, _51d_property_list, i); -#endif - chunk_reset(&trash); - - switch (_51d_dataset_status) { - case DATA_SET_INIT_STATUS_SUCCESS: - break; - case DATA_SET_INIT_STATUS_INSUFFICIENT_MEMORY: - chunk_printf(&trash, "Insufficient memory."); - break; - case DATA_SET_INIT_STATUS_CORRUPT_DATA: -#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED - chunk_printf(&trash, "Corrupt data file. Check that the data file provided is uncompressed and Trie data format."); -#endif -#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED - chunk_printf(&trash, "Corrupt data file. Check that the data file provided is uncompressed and Pattern data format."); -#endif - break; - case DATA_SET_INIT_STATUS_INCORRECT_VERSION: -#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED - chunk_printf(&trash, "Incorrect version. Check that the data file provided is uncompressed and Trie data format."); -#endif -#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED - chunk_printf(&trash, "Incorrect version. Check that the data file provided is uncompressed and Pattern data format."); -#endif - break; - case DATA_SET_INIT_STATUS_FILE_NOT_FOUND: - chunk_printf(&trash, "File not found."); - break; - case DATA_SET_INIT_STATUS_NOT_SET: - chunk_printf(&trash, "Data set not initialised."); - break; - } - if (_51d_dataset_status != DATA_SET_INIT_STATUS_SUCCESS) { - if (trash.len) - Alert("51Degrees Setup - Error reading 51Degrees data file. %s\n", trash.str); - else - Alert("51Degrees Setup - Error reading 51Degrees data file.\n"); - exit(1); - } - free(_51d_property_list); -#endif // USE_51DEGREES } static void deinit_acl_cond(struct acl_cond *cond) @@ -1261,9 +1206,6 @@ void deinit(void) struct logsrv *log, *logb; struct logformat_node *lf, *lfb; struct bind_conf *bind_conf, *bind_back; -#ifdef USE_51DEGREES - struct _51d_property_names *_51d_prop_name, *_51d_prop_nameb; -#endif int i; deinit_signals(); @@ -1517,18 +1459,8 @@ void deinit(void) #endif #ifdef USE_51DEGREES -#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED - fiftyoneDegreesDestroy(); -#endif -#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED - fiftyoneDegreesDestroy(&global._51d_data_set); + deinit_51degrees(); #endif - free(global._51d_data_file_path); global._51d_data_file_path = NULL; - list_for_each_entry_safe(_51d_prop_name, _51d_prop_nameb, &global._51d_property_names, list) { - LIST_DEL(&_51d_prop_name->list); - free(_51d_prop_name); - } -#endif // USE_51DEGREES free(global.log_send_hostname); global.log_send_hostname = NULL; free(global.log_tag); global.log_tag = NULL; diff --git a/src/sample.c b/src/sample.c index 425759b541..309ea11a2c 100644 --- a/src/sample.c +++ b/src/sample.c @@ -32,10 +32,6 @@ #include #include -#ifdef USE_51DEGREES -#include <51Degrees.h> -#endif - /* sample type names */ const char *smp_to_type[SMP_TYPES] = { [SMP_T_ANY] = "any", @@ -2187,122 +2183,6 @@ static int sample_conv_arith_even(const struct arg *arg_p, return 1; } -#ifdef USE_51DEGREES -#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED -static int -sample_fiftyone_degrees(const struct arg *args, struct sample *smp, void *private) -{ - int i; // used in loops. - int device_offset; - int property_index; - char no_data[] = "NoData"; // response when no data could be found. - struct chunk *tmp; - - // use a temporary trash buffer and copy data in it - smp->data.str.str[smp->data.str.len] = '\0'; - - // perform detection. - device_offset = fiftyoneDegreesGetDeviceOffset(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) { - // try to find request property in dataset. - property_index = fiftyoneDegreesGetPropertyIndex(args[i].data.str.str); - if (property_index > 0) { - chunk_appendf(tmp, "%s", fiftyoneDegreesGetValue(device_offset, property_index)); - } - else { - 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); - - return 1; -} -#endif // FIFTYONEDEGREES_H_TRIE_INCLUDED - -#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED -static int -sample_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. - const char* property_name; - 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. - for (j = 0; j < ws->dataSet->requiredPropertyCount; j++) { - property_name = fiftyoneDegreesGetPropertyName(ws->dataSet, ws->dataSet->requiredProperties[j]); - 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; - } - } - 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 // FIFTYONEDEGREES_H_PATTERN_INCLUDED -#endif // USE_51DEGREES - - /************************************************************************/ /* All supported sample fetch functions must be declared here */ /************************************************************************/ @@ -2596,9 +2476,6 @@ 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", sample_fiftyone_degrees,ARG5(1,STR,STR,STR,STR,STR), NULL, SMP_T_STR, SMP_T_STR }, -#endif { NULL, NULL, 0, 0, 0 }, }};