*/
static void stats_dump_html_px_hdr(struct stream_interface *si, struct proxy *px, struct uri_auth *uri)
{
+ char scope_txt[STAT_SCOPE_TXT_MAXLEN + sizeof STAT_SCOPE_PATTERN];
+
if (px->cap & PR_CAP_BE && px->srv && (si->applet.ctx.stats.flags & STAT_ADMIN)) {
/* A form to enable/disable this proxy servers */
+
+ /* scope_txt = search pattern + search query, si->applet.ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */
+ scope_txt[0] = 0;
+ if (si->applet.ctx.stats.scope_len) {
+ strcpy(scope_txt, STAT_SCOPE_PATTERN);
+ memcpy(scope_txt + strlen(STAT_SCOPE_PATTERN), bo_ptr(si->ob->buf) + si->applet.ctx.stats.scope_str, si->applet.ctx.stats.scope_len);
+ scope_txt[strlen(STAT_SCOPE_PATTERN) + si->applet.ctx.stats.scope_len] = 0;
+ }
+
chunk_appendf(&trash,
- "<form action=\"%s\" method=\"post\">",
- uri->uri_prefix);
+ "<form action=\"%s%s%s%s\" method=\"post\">",
+ uri->uri_prefix,
+ (si->applet.ctx.stats.flags & STAT_HIDE_DOWN) ? ";up" : "",
+ (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "",
+ scope_txt);
}
/* print a new table */
if ((px->cap & PR_CAP_BE) && px->srv && (si->applet.ctx.stats.flags & STAT_ADMIN)) {
/* close the form used to enable/disable this proxy servers */
chunk_appendf(&trash,
- "Choose the action to perform on the checked servers : "
- "<select name=action>"
- "<option value=\"\"></option>"
- "<option value=\"disable\">Disable</option>"
- "<option value=\"enable\">Enable</option>"
- "<option value=\"stop\">Soft Stop</option>"
- "<option value=\"start\">Soft Start</option>"
- "<option value=\"shutdown\">Kill Sessions</option>"
- "</select>"
- "<input type=\"hidden\" name=\"b\" value=\"#%d\">"
- " <input type=\"submit\" value=\"Apply\">"
- "</form>",
- px->uuid);
+ "Choose the action to perform on the checked servers : "
+ "<select name=action>"
+ "<option value=\"\"></option>"
+ "<option value=\"disable\">Disable</option>"
+ "<option value=\"enable\">Enable</option>"
+ "<option value=\"stop\">Soft Stop</option>"
+ "<option value=\"start\">Soft Start</option>"
+ "<option value=\"shutdown\">Kill Sessions</option>"
+ "</select>"
+ "<input type=\"hidden\" name=\"b\" value=\"#%d\">"
+ " <input type=\"submit\" value=\"Apply\">"
+ "</form>",
+ px->uuid);
}
chunk_appendf(&trash, "<p>\n");
return 1;
}
+ /* if the user has requested a limited output and the proxy
+ * name does not match, skip it.
+ */
+ if (si->applet.ctx.stats.scope_len &&
+ strnistr(px->id, strlen(px->id), bo_ptr(si->ob->buf) + si->applet.ctx.stats.scope_str, si->applet.ctx.stats.scope_len) == NULL)
+ return 1;
+
if ((si->applet.ctx.stats.flags & STAT_BOUND) &&
(si->applet.ctx.stats.iid != -1) &&
(px->uuid != si->applet.ctx.stats.iid))
static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *uri)
{
unsigned int up = (now.tv_sec - start_date.tv_sec);
+ char scope_txt[STAT_SCOPE_TXT_MAXLEN + sizeof STAT_SCOPE_PATTERN];
/* WARNING! this has to fit the first packet too.
* We are around 3.5 kB, add adding entries will
run_queue_cur, nb_tasks_cur, idle_pct
);
+ /* scope_txt = search query, si->applet.ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */
+ memcpy(scope_txt, bo_ptr(si->ob->buf) + si->applet.ctx.stats.scope_str, si->applet.ctx.stats.scope_len);
+ scope_txt[si->applet.ctx.stats.scope_len] = '\0';
+
+ chunk_appendf(&trash,
+ "<li><form method=GET ACTION='%s%s%s'>Scope : <input value='%s' name='" STAT_SCOPE_INPUT_NAME "' autofocus size=8 maxlength='%d'/></form>\n",
+ uri->uri_prefix,
+ (si->applet.ctx.stats.flags & STAT_HIDE_DOWN) ? ";up" : "",
+ (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "",
+ (si->applet.ctx.stats.scope_len > 0) ? scope_txt : "",
+ STAT_SCOPE_TXT_MAXLEN);
+
+ /* scope_txt = search pattern + search query, si->applet.ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */
+ scope_txt[0] = 0;
+ if (si->applet.ctx.stats.scope_len) {
+ strcpy(scope_txt, STAT_SCOPE_PATTERN);
+ memcpy(scope_txt + strlen(STAT_SCOPE_PATTERN), bo_ptr(si->ob->buf) + si->applet.ctx.stats.scope_str, si->applet.ctx.stats.scope_len);
+ scope_txt[strlen(STAT_SCOPE_PATTERN) + si->applet.ctx.stats.scope_len] = 0;
+ }
+
if (si->applet.ctx.stats.flags & STAT_HIDE_DOWN)
chunk_appendf(&trash,
- "<li><a href=\"%s%s%s\">Show all servers</a><br>\n",
+ "<li><a href=\"%s%s%s%s\">Show all servers</a><br>\n",
uri->uri_prefix,
"",
- (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "");
+ (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "",
+ scope_txt);
else
chunk_appendf(&trash,
- "<li><a href=\"%s%s%s\">Hide 'DOWN' servers</a><br>\n",
+ "<li><a href=\"%s%s%s%s\">Hide 'DOWN' servers</a><br>\n",
uri->uri_prefix,
";up",
- (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "");
+ (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "",
+ scope_txt);
if (uri->refresh > 0) {
if (si->applet.ctx.stats.flags & STAT_NO_REFRESH)
chunk_appendf(&trash,
- "<li><a href=\"%s%s%s\">Enable refresh</a><br>\n",
+ "<li><a href=\"%s%s%s%s\">Enable refresh</a><br>\n",
uri->uri_prefix,
(si->applet.ctx.stats.flags & STAT_HIDE_DOWN) ? ";up" : "",
- "");
+ "",
+ scope_txt);
else
chunk_appendf(&trash,
- "<li><a href=\"%s%s%s\">Disable refresh</a><br>\n",
+ "<li><a href=\"%s%s%s%s\">Disable refresh</a><br>\n",
uri->uri_prefix,
(si->applet.ctx.stats.flags & STAT_HIDE_DOWN) ? ";up" : "",
- ";norefresh");
+ ";norefresh",
+ scope_txt);
}
chunk_appendf(&trash,
- "<li><a href=\"%s%s%s\">Refresh now</a><br>\n",
+ "<li><a href=\"%s%s%s%s\">Refresh now</a><br>\n",
uri->uri_prefix,
(si->applet.ctx.stats.flags & STAT_HIDE_DOWN) ? ";up" : "",
- (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "");
+ (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "",
+ scope_txt);
chunk_appendf(&trash,
- "<li><a href=\"%s;csv%s\">CSV export</a><br>\n",
+ "<li><a href=\"%s;csv%s%s\">CSV export</a><br>\n",
uri->uri_prefix,
- (uri->refresh > 0) ? ";norefresh" : "");
+ (uri->refresh > 0) ? ";norefresh" : "",
+ scope_txt);
chunk_appendf(&trash,
"</ul></td>"
/* Was the status page requested with a POST ? */
if (unlikely(txn->meth == HTTP_METH_POST)) {
+ char scope_txt[STAT_SCOPE_TXT_MAXLEN + sizeof STAT_SCOPE_PATTERN];
+
if (si->applet.ctx.stats.flags & STAT_ADMIN) {
if (msg->msg_state < HTTP_MSG_100_SENT) {
/* If we have HTTP/1.1 and Expect: 100-continue, then we must
}
else
si->applet.ctx.stats.st_code = STAT_STATUS_DENY;
+ /* scope_txt = search pattern + search query, si->applet.ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */
+ scope_txt[0] = 0;
+ if (si->applet.ctx.stats.scope_len) {
+ strcpy(scope_txt, STAT_SCOPE_PATTERN);
+ memcpy(scope_txt + strlen(STAT_SCOPE_PATTERN), bo_ptr(req->buf) + si->applet.ctx.stats.scope_str, si->applet.ctx.stats.scope_len);
+ scope_txt[strlen(STAT_SCOPE_PATTERN) + si->applet.ctx.stats.scope_len] = 0;
+ }
+
/* We don't want to land on the posted stats page because a refresh will
* repost the data. We don't want this to happen on accident so we redirect
"Cache-Control: no-cache\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n"
- "Location: %s;st=%s\r\n"
+ "Location: %s;st=%s%s%s%s\r\n"
"\r\n",
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]);
+ stat_status_codes[STAT_STATUS_UNKN],
+ (si->applet.ctx.stats.flags & STAT_HIDE_DOWN) ? ";up" : "",
+ (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "",
+ scope_txt);
s->txn.status = 303;
s->logs.tv_request = now;
}
h++;
}
+
+ si->applet.ctx.stats.scope_str = 0;
+ si->applet.ctx.stats.scope_len = 0;
+ h = uri + uri_auth->uri_len;
+ while (h <= uri + msg->sl.rq.u_l - 8) {
+ if (memcmp(h, STAT_SCOPE_INPUT_NAME "=", strlen(STAT_SCOPE_INPUT_NAME) + 1) == 0) {
+ int itx = 0;
+ const char *h2;
+ char scope_txt[STAT_SCOPE_TXT_MAXLEN + 1];
+ const char *err;
+
+ h += strlen(STAT_SCOPE_INPUT_NAME) + 1;
+ h2 = h;
+ si->applet.ctx.stats.scope_str = h2 - msg->chn->buf->p;
+ while (*h != ';' && *h != '\0' && *h != '&' && *h != ' ' && *h != '\n') {
+ itx++;
+ h++;
+ }
+
+ if (itx > STAT_SCOPE_TXT_MAXLEN)
+ itx = STAT_SCOPE_TXT_MAXLEN;
+ si->applet.ctx.stats.scope_len = itx;
+
+ /* scope_txt = search query, si->applet.ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */
+ memcpy(scope_txt, h2, itx);
+ scope_txt[itx] = '\0';
+ err = invalid_char(scope_txt);
+ if (err) {
+ /* bad char in search text => clear scope */
+ si->applet.ctx.stats.scope_str = 0;
+ si->applet.ctx.stats.scope_len = 0;
+ }
+ break;
+ }
+ h++;
+ }
+
+
return 1;
}