From ca4758378788ee6a9b774590badbaa12d356e186 Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Tue, 19 Dec 2023 11:49:05 +0100 Subject: [PATCH] MINOR: map: add map_*_key converters to provide the matching key All map_*_ converters now have an additional output type: key. Such converters will return the matched entry's key (as found in the map file) as a string instead of the value. Consider this example map file: |example.com value1 |haproxy value2 With the above map file: str(test.example.com/url),map_dom_key(file.map) will return "example.com" str(running haproxy),map_sub_key(file.map) will return "haproxy" This should address GH #1446. --- doc/configuration.txt | 49 ++++++++++++++++++++++++------------------- src/map.c | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index daf02a4fb9..c66f5a3895 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -19265,33 +19265,38 @@ map__([,]) The following array contains the list of all map functions available sorted by input type, match type and output type. - input type | match method | output type str | output type int | output type ip - -----------+--------------+-----------------+-----------------+--------------- - str | str | map_str | map_str_int | map_str_ip - -----------+--------------+-----------------+-----------------+--------------- - str | beg | map_beg | map_beg_int | map_end_ip - -----------+--------------+-----------------+-----------------+--------------- - str | sub | map_sub | map_sub_int | map_sub_ip - -----------+--------------+-----------------+-----------------+--------------- - str | dir | map_dir | map_dir_int | map_dir_ip - -----------+--------------+-----------------+-----------------+--------------- - str | dom | map_dom | map_dom_int | map_dom_ip - -----------+--------------+-----------------+-----------------+--------------- - str | end | map_end | map_end_int | map_end_ip - -----------+--------------+-----------------+-----------------+--------------- - str | reg | map_reg | map_reg_int | map_reg_ip - -----------+--------------+-----------------+-----------------+--------------- - str | reg | map_regm | map_reg_int | map_reg_ip - -----------+--------------+-----------------+-----------------+--------------- - int | int | map_int | map_int_int | map_int_ip - -----------+--------------+-----------------+-----------------+--------------- - ip | ip | map_ip | map_ip_int | map_ip_ip - -----------+--------------+-----------------+-----------------+--------------- + input type | match method | output type str | output type int | output type ip | output type key + -----------+--------------+-----------------+-----------------+----------------+---------------- + str | str | map_str | map_str_int | map_str_ip | map_str_key + -----------+--------------+-----------------+-----------------+----------------+---------------- + str | beg | map_beg | map_beg_int | map_end_ip | map_end_key + -----------+--------------+-----------------+-----------------+----------------+---------------- + str | sub | map_sub | map_sub_int | map_sub_ip | map_sub_key + -----------+--------------+-----------------+-----------------+----------------+---------------- + str | dir | map_dir | map_dir_int | map_dir_ip | map_dir_key + -----------+--------------+-----------------+-----------------+----------------+---------------- + str | dom | map_dom | map_dom_int | map_dom_ip | map_dom_key + -----------+--------------+-----------------+-----------------+----------------+---------------- + str | end | map_end | map_end_int | map_end_ip | map_end_key + -----------+--------------+-----------------+-----------------+----------------+---------------- + str | reg | map_reg | map_reg_int | map_reg_ip | map_reg_key + -----------+--------------+-----------------+-----------------+----------------+---------------- + str | reg | map_regm | map_reg_int | map_reg_ip | map_reg_key + -----------+--------------+-----------------+-----------------+----------------+---------------- + int | int | map_int | map_int_int | map_int_ip | map_int_key + -----------+--------------+-----------------+-----------------+----------------+---------------- + ip | ip | map_ip | map_ip_int | map_ip_ip | map_ip_key + -----------+--------------+-----------------+-----------------+----------------+---------------- The special map called "map_regm" expect matching zone in the regular expression and modify the output replacing back reference (like "\1") by the corresponding match text. + Output type "key" means that it its the matched entry's key (as found in the + map file)that will be returned as a string instead of the value. Note that + optional argument is not supported when "key" output type is + used. + Files referenced by contains one key + value per line. Lines which start with '#' are ignored, just like empty lines. Leading tabs and spaces are stripped. The key is then the first "word" (series of non-space/tabs diff --git a/src/map.c b/src/map.c index ba7fd81f98..2c7157af53 100644 --- a/src/map.c +++ b/src/map.c @@ -170,6 +170,34 @@ int sample_load_map(struct arg *arg, struct sample_conv *conv, return 1; } +/* try to match input sample against map entries, returns matched entry's key + * on success + */ +static int sample_conv_map_key(const struct arg *arg_p, struct sample *smp, void *private) +{ + struct map_descriptor *desc; + struct pattern *pat; + + /* get config */ + desc = arg_p[0].data.map; + + /* Execute the match function. */ + pat = pattern_exec_match(&desc->pat, smp, 1); + + /* Match case. */ + if (pat) { + smp->data.type = SMP_T_STR; + smp->flags |= SMP_F_CONST; + smp->data.u.str.area = (char *)pat->ref->pattern; + smp->data.u.str.data = strlen(pat->ref->pattern); + return 1; + } + return 0; +} + +/* try to match input sample against map entries, returns matched entry's value + * on success + */ static int sample_conv_map(const struct arg *arg_p, struct sample *smp, void *private) { struct map_descriptor *desc; @@ -1226,6 +1254,16 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, { { "map_int_ip", sample_conv_map, ARG2(1,STR,STR), sample_load_map, SMP_T_SINT, SMP_T_ADDR, (void *)PAT_MATCH_INT }, { "map_ip_ip", sample_conv_map, ARG2(1,STR,STR), sample_load_map, SMP_T_ADDR, SMP_T_ADDR, (void *)PAT_MATCH_IP }, + { "map_str_key", sample_conv_map_key, ARG1(1,STR), sample_load_map, SMP_T_STR, SMP_T_STR, (void *)PAT_MATCH_STR }, + { "map_beg_key", sample_conv_map_key, ARG1(1,STR), sample_load_map, SMP_T_STR, SMP_T_STR, (void *)PAT_MATCH_BEG }, + { "map_sub_key", sample_conv_map_key, ARG1(1,STR), sample_load_map, SMP_T_STR, SMP_T_STR, (void *)PAT_MATCH_SUB }, + { "map_dir_key", sample_conv_map_key, ARG1(1,STR), sample_load_map, SMP_T_STR, SMP_T_STR, (void *)PAT_MATCH_DIR }, + { "map_dom_key", sample_conv_map_key, ARG1(1,STR), sample_load_map, SMP_T_STR, SMP_T_STR, (void *)PAT_MATCH_DOM }, + { "map_end_key", sample_conv_map_key, ARG1(1,STR), sample_load_map, SMP_T_STR, SMP_T_STR, (void *)PAT_MATCH_END }, + { "map_reg_key", sample_conv_map_key, ARG1(1,STR), sample_load_map, SMP_T_STR, SMP_T_STR, (void *)PAT_MATCH_REG }, + { "map_int_key", sample_conv_map_key, ARG1(1,STR), sample_load_map, SMP_T_SINT, SMP_T_STR, (void *)PAT_MATCH_INT }, + { "map_ip_key", sample_conv_map_key, ARG1(1,STR), sample_load_map, SMP_T_ADDR, SMP_T_STR, (void *)PAT_MATCH_IP }, + { /* END */ }, }}; -- 2.39.5