diff --git a/doc/configuration.txt b/doc/configuration.txt index 6d6f45edc..65df4172b 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -2847,8 +2847,8 @@ http-check send-state http-request { allow | deny | tarpit | auth [realm ] | redirect | add-header | set-header | - set-nice | set-log-level | set-tos | - set-mark } + del-header | set-nice | set-log-level | + set-tos | set-mark } [ { if | unless } ] Access control for Layer 7 requests @@ -2907,6 +2907,9 @@ http-request { allow | deny | tarpit | auth [realm ] | redirect | information to the server, where the header must not be manipulated by external users. + - "del-header" removes all HTTP header fields whose name is specified in + . + - "set-nice" sets the "nice" factor of the current request being processed. It only has effect against the other requests being processed at the same time. The default value is 0, unless altered by the "nice" setting on the @@ -2977,8 +2980,8 @@ http-request { allow | deny | tarpit | auth [realm ] | redirect | about ACL usage. http-response { allow | deny | add-header | set-nice | - set-header | set-log-level | - set-mark | set-tos } + set-header | del-header | + set-log-level | set-mark | set-tos } [ { if | unless } ] Access control for Layer 7 responses @@ -3014,6 +3017,9 @@ http-response { allow | deny | add-header | set-nice | information to the server, where the header must not be manipulated by external users. + - "del-header" removes all HTTP header fields whose name is specified in + . + - "set-nice" sets the "nice" factor of the current request being processed. It only has effect against the other requests being processed at the same time. The default value is 0, unless altered by the "nice" setting on the diff --git a/include/types/proto_http.h b/include/types/proto_http.h index f3fc1fc0b..53e9fb4e8 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -246,6 +246,7 @@ enum { HTTP_REQ_ACT_AUTH, HTTP_REQ_ACT_ADD_HDR, HTTP_REQ_ACT_SET_HDR, + HTTP_REQ_ACT_DEL_HDR, HTTP_REQ_ACT_REDIR, HTTP_REQ_ACT_SET_NICE, HTTP_REQ_ACT_SET_LOGL, @@ -261,6 +262,7 @@ enum { HTTP_RES_ACT_DENY, HTTP_RES_ACT_ADD_HDR, HTTP_RES_ACT_SET_HDR, + HTTP_RES_ACT_DEL_HDR, HTTP_RES_ACT_SET_NICE, HTTP_RES_ACT_SET_LOGL, HTTP_RES_ACT_SET_TOS, diff --git a/src/proto_http.c b/src/proto_http.c index 546b59eb5..3a4b0702e 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -3210,6 +3210,7 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct session s->logs.level = rule->arg.loglevel; break; + case HTTP_REQ_ACT_DEL_HDR: case HTTP_REQ_ACT_SET_HDR: ctx.idx = 0; /* remove all occurrences of the header */ @@ -3217,6 +3218,8 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct session txn->req.chn->buf->p, &txn->hdr_idx, &ctx)) { http_remove_header2(&txn->req, &txn->hdr_idx, &ctx); } + if (rule->action == HTTP_REQ_ACT_DEL_HDR) + break; /* now fall through to header addition */ case HTTP_REQ_ACT_ADD_HDR: @@ -3296,6 +3299,7 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct session s->logs.level = rule->arg.loglevel; break; + case HTTP_RES_ACT_DEL_HDR: case HTTP_RES_ACT_SET_HDR: ctx.idx = 0; /* remove all occurrences of the header */ @@ -3303,6 +3307,8 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct session txn->rsp.chn->buf->p, &txn->hdr_idx, &ctx)) { http_remove_header2(&txn->rsp, &txn->hdr_idx, &ctx); } + if (rule->action == HTTP_RES_ACT_DEL_HDR) + break; /* now fall through to header addition */ case HTTP_RES_ACT_ADD_HDR: @@ -8590,6 +8596,25 @@ struct http_req_rule *parse_http_req_cond(const char **args, const char *file, i proxy->conf.lfs_file = strdup(proxy->conf.args.file); proxy->conf.lfs_line = proxy->conf.args.line; cur_arg += 2; + } else if (strcmp(args[0], "del-header") == 0) { + rule->action = HTTP_REQ_ACT_DEL_HDR; + cur_arg = 1; + + if (!*args[cur_arg] || + (*args[cur_arg+1] && strcmp(args[cur_arg+1], "if") != 0 && strcmp(args[cur_arg+1], "unless") != 0)) { + Alert("parsing [%s:%d]: 'http-request %s' expects exactly 1 argument.\n", + file, linenum, args[0]); + goto out_err; + } + + rule->arg.hdr_add.name = strdup(args[cur_arg]); + rule->arg.hdr_add.name_len = strlen(rule->arg.hdr_add.name); + + proxy->conf.args.ctx = ARGC_HRQ; + free(proxy->conf.lfs_file); + proxy->conf.lfs_file = strdup(proxy->conf.args.file); + proxy->conf.lfs_line = proxy->conf.args.line; + cur_arg += 1; } else if (strcmp(args[0], "redirect") == 0) { struct redirect_rule *redir; char *errmsg = NULL; @@ -8762,6 +8787,25 @@ struct http_res_rule *parse_http_res_cond(const char **args, const char *file, i proxy->conf.lfs_file = strdup(proxy->conf.args.file); proxy->conf.lfs_line = proxy->conf.args.line; cur_arg += 2; + } else if (strcmp(args[0], "del-header") == 0) { + rule->action = HTTP_RES_ACT_DEL_HDR; + cur_arg = 1; + + if (!*args[cur_arg] || + (*args[cur_arg+1] && strcmp(args[cur_arg+1], "if") != 0 && strcmp(args[cur_arg+1], "unless") != 0)) { + Alert("parsing [%s:%d]: 'http-response %s' expects exactly 1 argument.\n", + file, linenum, args[0]); + goto out_err; + } + + rule->arg.hdr_add.name = strdup(args[cur_arg]); + rule->arg.hdr_add.name_len = strlen(rule->arg.hdr_add.name); + + proxy->conf.args.ctx = ARGC_HRS; + free(proxy->conf.lfs_file); + proxy->conf.lfs_file = strdup(proxy->conf.args.file); + proxy->conf.lfs_line = proxy->conf.args.line; + cur_arg += 1; } else { Alert("parsing [%s:%d]: 'http-response' expects 'allow', 'deny', 'redirect', 'add-header', 'set-header', 'set-nice', 'set-tos', 'set-mark', 'set-log-level', but got '%s'%s.\n", file, linenum, args[0], *args[0] ? "" : " (missing argument)");