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.
This commit is contained in:
Dragan Dosen 2015-06-29 16:43:25 +02:00 committed by Willy Tarreau
parent e44136fe69
commit 93b38d9191
9 changed files with 309 additions and 271 deletions

View File

@ -39,7 +39,7 @@
# USE_NS : enable network namespace support. Supported on Linux >= 2.6.24. # 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_DL : enable it if your system requires -ldl. Automatic on Linux.
# USE_DEVICEATLAS : enable DeviceAtlas api. # 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 # Options can be forced by specifying "USE_xxx=1" or can be disabled by using
# "USE_xxx=" (empty string). # "USE_xxx=" (empty string).
@ -604,7 +604,7 @@ endif
ifneq ($(USE_DEVICEATLAS),) ifneq ($(USE_DEVICEATLAS),)
# Use DEVICEATLAS_SRC and possibly DEVICEATLAS_INC and DEVICEATLAS_LIB to force path # 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_SRC =
DEVICEATLAS_INC = $(DEVICEATLAS_SRC) DEVICEATLAS_INC = $(DEVICEATLAS_SRC)
DEVICEATLAS_LIB = $(DEVICEATLAS_SRC) DEVICEATLAS_LIB = $(DEVICEATLAS_SRC)
@ -621,6 +621,8 @@ ifneq ($(USE_51DEGREES),)
51DEGREES_SRC = 51DEGREES_SRC =
51DEGREES_INC = $(51DEGREES_SRC) 51DEGREES_INC = $(51DEGREES_SRC)
51DEGREES_LIB = $(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)) OPTIONS_CFLAGS += -DUSE_51DEGREES $(if $(51DEGREES_INC),-I$(51DEGREES_INC))
BUILD_OPTIONS += $(call ignore_implicit,USE_51DEGREES) BUILD_OPTIONS += $(call ignore_implicit,USE_51DEGREES)
OPTIONS_LDFLAGS += $(if $(51DEGREES_LIB),-L$(51DEGREES_LIB)) -lz OPTIONS_LDFLAGS += $(if $(51DEGREES_LIB),-L$(51DEGREES_LIB)) -lz
@ -744,10 +746,6 @@ ifneq ($(TRACE),)
OBJS += src/trace.o OBJS += src/trace.o
endif endif
ifneq ($(USE_51DEGREES),)
OBJS += $(51DEGREES_SRC)/51Degrees.o
endif
WRAPPER_OBJS = src/haproxy-systemd-wrapper.o WRAPPER_OBJS = src/haproxy-systemd-wrapper.o
# Not used right now # Not used right now

6
README
View File

@ -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-data-file path to the pattern or trie data file
51degrees-property-name-list list of 51Degrees properties to detect 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. The following is an example of the settings for Pattern.
51degrees-data-file '51D_REPO_PATH'/data/51Degrees-Lite.dat 51degrees-data-file '51D_REPO_PATH'/data/51Degrees-Lite.dat
51degrees-property-name-list IsTablet DeviceType IsMobile 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 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 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 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 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 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. 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 The free Lite data file contains information about screen size in pixels and

View File

@ -542,7 +542,7 @@ The following keywords are supported in the "global" section :
- unix-bind - unix-bind
- 51degrees-data-file - 51degrees-data-file
- 51degrees-property-name-list - 51degrees-property-name-list
- 51degrees-property-seperator - 51degrees-property-separator
* Performance tuning * Performance tuning
- max-spread-checks - max-spread-checks
@ -886,7 +886,7 @@ description <text>
Please note that this options is only available when haproxy has been Please note that this options is only available when haproxy has been
compiled with USE_51DEGREES. compiled with USE_51DEGREES.
51degrees-property-seperator <char> 51degrees-property-separator <char>
A char that will be appended to every property value in a response header 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 ','. containing 51Degrees results. If not set that will be set as ','.

9
include/import/51d.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _IMPORT_51D_H
#define _IMPORT_51D_H
#include <51Degrees.h>
int init_51degrees(void);
void deinit_51degrees(void);
#endif

View File

