]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http-fetch: Add an option to 'query" to get the QS with the '?'
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 15 Nov 2024 16:25:47 +0000 (17:25 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 20 Nov 2024 09:20:05 +0000 (10:20 +0100)
As mentionned by Thayne McCombs in #2728, it could be handy to have a sample
fetch function to retrieve the query string with the question mark
character.

Indeed, for now, "query" sample fetch function already extract the query
string from the path, but the question mark character is not
included. Instead of adding a new sample fetch function with a too similar
name, an optional argument is added to "query". If "with_qm" is passed as
argument, the question mark will be included in the query string, but only
if it is not empty.

Thanks to this patch, the following rule:

  http-request redirect location /destination?%[query] if { -m found query }  some_condition
  http-request redirect location /destination if some_condition

can now be expressed this way:

  http-request redirect location /destination%[query(with_qm)] if some_condition

doc/configuration.txt
src/http_fetch.c

index a0e49ddb392192c5158792cadb65a6991c11f0aa..bf95d051ae55aa3312c10ce69faf8ac28c40ae61 100644 (file)
@@ -25201,7 +25201,7 @@ http_first_req                                     boolean
 method                                             integer
 path                                               string
 pathq                                              string
-query                                              string
+query([<options>])                                 string
 req.hdr_names([<delim>])                           string
 req.ver                                            string
 req_ver                                            string
@@ -25661,13 +25661,20 @@ pathq : string
   accept-unsafe-violations-in-http-request", then this fragment part will be
   accepted and will also appear in the path.
 
-query : string
+query([<options>]) : string
   This extracts the request's query string, which starts after the first
   question mark. If no question mark is present, this fetch returns nothing. If
   a question mark is present but nothing follows, it returns an empty string.
   This means it's possible to easily know whether a query string is present
   using the "found" matching method. This fetch is the complement of "path"
-  which stops before the question mark.
+  which stops before the question mark and of "query_string", which include the
+  question mark.
+
+  An optional parameter may be used to customize the return value. Following
+  options are supported:
+
+    - with_qm : Include the question mark at the beginning ot the query string,
+                if not empty.
 
 req.hdr_names([<delim>]) : string
   This builds a string made from the concatenation of all header names as they
index ad1e8c5435ec1980bc693eddf761d7bd1849dd67..28fe8ae7a35234aeef939bc6fea694b5b22fc094 100644 (file)
@@ -1284,6 +1284,9 @@ static int smp_fetch_query(const struct arg *args, struct sample *smp, const cha
                        return 0;
        } while (*ptr++ != '?');
 
+       if (ptr != end && args[0].type == ARGT_SINT && args[0].data.sint == 1)
+               ptr--;
+
        smp->data.type = SMP_T_STR;
        smp->data.u.str.area = ptr;
        smp->data.u.str.data = end - ptr;
@@ -2224,6 +2227,27 @@ int val_hdr(struct arg *arg, char **err_msg)
        return 1;
 }
 
+int val_query(struct arg *args, char **err_msg)
+{
+       if (args[0].type == ARGT_STOP)
+               return 1;
+
+       if (args[0].type != ARGT_STR) {
+               memprintf(err_msg, "first argument must be a string");
+               return 0;
+       }
+
+       if (chunk_strcmp(&args[0].data.str, "with_qm") != 0) {
+               memprintf(err_msg, "supported options are: 'with_qm'");
+               return 0;
+       }
+
+       chunk_destroy(&args[0].data.str);
+       args[0].type = ARGT_SINT;
+       args[0].data.sint = 1;
+       return 1;
+
+}
 /************************************************************************/
 /*      All supported sample fetch keywords must be declared here.      */
 /************************************************************************/
@@ -2274,7 +2298,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
        { "method",             smp_fetch_meth,               0,                NULL,    SMP_T_METH, SMP_USE_HRQHP },
        { "path",               smp_fetch_path,               0,                NULL,    SMP_T_STR,  SMP_USE_HRQHV },
        { "pathq",              smp_fetch_path,               0,                NULL,    SMP_T_STR,  SMP_USE_HRQHV },
-       { "query",              smp_fetch_query,              0,                NULL,    SMP_T_STR,  SMP_USE_HRQHV },
+       { "query",              smp_fetch_query,              ARG1(0,STR), val_query,    SMP_T_STR,  SMP_USE_HRQHV },
 
        /* HTTP protocol on the request path */
        { "req.proto_http",     smp_fetch_proto_http,         0,                NULL,    SMP_T_BOOL, SMP_USE_HRQHP },