MINOR: http-rules: Make set/del-map and add/del-acl custom actions

Now, these actions use their own dedicated function and are no longer handled
"in place" during the HTTP rules evaluation. Thus the action names
ACT_HTTP_*_ACL and ACT_HTTP_*_MAP are removed. The action type is now mapped as
following: 0 = add-acl, 1 = set-map, 2 = del-acl and 3 = del-map.
diff --git a/include/types/action.h b/include/types/action.h
index 16d669d..6d77f9c 100644
--- a/include/types/action.h
+++ b/include/types/action.h
@@ -84,10 +84,6 @@
 	ACT_HTTP_SET_LOGL,
 	ACT_HTTP_SET_TOS,
 	ACT_HTTP_SET_MARK,
-	ACT_HTTP_ADD_ACL,
-	ACT_HTTP_DEL_ACL,
-	ACT_HTTP_DEL_MAP,
-	ACT_HTTP_SET_MAP,
 	ACT_HTTP_EARLY_HINT,
 
 	/* http request actions. */
diff --git a/src/http_act.c b/src/http_act.c
index aa8dfff..537b1d0 100644
--- a/src/http_act.c
+++ b/src/http_act.c
@@ -37,6 +37,7 @@
 #include <proto/http_htx.h>
 #include <proto/log.h>
 #include <proto/http_ana.h>
+#include <proto/pattern.h>
 #include <proto/stream_interface.h>
 
 
@@ -1212,25 +1213,118 @@
 	return ACT_RET_PRS_OK;
 }
 
