diff --git a/include/proto/dumpstats.h b/include/proto/dumpstats.h index 4c3837b42..319ab48ec 100644 --- a/include/proto/dumpstats.h +++ b/include/proto/dumpstats.h @@ -55,15 +55,6 @@ #define STAT_CLI_O_TAB 8 /* dump tables */ #define STAT_CLI_O_CLR 9 /* clear tables */ -/* status codes (strictly 4 chars) used in the URL to display a message */ -#define STAT_STATUS_UNKN "UNKN" /* an unknown error occured, shouldn't happen */ -#define STAT_STATUS_DONE "DONE" /* the action is successful */ -#define STAT_STATUS_PART "PART" /* the action is partially successful */ -#define STAT_STATUS_NONE "NONE" /* nothing happened (no action chosen or servers state didn't change) */ -#define STAT_STATUS_ERRP "ERRP" /* an error occured due to invalid values in parameters */ -#define STAT_STATUS_EXCD "EXCD" /* an error occured because the buffer couldn't store all data */ -#define STAT_STATUS_DENY "DENY" /* action denied */ - extern struct si_applet http_stats_applet; void stats_io_handler(struct stream_interface *si); diff --git a/include/types/proto_http.h b/include/types/proto_http.h index a7b16aa25..51f321ece 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -258,6 +258,19 @@ enum { ST_ADM_ACTION_ENABLE, }; +/* status codes available for the stats admin page */ +enum { + STAT_STATUS_INIT = 0, + STAT_STATUS_DENY, /* action denied */ + STAT_STATUS_DONE, /* the action is successful */ + STAT_STATUS_ERRP, /* an error occured due to invalid values in parameters */ + STAT_STATUS_EXCD, /* an error occured because the buffer couldn't store all data */ + STAT_STATUS_NONE, /* nothing happened (no action chosen or servers state didn't change) */ + STAT_STATUS_PART, /* the action is partially successful */ + STAT_STATUS_UNKN, /* an unknown error occured, shouldn't happen */ + STAT_STATUS_SIZE +}; + /* This is an HTTP message, as described in RFC2616. It can be either a request * message or a response message. * diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index 5acbd5743..711394ada 100644 --- a/include/types/stream_interface.h +++ b/include/types/stream_interface.h @@ -149,7 +149,7 @@ struct stream_interface { int px_st; /* STAT_PX_ST* */ unsigned int flags; /* STAT_* */ int iid, type, sid; /* proxy id, type and service id if bounding of stats is enabled */ - const char *st_code; /* pointer to the status code returned by an action */ + int st_code; /* the status code returned by an action */ } stats; struct { struct bref bref; /* back-reference from the session being dumped */ diff --git a/src/dumpstats.c b/src/dumpstats.c index 3f88fc507..dc3ac752b 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -114,6 +114,8 @@ enum { STAT_PX_ST_FIN, }; +extern const char *stat_status_codes[]; + /* This function is called from the session-level accept() in order to instanciate * a new stats socket. It returns a positive value upon success, 0 if the connection * needs to be closed and ignored, or a negative value upon critical failure. @@ -1686,7 +1688,12 @@ static int stats_http_redir(struct stream_interface *si, struct uri_auth *uri) "Content-Type: text/plain\r\n" "Connection: close\r\n" "Location: %s;st=%s", - uri->uri_prefix, si->applet.ctx.stats.st_code); + uri->uri_prefix, + ((si->applet.ctx.stats.st_code > STAT_STATUS_INIT) && + (si->applet.ctx.stats.st_code < STAT_STATUS_SIZE) && + stat_status_codes[si->applet.ctx.stats.st_code]) ? + stat_status_codes[si->applet.ctx.stats.st_code] : + stat_status_codes[STAT_STATUS_UNKN]); chunk_printf(&msg, "\r\n\r\n"); if (buffer_feed_chunk(si->ib, &msg) >= 0) @@ -2023,29 +2030,30 @@ static int stats_dump_http(struct stream_interface *si, struct uri_auth *uri) ); if (si->applet.ctx.stats.st_code) { - if (strcmp(si->applet.ctx.stats.st_code, STAT_STATUS_DONE) == 0) { + switch (si->applet.ctx.stats.st_code) { + case STAT_STATUS_DONE: chunk_printf(&msg, "

" "[X] " "Action processed successfully." "
\n", uri->uri_prefix); - } - else if (strcmp(si->applet.ctx.stats.st_code, STAT_STATUS_NONE) == 0) { + break; + case STAT_STATUS_NONE: chunk_printf(&msg, "

