MINOR: sample: regsub now supports backreferences

Now that the configuration parser is more flexible with samples,
converters and their arguments, we can leverage this to enable
support for backreferences in regsub.
This commit is contained in:
Jerome Magnin 2020-02-16 19:20:19 +01:00 committed by Willy Tarreau
parent 9af749b43e
commit 07e1e3c93e
2 changed files with 15 additions and 4 deletions

View File

@ -14161,6 +14161,11 @@ regsub(<regex>,<subst>[,<flags>])
# copy query string to x-query and drop all leading '?', ';' and '&'
http-request set-header x-query "%[query,regsub([?;&]*,'')]"
# capture groups and backreferences
# both lines do the same.
http-request redirect location %[url,'regsub("(foo|bar)([0-9]+)?","\2\1",i)]'
http-request redirect location %[url,regsub(\"(foo|bar)([0-9]+)?\",\"\2\1\",i)]
capture-req(<id>)
Capture the string entry in the request slot <id> and returns the entry as
is. If the slot doesn't exist, the capture fails silently.

View File

@ -2354,6 +2354,7 @@ static int sample_conv_regsub(const struct arg *arg_p, struct sample *smp, void
struct my_regex *reg = arg_p[0].data.reg;
regmatch_t pmatch[MAX_MATCH];
struct buffer *trash = get_trash_chunk();
struct buffer *output;
int flag, max;
int found;
@ -2386,16 +2387,21 @@ static int sample_conv_regsub(const struct arg *arg_p, struct sample *smp, void
if (!found)
break;
output = alloc_trash_chunk();
output->data = exp_replace(output->area, output->size, start, arg_p[1].data.str.area, pmatch);
/* replace the matching part */
max = trash->size - trash->data;
max = output->size - output->data;
if (max) {
if (max > arg_p[1].data.str.data)
max = arg_p[1].data.str.data;
if (max > output->data)
max = output->data;
memcpy(trash->area + trash->data,
arg_p[1].data.str.area, max);
output->area, max);
trash->data += max;
}
free_trash_chunk(output);
/* stop here if we're done with this string */
if (start >= end)
break;