MEDIUM: bwlim: Support constants limit or period on set-bandwidth-limit actions

It is now possible to set a constant for the limit or period parameters on a
set-bandwidth-limit actions. The limit must follow the HAProxy size format
and is expressed in bytes. The period must follow the HAProxy time format
and is expressed in milliseconds. Of course, it is still possible to use
sample expressions instead.

The documentation was updated accordingly.

It is not really a bug. Only exemples were written this way in the
documentation. But it could be good to backport this change in 2.7.
diff --git a/src/flt_bwlim.c b/src/flt_bwlim.c
index d59da23..ff39d66 100644
--- a/src/flt_bwlim.c
+++ b/src/flt_bwlim.c
@@ -35,6 +35,11 @@
 #define BWLIM_FL_OUT     0x00000002 /* Limit clients downloads */
 #define BWLIM_FL_SHARED  0x00000004 /* Limit shared between clients (using stick-tables) */
 
+#define BWLIM_ACT_LIMIT_EXPR   0x00000001
+#define BWLIM_ACT_LIMIT_CONST  0x00000002
+#define BWLIM_ACT_PERIOD_EXPR  0x00000004
+#define BWLIM_ACT_PERIOD_CONST 0x00000008
+
 struct bwlim_config {
 	struct proxy *proxy;
 	char         *name;
@@ -384,16 +389,21 @@
 
 		st->limit = 0;
 		st->period = 0;
-		if (rule->arg.act.p[1]) {
+		if (rule->action & BWLIM_ACT_LIMIT_EXPR) {
 			smp = sample_fetch_as_type(px, sess, s, opt, rule->arg.act.p[1], SMP_T_SINT);
 			if (smp && smp->data.u.sint > 0)
 				st->limit = smp->data.u.sint;
 		}
-		if (rule->arg.act.p[2]) {
+		else if (rule->action & BWLIM_ACT_LIMIT_CONST)
+			st->limit = (uintptr_t)rule->arg.act.p[1];
+
+		if (rule->action & BWLIM_ACT_PERIOD_EXPR) {
 			smp = sample_fetch_as_type(px, sess, s, opt, rule->arg.act.p[2], SMP_T_SINT);
 			if (smp && smp->data.u.sint > 0)
 				st->period = smp->data.u.sint;
 		}
+		else if (rule->action & BWLIM_ACT_PERIOD_CONST)
+			st->period = (uintptr_t)rule->arg.act.p[2];
 	}
 
 	st->exp = TICK_ETERNITY;
@@ -445,7 +455,7 @@
 	if (px->cap & PR_CAP_BE)
 		where |= (rule->from == ACT_F_HTTP_REQ ? SMP_VAL_BE_HRQ_HDR : SMP_VAL_BE_HRS_HDR);
 
-	if (rule->arg.act.p[1]) {
+	if ((rule->action & BWLIM_ACT_LIMIT_EXPR) && rule->arg.act.p[1]) {
 		struct sample_expr *expr = rule->arg.act.p[1];
 
 		if (!(expr->fetch->val & where)) {
@@ -465,7 +475,7 @@
 		}
 	}
 
-	if (rule->arg.act.p[2]) {
+	if ((rule->action & BWLIM_ACT_PERIOD_EXPR) && rule->arg.act.p[2]) {
 		struct sample_expr *expr = rule->arg.act.p[2];
 
 		if (!(expr->fetch->val & where)) {
@@ -512,11 +522,11 @@
 static void release_bwlim_action(struct act_rule *rule)
 {
 	ha_free(&rule->arg.act.p[0]);
-	if (rule->arg.act.p[1]) {
+	if ((rule->action & BWLIM_ACT_LIMIT_EXPR) && rule->arg.act.p[1]) {
 		release_sample_expr(rule->arg.act.p[1]);
 		rule->arg.act.p[1] = NULL;
 	}
-	if (rule->arg.act.p[2]) {
+	if ((rule->action & BWLIM_ACT_PERIOD_EXPR) && rule->arg.act.p[2]) {
 		release_sample_expr(rule->arg.act.p[2]);
 		rule->arg.act.p[2] = NULL;
 	}
@@ -556,27 +566,55 @@
 
 	while (1) {
 		if (strcmp(args[cur_arg], "limit") == 0) {
+			const char *res;
+			unsigned int limit;
+
 			cur_arg++;
 			if (!args[cur_arg]) {
-				memprintf(err, "missing limit expression");
+				memprintf(err, "missing limit value or expression");
 				goto error;
 			}
 
+			res = parse_size_err(args[cur_arg], &limit);
+			if (!res) {
+				rule->action |= BWLIM_ACT_LIMIT_CONST;
+				rule->arg.act.p[1] = (void *)(uintptr_t)limit;
+				cur_arg++;
+				continue;
+			}
+
-			expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, err, &px->conf.args, NULL);
-			if (!expr)
+			expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, NULL, &px->conf.args, NULL);
+			if (!expr) {
+				memprintf(err, "'%s': invalid size value or unknown fetch method '%s'", args[cur_arg-1], args[cur_arg]);
 				goto error;
+			}
+			rule->action |= BWLIM_ACT_LIMIT_EXPR;
 			rule->arg.act.p[1] = expr;
 		}
 		else if (strcmp(args[cur_arg], "period") == 0) {
+			const char *res;
+			unsigned int period;
+
 			cur_arg++;
 			if (!args[cur_arg]) {
-				memprintf(err, "missing period expression");
+				memprintf(err, "missing period value or expression");
 				goto error;
 			}
 
-			expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, err, &px->conf.args, NULL);
-			if (!expr)
+			res = parse_time_err(args[cur_arg], &period, TIME_UNIT_MS);
+			if (!res) {
+				rule->action |= BWLIM_ACT_PERIOD_CONST;
+				rule->arg.act.p[2] = (void *)(uintptr_t)period;
+				cur_arg++;
+				continue;
+			}
+
+			expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, NULL, &px->conf.args, NULL);
+			if (!expr) {
+				memprintf(err, "'%s': invalid time value or unknown fetch method '%s'", args[cur_arg-1], args[cur_arg]);
 				goto error;
+			}
+			rule->action |= BWLIM_ACT_PERIOD_EXPR;
 			rule->arg.act.p[2] = expr;
 		}
 		else