MEDIUM: actions: Normalize the return code of the configuration parsers

This patch normalize the return code of the configuration parsers. Before
these changes, the tcp action parser returned -1 if fail and 0 for the
succes. The http action returned 0 if fail and 1 if succes.

The normalisation does:
 - ACT_RET_PRS_OK for succes
 - ACT_RET_PRS_ERR for failure
This commit is contained in:
Thierry FOURNIER 2015-08-19 09:04:15 +02:00 committed by Willy Tarreau
parent 322a124867
commit afa80496db
5 changed files with 75 additions and 67 deletions

View File

@ -38,6 +38,11 @@ enum act_return {
ACT_RET_ERR, /* processing error. */ ACT_RET_ERR, /* processing error. */
}; };
enum act_parse_ret {
ACT_RET_PRS_OK, /* continue processing. */
ACT_RET_PRS_ERR, /* abort processing. */
};
enum act_name { enum act_name {
ACT_ACTION_CONT = 0, ACT_ACTION_CONT = 0,
ACT_ACTION_STOP, ACT_ACTION_STOP,
@ -134,8 +139,8 @@ struct act_rule {
struct action_kw { struct action_kw {
const char *kw; const char *kw;
int (*parse)(const char **args, int *cur_arg, struct proxy *px, enum act_parse_ret (*parse)(const char **args, int *cur_arg, struct proxy *px,
struct act_rule *rule, char **err); struct act_rule *rule, char **err);
int match_pfx; int match_pfx;
}; };

View File

@ -4414,47 +4414,47 @@ enum act_return hlua_http_res_act_wrapper(struct act_rule *rule, struct proxy *p
} }
/* tcp-request <*> configuration wrapper. */ /* tcp-request <*> configuration wrapper. */
static int tcp_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px, static enum act_parse_ret tcp_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
struct act_rule *rule, char **err) struct act_rule *rule, char **err)
{ {
if (!hlua_parse_rule(args, cur_arg, px, &rule->arg.hlua_rule, err)) if (!hlua_parse_rule(args, cur_arg, px, &rule->arg.hlua_rule, err))
return 0; return ACT_RET_PRS_ERR;
rule->action = ACT_ACTION_CONT; rule->action = ACT_ACTION_CONT;
rule->action_ptr = hlua_tcp_req_act_wrapper; rule->action_ptr = hlua_tcp_req_act_wrapper;
return 1; return ACT_RET_PRS_OK;
} }
/* tcp-response <*> configuration wrapper. */ /* tcp-response <*> configuration wrapper. */
static int tcp_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px, static enum act_parse_ret tcp_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
struct act_rule *rule, char **err) struct act_rule *rule, char **err)
{ {
if (!hlua_parse_rule(args, cur_arg, px, &rule->arg.hlua_rule, err)) if (!hlua_parse_rule(args, cur_arg, px, &rule->arg.hlua_rule, err))
return 0; return ACT_RET_PRS_ERR;
rule->action = ACT_ACTION_CONT; rule->action = ACT_ACTION_CONT;
rule->action_ptr = hlua_tcp_res_act_wrapper; rule->action_ptr = hlua_tcp_res_act_wrapper;
return 1; return ACT_RET_PRS_OK;
} }
/* http-request <*> configuration wrapper. */ /* http-request <*> configuration wrapper. */
static int http_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px, static enum act_parse_ret http_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
struct act_rule *rule, char **err) struct act_rule *rule, char **err)
{ {
if (!hlua_parse_rule(args, cur_arg, px, &rule->arg.hlua_rule, err)) if (!hlua_parse_rule(args, cur_arg, px, &rule->arg.hlua_rule, err))
return -1; return ACT_RET_PRS_ERR;
rule->action = ACT_ACTION_CONT; rule->action = ACT_ACTION_CONT;
rule->action_ptr = hlua_http_req_act_wrapper; rule->action_ptr = hlua_http_req_act_wrapper;
return 1; return ACT_RET_PRS_OK;
} }
/* http-response <*> configuration wrapper. */ /* http-response <*> configuration wrapper. */
static int http_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px, static enum act_parse_ret http_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
struct act_rule *rule, char **err) struct act_rule *rule, char **err)
{ {
if (!hlua_parse_rule(args, cur_arg, px, &rule->arg.hlua_rule, err)) if (!hlua_parse_rule(args, cur_arg, px, &rule->arg.hlua_rule, err))
return -1; return ACT_RET_PRS_ERR;
rule->action = ACT_ACTION_CONT; rule->action = ACT_ACTION_CONT;
rule->action_ptr = hlua_http_res_act_wrapper; rule->action_ptr = hlua_http_res_act_wrapper;
return 1; return ACT_RET_PRS_OK;
} }
static int hlua_read_timeout(char **args, int section_type, struct proxy *curpx, static int hlua_read_timeout(char **args, int section_type, struct proxy *curpx,

View File

@ -9368,7 +9368,7 @@ struct act_rule *parse_http_req_cond(const char **args, const char *file, int li
cur_arg = 1; cur_arg = 1;
/* try in the module list */ /* try in the module list */
rule->from = ACT_F_HTTP_REQ; rule->from = ACT_F_HTTP_REQ;
if (custom->parse(args, &cur_arg, proxy, rule, &errmsg) < 0) { if (custom->parse(args, &cur_arg, proxy, rule, &errmsg) == ACT_RET_PRS_ERR) {
Alert("parsing [%s:%d] : error detected in %s '%s' while parsing 'http-request %s' rule : %s.\n", Alert("parsing [%s:%d] : error detected in %s '%s' while parsing 'http-request %s' rule : %s.\n",
file, linenum, proxy_type_str(proxy), proxy->id, args[0], errmsg); file, linenum, proxy_type_str(proxy), proxy->id, args[0], errmsg);
free(errmsg); free(errmsg);
@ -9724,7 +9724,7 @@ struct act_rule *parse_http_res_cond(const char **args, const char *file, int li
cur_arg = 1; cur_arg = 1;
/* try in the module list */ /* try in the module list */
rule->from = ACT_F_HTTP_RES; rule->from = ACT_F_HTTP_RES;
if (custom->parse(args, &cur_arg, proxy, rule, &errmsg) < 0) { if (custom->parse(args, &cur_arg, proxy, rule, &errmsg) == ACT_RET_PRS_ERR) {
Alert("parsing [%s:%d] : error detected in %s '%s' while parsing 'http-response %s' rule : %s.\n", Alert("parsing [%s:%d] : error detected in %s '%s' while parsing 'http-response %s' rule : %s.\n",
file, linenum, proxy_type_str(proxy), proxy->id, args[0], errmsg); file, linenum, proxy_type_str(proxy), proxy->id, args[0], errmsg);
free(errmsg); free(errmsg);
@ -12283,9 +12283,10 @@ enum act_return http_action_set_req_line(struct act_rule *rule, struct proxy *px
* All of them accept a single argument of type string representing a log-format. * 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 * 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). * head, and p[2] to store the action as an int (0=method, 1=path, 2=query, 3=uri).
* It returns 0 on success, < 0 on error. * It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
*/ */
int parse_set_req_line(const char **args, int *orig_arg, struct proxy *px, struct act_rule *rule, char **err) enum act_parse_ret parse_set_req_line(const char **args, int *orig_arg, struct proxy *px,
struct act_rule *rule, char **err)
{ {
int cur_arg = *orig_arg; int cur_arg = *orig_arg;
@ -12310,13 +12311,13 @@ int parse_set_req_line(const char **args, int *orig_arg, struct proxy *px, struc
break; break;
default: default:
memprintf(err, "internal error: unhandled action '%s'", args[0]); memprintf(err, "internal error: unhandled action '%s'", args[0]);
return -1; return ACT_RET_PRS_ERR;
} }
if (!*args[cur_arg] || if (!*args[cur_arg] ||
(*args[cur_arg + 1] && strcmp(args[cur_arg + 1], "if") != 0 && strcmp(args[cur_arg + 1], "unless") != 0)) { (*args[cur_arg + 1] && strcmp(args[cur_arg + 1], "if") != 0 && strcmp(args[cur_arg + 1], "unless") != 0)) {
memprintf(err, "expects exactly 1 argument <format>"); memprintf(err, "expects exactly 1 argument <format>");
return -1; return ACT_RET_PRS_ERR;
} }
LIST_INIT(&rule->arg.http.logfmt); LIST_INIT(&rule->arg.http.logfmt);
@ -12326,7 +12327,7 @@ int parse_set_req_line(const char **args, int *orig_arg, struct proxy *px, struc
proxy->conf.args.file, proxy->conf.args.line); proxy->conf.args.file, proxy->conf.args.line);
(*orig_arg)++; (*orig_arg)++;
return 0; return ACT_RET_PRS_OK;
} }
/* This function executes the "capture" action. It executes a fetch expression, /* This function executes the "capture" action. It executes a fetch expression,
@ -12405,9 +12406,10 @@ enum act_return http_action_req_capture_by_id(struct act_rule *rule, struct prox
/* parse an "http-request capture" action. It takes a single argument which is /* 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 * 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]. * the allocated hdr_cap struct or the preallocated "id" into arg->act.p[1].
* It returns 0 on success, < 0 on error. * It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
*/ */
int parse_http_req_capture(const char **args, int *orig_arg, struct proxy *px, struct act_rule *rule, char **err) enum act_parse_ret parse_http_req_capture(const char **args, int *orig_arg, struct proxy *px,
struct act_rule *rule, char **err)
{ {
struct sample_expr *expr; struct sample_expr *expr;
struct cap_hdr *hdr; struct cap_hdr *hdr;
@ -12421,26 +12423,26 @@ int parse_http_req_capture(const char **args, int *orig_arg, struct proxy *px, s
if (cur_arg < *orig_arg + 3) { if (cur_arg < *orig_arg + 3) {
memprintf(err, "expects <expression> [ 'len' <length> | id <idx> ]"); memprintf(err, "expects <expression> [ 'len' <length> | id <idx> ]");
return -1; return ACT_RET_PRS_ERR;
} }
cur_arg = *orig_arg; cur_arg = *orig_arg;
expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, err, &px->conf.args); expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, err, &px->conf.args);
if (!expr) if (!expr)
return -1; return ACT_RET_PRS_ERR;
if (!(expr->fetch->val & SMP_VAL_FE_HRQ_HDR)) { if (!(expr->fetch->val & SMP_VAL_FE_HRQ_HDR)) {
memprintf(err, memprintf(err,
"fetch method '%s' extracts information from '%s', none of which is available here", "fetch method '%s' extracts information from '%s', none of which is available here",
args[cur_arg-1], sample_src_names(expr->fetch->use)); args[cur_arg-1], sample_src_names(expr->fetch->use));
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
if (!args[cur_arg] || !*args[cur_arg]) { if (!args[cur_arg] || !*args[cur_arg]) {
memprintf(err, "expects 'len or 'id'"); memprintf(err, "expects 'len or 'id'");
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
if (strcmp(args[cur_arg], "len") == 0) { if (strcmp(args[cur_arg], "len") == 0) {
@ -12448,7 +12450,7 @@ int parse_http_req_capture(const char **args, int *orig_arg, struct proxy *px, s
if (!(px->cap & PR_CAP_FE)) { if (!(px->cap & PR_CAP_FE)) {
memprintf(err, "proxy '%s' has no frontend capability", px->id); memprintf(err, "proxy '%s' has no frontend capability", px->id);
return -1; return ACT_RET_PRS_ERR;
} }
proxy->conf.args.ctx = ARGC_CAP; proxy->conf.args.ctx = ARGC_CAP;
@ -12456,21 +12458,21 @@ int parse_http_req_capture(const char **args, int *orig_arg, struct proxy *px, s
if (!args[cur_arg]) { if (!args[cur_arg]) {
memprintf(err, "missing length value"); memprintf(err, "missing length value");
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
/* we copy the table name for now, it will be resolved later */ /* we copy the table name for now, it will be resolved later */
len = atoi(args[cur_arg]); len = atoi(args[cur_arg]);
if (len <= 0) { if (len <= 0) {
memprintf(err, "length must be > 0"); memprintf(err, "length must be > 0");
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
cur_arg++; cur_arg++;
if (!len) { if (!len) {
memprintf(err, "a positive 'len' argument is mandatory"); memprintf(err, "a positive 'len' argument is mandatory");
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
hdr = calloc(sizeof(struct cap_hdr), 1); hdr = calloc(sizeof(struct cap_hdr), 1);
@ -12499,14 +12501,14 @@ int parse_http_req_capture(const char **args, int *orig_arg, struct proxy *px, s
if (!args[cur_arg]) { if (!args[cur_arg]) {
memprintf(err, "missing id value"); memprintf(err, "missing id value");
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
id = strtol(args[cur_arg], &error, 10); id = strtol(args[cur_arg], &error, 10);
if (*error != '\0') { if (*error != '\0') {
memprintf(err, "cannot parse id '%s'", args[cur_arg]); memprintf(err, "cannot parse id '%s'", args[cur_arg]);
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
cur_arg++; cur_arg++;
@ -12521,11 +12523,11 @@ int parse_http_req_capture(const char **args, int *orig_arg, struct proxy *px, s
else { else {
memprintf(err, "expects 'len' or 'id', found '%s'", args[cur_arg]); memprintf(err, "expects 'len' or 'id', found '%s'", args[cur_arg]);
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
*orig_arg = cur_arg; *orig_arg = cur_arg;
return 0; return ACT_RET_PRS_OK;
} }
/* This function executes the "capture" action and store the result in a /* This function executes the "capture" action and store the result in a
@ -12572,9 +12574,10 @@ enum act_return http_action_res_capture_by_id(struct act_rule *rule, struct prox
/* parse an "http-response capture" action. It takes a single argument which is /* parse an "http-response capture" action. It takes a single argument which is
* a sample fetch expression. It stores the expression into arg->act.p[0] and * a sample fetch expression. It stores the expression into arg->act.p[0] and
* the allocated hdr_cap struct od the preallocated id into arg->act.p[1]. * the allocated hdr_cap struct od the preallocated id into arg->act.p[1].
* It returns 0 on success, < 0 on error. * It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
*/ */
int parse_http_res_capture(const char **args, int *orig_arg, struct proxy *px, struct act_rule *rule, char **err) enum act_parse_ret parse_http_res_capture(const char **args, int *orig_arg, struct proxy *px,
struct act_rule *rule, char **err)
{ {
struct sample_expr *expr; struct sample_expr *expr;
int cur_arg; int cur_arg;
@ -12588,32 +12591,32 @@ int parse_http_res_capture(const char **args, int *orig_arg, struct proxy *px, s
if (cur_arg < *orig_arg + 3) { if (cur_arg < *orig_arg + 3) {
memprintf(err, "expects <expression> [ 'len' <length> | id <idx> ]"); memprintf(err, "expects <expression> [ 'len' <length> | id <idx> ]");
return -1; return ACT_RET_PRS_ERR;
} }
cur_arg = *orig_arg; cur_arg = *orig_arg;
expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, err, &px->conf.args); expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, err, &px->conf.args);
if (!expr) if (!expr)
return -1; return ACT_RET_PRS_ERR;
if (!(expr->fetch->val & SMP_VAL_FE_HRS_HDR)) { if (!(expr->fetch->val & SMP_VAL_FE_HRS_HDR)) {
memprintf(err, memprintf(err,
"fetch method '%s' extracts information from '%s', none of which is available here", "fetch method '%s' extracts information from '%s', none of which is available here",
args[cur_arg-1], sample_src_names(expr->fetch->use)); args[cur_arg-1], sample_src_names(expr->fetch->use));
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
if (!args[cur_arg] || !*args[cur_arg]) { if (!args[cur_arg] || !*args[cur_arg]) {
memprintf(err, "expects 'len or 'id'"); memprintf(err, "expects 'len or 'id'");
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
if (strcmp(args[cur_arg], "id") != 0) { if (strcmp(args[cur_arg], "id") != 0) {
memprintf(err, "expects 'id', found '%s'", args[cur_arg]); memprintf(err, "expects 'id', found '%s'", args[cur_arg]);
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
cur_arg++; cur_arg++;
@ -12621,14 +12624,14 @@ int parse_http_res_capture(const char **args, int *orig_arg, struct proxy *px, s
if (!args[cur_arg]) { if (!args[cur_arg]) {
memprintf(err, "missing id value"); memprintf(err, "missing id value");
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
id = strtol(args[cur_arg], &error, 10); id = strtol(args[cur_arg], &error, 10);
if (*error != '\0') { if (*error != '\0') {
memprintf(err, "cannot parse id '%s'", args[cur_arg]); memprintf(err, "cannot parse id '%s'", args[cur_arg]);
free(expr); free(expr);
return -1; return ACT_RET_PRS_ERR;
} }
cur_arg++; cur_arg++;
@ -12640,7 +12643,7 @@ int parse_http_res_capture(const char **args, int *orig_arg, struct proxy *px, s
rule->arg.capid.idx = id; rule->arg.capid.idx = id;
*orig_arg = cur_arg; *orig_arg = cur_arg;
return 0; return ACT_RET_PRS_OK;
} }
/* /*

View File

@ -1465,7 +1465,7 @@ static int tcp_parse_response_rule(char **args, int arg, int section_type,
if (kw) { if (kw) {
arg++; arg++;
rule->from = ACT_F_TCP_RES_CNT; rule->from = ACT_F_TCP_RES_CNT;
if (!kw->parse((const char **)args, &arg, curpx, rule, err)) if (kw->parse((const char **)args, &arg, curpx, rule, err) == ACT_RET_PRS_ERR)
return -1; return -1;
} else { } else {
memprintf(err, memprintf(err,
@ -1673,7 +1673,7 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type,
} }
if (kw) { if (kw) {
arg++; arg++;
if (!kw->parse((const char **)args, &arg, curpx, rule, err)) if (kw->parse((const char **)args, &arg, curpx, rule, err) == ACT_RET_PRS_ERR)
return -1; return -1;
} else { } else {
memprintf(err, memprintf(err,

View File

@ -602,59 +602,59 @@ static int parse_vars(const char **args, int *arg, struct proxy *px,
} }
/* Wrapper for parse_vars */ /* Wrapper for parse_vars */
static int parse_tcp_req_store(const char **args, int *arg, struct proxy *px, static enum act_parse_ret parse_tcp_req_store(const char **args, int *arg, struct proxy *px,
struct act_rule *rule, char **err) struct act_rule *rule, char **err)
{ {
if (!parse_vars(args, arg, px, SMP_VAL_FE_REQ_CNT, err, if (!parse_vars(args, arg, px, SMP_VAL_FE_REQ_CNT, err,
&rule->arg.vars.expr, &rule->arg.vars.expr,
&rule->arg.vars.name, &rule->arg.vars.name,
&rule->arg.vars.scope)) &rule->arg.vars.scope))
return 0; return ACT_RET_PRS_ERR;
rule->action = ACT_ACTION_CONT; rule->action = ACT_ACTION_CONT;
rule->action_ptr = action_tcp_req_store; rule->action_ptr = action_tcp_req_store;
return 1; return ACT_RET_PRS_OK;
} }
/* Wrapper for parse_vars */ /* Wrapper for parse_vars */
static int parse_tcp_res_store(const char **args, int *arg, struct proxy *px, static enum act_parse_ret parse_tcp_res_store(const char **args, int *arg, struct proxy *px,
struct act_rule *rule, char **err) struct act_rule *rule, char **err)
{ {
if (!parse_vars(args, arg, px, SMP_VAL_BE_RES_CNT, err, if (!parse_vars(args, arg, px, SMP_VAL_BE_RES_CNT, err,
&rule->arg.vars.expr, &rule->arg.vars.expr,
&rule->arg.vars.name, &rule->arg.vars.name,
&rule->arg.vars.scope)) &rule->arg.vars.scope))
return 0; return ACT_RET_PRS_ERR;
rule->action = ACT_ACTION_CONT; rule->action = ACT_ACTION_CONT;
rule->action_ptr = action_tcp_res_store; rule->action_ptr = action_tcp_res_store;
return 1; return ACT_RET_PRS_OK;
} }
/* Wrapper for parse_vars */ /* Wrapper for parse_vars */
static int parse_http_req_store(const char **args, int *arg, struct proxy *px, static enum act_parse_ret parse_http_req_store(const char **args, int *arg, struct proxy *px,
struct act_rule *rule, char **err) struct act_rule *rule, char **err)
{ {
if (!parse_vars(args, arg, px, SMP_VAL_FE_HRQ_HDR, err, if (!parse_vars(args, arg, px, SMP_VAL_FE_HRQ_HDR, err,
&rule->arg.vars.expr, &rule->arg.vars.expr,
&rule->arg.vars.name, &rule->arg.vars.name,
&rule->arg.vars.scope)) &rule->arg.vars.scope))
return -1; return ACT_RET_PRS_ERR;
rule->action = ACT_ACTION_CONT; rule->action = ACT_ACTION_CONT;
rule->action_ptr = action_http_req_store; rule->action_ptr = action_http_req_store;
return 0; return ACT_RET_PRS_OK;
} }
/* Wrapper for parse_vars */ /* Wrapper for parse_vars */
static int parse_http_res_store(const char **args, int *arg, struct proxy *px, static enum act_parse_ret parse_http_res_store(const char **args, int *arg, struct proxy *px,
struct act_rule *rule, char **err) struct act_rule *rule, char **err)
{ {
if (!parse_vars(args, arg, px, SMP_VAL_BE_HRS_HDR, err, if (!parse_vars(args, arg, px, SMP_VAL_BE_HRS_HDR, err,
&rule->arg.vars.expr, &rule->arg.vars.expr,
&rule->arg.vars.name, &rule->arg.vars.name,
&rule->arg.vars.scope)) &rule->arg.vars.scope))
return -1; return ACT_RET_PRS_ERR;
rule->action = ACT_ACTION_CONT; rule->action = ACT_ACTION_CONT;
rule->action_ptr = action_http_res_store; rule->action_ptr = action_http_res_store;
return 0; return ACT_RET_PRS_OK;
} }
static int vars_max_size(char **args, int section_type, struct proxy *curpx, static int vars_max_size(char **args, int section_type, struct proxy *curpx,