]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: actions: Regroup some info about HTTP rules in the same struct
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 17 Dec 2019 12:46:18 +0000 (13:46 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 20 Jan 2020 14:18:45 +0000 (15:18 +0100)
Info used by HTTP rules manipulating the message itself are splitted in several
structures in the arg union. But it is possible to group all of them in a unique
struct. Now, <arg.http> is used by most of these rules, which contains:

  * <arg.http.i>   : an integer used as status code, nice/tos/mark/loglevel or
                     action id.
  * <arg.http.str> : an IST used as header name, reason string or auth realm.
  * <arg.http.fmt> : a log-format compatible expression
  * <arg.http.re>  : a regular expression used by replace rules

include/proto/http_ana.h
include/types/action.h
src/hlua.c
src/http_act.c
src/http_ana.c

index b324ea9046ca6b0efb6c7438dde7f4bd64dcfa6d..10ee78aefbac438ad177dd133d879dd34d3a8f86 100644 (file)
@@ -44,7 +44,7 @@ int http_transform_header_str(struct stream* s, struct channel *chn, struct htx
                              struct ist name, const char *str, struct my_regex *re, int action);
 int http_req_replace_stline(int action, const char *replace, int len,
                            struct proxy *px, struct stream *s);
-int http_res_set_status(unsigned int status, const char *reason, struct stream *s);
+int http_res_set_status(unsigned int status, struct ist reason, struct stream *s);
 void http_check_request_for_cacheability(struct stream *s, struct channel *req);
 void http_check_response_for_cacheability(struct stream *s, struct channel *res);
 void http_perform_server_redirect(struct stream *s, struct stream_interface *si);
index 01447efc3e9a52c5f0f0dc9843deee1f47842730..8f0961e6411cc15d4daed7566410420738c242dc 100644 (file)
@@ -104,7 +104,6 @@ struct act_rule {
        struct acl_cond *cond;                 /* acl condition to meet */
        enum act_name action;                  /* ACT_ACTION_* */
        enum act_from from;                    /* ACT_F_* */
-       short deny_status;                     /* HTTP status to return to user when denying */
        enum act_return (*action_ptr)(struct act_rule *rule, struct proxy *px,  /* ptr to custom action */
                                      struct session *sess, struct stream *s, int flags);
        int (*check_ptr)(struct act_rule *rule, struct proxy *px, char **err); /* ptr to check function */
@@ -118,44 +117,24 @@ struct act_rule {
                        char *resolvers_id;
                        struct dns_resolvers *resolvers;
                        struct dns_options dns_opts;
-               } dns;                        /* dns resolution */
+               } dns;                         /* dns resolution */
                struct {
-                       char *realm;
-               } auth;                        /* arg used by "auth" */
-               struct {
-                       char *name;            /* header name */
-                       int name_len;          /* header name's length */
-                       struct list fmt;       /* log-format compatible expression */
-                       struct my_regex *re;   /* used by replace-header and replace-value */
-               } hdr_add;                     /* args used by "add-header" and "set-header" */
-               struct {
-                       char *name;            /* header name */
-                       int name_len;          /* header name's length */
+                       int i;                 /* integer param (status, nice, loglevel, ..) */
+                       struct ist str;        /* string param (reason, header name, ...) */
                        struct list fmt;       /* log-format compatible expression */
-               } early_hint;
+                       struct my_regex *re;   /* used by replace-header/value/uri/path */
+               } http;                        /* args used by some HTTP rules */
                struct redirect_rule *redir;   /* redirect rule or "http-request redirect" */
-               int nice;                      /* nice value for ACT_HTTP_SET_NICE */
-               int loglevel;                  /* log-level value for ACT_HTTP_SET_LOGL */
-               int tos;                       /* tos value for ACT_HTTP_SET_TOS */
-               int mark;                      /* nfmark value for ACT_HTTP_SET_MARK */
                struct {
                        char *ref;             /* MAP or ACL file name to update */
                        struct list key;       /* pattern to retrieve MAP or ACL key */
                        struct list value;     /* pattern to retrieve MAP value */
                } map;
                struct sample_expr *expr;
