]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: map: add map_*_key converters to provide the matching key
authorAurelien DARRAGON <adarragon@haproxy.com>
Tue, 19 Dec 2023 10:49:05 +0000 (11:49 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 21 Dec 2023 13:22:27 +0000 (14:22 +0100)
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
src/map.c

index daf02a4fb9362260ce1a37c9a24a9b2f95bdb402..c66f5a3895aae1e5d592156d4dbf83368abdb758 100644 (file)
@@ -19265,33 +19265,38 @@ map_<match_type>_<output_type>(<map_name>[,<default_value>])
   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 <default_value> argument is not supported when "key" output type is
+  used.
+
   Files referenced by <map_name> 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
index ba7fd81f984680190d002488c05232bc6c685eef..2c7157af53d3c1286c68cb3de323252c98006e3a 100644 (file)
--- 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 */ },
 }};