MINOR: http-rules: Add release functions for existing HTTP actions

HTTP actions allocating memory during configuration parsing now use dedicated
functions to release it.
diff --git a/src/http_act.c b/src/http_act.c
index 986e542..b01bd40 100644
--- a/src/http_act.c
+++ b/src/http_act.c
@@ -40,6 +40,25 @@
 #include <proto/pattern.h>
 #include <proto/stream_interface.h>
 
+/* Release memory allocated by most of HTTP actions. Concretly, it releases
+ * <arg.http>.
+ */
+static void release_http_action(struct act_rule *rule)
+{
+	struct logformat_node *lf, *lfb;
+
+	if (rule->arg.http.str.ptr)
+		free(rule->arg.http.str.ptr);
+	if (rule->arg.http.re)
+		regex_free(rule->arg.http.re);
+	list_for_each_entry_safe(lf, lfb, &rule->arg.http.fmt, list) {
+		LIST_DEL(&lf->list);
+		release_sample_expr(lf->expr);
+		free(lf->arg);
+		free(lf);
+	}
+}
+
 
 /* This function executes one of the set-{method,path,query,uri} actions. It
  * builds a string in the trash from the specified format string. It finds
@@ -127,6 +146,7 @@
 		return ACT_RET_PRS_ERR;
 	}
 	rule->action_ptr = http_action_set_req_line;
+	rule->release_ptr = release_http_action;
 
 	if (!*args[cur_arg] ||
 	    (*args[cur_arg + 1] && strcmp(args[cur_arg + 1], "if") != 0 && strcmp(args[cur_arg + 1], "unless") != 0)) {
@@ -230,6 +250,7 @@
 		rule->action = 3; // replace-uri, same as set-uri
 
 	rule->action_ptr = http_action_replace_uri;
+	rule->release_ptr = release_http_action;
 
 	if (!*args[cur_arg] || !*args[cur_arg+1] ||
 	    (*args[cur_arg+2] && strcmp(args[cur_arg+2], "if") != 0 && strcmp(args[cur_arg+2], "unless") != 0)) {
@@ -286,6 +307,7 @@
 
 	rule->action = ACT_CUSTOM;
 	rule->action_ptr = action_http_set_status;
+	rule->release_ptr = release_http_action;
 
 	/* Check if an argument is available */
 	if (!*args[*orig_arg]) {
@@ -480,6 +502,15 @@
 	return 1;
 }
 