-               struct {
-                       struct list logfmt;
-                       int action;
-               } http;
                struct {
                        struct sample_expr *expr; /* expression used as the key */
                        struct cap_hdr *hdr;      /* the capture storage */
                } cap;
-               struct {
-                       unsigned int code;     /* HTTP status code */
-                       const char *reason;    /* HTTP status reason */
-               } status;
                struct {
                        struct sample_expr *expr;
                        int idx;
index 8f46566c23ce3001107cadd7db250c18679c5265..ee36cd9c2342b45380dc367b971ce144ed8a5553 100644 (file)
@@ -5051,7 +5051,8 @@ static int hlua_http_res_set_status(lua_State *L)
 {
        struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
        unsigned int code = MAY_LJMP(luaL_checkinteger(L, 2));
-       const char *reason = MAY_LJMP(luaL_optlstring(L, 3, NULL, NULL));
+       const char *str = MAY_LJMP(luaL_optlstring(L, 3, NULL, NULL));
+       const struct ist reason = ist2(str, (str ? strlen(str) : 0));
 
        if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
                WILL_LJMP(lua_error(L));
index cf0d8bf84efec4bff53ded95705437004a6bc41d..994e3b47c0524ca7983625e8d735493b5736ae98 100644 (file)
@@ -42,7 +42,7 @@
 
 /* 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
- * the action to be performed in <http.action>, previously filled by function
+ * the action to be performed in <http.i>, previously filled by function
  * parse_set_req_line(). The replacement action is excuted by the function
  * http_action_set_req_line(). On success, it returns ACT_RET_CONT. If an error
  * occurs while soft rewrites are enabled, the action is canceled, but the rule
@@ -59,13 +59,13 @@ static enum act_return http_action_set_req_line(struct act_rule *rule, struct pr
                goto fail_alloc;
 
        /* If we have to create a query string, prepare a '?'. */
-       if (rule->arg.http.action == 2)
+       if (rule->arg.http.i == 2) // set-query
                replace->area[replace->data++] = '?';
        replace->data += build_logline(s, replace->area + replace->data,
                                       replace->size - replace->data,
-                                      &rule->arg.http.logfmt);
+                                      &rule->arg.http.fmt);
 
-       if (http_req_replace_stline(rule->arg.http.action, replace->area,
+       if (http_req_replace_stline(rule->arg.http.i, replace->area,
                                    replace->data, px, s) == -1)
                goto fail_rewrite;
 
@@ -100,8 +100,8 @@ static enum act_return http_action_set_req_line(struct act_rule *rule, struct pr
  *   set-uri
  *
  * All of them accept a single argument of type string representing a log-format.
- * The resulting rule makes use of arg->act.p[0..1] to store the log-format list
- * head, and p[2] to store the action as an int (0=method, 1=path, 2=query, 3=uri).
+ * The resulting rule makes use of <http.fmt> to store the log-format list head,
+ * and <http.i> to store the action as an int (0=method, 1=path, 2=query, 3=uri).
  * It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
  */
 static enum act_parse_ret parse_set_req_line(const char **args, int *orig_arg, struct proxy *px,
@@ -113,25 +113,22 @@ static enum act_parse_ret parse_set_req_line(const char **args, int *orig_arg, s
 
        switch (args[0][4]) {
        case 'm' :
-               rule->arg.http.action = 0;
-               rule->action_ptr = http_action_set_req_line;
+               rule->arg.http.i = 0; // set-method
                break;
        case 'p' :
-               rule->arg.http.action = 1;
-               rule->action_ptr = http_action_set_req_line;
+               rule->arg.http.i = 1; // set-path
                break;
        case 'q' :
-               rule->arg.http.action = 2;
-               rule->action_ptr = http_action_set_req_line;
+               rule->arg.http.i = 2; // set-query
                break;
        case 'u' :
-               rule->arg.http.action = 3;
-               rule->action_ptr = http_action_set_req_line;
+               rule->arg.http.i = 3; // set-uri
                break;
        default:
                memprintf(err, "internal error: unhandled action '%s'", args[0]);
                return ACT_RET_PRS_ERR;
        }
+       rule->action_ptr = http_action_set_req_line;
 
        if (!*args[cur_arg] ||
            (*args[cur_arg + 1] && strcmp(args[cur_arg + 1], "if") != 0 && strcmp(args[cur_arg + 1], "unless") != 0)) {
@@ -139,9 +136,9 @@ static enum act_parse_ret parse_set_req_line(const char **args, int *orig_arg, s
                return ACT_RET_PRS_ERR;
        }
 
-       LIST_INIT(&rule->arg.http.logfmt);
+       LIST_INIT(&rule->arg.http.fmt);
        px->conf.args.ctx = ARGC_HRQ;
-       if (!parse_logformat_string(args[cur_arg], px, &rule->arg.http.logfmt, LOG_OPT_HTTP,
+       if (!parse_logformat_string(args[cur_arg], px, &rule->arg.http.fmt, LOG_OPT_HTTP,
                                    (px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, err)) {
                return ACT_RET_PRS_ERR;
        }
@@ -151,14 +148,14 @@ static enum act_parse_ret parse_set_req_line(const char **args, int *orig_arg, s
 }
 
 /* This function executes a replace-uri action. It finds its arguments in
- * <rule>.arg.act.p[]. It builds a string in the trash from the format string
+ * <rule>.arg.http. It builds a string in the trash from the format string
  * previously filled by function parse_replace_uri() and will execute the regex
- * in p[1] to replace the URI. It uses the format string present in act.p[2..3].
- * The component to act on (path/uri) is taken from act.p[0] which contains 1
- * for the path or 3 for the URI (values used by http_req_replace_stline()).
- * On success, it returns ACT_RET_CONT. If an error occurs while soft rewrites
- * are enabled, the action is canceled, but the rule processing continue.
- * Otherwsize ACT_RET_ERR is returned.
+ * in <http.re> to replace the URI. It uses the format string present in
+ * <http.fmt>. The component to act on (path/uri) is taken from <http.i> which
+ * contains 1 for the path or 3 for the URI (values used by
+ * http_req_replace_stline()). On success, it returns ACT_RET_CONT. If an error
+ * occurs while soft rewrites are enabled, the action is canceled, but the rule
+ * processing continue. Otherwsize ACT_RET_ERR is returned.
  */
 static enum act_return http_action_replace_uri(struct act_rule *rule, struct proxy *px,
                                                struct session *sess, struct stream *s, int flags)
@@ -174,13 +171,13 @@ static enum act_return http_action_replace_uri(struct act_rule *rule, struct pro
                goto fail_alloc;
        uri = htx_sl_req_uri(http_get_stline(htxbuf(&s->req.buf)));
 
-       if (rule->arg.act.p[0] == (void *)1)
-               uri = http_get_path(uri); // replace path
+       if (rule->arg.http.i == 1) // replace-path
+               uri = http_get_path(uri);
 
-       if (!regex_exec_match2(rule->arg.act.p[1], uri.ptr, uri.len, MAX_MATCH, pmatch, 0))
+       if (!regex_exec_match2(rule->arg.http.re, uri.ptr, uri.len, MAX_MATCH, pmatch, 0))
                goto leave;
 
-       replace->data = build_logline(s, replace->area, replace->size, (struct list *)&rule->arg.act.p[2]);
+       replace->data = build_logline(s, replace->area, replace->size, &rule->arg.http.fmt);
 
        /* note: uri.ptr doesn't need to be zero-terminated because it will
         * only be used to pick pmatch references.
@@ -189,7 +186,7 @@ static enum act_return http_action_replace_uri(struct act_rule *rule, struct pro
        if (len == -1)
                goto fail_rewrite;
 
-       if (http_req_replace_stline((long)rule->arg.act.p[0], output->area, len, px, s) == -1)
+       if (http_req_replace_stline(rule->arg.http.i, output->area, len, px, s) == -1)
                goto fail_rewrite;
 
   leave:
@@ -219,8 +216,8 @@ static enum act_return http_action_replace_uri(struct act_rule *rule, struct pro
 
 /* parse a "replace-uri" or "replace-path" http-request action.
  * This action takes 2 arguments (a regex and a replacement format string).
- * The resulting rule makes use of arg->act.p[0] to store the action (1/3 for now),
- * p[1] to store the compiled regex, and arg->act.p[2..3] to store the log-format
+ * The resulting rule makes use of <http.i> to store the action (1/3 for now),
+ * <http.re> to store the compiled regex, and <http.fmt> to store the log-format
  * list head. It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
  */
 static enum act_parse_ret parse_replace_uri(const char **args, int *orig_arg, struct proxy *px,
@@ -231,9 +228,9 @@ static enum act_parse_ret parse_replace_uri(const char **args, int *orig_arg, st
 
        rule->action = ACT_CUSTOM;
        if (strcmp(args[cur_arg-1], "replace-path") == 0)
-               rule->arg.act.p[0] = (void *)1; // replace-path
+               rule->arg.http.i = 1; // replace-path
        else
-               rule->arg.act.p[0] = (void *)3; // replace-uri
+               rule->arg.http.i = 3; // replace-uri
 
        rule->action_ptr = http_action_replace_uri;
 
@@ -243,15 +240,15 @@ static enum act_parse_ret parse_replace_uri(const char **args, int *orig_arg, st
                return ACT_RET_PRS_ERR;
        }
 
-       if (!(rule->arg.act.p[1] = regex_comp(args[cur_arg], 1, 1, &error))) {
+       if (!(rule->arg.http.re = regex_comp(args[cur_arg], 1, 1, &error))) {
                memprintf(err, "failed to parse the regex : %s", error);
                free(error);
                return ACT_RET_PRS_ERR;
        }
 
-       LIST_INIT((struct list *)&rule->arg.act.p[2]);
+       LIST_INIT(&rule->arg.http.fmt);
        px->conf.args.ctx = ARGC_HRQ;
-       if (!parse_logformat_string(args[cur_arg + 1], px, (struct list *)&rule->arg.act.p[2], LOG_OPT_HTTP,
+       if (!parse_logformat_string(args[cur_arg + 1], px, &rule->arg.http.fmt, LOG_OPT_HTTP,
                                    (px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, err)) {
                return ACT_RET_PRS_ERR;
        }
@@ -264,7 +261,7 @@ static enum act_parse_ret parse_replace_uri(const char **args, int *orig_arg, st
 static enum act_return action_http_set_status(struct act_rule *rule, struct proxy *px,
                                               struct session *sess, struct stream *s, int flags)
 {
-       if (http_res_set_status(rule->arg.status.code, rule->arg.status.reason, s) == -1) {
+       if (http_res_set_status(rule->arg.http.i, rule->arg.http.str, s) == -1) {
                _HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_rewrites, 1);
                if (s->flags & SF_BE_ASSIGNED)
                        _HA_ATOMIC_ADD(&s->be->be_counters.failed_rewrites, 1);
@@ -300,8 +297,8 @@ static enum act_parse_ret parse_http_set_status(const char **args, int *orig_arg
        }
 
        /* convert status code as integer */
-       rule->arg.status.code = strtol(args[*orig_arg], &error, 10);
-       if (*error != '\0' || rule->arg.status.code < 100 || rule->arg.status.code > 999) {
+       rule->arg.http.i = strtol(args[*orig_arg], &error, 10);
+       if (*error != '\0' || rule->arg.http.i < 100 || rule->arg.http.i > 999) {
                memprintf(err, "expects an integer status code between 100 and 999");
                return ACT_RET_PRS_ERR;
        }
@@ -309,11 +306,12 @@ static enum act_parse_ret parse_http_set_status(const char **args, int *orig_arg
        (*orig_arg)++;
 
        /* set custom reason string */
-       rule->arg.status.reason = NULL; // If null, we use the default reason for the status code.
+       rule->arg.http.str = ist(NULL); // If null, we use the default reason for the status code.
        if (*args[*orig_arg] && strcmp(args[*orig_arg], "reason") == 0 &&
            (*args[*orig_arg + 1] && strcmp(args[*orig_arg + 1], "if") != 0 && strcmp(args[*orig_arg + 1], "unless") != 0)) {
                (*orig_arg)++;
-               rule->arg.status.reason = strdup(args[*orig_arg]);
+               rule->arg.http.str.ptr = strdup(args[*orig_arg]);
+               rule->arg.http.str.len = strlen(rule->arg.http.str.ptr);
                (*orig_arg)++;
        }
 
@@ -765,11 +763,11 @@ static enum act_parse_ret parse_http_req_deny(const char **args, int *orig_arg,
        cur_arg = *orig_arg;
        if (!strcmp(args[cur_arg-1], "tarpit")) {
                rule->action = ACT_HTTP_REQ_TARPIT;
-               rule->deny_status = HTTP_ERR_500;
+               rule->arg.http.i = HTTP_ERR_500;
        }
        else {
                rule->action = ACT_ACTION_DENY;
-               rule->deny_status = HTTP_ERR_403;
+               rule->arg.http.i = HTTP_ERR_403;
        }
 
        if (strcmp(args[cur_arg], "deny_status") == 0) {
@@ -783,13 +781,13 @@ static enum act_parse_ret parse_http_req_deny(const char **args, int *orig_arg,
                cur_arg++;
                for (hc = 0; hc < HTTP_ERR_SIZE; hc++) {
                        if (http_err_codes[hc] == code) {
-                               rule->deny_status = hc;
+                               rule->arg.http.i = hc;
                                break;
                        }
                }
                if (hc >= HTTP_ERR_SIZE)
                        memprintf(err, "status code %d not handled, using default code %d",
-                                 code, http_err_codes[rule->deny_status]);
+                                 code, http_err_codes[rule->arg.http.i]);
        }
 
        *orig_arg = cur_arg;
@@ -823,7 +821,8 @@ static enum act_parse_ret parse_http_auth(const char **args, int *orig_arg, stru
                        memprintf(err, "missing realm value.\n");
                        return ACT_RET_PRS_ERR;
                }
-               rule->arg.auth.realm = strdup(args[cur_arg]);
+               rule->arg.http.str.ptr = strdup(args[cur_arg]);
+               rule->arg.http.str.len = strlen(rule->arg.http.str.ptr);
                cur_arg++;
        }
 
@@ -846,11 +845,11 @@ static enum act_parse_ret parse_http_set_nice(const char **args, int *orig_arg,
                memprintf(err, "expects exactly 1 argument (integer value)");
                return ACT_RET_PRS_ERR;
        }
-       rule->arg.nice = atoi(args[cur_arg]);
-       if (rule->arg.nice < -1024)
-               rule->arg.nice = -1024;
-       else if (rule->arg.nice > 1024)
-               rule->arg.nice = 1024;
+       rule->arg.http.i = atoi(args[cur_arg]);
+       if (rule->arg.http.i < -1024)
+               rule->arg.http.i = -1024;
+       else if (rule->arg.http.i > 1024)
+               rule->arg.http.i = 1024;
 
        *orig_arg = cur_arg + 1;
        return ACT_RET_PRS_OK;
@@ -873,7 +872,7 @@ static enum act_parse_ret parse_http_set_tos(const char **args, int *orig_arg, s
                memprintf(err, "expects exactly 1 argument (integer/hex value)");
                return ACT_RET_PRS_ERR;
        }
-       rule->arg.tos = strtol(args[cur_arg], &endp, 0);
+       rule->arg.http.i = strtol(args[cur_arg], &endp, 0);
        if (endp && *endp != '\0') {
                memprintf(err, "invalid character starting at '%s' (integer/hex value expected)", endp);
                return ACT_RET_PRS_ERR;
@@ -904,7 +903,7 @@ static enum act_parse_ret parse_http_set_mark(const char **args, int *orig_arg,
                memprintf(err, "expects exactly 1 argument (integer/hex value)");
                return ACT_RET_PRS_ERR;
        }
-       rule->arg.mark = strtoul(args[cur_arg], &endp, 0);
+       rule->arg.http.i = strtoul(args[cur_arg], &endp, 0);
        if (endp && *endp != '\0') {
                memprintf(err, "invalid character starting at '%s' (integer/hex value expected)", endp);
                return ACT_RET_PRS_ERR;
@@ -936,8 +935,8 @@ static enum act_parse_ret parse_http_set_log_level(const char **args, int *orig_
                return ACT_RET_PRS_ERR;
        }
        if (strcmp(args[cur_arg], "silent") == 0)
-               rule->arg.loglevel = -1;
-       else if ((rule->arg.loglevel = get_log_level(args[cur_arg]) + 1) == 0)
+               rule->arg.http.i = -1;
+       else if ((rule->arg.http.i = get_log_level(args[cur_arg]) + 1) == 0)
                goto bad_log_level;
 
        *orig_arg = cur_arg + 1;
@@ -954,9 +953,6 @@ static enum act_parse_ret parse_http_set_log_level(const char **args, int *orig_
 static enum act_parse_ret parse_http_set_header(const char **args, int *orig_arg, struct proxy *px,
                                                   struct act_rule *rule, char **err)
 {
-       char **hdr_name;
-       int *hdr_name_len;
-       struct list *fmt;
        int cap, cur_arg;
 
        rule->action = (*args[*orig_arg-1] == 'a' ? ACT_HTTP_ADD_HDR :
@@ -968,13 +964,10 @@ static enum act_parse_ret parse_http_set_header(const char **args, int *orig_arg
                return ACT_RET_PRS_ERR;
        }
 
-       hdr_name     = (*args[cur_arg-1] == 'e' ? &rule->arg.early_hint.name     : &rule->arg.hdr_add.name);
-       hdr_name_len = (*args[cur_arg-1] == 'e' ? &rule->arg.early_hint.name_len : &rule->arg.hdr_add.name_len);
-       fmt          = (*args[cur_arg-1] == 'e' ? &rule->arg.early_hint.fmt      : &rule->arg.hdr_add.fmt);
 
-       *hdr_name = strdup(args[cur_arg]);
-       *hdr_name_len = strlen(*hdr_name);
-       LIST_INIT(fmt);
+       rule->arg.http.str.ptr = strdup(args[cur_arg]);
+       rule->arg.http.str.len = strlen(rule->arg.http.str.ptr);
+       LIST_INIT(&rule->arg.http.fmt);
 
        if (rule->from == ACT_F_HTTP_REQ) {
                px->conf.args.ctx = ARGC_HRQ;
@@ -986,7 +979,7 @@ static enum act_parse_ret parse_http_set_header(const char **args, int *orig_arg
        }
 
        cur_arg++;
-       if (!parse_logformat_string(args[cur_arg], px, fmt, LOG_OPT_HTTP, cap, err))
+       if (!parse_logformat_string(args[cur_arg], px, &rule->arg.http.fmt, LOG_OPT_HTTP, cap, err))
                return ACT_RET_PRS_ERR;
 
        free(px->conf.lfs_file);
@@ -1014,12 +1007,12 @@ static enum act_parse_ret parse_http_replace_header(const char **args, int *orig
                return ACT_RET_PRS_ERR;
        }
 
-       rule->arg.hdr_add.name = strdup(args[cur_arg]);
-       rule->arg.hdr_add.name_len = strlen(rule->arg.hdr_add.name);
-       LIST_INIT(&rule->arg.hdr_add.fmt);
+       rule->arg.http.str.ptr = strdup(args[cur_arg]);
+       rule->arg.http.str.len = strlen(rule->arg.http.str.ptr);
+       LIST_INIT(&rule->arg.http.fmt);
 
        cur_arg++;
-       if (!(rule->arg.hdr_add.re = regex_comp(args[cur_arg], 1, 1, err)))
+       if (!(rule->arg.http.re = regex_comp(args[cur_arg], 1, 1, err)))
                return ACT_RET_PRS_ERR;
 
        if (rule->from == ACT_F_HTTP_REQ) {
@@ -1032,7 +1025,7 @@ static enum act_parse_ret parse_http_replace_header(const char **args, int *orig
        }
 
        cur_arg++;
-       if (!parse_logformat_string(args[cur_arg], px, &rule->arg.hdr_add.fmt, LOG_OPT_HTTP, cap, err))
+       if (!parse_logformat_string(args[cur_arg], px, &rule->arg.http.fmt, LOG_OPT_HTTP, cap, err))
                return ACT_RET_PRS_ERR;
 
        free(px->conf.lfs_file);
@@ -1059,8 +1052,8 @@ static enum act_parse_ret parse_http_del_header(const char **args, int *orig_arg
                return ACT_RET_PRS_ERR;
        }
 
-       rule->arg.hdr_add.name = strdup(args[cur_arg]);
-       rule->arg.hdr_add.name_len = strlen(rule->arg.hdr_add.name);
+       rule->arg.http.str.ptr = strdup(args[cur_arg]);
+       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);
 
index 538797feff9d8f08598e607ded84d894a99c7a41..9d513495285f409c2ca2c759faa0ce58d149b88e 100644 (file)
@@ -2886,7 +2886,7 @@ int http_req_replace_stline(int action, const char *replace, int len,
  * variable <status> contains the new status code. This function never fails. It
  * returns 0 in case of success, -1 in case of internal error.
  */
-int http_res_set_status(unsigned int status, const char *reason, struct stream *s)
+int http_res_set_status(unsigned int status, struct ist reason, struct stream *s)
 {
        struct htx *htx = htxbuf(&s->res.buf);
        char *res;
@@ -2896,12 +2896,14 @@ int http_res_set_status(unsigned int status, const char *reason, struct stream *
        trash.data = res - trash.area;
 
        /* Do we have a custom reason format string? */
-       if (reason == NULL)
-               reason = http_get_reason(status);
+       if (reason.ptr == NULL) {
+               const char *str = http_get_reason(status);
+               reason = ist2(str, strlen(str));
+       }
 
        if (!http_replace_res_status(htx, ist2(trash.area, trash.data)))
                return -1;
-       if (!http_replace_res_reason(htx, ist2(reason, strlen(reason))))
+       if (!http_replace_res_reason(htx, reason))
                return -1;
        return 0;
 }
@@ -2978,20 +2980,20 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
 
                        case ACT_ACTION_DENY:
                                if (deny_status)
-                                       *deny_status = rule->deny_status;
+                                       *deny_status = rule->arg.http.i;
                                rule_ret = HTTP_RULE_RES_DENY;
                                goto end;
 
                        case ACT_HTTP_REQ_TARPIT:
                                txn->flags |= TX_CLTARPIT;
                                if (deny_status)
-                                       *deny_status = rule->deny_status;
+                                       *deny_status = rule->arg.http.i;
                                rule_ret = HTTP_RULE_RES_DENY;
                                goto end;
 
                        case ACT_HTTP_REQ_AUTH:
                                /* Auth might be performed on regular http-req rules as well as on stats */
-                               auth_realm = rule->arg.auth.realm;
+                               auth_realm = rule->arg.http.str.ptr;
                                if (!auth_realm) {
                                        if (px->uri_auth && rules == &px->uri_auth->http_req_rules)
                                                auth_realm = STATS_DEFAULT_REALM;
@@ -3015,27 +3017,26 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
                                goto end;
 
                        case ACT_HTTP_SET_NICE:
-                               s->task->nice = rule->arg.nice;
+                               s->task->nice = rule->arg.http.i;
                                break;
 
                        case ACT_HTTP_SET_TOS:
-                               conn_set_tos(objt_conn(sess->origin), rule->arg.tos);
+                               conn_set_tos(objt_conn(sess->origin), rule->arg.http.i);
                                break;
 
                        case ACT_HTTP_SET_MARK:
-                               conn_set_mark(objt_conn(sess->origin), rule->arg.mark);
+                               conn_set_mark(objt_conn(sess->origin), rule->arg.http.i);
                                break;
 
                        case ACT_HTTP_SET_LOGL:
-                               s->logs.level = rule->arg.loglevel;
+                               s->logs.level = rule->arg.http.i;
                                break;
 
                        case ACT_HTTP_REPLACE_HDR:
                        case ACT_HTTP_REPLACE_VAL:
-                               if (http_transform_header(s, &s->req, htx,
-                                                         ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len),
-                                                         &rule->arg.hdr_add.fmt,
-                                                         rule->arg.hdr_add.re, rule->action)) {
+                               if (http_transform_header(s, &s->req, htx, rule->arg.http.str,
+                                                         &rule->arg.http.fmt,
+                                                         rule->arg.http.re, rule->action)) {
                                        rule_ret = HTTP_RULE_RES_ERROR;
                                        goto end;
                                }
@@ -3044,7 +3045,7 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
                        case ACT_HTTP_DEL_HDR:
                                /* remove all occurrences of the header */
                                ctx.blk = NULL;
-                               while (http_find_header(htx, ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len), &ctx, 1))
+                               while (http_find_header(htx, rule->arg.http.str, &ctx, 1))
                                        http_remove_header(htx, &ctx);
                                break;
 
@@ -3067,14 +3068,14 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
                                        goto end;
                                }
 
-                               replace->data = build_logline(s, replace->area, replace->size, &rule->arg.hdr_add.fmt);
-                               n = ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len);
+                               replace->data = build_logline(s, replace->area, replace->size, &rule->arg.http.fmt);
+                               n = rule->arg.http.str;
                                v = ist2(replace->area, replace->data);
 
                                if (rule->action == ACT_HTTP_SET_HDR) {
                                        /* remove all occurrences of the header */
                                        ctx.blk = NULL;
-                                       while (http_find_header(htx, ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len), &ctx, 1))
+                                       while (http_find_header(htx, n, &ctx, 1))
                                                http_remove_header(htx, &ctx);
                                }
 
@@ -3213,9 +3214,7 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
                        case ACT_HTTP_EARLY_HINT:
                                if (!(txn->req.flags & HTTP_MSGF_VER_11))
                                        break;
-                               early_hints = http_add_early_hint_header(s, early_hints,
-                                                                        ist2(rule->arg.early_hint.name, rule->arg.early_hint.name_len),
-                                                                        &rule->arg.early_hint.fmt);
+                               early_hints = http_add_early_hint_header(s, early_hints, rule->arg.http.str, &rule->arg.http.fmt);
                                if (early_hints == -1) {
                                        rule_ret = HTTP_RULE_RES_ERROR;
                                        goto end;
@@ -3386,27 +3385,26 @@ resume_execution:
                                goto end;
 
                        case ACT_HTTP_SET_NICE:
-                               s->task->nice = rule->arg.nice;
+                               s->task->nice = rule->arg.http.i;
                                break;
 
                        case ACT_HTTP_SET_TOS:
-                               conn_set_tos(objt_conn(sess->origin), rule->arg.tos);
+                               conn_set_tos(objt_conn(sess->origin), rule->arg.http.i);
                                break;
 
                        case ACT_HTTP_SET_MARK:
-                               conn_set_mark(objt_conn(sess->origin), rule->arg.mark);
+                               conn_set_mark(objt_conn(sess->origin), rule->arg.http.i);
                                break;
 
                        case ACT_HTTP_SET_LOGL:
-                               s->logs.level = rule->arg.loglevel;
+                               s->logs.level = rule->arg.http.i;
                                break;
 
                        case ACT_HTTP_REPLACE_HDR:
                        case ACT_HTTP_REPLACE_VAL:
-                               if (http_transform_header(s, &s->res, htx,
-                                                         ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len),
-                                                         &rule->arg.hdr_add.fmt,
-                                                         rule->arg.hdr_add.re, rule->action)) {
+                               if (http_transform_header(s, &s->res, htx, rule->arg.http.str,
+                                                         &rule->arg.http.fmt,
+                                                         rule->arg.http.re, rule->action)) {
                                        rule_ret = HTTP_RULE_RES_ERROR;
                                        goto end;
                                }
@@ -3415,7 +3413,7 @@ resume_execution:
                        case ACT_HTTP_DEL_HDR:
                                /* remove all occurrences of the header */
                                ctx.blk = NULL;
-                               while (http_find_header(htx, ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len), &ctx, 1))
+                               while (http_find_header(htx, rule->arg.http.str, &ctx, 1))
                                        http_remove_header(htx, &ctx);
                                break;
 
@@ -3432,14 +3430,14 @@ resume_execution:
                                        goto end;
                                }
 
-                               replace->data = build_logline(s, replace->area, replace->size, &rule->arg.hdr_add.fmt);
-                               n = ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len);
+                               replace->data = build_logline(s, replace->area, replace->size, &rule->arg.http.fmt);
+                               n = rule->arg.http.str;
                                v = ist2(replace->area, replace->data);
 
                                if (rule->action == ACT_HTTP_SET_HDR) {
                                        /* remove all occurrences of the header */
                                        ctx.blk = NULL;
-                                       while (http_find_header(htx, ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len), &ctx, 1))
+                                       while (http_find_header(htx, n, &ctx, 1))
                                                http_remove_header(htx, &ctx);
                                }