@ -33,7 +33,7 @@
#include <types/task.h> #include <types/task.h>
#ifdef USE_51DEGREES #ifdef USE_51DEGREES
#include <51Degrees.h> #include <import/51d.h>
#endif #endif
#ifndef UNIX_MAX_PATH #ifndef UNIX_MAX_PATH
@ -185,25 +185,18 @@ struct global {
char separator; char separator;
} deviceatlas; } deviceatlas;
#endif #endif
#ifdef USE_51DEGREES #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 {
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 property_separator; /* the separator to use in the response for the values. this is taken from 51degrees-property-separator from config. */
char * _51d_data_file_path; 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 #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 #endif
} _51degrees;
#endif #endif
}; };
#ifdef USE_51DEGREES
struct _51d_property_names {
struct list list;
char *name;
};
#endif
extern struct global global; extern struct global global;
extern int pid; /* current process id */ extern int pid; /* current process id */
extern int relative_pid; /* process id starting at 1 */ extern int relative_pid; /* process id starting at 1 */

271
src/51d.c Normal file
View File

@ -0,0 +1,271 @@
#include <stdio.h>
#include <common/cfgparse.h>
#include <common/chunk.h>
#include <proto/arg.h>
#include <proto/log.h>
#include <proto/sample.h>
#include <import/xxhash.h>
#include <import/51d.h>
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 <const> 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);
}

View File

@ -1766,48 +1766,6 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
goto out; goto out;
#endif #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 { else {
struct cfg_kw_list *kwl; struct cfg_kw_list *kwl;
int index; int index;

View File

@ -117,7 +117,7 @@
#endif #endif
#ifdef USE_51DEGREES #ifdef USE_51DEGREES
#include <51Degrees.h> #include <import/51d.h>
#endif #endif
/*********************************************************************/ /*********************************************************************/
@ -189,7 +189,14 @@ struct global global = {
}, },
#endif #endif
#ifdef USE_51DEGREES #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 #endif
/* others NULL OK */ /* others NULL OK */
}; };
@ -550,12 +557,6 @@ void init(int argc, char **argv)
char *progname; char *progname;
char *change_dir = NULL; char *change_dir = NULL;
struct tm curtime; 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); chunk_init(&trash, malloc(global.tune.bufsize), global.tune.bufsize);
alloc_trash_buffers(global.tune.bufsize); alloc_trash_buffers(global.tune.bufsize);
@ -819,6 +820,9 @@ void init(int argc, char **argv)
#if defined(USE_DEVICEATLAS) #if defined(USE_DEVICEATLAS)
init_deviceatlas(); init_deviceatlas();
#endif #endif
#ifdef USE_51DEGREES
init_51degrees();
#endif
if (have_appsession) if (have_appsession)
appsession_init(); appsession_init();
@ -1106,65 +1110,6 @@ void init(int argc, char **argv)
/* initialize structures for name resolution */ /* initialize structures for name resolution */
if (!dns_init_resolvers()) if (!dns_init_resolvers())
exit(1); 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) static void deinit_acl_cond(struct acl_cond *cond)
@ -1261,9 +1206,6 @@ void deinit(void)
struct logsrv *log, *logb; struct logsrv *log, *logb;
struct logformat_node *lf, *lfb; struct logformat_node *lf, *lfb;
struct bind_conf *bind_conf, *bind_back; struct bind_conf *bind_conf, *bind_back;
#ifdef USE_51DEGREES
struct _51d_property_names *_51d_prop_name, *_51d_prop_nameb;
#endif
int i; int i;
deinit_signals(); deinit_signals();
@ -1517,18 +1459,8 @@ void deinit(void)
#endif #endif
#ifdef USE_51DEGREES #ifdef USE_51DEGREES
#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED deinit_51degrees();
fiftyoneDegreesDestroy();
#endif #endif
#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED
fiftyoneDegreesDestroy(&global._51d_data_set);
#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_send_hostname); global.log_send_hostname = NULL;
free(global.log_tag); global.log_tag = NULL; free(global.log_tag); global.log_tag = NULL;

View File

@ -32,10 +32,6 @@
#include <proto/sample.h> #include <proto/sample.h>
#include <proto/stick_table.h> #include <proto/stick_table.h>
#ifdef USE_51DEGREES
#include <51Degrees.h>
#endif
/* sample type names */ /* sample type names */
const char *smp_to_type[SMP_TYPES] = { const char *smp_to_type[SMP_TYPES] = {
[SMP_T_ANY] = "any", [SMP_T_ANY] = "any",
@ -2187,122 +2183,6 @@ static int sample_conv_arith_even(const struct arg *arg_p,
return 1; 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 */ /* 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 }, { "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 }, { "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 }, { "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 }, { NULL, NULL, 0, 0, 0 },
}}; }};