MINOR: http_act: Add -m flag for del-header name matching method
This patch adds -m flag which allows to specify header name
matching method when deleting headers from http request/response.
Currently beg, end, sub, str and reg are supported.
This is related to GitHub issue #909
(cherry picked from commit ebdd4c55da4360bde7878604ea528c2031a26541)
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
diff --git a/src/http_act.c b/src/http_act.c
index 27db478..13a5c37 100644
--- a/src/http_act.c
+++ b/src/http_act.c
@@ -1438,20 +1438,67 @@
return ACT_RET_PRS_OK;
}
-/* Parse a "del-header" action. It takes an header name as argument. It returns
- * ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
+/* This function executes a del-header action with selected matching mode for
+ * header name. It finds the matching method to be performed in <.action>, previously
+ * filled by function parse_http_del_header(). On success, it returns ACT_RET_CONT.
+ * Otherwise ACT_RET_ERR is returned.
+ */
+static enum act_return http_action_del_header(struct act_rule *rule, struct proxy *px,
+ struct session *sess, struct stream *s, int flags)
+{
+ struct http_hdr_ctx ctx;
+ struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp);
+ struct htx *htx = htxbuf(&msg->chn->buf);
+ enum act_return ret = ACT_RET_CONT;
+
+ /* remove all occurrences of the header */
+ ctx.blk = NULL;
+ switch (rule->action) {
+ case PAT_MATCH_STR:
+ while (http_find_header(htx, rule->arg.http.str, &ctx, 1))
+ http_remove_header(htx, &ctx);
+ break;
+ case PAT_MATCH_BEG:
+ while (http_find_pfx_header(htx, rule->arg.http.str, &ctx, 1))
+ http_remove_header(htx, &ctx);
+ break;
+ case PAT_MATCH_END:
+ while (http_find_sfx_header(htx, rule->arg.http.str, &ctx, 1))
+ http_remove_header(htx, &ctx);
+ break;
+ case PAT_MATCH_SUB:
+ while (http_find_sub_header(htx, rule->arg.http.str, &ctx, 1))
+ http_remove_header(htx, &ctx);
+ break;
+ case PAT_MATCH_REG:
+ while (http_match_header(htx, rule->arg.http.re, &ctx, 1))
+ http_remove_header(htx, &ctx);
+ break;
+ default:
+ return ACT_RET_ERR;
+ }
+ return ret;
+}
+
+/* Parse a "del-header" action. It takes string as a required argument,
+ * optional flag (currently only -m) and optional matching method of input string
+ * with header name to be deleted. Default matching method is exact match (-m str).
+ * It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
*/
static enum act_parse_ret parse_http_del_header(const char **args, int *orig_arg, struct proxy *px,
struct act_rule *rule, char **err)
{
int cur_arg;
+ int pat_idx;
- rule->action = ACT_HTTP_DEL_HDR;
+ /* set exact matching (-m str) as default */
+ rule->action = PAT_MATCH_STR;
+ rule->action_ptr = http_action_del_header;
rule->release_ptr = release_http_action;
cur_arg = *orig_arg;
if (!*args[cur_arg]) {
- memprintf(err, "expects exactly 1 arguments");
+ memprintf(err, "expects at least 1 argument");
return ACT_RET_PRS_ERR;
}
@@ -1459,7 +1506,32 @@
rule->arg.http.str.len = strlen(rule->arg.http.str.ptr);
px->conf.args.ctx = (rule->from == ACT_F_HTTP_REQ ? ARGC_HRQ : ARGC_HRS);
+ if (strcmp(args[cur_arg+1], "-m") == 0) {
+ cur_arg++;
+ if (!*args[cur_arg+1]) {
+ memprintf(err, "-m flag expects exactly 1 argument");
+ return ACT_RET_PRS_ERR;
+ }
+
+ cur_arg++;
+ pat_idx = pat_find_match_name(args[cur_arg]);
+ switch (pat_idx) {
+ case PAT_MATCH_REG:
+ if (!(rule->arg.http.re = regex_comp(rule->arg.http.str.ptr, 1, 1, err)))
+ return ACT_RET_PRS_ERR;
+ /* fall through */
+ case PAT_MATCH_STR:
+ case PAT_MATCH_BEG:
+ case PAT_MATCH_END:
+ case PAT_MATCH_SUB:
+ rule->action = pat_idx;
+ break;
+ default:
+ memprintf(err, "-m with unsupported matching method '%s'", args[cur_arg]);
+ return ACT_RET_PRS_ERR;
+ }
+ }
+
- LIST_INIT(&rule->arg.http.fmt);
*orig_arg = cur_arg + 1;
return ACT_RET_PRS_OK;
}