+/* This function executes a add-acl, del-acl, set-map or del-map actions. On
+ * success, it returns ACT_RET_CONT. Otherwsize ACT_RET_ERR is returned.
+ */
+static enum act_return http_action_set_map(struct act_rule *rule, struct proxy *px,
+					   struct session *sess, struct stream *s, int flags)
+{
+	struct pat_ref *ref;
+	struct buffer *key = NULL, *value = NULL;
+	enum act_return ret = ACT_RET_CONT;
+
+	/* collect reference */
+	ref = pat_ref_lookup(rule->arg.map.ref);
+	if (!ref)
+		goto leave;
+
+	/* allocate key */
+	key = alloc_trash_chunk();
+	if (!key)
+		goto fail_alloc;
+
+	/* collect key */
+	key->data = build_logline(s, key->area, key->size, &rule->arg.map.key);
+	key->area[key->data] = '\0';
+
+	switch (rule->action) {
+	case 0: // add-acl
+		/* add entry only if it does not already exist */
+		HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
+		if (pat_ref_find_elt(ref, key->area) == NULL)
+			pat_ref_add(ref, key->area, NULL, NULL);
+		HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
+		break;
+
+	case 1: // set-map
+		/* allocate value */
+		value = alloc_trash_chunk();
+		if (!value)
+			goto fail_alloc;
+
+		/* collect value */
+		value->data = build_logline(s, value->area, value->size, &rule->arg.map.value);
+		value->area[value->data] = '\0';
+
+		HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
+		if (pat_ref_find_elt(ref, key->area) != NULL) {
+			/* update entry if it exists */
+			pat_ref_set(ref, key->area, value->area, NULL);
+		}
+		else {
+			/* insert a new entry */
+			pat_ref_add(ref, key->area, value->area, NULL);
+		}
+		HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
+		break;
+
+	case 2: // del-acl
+	case 3: // del-map
+		/* returned code: 1=ok, 0=ko */
+		HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
+		pat_ref_delete(ref, key->area);
+		HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
+		break;
+
+	default:
+		ret = ACT_RET_ERR;
+	}
+
+
+  leave:
+	free_trash_chunk(key);
+	free_trash_chunk(value);
+	return ret;
+
+  fail_alloc:
+	if (!(s->flags & SF_ERR_MASK))
+		s->flags |= SF_ERR_RESOURCE;
+	ret = ACT_RET_ERR;
+	goto leave;
+}
+
 /* Parse a "add-acl", "del-acl", "set-map" or "del-map" actions. It takes one or
- * two log-format string as argument depending on the action. It returns
- * ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
+ * two log-format string as argument depending on the action. The action is
+ * stored in <.action> as an int (0=add-acl, 1=set-map, 2=del-acl,
+ * 3=del-map). It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
  */
 static enum act_parse_ret parse_http_set_map(const char **args, int *orig_arg, struct proxy *px,
 					     struct act_rule *rule, char **err)
 {
 	int cap, cur_arg;
 
-	rule->action = (args[*orig_arg-1][0] == 'a' ? ACT_HTTP_ADD_ACL :
-			(args[*orig_arg-1][0] == 's' ? ACT_HTTP_SET_MAP :
-			 (args[*orig_arg-1][4] == 'a' ? ACT_HTTP_DEL_ACL : ACT_HTTP_DEL_MAP)));
+	if (args[*orig_arg-1][0] == 'a') // add-acl
+		rule->action = 0;
+	else if (args[*orig_arg-1][0] == 's') // set-map
+		rule->action = 1;
+	else if (args[*orig_arg-1][4] == 'a') // del-acl
+		rule->action = 2;
+	else if (args[*orig_arg-1][4] == 'm') // del-map
+		rule->action = 3;
+	else {
+		memprintf(err, "internal error: unhandled action '%s'", args[0]);
+		return ACT_RET_PRS_ERR;
+	}
+	rule->action_ptr = http_action_set_map;
 
 	cur_arg = *orig_arg;
-	if (rule->action == ACT_HTTP_SET_MAP && (!*args[cur_arg] || !*args[cur_arg+1])) {
+	if (rule->action == 1 && (!*args[cur_arg] || !*args[cur_arg+1])) {
+		/* 2 args for set-map */
 		memprintf(err, "expects exactly 2 arguments");
 		return ACT_RET_PRS_ERR;
 	}
 	else if (!*args[cur_arg]) {
+		/* only one arg for other actions */
 		memprintf(err, "expects exactly 1 arguments");
 		return ACT_RET_PRS_ERR;
 	}
@@ -1255,7 +1349,7 @@
 	if (!parse_logformat_string(args[cur_arg], px, &rule->arg.map.key, LOG_OPT_HTTP, cap, err))
 		return ACT_RET_PRS_ERR;
 
-	if (rule->action == ACT_HTTP_SET_MAP) {
+	if (rule->action == 1) {
 		/* value pattern for set-map only */
 		cur_arg++;
 		LIST_INIT(&rule->arg.map.value);
diff --git a/src/http_ana.c b/src/http_ana.c
index dc9f06e..1002dab 100644
--- a/src/http_ana.c
+++ b/src/http_ana.c
@@ -26,7 +26,6 @@
 #include <proto/filters.h>
 #include <proto/http_htx.h>
 #include <proto/log.h>
-#include <proto/pattern.h>
 #include <proto/http_ana.h>
 #include <proto/proxy.h>
 #include <proto/server.h>
@@ -3038,122 +3037,6 @@
 					http_remove_header(htx, &ctx);
 				break;
 
-			case ACT_HTTP_DEL_ACL:
-			case ACT_HTTP_DEL_MAP: {
-				struct pat_ref *ref;
-				struct buffer *key;
-
-				/* collect reference */
-				ref = pat_ref_lookup(rule->arg.map.ref);
-				if (!ref)
-					continue;
-
-				/* allocate key */
-				key = alloc_trash_chunk();
-				if (!key) {
-					if (!(s->flags & SF_ERR_MASK))
-						s->flags |= SF_ERR_RESOURCE;
-					rule_ret = HTTP_RULE_RES_ERROR;
-					goto end;
-				}
-
-				/* collect key */
-				key->data = build_logline(s, key->area, key->size, &rule->arg.map.key);
-				key->area[key->data] = '\0';
-
-				/* perform update */
-				/* returned code: 1=ok, 0=ko */
-				HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
-				pat_ref_delete(ref, key->area);
-				HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
-
-				free_trash_chunk(key);
-				break;
-			}
-
-			case ACT_HTTP_ADD_ACL: {
-				struct pat_ref *ref;
-				struct buffer *key;
-
-				/* collect reference */
-				ref = pat_ref_lookup(rule->arg.map.ref);
-				if (!ref)
-					continue;
-
-				/* allocate key */
-				key = alloc_trash_chunk();
-				if (!key) {
-					if (!(s->flags & SF_ERR_MASK))
-						s->flags |= SF_ERR_RESOURCE;
-					rule_ret = HTTP_RULE_RES_ERROR;
-					goto end;
-				}
-
-				/* collect key */
-				key->data = build_logline(s, key->area, key->size, &rule->arg.map.key);
-				key->area[key->data] = '\0';
-
-				/* perform update */
-				/* add entry only if it does not already exist */
-				HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
-				if (pat_ref_find_elt(ref, key->area) == NULL)
-					pat_ref_add(ref, key->area, NULL, NULL);
-				HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
-
-				free_trash_chunk(key);
-				break;
-			}
-
-			case ACT_HTTP_SET_MAP: {
-				struct pat_ref *ref;
-				struct buffer *key, *value;
-
-				/* collect reference */
-				ref = pat_ref_lookup(rule->arg.map.ref);
-				if (!ref)
-					continue;
-
-				/* allocate key */
-				key = alloc_trash_chunk();
-				if (!key) {
-					if (!(s->flags & SF_ERR_MASK))
-						s->flags |= SF_ERR_RESOURCE;
-					rule_ret = HTTP_RULE_RES_ERROR;
-					goto end;
-				}
-
-				/* allocate value */
-				value = alloc_trash_chunk();
-				if (!value) {
-					free_trash_chunk(key);
-					if (!(s->flags & SF_ERR_MASK))
-						s->flags |= SF_ERR_RESOURCE;
-					rule_ret = HTTP_RULE_RES_ERROR;
-					goto end;
-				}
-
-				/* collect key */
-				key->data = build_logline(s, key->area, key->size, &rule->arg.map.key);
-				key->area[key->data] = '\0';
-
-				/* collect value */
-				value->data = build_logline(s, value->area, value->size, &rule->arg.map.value);
-				value->area[value->data] = '\0';
-
-				/* perform update */
-				HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
-				if (pat_ref_find_elt(ref, key->area) != NULL)
-					/* update entry if it exists */
-					pat_ref_set(ref, key->area, value->area, NULL);
-				else
-					/* insert a new entry */
-					pat_ref_add(ref, key->area, value->area, NULL);
-				HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
-				free_trash_chunk(key);
-				free_trash_chunk(value);
-				break;
-			}
-
 			case ACT_HTTP_EARLY_HINT:
 				if (!(txn->req.flags & HTTP_MSGF_VER_11))
 					break;
@@ -3354,121 +3237,6 @@
 					http_remove_header(htx, &ctx);
 				break;
 
-			case ACT_HTTP_DEL_ACL:
-			case ACT_HTTP_DEL_MAP: {
-				struct pat_ref *ref;
-				struct buffer *key;
-
-				/* collect reference */
-				ref = pat_ref_lookup(rule->arg.map.ref);
-				if (!ref)
-					continue;
-
-			/* allocate key */
-				key = alloc_trash_chunk();
-				if (!key) {
-					if (!(s->flags & SF_ERR_MASK))
-						s->flags |= SF_ERR_RESOURCE;
-					rule_ret = HTTP_RULE_RES_ERROR;
-					goto end;
-				}
-
-				/* collect key */
-				key->data = build_logline(s, key->area, key->size, &rule->arg.map.key);
-				key->area[key->data] = '\0';
-
-				/* perform update */
-				/* returned code: 1=ok, 0=ko */
-				HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
-				pat_ref_delete(ref, key->area);
-				HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
-
-				free_trash_chunk(key);
-				break;
-			}
-
-			case ACT_HTTP_ADD_ACL: {
-				struct pat_ref *ref;
-				struct buffer *key;
-
-				/* collect reference */
-				ref = pat_ref_lookup(rule->arg.map.ref);
-				if (!ref)
-					continue;
-
-				/* allocate key */
-				key = alloc_trash_chunk();
-				if (!key) {
-					if (!(s->flags & SF_ERR_MASK))
-						s->flags |= SF_ERR_RESOURCE;
-					rule_ret = HTTP_RULE_RES_ERROR;
-					goto end;
-				}
-
-				/* collect key */
-				key->data = build_logline(s, key->area, key->size, &rule->arg.map.key);
-				key->area[key->data] = '\0';
-
-				/* perform update */
-				/* check if the entry already exists */
-				HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
-				if (pat_ref_find_elt(ref, key->area) == NULL)
-					pat_ref_add(ref, key->area, NULL, NULL);
-				HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
-				free_trash_chunk(key);
-				break;
-			}
-
-			case ACT_HTTP_SET_MAP: {
-				struct pat_ref *ref;
-				struct buffer *key, *value;
-
-				/* collect reference */
-				ref = pat_ref_lookup(rule->arg.map.ref);
-				if (!ref)
-					continue;
-
-				/* allocate key */
-				key = alloc_trash_chunk();
-				if (!key) {
-					if (!(s->flags & SF_ERR_MASK))
-						s->flags |= SF_ERR_RESOURCE;
-					rule_ret = HTTP_RULE_RES_ERROR;
-					goto end;
-				}
-
-				/* allocate value */
-				value = alloc_trash_chunk();
-				if (!value) {
-					free_trash_chunk(key);
-					if (!(s->flags & SF_ERR_MASK))
-						s->flags |= SF_ERR_RESOURCE;
-					rule_ret = HTTP_RULE_RES_ERROR;
-					goto end;
-				}
-
-				/* collect key */
-				key->data = build_logline(s, key->area, key->size, &rule->arg.map.key);
-				key->area[key->data] = '\0';
-
-				/* collect value */
-				value->data = build_logline(s, value->area, value->size, &rule->arg.map.value);
-				value->area[value->data] = '\0';
-
-				/* perform update */
-				HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
-				if (pat_ref_find_elt(ref, key->area) != NULL)
-					/* update entry if it exists */
-					pat_ref_set(ref, key->area, value->area, NULL);
-				else
-					/* insert a new entry */
-					pat_ref_add(ref, key->area, value->area, NULL);
-				HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
-				free_trash_chunk(key);
-				free_trash_chunk(value);
-				break;
-			}
-
 			case ACT_HTTP_REDIR:
 				rule_ret = HTTP_RULE_RES_DONE;
 				if (!http_apply_redirect_rule(rule->arg.redir, s, txn))