module AP_MODULE_DECLARE_DATA proxy_balancer_module;
+static APR_OPTIONAL_FN_TYPE(set_worker_hc_param) *set_worker_hc_param_f = NULL;
+
static int (*ap_proxy_retry_worker_fn)(const char *proxy_function,
proxy_worker *worker, server_rec *s) = NULL;
if (rv != APR_SUCCESS) {
return rv;
}
-
+ set_worker_hc_param_f = APR_RETRIEVE_OPTIONAL_FN(set_worker_hc_param);
return OK;
}
apr_port_t port = 0;
/* TODO: offset of BALANCER_PREFIX ?? */
- if (strncasecmp(url, "balancer:", 9) == 0) {
+ if (ap_casecmpstrn(url, "balancer:", 9) == 0) {
url += 9;
}
else {
if (path == NULL)
return HTTP_BAD_REQUEST;
- r->filename = apr_pstrcat(r->pool, "proxy:", BALANCER_PREFIX, host,
+ r->filename = apr_pstrcat(r->pool, "proxy:" BALANCER_PREFIX, host,
"/", path, (search) ? "?" : "", (search) ? search : "", NULL);
r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
int worker_is_initialized;
proxy_worker *worker = *workers;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01158)
- "Looking at %s -> %s initialized?", balancer->s->name, worker->s->name);
+ "Looking at %s -> %s initialized?", balancer->s->name,
+ ap_proxy_worker_name(p, worker));
worker_is_initialized = PROXY_WORKER_IS_INITIALIZED(worker);
if (!worker_is_initialized) {
ap_proxy_initialize_worker(worker, s, p);
return HTTP_INTERNAL_SERVER_ERROR;
}
- if (!apr_is_empty_array(balancer->errstatuses)) {
+ if (!apr_is_empty_array(balancer->errstatuses)
+ && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
int i;
for (i = 0; i < balancer->errstatuses->nelts; i++) {
int val = ((int *)balancer->errstatuses->elts)[i];
if (r->status == val) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01174)
- "%s: Forcing worker (%s) into error state "
+ "%s: Forcing worker (%s) into error state "
"due to status code %d matching 'failonstatus' "
"balancer parameter",
- balancer->s->name, worker->s->name, val);
+ balancer->s->name, ap_proxy_worker_name(r->pool, worker),
+ val);
worker->s->status |= PROXY_WORKER_IN_ERROR;
worker->s->error_time = apr_time_now();
break;
}
}
+ if (balancer->failontimeout
+ && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)
+ && (apr_table_get(r->notes, "proxy_timedout")) != NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02460)
+ "%s: Forcing worker (%s) into error state "
+ "due to timeout and 'failontimeout' parameter being set",
+ balancer->s->name, ap_proxy_worker_name(r->pool, worker));
+ worker->s->status |= PROXY_WORKER_IN_ERROR;
+ worker->s->error_time = apr_time_now();
+
+ }
+
if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01175)
"%s: Unlock failed for post_request", balancer->s->name);
continue;
}
if (conf->bal_persist) {
- type = AP_SLOTMEM_TYPE_PREGRAB | AP_SLOTMEM_TYPE_PERSIST;
+ type = AP_SLOTMEM_TYPE_PERSIST;
} else {
- type = AP_SLOTMEM_TYPE_PREGRAB;
+ type = 0;
}
if (conf->balancers->nelts) {
conf->max_balancers = conf->balancers->nelts + conf->bgrowth;
static void create_radio(const char *name, unsigned int flag, request_rec *r)
{
- ap_rvputs(r, "<td>On <input name='", name, "' id='", name, "' value='1' type=radio", NULL);
+ ap_rvputs(r, "<td><label for='", name, "1'>On</label> <input name='", name, "' id='", name, "1' value='1' type=radio", NULL);
if (flag)
ap_rputs(" checked", r);
- ap_rvputs(r, "> <br/> Off <input name='", name, "' id='", name, "' value='0' type=radio", NULL);
+ ap_rvputs(r, "> <br/> <label for='", name, "0'>Off</label> <input name='", name, "' id='", name, "0' value='0' type=radio", NULL);
if (!flag)
ap_rputs(" checked", r);
ap_rputs("></td>\n", r);
rv = ap_get_brigade(r->input_filters, ib, AP_MODE_READBYTES,
APR_BLOCK_READ, len);
if (rv != APR_SUCCESS) {
- return HTTP_INTERNAL_SERVER_ERROR;
+ return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
}
apr_brigade_flatten(ib, buf, &len);
buf[len] = '\0';
*wsel->s->redirect = '\0';
}
if ((val = apr_table_get(params, "w_status_I"))) {
- ap_proxy_set_wstatus('I', atoi(val), wsel);
+ ap_proxy_set_wstatus(PROXY_WORKER_IGNORE_ERRORS_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_status_N"))) {
- ap_proxy_set_wstatus('N', atoi(val), wsel);
+ ap_proxy_set_wstatus(PROXY_WORKER_DRAIN_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_status_D"))) {
- ap_proxy_set_wstatus('D', atoi(val), wsel);
+ ap_proxy_set_wstatus(PROXY_WORKER_DISABLED_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_status_H"))) {
- ap_proxy_set_wstatus('H', atoi(val), wsel);
+ ap_proxy_set_wstatus(PROXY_WORKER_HOT_STANDBY_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_ls"))) {
int ival = atoi(val);
(val = apr_table_get(params, "b_nwrkr"))) {
char *ret;
proxy_worker *nworker;
- nworker = ap_proxy_get_worker(conf->pool, bsel, conf, val);
+ nworker = ap_proxy_get_worker(r->pool, bsel, conf, val);
if (!nworker && storage->num_free_slots(bsel->wslot)) {
if ((rv = PROXY_GLOBAL_LOCK(bsel)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01194)
/* sync all timestamps */
bsel->wupdated = bsel->s->wupdated = nworker->s->updated = apr_time_now();
/* by default, all new workers are disabled */
- ap_proxy_set_wstatus('D', 1, nworker);
+ ap_proxy_set_wstatus(PROXY_WORKER_DISABLED_FLAG, 1, nworker);
}
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01203)
ap_rputs(" <httpd:balancer>\n", r);
/* Start proxy_balancer */
ap_rvputs(r, " <httpd:name>", balancer->s->name, "</httpd:name>\n", NULL);
- if (balancer->s->sticky) {
+ if (*balancer->s->sticky) {
ap_rvputs(r, " <httpd:stickysession>", balancer->s->sticky,
"</httpd:stickysession>\n", NULL);
ap_rprintf(r,
}
ap_rvputs(r, " <httpd:lbmethod>", balancer->lbmethod->name,
"</httpd:lbmethod>\n", NULL);
- if (balancer->s->sticky) {
+ if (*balancer->s->sticky) {
ap_rprintf(r,
" <httpd:scolonpathdelim>%s</httpd:scolonpathdelim>\n",
(balancer->s->scolonsep ? "On" : "Off"));
worker = *workers;
/* Start proxy_worker */
ap_rputs(" <httpd:worker>\n", r);
- ap_rvputs(r, " <httpd:name>", worker->s->name,
+ ap_rvputs(r, " <httpd:name>", ap_proxy_worker_name(r->pool, worker),
"</httpd:name>\n", NULL);
ap_rvputs(r, " <httpd:scheme>", worker->s->scheme,
"</httpd:scheme>\n", NULL);
ap_rprintf(r, " <httpd:lbset>%d</httpd:lbset>\n",
worker->s->lbset);
/* End proxy_worker_stat */
- if (!strcasecmp(worker->s->scheme, "ajp")) {
+ if (!ap_casecmpstr(worker->s->scheme, "ajp")) {
ap_rputs(" <httpd:flushpackets>", r);
switch (worker->s->flush_packets) {
case flush_off:
" padding: 2px;\n"
" border-style: dotted;\n"
" border-color: gray;\n"
- " background-color: white;\n"
+ " background-color: lightgray;\n"
" text-align: center;\n"
"}\n"
"td {\n"
ap_rvputs(r, "<dl><dt>Server Version: ",
ap_get_server_description(), "</dt>\n", NULL);
ap_rvputs(r, "<dt>Server Built: ",
- ap_get_server_built(), "\n</dt></dl>\n", NULL);
+ 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,
+ "&nonce=", balancer->s->nonce,
"\">", NULL);
ap_rvputs(r, balancer->s->name, "</a> [",balancer->s->sname, "]</h3>\n", NULL);
ap_rputs("\n\n<table><tr>"
else {
ap_rputs("<td> (None) ", r);
}
- ap_rprintf(r, "<td>%s</td>\n",
+ ap_rprintf(r, "</td><td>%s</td>\n",
balancer->s->sticky_force ? "On" : "Off");
- ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",
+ 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 && *(balancer->s->vhost)) {
+ if (*balancer->s->vhost) {
ap_rvputs(r, balancer->s->vhost, " -> ", NULL);
}
ap_rvputs(r, balancer->s->vpath, "</td>\n", NULL);
"<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>"
- "</tr>\n", r);
+ "<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>Method</th><th>Interval</th><th>Passes</th><th>Fails</th><th>URI</th>", r);
+ }
+ ap_rputs("</tr>\n", r);
workers = (proxy_worker **)balancer->workers->elts;
for (n = 0; n < balancer->workers->nelts; n++) {
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=",
+ balancer->s->name + sizeof(BALANCER_PREFIX) - 1, "&w=",
ap_escape_uri(r->pool, worker->s->name),
- "&nonce=", balancer->s->nonce,
+ "&nonce=", balancer->s->nonce,
"\">", NULL);
- ap_rvputs(r, worker->s->name, "</a></td>", NULL);
+ ap_rvputs(r, (*worker->s->uds_path ? "<i>" : ""), ap_proxy_worker_name(r->pool, 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_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>%d</td>", (int)apr_time_sec(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", worker->s->hcuri);
+ }
ap_rputs("</td></tr>\n", r);
++workers;
ap_rputs("<hr />\n", r);
if (wsel && bsel) {
ap_rputs("<h3>Edit worker settings for ", r);
- ap_rvputs(r, wsel->s->name, "</h3>\n", NULL);
+ ap_rvputs(r, (*wsel->s->uds_path?"<i>":""), ap_proxy_worker_name(r->pool, 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("<dl>\n<table><tr><td>Load factor:</td><td><input name='w_lf' id='w_lf' type=text ", r);
+ ap_rputs("<table><tr><td>Load factor:</td><td><input name='w_lf' id='w_lf' type=text ", r);
ap_rprintf(r, "value='%d'></td></tr>\n", wsel->s->lbfactor);
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("<h3>Edit balancer settings for ", r);
ap_rvputs(r, bsel->s->name, "</h3>\n", NULL);
ap_rputs("<form method='POST' enctype='application/x-www-form-urlencoded' action='", r);
- ap_rvputs(r, action, "'>\n", NULL);
- ap_rputs("<dl>\n<table>\n", 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);
* initializes
*/
static const char *const aszPred[] = { "mpm_winnt.c", "mod_slotmem_shm.c", NULL};
+ static const char *const aszPred2[] = { "mod_proxy.c", NULL};
/* manager handler */
- ap_hook_post_config(balancer_post_config, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_config(balancer_post_config, aszPred2, NULL, APR_HOOK_MIDDLE);
ap_hook_pre_config(balancer_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(balancer_handler, NULL, NULL, APR_HOOK_FIRST);
ap_hook_child_init(balancer_child_init, aszPred, NULL, APR_HOOK_MIDDLE);