" "[X] " "Nothing has changed." "
\n", uri->uri_prefix); - } - else if (strcmp(si->applet.ctx.stats.st_code, STAT_STATUS_PART) == 0) { + break; + case STAT_STATUS_PART: chunk_printf(&msg, "

" "[X] " "Action partially processed.
" "Some server names are probably unknown or ambiguous (duplicated names in the backend)." "
\n", uri->uri_prefix); - } - else if (strcmp(si->applet.ctx.stats.st_code, STAT_STATUS_ERRP) == 0) { + break; + case STAT_STATUS_ERRP: chunk_printf(&msg, "

" "[X] " @@ -2056,23 +2064,23 @@ static int stats_dump_http(struct stream_interface *si, struct uri_auth *uri) "
  • Some server names are probably unknown or ambiguous (duplicated names in the backend).
  • " "" "
    \n", uri->uri_prefix); - } - else if (strcmp(si->applet.ctx.stats.st_code, STAT_STATUS_EXCD) == 0) { + break; + case STAT_STATUS_EXCD: chunk_printf(&msg, "

    " "[X] " "Action not processed : the buffer couldn't store all the data.
    " "You should retry with less servers at a time.
    " "
    \n", uri->uri_prefix); - } - else if (strcmp(si->applet.ctx.stats.st_code, STAT_STATUS_DENY) == 0) { + break; + case STAT_STATUS_DENY: chunk_printf(&msg, "

    " "[X] " "Action denied." "
    \n", uri->uri_prefix); - } - else { + break; + default: chunk_printf(&msg, "

    " "[X] " diff --git a/src/proto_http.c b/src/proto_http.c index bf91328fe..3f6ec0484 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -188,6 +188,18 @@ static const char *http_err_msgs[HTTP_ERR_SIZE] = { }; +/* status codes available for the stats admin page (strictly 4 chars length) */ +const char *stat_status_codes[STAT_STATUS_SIZE] = { + [STAT_STATUS_DENY] = "DENY", + [STAT_STATUS_DONE] = "DONE", + [STAT_STATUS_ERRP] = "ERRP", + [STAT_STATUS_EXCD] = "EXCD", + [STAT_STATUS_NONE] = "NONE", + [STAT_STATUS_PART] = "PART", + [STAT_STATUS_UNKN] = "UNKN", +}; + + /* We must put the messages here since GCC cannot initialize consts depending * on strlen(). */ @@ -7132,6 +7144,7 @@ int stats_check_uri(struct stream_interface *si, struct http_txn *txn, struct pr return 0; memset(&si->applet.ctx.stats, 0, sizeof(si->applet.ctx.stats)); + si->applet.ctx.stats.st_code = STAT_STATUS_INIT; /* check URI size */ if (uri_auth->uri_len > txn->req.sl.rq.u_l) @@ -7175,22 +7188,15 @@ int stats_check_uri(struct stream_interface *si, struct http_txn *txn, struct pr h = txn->req.sol + txn->req.sl.rq.u + uri_auth->uri_len; while (h <= txn->req.sol + txn->req.sl.rq.u + txn->req.sl.rq.u_l - 8) { if (memcmp(h, ";st=", 4) == 0) { + int i; h += 4; - - if (memcmp(h, STAT_STATUS_DONE, 4) == 0) - si->applet.ctx.stats.st_code = STAT_STATUS_DONE; - else if (memcmp(h, STAT_STATUS_NONE, 4) == 0) - si->applet.ctx.stats.st_code = STAT_STATUS_NONE; - else if (memcmp(h, STAT_STATUS_PART, 4) == 0) - si->applet.ctx.stats.st_code = STAT_STATUS_PART; - else if (memcmp(h, STAT_STATUS_ERRP, 4) == 0) - si->applet.ctx.stats.st_code = STAT_STATUS_ERRP; - else if (memcmp(h, STAT_STATUS_EXCD, 4) == 0) - si->applet.ctx.stats.st_code = STAT_STATUS_EXCD; - else if (memcmp(h, STAT_STATUS_DENY, 4) == 0) - si->applet.ctx.stats.st_code = STAT_STATUS_DENY; - else - si->applet.ctx.stats.st_code = STAT_STATUS_UNKN; + for (i = STAT_STATUS_INIT + 1; i < STAT_STATUS_SIZE; i++) { + if (strncmp(stat_status_codes[i], h, 4) == 0) { + si->applet.ctx.stats.st_code = i; + break; + } + } + si->applet.ctx.stats.st_code = STAT_STATUS_UNKN; break; } h++;