MINOR: http_fetch: Add case-insensitive argument for url_param/urlp_val
This commit adds a new optional argument to smp_fetch_url_param
and smp_fetch_url_param_val that makes the parameter key comparison
case-insensitive.
Now users can retrieve URL parameters regardless of their case,
allowing to match parameters in case insensitive application.
Doc was updated.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 38f93c7..e236f0a 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -21401,17 +21401,17 @@
recommended to use "option http-buffer-request" to be sure to wait, as much
as possible, for the request's body.
-req.body_param([<name>) : string
+req.body_param([<name>[,i]]) : string
This fetch assumes that the body of the POST request is url-encoded. The user
can check if the "content-type" contains the value
"application/x-www-form-urlencoded". This extracts the first occurrence of the
parameter <name> in the body, which ends before '&'. The parameter name is
- case-sensitive. If no name is given, any parameter will match, and the first
- one will be returned. The result is a string corresponding to the value of the
- parameter <name> as presented in the request body (no URL decoding is
- performed). Note that the ACL version of this fetch iterates over multiple
- parameters and will iteratively report all parameters values if no name is
- given.
+ case-sensitive, unless "i" is added as a second argument. If no name is
+ given, any parameter will match, and the first one will be returned. The
+ result is a string corresponding to the value of the parameter <name> as
+ presented in the request body (no URL decoding is performed). Note that the
+ ACL version of this fetch iterates over multiple parameters and will
+ iteratively report all parameters values if no name is given.
req.body_len : integer
This returns the length of the HTTP request's available body in bytes. It may
@@ -21930,18 +21930,18 @@
This extracts the port part from the request's URL. Note that if the port is
not specified in the request, port 80 is assumed..
-urlp([<name>[,<delim>]]) : string
-url_param([<name>[,<delim>]]) : string
+urlp([<name>[,<delim>[,i]]]) : string
+url_param([<name>[,<delim>[,i]]]) : string
This extracts the first occurrence of the parameter <name> in the query
string, which begins after either '?' or <delim>, and which ends before '&',
- ';' or <delim>. The parameter name is case-sensitive. If no name is given,
- any parameter will match, and the first one will be returned. The result is
- a string corresponding to the value of the parameter <name> as presented in
- the request (no URL decoding is performed). This can be used for session
- stickiness based on a client ID, to extract an application cookie passed as a
- URL parameter, or in ACLs to apply some checks. Note that the ACL version of
- this fetch iterates over multiple parameters and will iteratively report all
- parameters values if no name is given
+ ';' or <delim>. The parameter name is case-sensitive, unless"i" is added as a
+ third argument. If no name is given, any parameter will match, and the first
+ one will be returned. The result is a string corresponding to the value of the
+ parameter <name> as presented in the request (no URL decoding is performed).
+ This can be used for session stickiness based on a client ID, to extract an
+ application cookie passed as a URL parameter, or in ACLs to apply some checks.
+ Note that the ACL version of this fetch iterates over multiple parameters and
+ will iteratively report all parameters values if no name is given
ACL derivatives :
urlp(<name>[,<delim>]) : exact string match
@@ -21960,7 +21960,7 @@
# match http://example.com/foo;JSESSIONID=some_id
stick on urlp(JSESSIONID,;)
-urlp_val([<name>[,<delim>]]) : integer
+urlp_val([<name>[,<delim>[,i]]]) : integer
See "urlp" above. This one extracts the URL parameter <name> in the request
and converts it to an integer value. This can be used for session stickiness
based on a user ID for example, or with ACLs to match a page number or price.
diff --git a/src/http_fetch.c b/src/http_fetch.c
index 270ef97..1775bc6 100644
--- a/src/http_fetch.c
+++ b/src/http_fetch.c
@@ -1890,9 +1890,11 @@
char delim = '?';
const char *name;
int name_len;
+ char insensitive = 0;
if ((args[0].type && args[0].type != ARGT_STR) ||
- (args[1].type && args[1].type != ARGT_STR))
+ (args[1].type && args[1].type != ARGT_STR) ||
+ (args[2].type && args[2].type != ARGT_STR))
return 0;
name = "";
@@ -1904,6 +1906,8 @@
if (args[1].type && *args[1].data.str.area)
delim = *args[1].data.str.area;
+ if (args[2].type && *args[2].data.str.area == 'i')
+ insensitive = 1;
if (!smp->ctx.a[0]) { // first call, find the query string
struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
@@ -1926,7 +1930,7 @@
*/
}
- return smp_fetch_param(delim, name, name_len, args, smp, kw, private, 0);
+ return smp_fetch_param(delim, name, name_len, args, smp, kw, private, insensitive);
}
/* This function iterates over each parameter of the body. This requires
@@ -1941,8 +1945,10 @@
struct channel *chn = SMP_REQ_CHN(smp);
const char *name;
int name_len;
+ char insensitive = 0;
- if (args[0].type && args[0].type != ARGT_STR)
+ if ((args[0].type && args[0].type != ARGT_STR) ||
+ (args[1].type && args[1].type != ARGT_STR))
return 0;
name = "";
@@ -1952,6 +1958,9 @@
name_len = args[0].data.str.data;
}
+ if (args[1].type && *args[1].data.str.area == 'i')
+ insensitive = 1;
+
if (!smp->ctx.a[0]) { // first call, find the query string
struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct buffer *temp;
@@ -1984,7 +1993,7 @@
}
- return smp_fetch_param('&', name, name_len, args, smp, kw, private, 0);
+ return smp_fetch_param('&', name, name_len, args, smp, kw, private, insensitive);
}
/* Return the signed integer value for the specified url parameter (see url_param
@@ -2179,7 +2188,7 @@
{ "req.body", smp_fetch_body, 0, NULL, SMP_T_BIN, SMP_USE_HRQHV },
{ "req.body_len", smp_fetch_body_len, 0, NULL, SMP_T_SINT, SMP_USE_HRQHV },
{ "req.body_size", smp_fetch_body_size, 0, NULL, SMP_T_SINT, SMP_USE_HRQHV },
- { "req.body_param", smp_fetch_body_param, ARG1(0,STR), NULL, SMP_T_BIN, SMP_USE_HRQHV },
+ { "req.body_param", smp_fetch_body_param, ARG2(0,STR,STR), NULL, SMP_T_BIN, SMP_USE_HRQHV },
{ "req.hdrs", smp_fetch_hdrs, 0, NULL, SMP_T_BIN, SMP_USE_HRQHV },
{ "req.hdrs_bin", smp_fetch_hdrs_bin, 0, NULL, SMP_T_BIN, SMP_USE_HRQHV },
@@ -2239,9 +2248,9 @@
{ "url32+src", smp_fetch_url32_src, 0, NULL, SMP_T_BIN, SMP_USE_HRQHV },
{ "url_ip", smp_fetch_url_ip, 0, NULL, SMP_T_IPV4, SMP_USE_HRQHV },
{ "url_port", smp_fetch_url_port, 0, NULL, SMP_T_SINT, SMP_USE_HRQHV },
- { "url_param", smp_fetch_url_param, ARG2(0,STR,STR), NULL, SMP_T_STR, SMP_USE_HRQHV },
- { "urlp" , smp_fetch_url_param, ARG2(0,STR,STR), NULL, SMP_T_STR, SMP_USE_HRQHV },
- { "urlp_val", smp_fetch_url_param_val, ARG2(0,STR,STR), NULL, SMP_T_SINT, SMP_USE_HRQHV },
+ { "url_param", smp_fetch_url_param, ARG3(0,STR,STR,STR), NULL, SMP_T_STR, SMP_USE_HRQHV },
+ { "urlp" , smp_fetch_url_param, ARG3(0,STR,STR,STR), NULL, SMP_T_STR, SMP_USE_HRQHV },
+ { "urlp_val", smp_fetch_url_param_val, ARG3(0,STR,STR,STR), NULL, SMP_T_SINT, SMP_USE_HRQHV },
{ /* END */ },
}};