"Nothing has changed."
"</div>\n", uri->uri_prefix);
}
+ else if (strcmp(si->applet.ctx.stats.st_code, STAT_STATUS_PART) == 0) {
+ chunk_printf(&msg,
+ "<p><div class=active2>"
+ "<a class=lfsb href=\"%s\" title=\"Remove this message\">[X]</a> "
+ "Action partially processed.<br>"
+ "Some server names are probably unknown or ambiguous (duplicated names in the backend)."
+ "</div>\n", uri->uri_prefix);
+ }
+ else if (strcmp(si->applet.ctx.stats.st_code, STAT_STATUS_ERRP) == 0) {
+ chunk_printf(&msg,
+ "<p><div class=active0>"
+ "<a class=lfsb href=\"%s\" title=\"Remove this message\">[X]</a> "
+ "Action not processed because of invalid parameters."
+ "<ul>"
+ "<li>The action is maybe unknown.</li>"
+ "<li>The backend name is probably unknown or ambiguous (duplicated names).</li>"
+ "<li>Some server names are probably unknown or ambiguous (duplicated names in the backend).</li>"
+ "</ul>"
+ "</div>\n", uri->uri_prefix);
+ }
else if (strcmp(si->applet.ctx.stats.st_code, STAT_STATUS_EXCD) == 0) {
chunk_printf(&msg,
"<p><div class=active0>"
*/
int http_process_req_stat_post(struct stream_interface *si, struct http_txn *txn, struct buffer *req)
{
- struct proxy *px;
- struct server *sv;
+ struct proxy *px = NULL;
+ struct server *sv = NULL;
- char *backend = NULL;
- int action = 0;
+ char key[LINESIZE];
+ int action = ST_ADM_ACTION_NONE;
+ int reprocess = 0;
+
+ int total_servers = 0;
+ int altered_servers = 0;
char *first_param, *cur_param, *next_param, *end_params;
+ char *st_cur_param, *st_next_param;
first_param = req->data + txn->req.eoh + 2;
end_params = first_param + txn->req.body_len;
* From the html form, the backend and the action are at the end.
*/
while (cur_param > first_param) {
- char *key, *value;
+ char *value;
+ int poffset, plen;
cur_param--;
if ((*cur_param == '&') || (cur_param == first_param)) {
+ reprocess_servers:
/* Parse the key */
- key = cur_param;
- if (cur_param != first_param) {
- /* delimit the string for the next loop */
- *key++ = '\0';
+ poffset = (cur_param != first_param ? 1 : 0);
+ plen = next_param - cur_param + (cur_param == first_param ? 1 : 0);
+ if ((plen > 0) && (plen <= sizeof(key))) {
+ strncpy(key, cur_param + poffset, plen);
+ key[plen - 1] = '\0';
+ } else {
+ si->applet.ctx.stats.st_code = STAT_STATUS_EXCD;
+ goto out;
}
/* Parse the value */
break;
/* Now we can check the key to see what to do */
- if (!backend && strcmp(key, "b") == 0) {
- backend = value;
+ if (!px && (strcmp(key, "b") == 0)) {
+ if ((px = findproxy(value, PR_CAP_BE)) == NULL) {
+ /* the backend name is unknown or ambiguous (duplicate names) */
+ si->applet.ctx.stats.st_code = STAT_STATUS_ERRP;
+ goto out;
+ }
}
- else if (!action && strcmp(key, "action") == 0) {
+ else if (!action && (strcmp(key, "action") == 0)) {
if (strcmp(value, "disable") == 0) {
- action = 1;
+ action = ST_ADM_ACTION_DISABLE;
}
else if (strcmp(value, "enable") == 0) {
- action = 2;
- } else {
- /* unknown action, no need to continue */
- break;
+ action = ST_ADM_ACTION_ENABLE;
+ }
+ else {
+ si->applet.ctx.stats.st_code = STAT_STATUS_ERRP;
+ goto out;
}
}
else if (strcmp(key, "s") == 0) {
- if (backend && action && get_backend_server(backend, value, &px, &sv)) {
+ if (!(px && action)) {
+ /*
+ * Indicates that we'll need to reprocess the parameters
+ * as soon as backend and action are known
+ */
+ if (!reprocess) {
+ st_cur_param = cur_param;
+ st_next_param = next_param;
+ }
+ reprocess = 1;
+ }
+ else if ((sv = findserver(px, value)) != NULL) {
switch (action) {
- case 1:
+ case ST_ADM_ACTION_DISABLE:
if ((px->state != PR_STSTOPPED) && !(sv->state & SRV_MAINTAIN)) {
/* Not already in maintenance, we can change the server state */
sv->state |= SRV_MAINTAIN;
set_server_down(sv);
- si->applet.ctx.stats.st_code = STAT_STATUS_DONE;
+ altered_servers++;
+ total_servers++;
}
break;
- case 2:
+ case ST_ADM_ACTION_ENABLE:
if ((px->state != PR_STSTOPPED) && (sv->state & SRV_MAINTAIN)) {
/* Already in maintenance, we can change the server state */
set_server_up(sv);
sv->health = sv->rise; /* up, but will fall down at first failure */
- si->applet.ctx.stats.st_code = STAT_STATUS_DONE;
+ altered_servers++;
+ total_servers++;
}
break;
}
+ } else {
+ /* the server name is unknown or ambiguous (duplicate names) */
+ total_servers++;
}
}
+ if (reprocess && px && action) {
+ /* Now, we know the backend and the action chosen by the user.
+ * We can safely restart from the first server parameter
+ * to reprocess them
+ */
+ cur_param = st_cur_param;
+ next_param = st_next_param;
+ reprocess = 0;
+ goto reprocess_servers;
+ }
+
next_param = cur_param;
}
}
+
+ if (total_servers == 0) {
+ si->applet.ctx.stats.st_code = STAT_STATUS_NONE;
+ }
+ else if (altered_servers == 0) {
+ si->applet.ctx.stats.st_code = STAT_STATUS_ERRP;
+ }
+ else if (altered_servers == total_servers) {
+ si->applet.ctx.stats.st_code = STAT_STATUS_DONE;
+ }
+ else {
+ si->applet.ctx.stats.st_code = STAT_STATUS_PART;
+ }
+ out:
return 1;
}
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)