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 */ },
 }};