in modules/proxy/mod_proxy_balancer.c [1408:1868]
static void balancer_display_page(request_rec *r, proxy_server_conf *conf,
proxy_balancer *bsel,
proxy_worker *wsel,
int usexml)
{
const char *action;
proxy_balancer *balancer;
proxy_worker *worker;
proxy_worker **workers;
int i, n;
action = ap_construct_url(r->pool, r->uri, r);
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01204) "genning page");
if (usexml) {
char date[APR_RFC822_DATE_LEN];
ap_set_content_type_ex(r, "text/xml", 1);
ap_rputs("<?xml version='1.0' encoding='UTF-8' ?>\n", r);
ap_rputs("<httpd:manager xmlns:httpd='http://httpd.apache.org'>\n", r);
ap_rputs(" <httpd:balancers>\n", r);
balancer = (proxy_balancer *)conf->balancers->elts;
for (i = 0; i < conf->balancers->nelts; i++) {
ap_rputs(" <httpd:balancer>\n", r);
/* Start proxy_balancer */
ap_rvputs(r, " <httpd:name>", balancer->s->name, "</httpd:name>\n", NULL);
ap_rvputs(r, " <httpd:nonce>", balancer->s->nonce, "</httpd:nonce>\n", NULL);
if (*balancer->s->sticky) {
ap_rvputs(r, " <httpd:stickysession>", ap_escape_html(r->pool, balancer->s->sticky),
"</httpd:stickysession>\n", NULL);
ap_rprintf(r,
" <httpd:nofailover>%s</httpd:nofailover>\n",
(balancer->s->sticky_force ? "On" : "Off"));
}
ap_rprintf(r,
" <httpd:timeout>%" APR_TIME_T_FMT "</httpd:timeout>\n",
apr_time_sec(balancer->s->timeout));
if (balancer->s->max_attempts_set) {
ap_rprintf(r,
" <httpd:maxattempts>%d</httpd:maxattempts>\n",
balancer->s->max_attempts);
}
ap_rvputs(r, " <httpd:lbmethod>", balancer->lbmethod->name,
"</httpd:lbmethod>\n", NULL);
if (*balancer->s->sticky) {
ap_rprintf(r,
" <httpd:scolonpathdelim>%s</httpd:scolonpathdelim>\n",
(balancer->s->scolonsep ? "On" : "Off"));
}
/* End proxy_balancer */
ap_rputs(" <httpd:workers>\n", r);
workers = (proxy_worker **)balancer->workers->elts;
for (n = 0; n < balancer->workers->nelts; n++) {
worker = *workers;
/* Start proxy_worker */
ap_rputs(" <httpd:worker>\n", r);
ap_rvputs(r, " <httpd:name>", ap_proxy_worker_get_name(worker),
"</httpd:name>\n", NULL);
ap_rvputs(r, " <httpd:scheme>", worker->s->scheme,
"</httpd:scheme>\n", NULL);
ap_rvputs(r, " <httpd:hostname>", worker->s->hostname_ex,
"</httpd:hostname>\n", NULL);
ap_rprintf(r, " <httpd:loadfactor>%.2f</httpd:loadfactor>\n",
(float)(worker->s->lbfactor)/100.0);
ap_rprintf(r,
" <httpd:port>%d</httpd:port>\n",
worker->s->port);
ap_rprintf(r, " <httpd:min>%d</httpd:min>\n",
worker->s->min);
ap_rprintf(r, " <httpd:smax>%d</httpd:smax>\n",
worker->s->smax);
ap_rprintf(r, " <httpd:max>%d</httpd:max>\n",
worker->s->hmax);
ap_rprintf(r,
" <httpd:ttl>%" APR_TIME_T_FMT "</httpd:ttl>\n",
apr_time_sec(worker->s->ttl));
if (worker->s->timeout_set) {
ap_rprintf(r,
" <httpd:timeout>%" APR_TIME_T_FMT "</httpd:timeout>\n",
apr_time_sec(worker->s->timeout));
}
if (worker->s->acquire_set) {
ap_rprintf(r,
" <httpd:acquire>%" APR_TIME_T_FMT "</httpd:acquire>\n",
apr_time_msec(worker->s->acquire));
}
if (worker->s->recv_buffer_size_set) {
ap_rprintf(r,
" <httpd:recv_buffer_size>%" APR_SIZE_T_FMT "</httpd:recv_buffer_size>\n",
worker->s->recv_buffer_size);
}
if (worker->s->io_buffer_size_set) {
ap_rprintf(r,
" <httpd:io_buffer_size>%" APR_SIZE_T_FMT "</httpd:io_buffer_size>\n",
worker->s->io_buffer_size);
}
if (worker->s->keepalive_set) {
ap_rprintf(r,
" <httpd:keepalive>%s</httpd:keepalive>\n",
(worker->s->keepalive ? "On" : "Off"));
}
/* Begin proxy_worker_stat */
ap_rputs(" <httpd:status>", r);
ap_rputs(ap_proxy_parse_wstatus(r->pool, worker), r);
ap_rputs("</httpd:status>\n", r);
if ((worker->s->error_time > 0) && apr_rfc822_date(date, worker->s->error_time) == APR_SUCCESS) {
ap_rvputs(r, " <httpd:error_time>", date,
"</httpd:error_time>\n", NULL);
}
ap_rprintf(r,
" <httpd:retries>%d</httpd:retries>\n",
worker->s->retries);
ap_rprintf(r,
" <httpd:lbstatus>%d</httpd:lbstatus>\n",
worker->s->lbstatus);
ap_rprintf(r,
" <httpd:loadfactor>%.2f</httpd:loadfactor>\n",
(float)(worker->s->lbfactor)/100.0);
ap_rprintf(r,
" <httpd:transferred>%" APR_OFF_T_FMT "</httpd:transferred>\n",
worker->s->transferred);
ap_rprintf(r,
" <httpd:read>%" APR_OFF_T_FMT "</httpd:read>\n",
worker->s->read);
ap_rprintf(r,
" <httpd:elected>%" APR_SIZE_T_FMT "</httpd:elected>\n",
worker->s->elected);
ap_rvputs(r, " <httpd:route>",
ap_escape_html(r->pool, worker->s->route),
"</httpd:route>\n", NULL);
ap_rvputs(r, " <httpd:redirect>",
ap_escape_html(r->pool, worker->s->redirect),
"</httpd:redirect>\n", NULL);
ap_rprintf(r,
" <httpd:busy>%" APR_SIZE_T_FMT "</httpd:busy>\n",
ap_proxy_get_busy_count(worker));
ap_rprintf(r, " <httpd:lbset>%d</httpd:lbset>\n",
worker->s->lbset);
/* End proxy_worker_stat */
if (!ap_cstr_casecmp(worker->s->scheme, "ajp")) {
ap_rputs(" <httpd:flushpackets>", r);
switch (worker->s->flush_packets) {
case flush_off:
ap_rputs("Off", r);
break;
case flush_on:
ap_rputs("On", r);
break;
case flush_auto:
ap_rputs("Auto", r);
break;
}
ap_rputs("</httpd:flushpackets>\n", r);
if (worker->s->flush_packets == flush_auto) {
ap_rprintf(r,
" <httpd:flushwait>%d</httpd:flushwait>\n",
worker->s->flush_wait);
}
if (worker->s->ping_timeout_set) {
ap_rprintf(r,
" <httpd:ping>%" APR_TIME_T_FMT "</httpd:ping>",
apr_time_msec(worker->s->ping_timeout));
}
}
if (worker->s->disablereuse_set) {
ap_rprintf(r,
" <httpd:disablereuse>%s</httpd:disablereuse>\n",
(worker->s->disablereuse ? "On" : "Off"));
}
if (worker->s->conn_timeout_set) {
ap_rprintf(r,
" <httpd:connectiontimeout>%" APR_TIME_T_FMT "</httpd:connectiontimeout>\n",
apr_time_msec(worker->s->conn_timeout));
}
if (worker->s->retry_set) {
ap_rprintf(r,
" <httpd:retry>%" APR_TIME_T_FMT "</httpd:retry>\n",
apr_time_sec(worker->s->retry));
}
ap_rputs(" </httpd:worker>\n", r);
++workers;
}
ap_rputs(" </httpd:workers>\n", r);
ap_rputs(" </httpd:balancer>\n", r);
++balancer;
}
ap_rputs(" </httpd:balancers>\n", r);
ap_rputs("</httpd:manager>", r);
}
else {
ap_set_content_type_ex(r, "text/html; charset=ISO-8859-1", 1);
ap_rputs(DOCTYPE_HTML_4_01
"<html><head><title>Balancer Manager</title>\n", r);
ap_rputs("<style type='text/css'>\n"
"table {\n"
" border-width: 1px;\n"
" border-spacing: 3px;\n"
" border-style: solid;\n"
" border-color: gray;\n"
" border-collapse: collapse;\n"
" background-color: white;\n"
" text-align: center;\n"
"}\n"
"th {\n"
" border-width: 1px;\n"
" padding: 2px;\n"
" border-style: dotted;\n"
" border-color: gray;\n"
" background-color: lightgray;\n"
" text-align: center;\n"
"}\n"
"td {\n"
" border-width: 1px;\n"
" padding: 2px;\n"
" border-style: dotted;\n"
" border-color: gray;\n"
" background-color: white;\n"
" text-align: center;\n"
"}\n"
"</style>\n</head>\n", r);
ap_rputs("<body><h1>Load Balancer Manager for ", r);
ap_rvputs(r, ap_escape_html(r->pool, ap_get_server_name(r)),
"</h1>\n\n", NULL);
ap_rvputs(r, "<dl><dt>Server Version: ",
ap_get_server_description(), "</dt>\n", NULL);
ap_rvputs(r, "<dt>Server Built: ",
ap_get_server_built(), "</dt>\n", NULL);
ap_rvputs(r, "<dt>Balancer changes will ", conf->bal_persist ? "" : "NOT ",
"be persisted on restart.</dt>", NULL);
ap_rvputs(r, "<dt>Balancers are ", conf->inherit ? "" : "NOT ",
"inherited from main server.</dt>", NULL);
ap_rvputs(r, "<dt>ProxyPass settings are ", conf->ppinherit ? "" : "NOT ",
"inherited from main server.</dt>", NULL);
ap_rputs("</dl>\n", r);
balancer = (proxy_balancer *)conf->balancers->elts;
for (i = 0; i < conf->balancers->nelts; i++) {
ap_rputs("<hr />\n<h3>LoadBalancer Status for ", r);
ap_rvputs(r, "<a href=\"", ap_escape_uri(r->pool, r->uri), "?b=",
balancer->s->name + sizeof(BALANCER_PREFIX) - 1,
"&nonce=", balancer->s->nonce,
"\">", NULL);
ap_rvputs(r, balancer->s->name, "</a> [",balancer->s->sname, "]</h3>\n", NULL);
ap_rputs("\n\n<table><tr>"
"<th>MaxMembers</th><th>StickySession</th><th>DisableFailover</th><th>Timeout</th><th>FailoverAttempts</th><th>Method</th>"
"<th>Path</th><th>Active</th></tr>\n<tr>", r);
/* the below is a safe cast, since the number of slots total will
* never be more than max_workers, which is restricted to int */
ap_rprintf(r, "<td>%d [%d Used]</td>\n", balancer->max_workers,
balancer->max_workers - (int)storage->num_free_slots(balancer->wslot));
if (*balancer->s->sticky) {
if (strcmp(balancer->s->sticky, balancer->s->sticky_path)) {
ap_rvputs(r, "<td>", ap_escape_html(r->pool, balancer->s->sticky), "|",
ap_escape_html(r->pool, balancer->s->sticky_path), NULL);
}
else {
ap_rvputs(r, "<td>", ap_escape_html(r->pool, balancer->s->sticky), NULL);
}
}
else {
ap_rputs("<td> (None) ", r);
}
ap_rprintf(r, "</td><td>%s</td>\n",
balancer->s->sticky_force ? "On" : "Off");
ap_rprintf(r, "<td>%" APR_TIME_T_FMT "</td>",
apr_time_sec(balancer->s->timeout));
ap_rprintf(r, "<td>%d</td>\n", balancer->s->max_attempts);
ap_rprintf(r, "<td>%s</td>\n",
balancer->s->lbpname);
ap_rputs("<td>", r);
if (*balancer->s->vhost) {
ap_rvputs(r, balancer->s->vhost, " -> ", NULL);
}
ap_rvputs(r, balancer->s->vpath, "</td>\n", NULL);
ap_rprintf(r, "<td>%s</td>\n",
!balancer->s->inactive ? "Yes" : "No");
ap_rputs("</tr>\n</table>\n<br />", r);
ap_rputs("\n\n<table><tr>"
"<th>Worker URL</th>"
"<th>Route</th><th>RouteRedir</th>"
"<th>Factor</th><th>Set</th><th>Status</th>"
"<th>Elected</th><th>Busy</th><th>Load</th><th>To</th><th>From</th>", r);
if (set_worker_hc_param_f) {
ap_rputs("<th>HC Method</th><th>HC Interval</th><th>Passes</th><th>Fails</th><th>HC uri</th><th>HC Expr</th>", r);
}
ap_rputs("</tr>\n", r);
workers = (proxy_worker **)balancer->workers->elts;
for (n = 0; n < balancer->workers->nelts; n++) {
char fbuf[50];
worker = *workers;
ap_rvputs(r, "<tr>\n<td><a href=\"",
ap_escape_uri(r->pool, r->uri), "?b=",
balancer->s->name + sizeof(BALANCER_PREFIX) - 1, "&w=",
ap_escape_uri(r->pool, worker->s->name),
"&nonce=", balancer->s->nonce,
"\">", NULL);
ap_rvputs(r, (*worker->s->uds_path ? "<i>" : ""), ap_proxy_worker_get_name(worker),
(*worker->s->uds_path ? "</i>" : ""), "</a></td>", NULL);
ap_rvputs(r, "<td>", ap_escape_html(r->pool, worker->s->route),
NULL);
ap_rvputs(r, "</td><td>",
ap_escape_html(r->pool, worker->s->redirect), NULL);
ap_rprintf(r, "</td><td>%.2f</td>", (float)(worker->s->lbfactor)/100.0);
ap_rprintf(r, "<td>%d</td><td>", worker->s->lbset);
ap_rvputs(r, ap_proxy_parse_wstatus(r->pool, worker), NULL);
ap_rputs("</td>", r);
ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td>", worker->s->elected);
ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td>", ap_proxy_get_busy_count(worker));
ap_rprintf(r, "<td>%d</td><td>", worker->s->lbstatus);
ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r);
ap_rputs("</td><td>", r);
ap_rputs(apr_strfsize(worker->s->read, fbuf), r);
if (set_worker_hc_param_f) {
ap_rprintf(r, "</td><td>%s</td>", ap_proxy_show_hcmethod(worker->s->method));
ap_rprintf(r, "<td>%" APR_TIME_T_FMT "ms</td>", apr_time_as_msec(worker->s->interval));
ap_rprintf(r, "<td>%d (%d)</td>", worker->s->passes,worker->s->pcount);
ap_rprintf(r, "<td>%d (%d)</td>", worker->s->fails, worker->s->fcount);
ap_rprintf(r, "<td>%s</td>", ap_escape_html(r->pool, worker->s->hcuri));
ap_rprintf(r, "<td>%s", worker->s->hcexpr);
}
ap_rputs("</td></tr>\n", r);
++workers;
}
ap_rputs("</table>\n", r);
++balancer;
}
ap_rputs("<hr />\n", r);
if (hc_show_exprs_f) {
hc_show_exprs_f(r);
}
if (wsel && bsel) {
ap_rputs("<h3>Edit worker settings for ", r);
ap_rvputs(r, (*wsel->s->uds_path?"<i>":""), ap_proxy_worker_get_name(wsel), (*wsel->s->uds_path?"</i>":""), "</h3>\n", NULL);
ap_rputs("<form method='POST' enctype='application/x-www-form-urlencoded' action=\"", r);
ap_rvputs(r, ap_escape_uri(r->pool, action), "\">\n", NULL);
ap_rputs("<table><tr><td>Load factor:</td><td><input name='w_lf' id='w_lf' type=text ", r);
ap_rprintf(r, "value='%.2f'></td></tr>\n", (float)(wsel->s->lbfactor)/100.0);
ap_rputs("<tr><td>LB Set:</td><td><input name='w_ls' id='w_ls' type=text ", r);
ap_rprintf(r, "value='%d'></td></tr>\n", wsel->s->lbset);
ap_rputs("<tr><td>Route:</td><td><input name='w_wr' id='w_wr' type=text ", r);
ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->route),
NULL);
ap_rputs("\"></td></tr>\n", r);
ap_rputs("<tr><td>Route Redirect:</td><td><input name='w_rr' id='w_rr' type=text ", r);
ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->redirect),
NULL);
ap_rputs("\"></td></tr>\n", r);
ap_rputs("<tr><td>Status:</td>", r);
ap_rputs("<td><table><tr>"
"<th>Ignore Errors</th>"
"<th>Draining Mode</th>"
"<th>Disabled</th>"
"<th>Hot Standby</th>"
"<th>Hot Spare</th>", r);
if (hc_show_exprs_f) {
ap_rputs("<th>HC Fail</th>", r);
}
ap_rputs("<th>Stopped</th></tr>\n<tr>", r);
create_radio("w_status_I", (PROXY_WORKER_IS(wsel, PROXY_WORKER_IGNORE_ERRORS)), r);
create_radio("w_status_N", (PROXY_WORKER_IS(wsel, PROXY_WORKER_DRAIN)), r);
create_radio("w_status_D", (PROXY_WORKER_IS(wsel, PROXY_WORKER_DISABLED)), r);
create_radio("w_status_H", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HOT_STANDBY)), r);
create_radio("w_status_R", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HOT_SPARE)), r);
if (hc_show_exprs_f) {
create_radio("w_status_C", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HC_FAIL)), r);
}
create_radio("w_status_S", (PROXY_WORKER_IS(wsel, PROXY_WORKER_STOPPED)), r);
ap_rputs("</tr></table></td></tr>\n", r);
if (hc_select_exprs_f) {
proxy_hcmethods_t *method = proxy_hcmethods;
ap_rputs("<tr><td colspan='2'>\n<table align='center'><tr><th>Health Check param</th><th>Value</th></tr>\n", r);
ap_rputs("<tr><td>Method</td><td><select name='w_hm'>\n", r);
for (; method->name; method++) {
if (method->implemented) {
ap_rprintf(r, "<option value='%s' %s >%s</option>\n",
method->name,
(wsel->s->method == method->method) ? "selected" : "",
method->name);
}
}
ap_rputs("</select>\n</td></tr>\n", r);
ap_rputs("<tr><td>Expr</td><td><select name='w_he'>\n", r);
hc_select_exprs_f(r, wsel->s->hcexpr);
ap_rputs("</select>\n</td></tr>\n", r);
ap_rprintf(r, "<tr><td>Interval (ms)</td><td><input name='w_hi' id='w_hi' type='text' "
"value='%" APR_TIME_T_FMT "'></td></tr>\n", apr_time_as_msec(wsel->s->interval));
ap_rprintf(r, "<tr><td>Passes trigger</td><td><input name='w_hp' id='w_hp' type='text' "
"value='%d'></td></tr>\n", wsel->s->passes);
ap_rprintf(r, "<tr><td>Fails trigger)</td><td><input name='w_hf' id='w_hf' type='text' "
"value='%d'></td></tr>\n", wsel->s->fails);
ap_rprintf(r, "<tr><td>HC uri</td><td><input name='w_hu' id='w_hu' type='text' "
"value=\"%s\"></td></tr>\n", ap_escape_html(r->pool, wsel->s->hcuri));
ap_rputs("</table>\n</td></tr>\n", r);
}
ap_rputs("<tr><td colspan='2'><input type=submit value='Submit'></td></tr>\n", r);
ap_rvputs(r, "</table>\n<input type=hidden name='w' id='w' ", NULL);
ap_rvputs(r, "value=\"", ap_escape_uri(r->pool, wsel->s->name), "\">\n", NULL);
ap_rvputs(r, "<input type=hidden name='b' id='b' ", NULL);
ap_rvputs(r, "value=\"", ap_escape_html(r->pool, bsel->s->name + sizeof(BALANCER_PREFIX) - 1),
"\">\n", NULL);
ap_rvputs(r, "<input type=hidden name='nonce' id='nonce' value='",
bsel->s->nonce, "'>\n", NULL);
ap_rputs("</form>\n", r);
ap_rputs("<hr />\n", r);
} else if (bsel) {
const apr_array_header_t *provs;
const ap_list_provider_names_t *pname;
int i;
ap_rputs("<h3>Edit balancer settings for ", r);
ap_rvputs(r, ap_escape_html(r->pool, bsel->s->name), "</h3>\n", NULL);
ap_rputs("<form method='POST' enctype='application/x-www-form-urlencoded' action=\"", r);
ap_rvputs(r, ap_escape_uri(r->pool, action), "\">\n", NULL);
ap_rputs("<table>\n", r);
provs = ap_list_provider_names(r->pool, PROXY_LBMETHOD, "0");
if (provs) {
ap_rputs("<tr><td>LBmethod:</td>", r);
ap_rputs("<td>\n<select name='b_lbm' id='b_lbm'>", r);
pname = (ap_list_provider_names_t *)provs->elts;
for (i = 0; i < provs->nelts; i++, pname++) {
ap_rvputs(r,"<option value='", pname->provider_name, "'", NULL);
if (strcmp(pname->provider_name, bsel->s->lbpname) == 0)
ap_rputs(" selected ", r);
ap_rvputs(r, ">", pname->provider_name, "\n", NULL);
}
ap_rputs("</select>\n</td></tr>\n", r);
}
ap_rputs("<tr><td>Timeout:</td><td><input name='b_tmo' id='b_tmo' type=text ", r);
ap_rprintf(r, "value='%" APR_TIME_T_FMT "'></td></tr>\n", apr_time_sec(bsel->s->timeout));
ap_rputs("<tr><td>Failover Attempts:</td><td><input name='b_max' id='b_max' type=text ", r);
ap_rprintf(r, "value='%d'></td></tr>\n", bsel->s->max_attempts);
ap_rputs("<tr><td>Disable Failover:</td>", r);
create_radio("b_sforce", bsel->s->sticky_force, r);
ap_rputs("</tr>\n", r);
ap_rputs("<tr><td>Sticky Session:</td><td><input name='b_ss' id='b_ss' size=64 type=text ", r);
if (strcmp(bsel->s->sticky, bsel->s->sticky_path)) {
ap_rvputs(r, "value =\"", ap_escape_html(r->pool, bsel->s->sticky), "|",
ap_escape_html(r->pool, bsel->s->sticky_path), NULL);
}
else {
ap_rvputs(r, "value =\"", ap_escape_html(r->pool, bsel->s->sticky), NULL);
}
ap_rputs("\"> (Use '-' to delete)</td></tr>\n", r);
if (storage->num_free_slots(bsel->wslot) != 0) {
ap_rputs("<tr><td>Add New Worker:</td><td><input name='b_nwrkr' id='b_nwrkr' size=32 type=text>"
" Are you sure? <input name='b_wyes' id='b_wyes' type=checkbox value='1'>"
"</td></tr>", r);
}
ap_rputs("<tr><td colspan=2><input type=submit value='Submit'></td></tr>\n", r);
ap_rvputs(r, "</table>\n<input type=hidden name='b' id='b' ", NULL);
ap_rvputs(r, "value=\"", ap_escape_html(r->pool, bsel->s->name + sizeof(BALANCER_PREFIX) - 1),
"\">\n", NULL);
ap_rvputs(r, "<input type=hidden name='nonce' id='nonce' value='",
bsel->s->nonce, "'>\n", NULL);
ap_rputs("</form>\n", r);
ap_rputs("<hr />\n", r);
}
ap_rputs(ap_psignature("",r), r);
ap_rputs("</body></html>\n", r);
ap_rflush(r);
}
}