+/* Release memory allocate by an http capture action */
+static void release_http_capture(struct act_rule *rule)
+{
+	if (rule->action_ptr == http_action_req_capture)
+		release_sample_expr(rule->arg.cap.expr);
+	else
+		release_sample_expr(rule->arg.capid.expr);
+}
+
 /* parse an "http-request capture" action. It takes a single argument which is
  * a sample fetch expression. It stores the expression into arg->act.p[0] and
  * the allocated hdr_cap struct or the preallocated "id" into arg->act.p[1].
@@ -559,6 +590,7 @@
 
 		rule->action       = ACT_CUSTOM;
 		rule->action_ptr   = http_action_req_capture;
+		rule->release_ptr  = release_http_capture;
 		rule->arg.cap.expr = expr;
 		rule->arg.cap.hdr  = hdr;
 	}
@@ -588,6 +620,7 @@
 		rule->action       = ACT_CUSTOM;
 		rule->action_ptr   = http_action_req_capture_by_id;
 		rule->check_ptr    = check_http_req_capture;
+		rule->release_ptr  = release_http_capture;
 		rule->arg.capid.expr = expr;
 		rule->arg.capid.idx  = id;
 	}
@@ -731,6 +764,7 @@
 	rule->action       = ACT_CUSTOM;
 	rule->action_ptr   = http_action_res_capture_by_id;
 	rule->check_ptr    = check_http_res_capture;
+	rule->release_ptr  = release_http_capture;
 	rule->arg.capid.expr = expr;
 	rule->arg.capid.idx  = id;
 
@@ -814,6 +848,7 @@
 
 	rule->action = ACT_HTTP_REQ_AUTH;
 	rule->flags |= ACT_FLAG_FINAL;
+	rule->release_ptr = release_http_action;
 
 	cur_arg = *orig_arg;
 	if (!strcmp(args[cur_arg], "realm")) {
@@ -1107,6 +1142,7 @@
 			rule->action = 1; // add-header
 		rule->action_ptr = http_action_set_header;
 	}
+	rule->release_ptr = release_http_action;
 
 	cur_arg = *orig_arg;
 	if (!*args[cur_arg] || !*args[cur_arg+1]) {
@@ -1204,6 +1240,7 @@
 	else
 		rule->action = 1; // replace-value
 	rule->action_ptr = http_action_replace_header;
+	rule->release_ptr = release_http_action;
 
 	cur_arg = *orig_arg;
 	if (!*args[cur_arg] || !*args[cur_arg+1] || !*args[cur_arg+2]) {
@@ -1249,6 +1286,7 @@
 	int cur_arg;
 
 	rule->action = ACT_HTTP_DEL_HDR;
+	rule->release_ptr = release_http_action;
 
 	cur_arg = *orig_arg;
 	if (!*args[cur_arg]) {
@@ -1265,6 +1303,27 @@
 	return ACT_RET_PRS_OK;
 }
 
+/* Release memory allocated by an http redirect action. */
+static void release_http_redir(struct act_rule *rule)
+{
+	struct logformat_node *lf, *lfb;
+	struct redirect_rule *redir;
+
+	redir = rule->arg.redir;
+	LIST_DEL(&redir->list);
+	if (redir->cond) {
+		prune_acl_cond(redir->cond);
+		free(redir->cond);
+	}
+	free(redir->rdr_str);
+	free(redir->cookie_str);
+	list_for_each_entry_safe(lf, lfb, &redir->rdr_fmt, list) {
+		LIST_DEL(&lf->list);
+		free(lf);
+	}
+	free(redir);
+}
+
 /* Parse a "redirect" action. It returns ACT_RET_PRS_OK on success,
  * ACT_RET_PRS_ERR on error.
  */
@@ -1276,6 +1335,7 @@
 
 	rule->action = ACT_HTTP_REDIR;
 	rule->flags |= ACT_FLAG_FINAL;
+	rule->release_ptr = release_http_redir;
 
 	cur_arg = *orig_arg;
 
@@ -1375,6 +1435,28 @@
 	goto leave;
 }
 
+/* Release memory allocated by an http map/acl action. */
+static void release_http_map(struct act_rule *rule)
+{
+	struct logformat_node *lf, *lfb;
+
+	free(rule->arg.map.ref);
+	list_for_each_entry_safe(lf, lfb, &rule->arg.map.key, list) {
+		LIST_DEL(&lf->list);
+		release_sample_expr(lf->expr);
+		free(lf->arg);
+		free(lf);
+	}
+	if (rule->action == 1) {
+		list_for_each_entry_safe(lf, lfb, &rule->arg.map.value, list) {
+			LIST_DEL(&lf->list);
+			release_sample_expr(lf->expr);
+			free(lf->arg);
+			free(lf);
+		}
+	}
+}
+
 /* 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. The action is
  * stored in <.action> as an int (0=add-acl, 1=set-map, 2=del-acl,
@@ -1398,6 +1480,7 @@
 		return ACT_RET_PRS_ERR;
 	}
 	rule->action_ptr = http_action_set_map;
+	rule->release_ptr = release_http_map;
 
 	cur_arg = *orig_arg;
 	if (rule->action == 1 && (!*args[cur_arg] || !*args[cur_arg+1])) {
@@ -1517,6 +1600,11 @@
 	return ACT_RET_CONT;
 }
 
+static void release_http_track_sc(struct act_rule *rule)
+{
+	release_sample_expr(rule->arg.trk_ctr.expr);
+}
+
 /* Parse a "track-sc*" actions. It returns ACT_RET_PRS_OK on success,
  * ACT_RET_PRS_ERR on error.
  */
@@ -1566,6 +1654,7 @@
 	rule->action = tsc_num;
 	rule->arg.trk_ctr.expr = expr;
 	rule->action_ptr = http_action_track_sc;
+	rule->release_ptr = release_http_track_sc;
 	rule->check_ptr = check_trk_action;
 
 	*orig_arg = cur_arg;