From: William A. Rowe Jr Date: Thu, 7 Oct 2010 18:51:18 +0000 (+0000) Subject: mod_proxy_balancer: Force workers into PROXY_WORKER_IN_ERROR when configured X-Git-Tag: 2.2.17~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e2b5984596e99f152c7daf14e71d9b1ac54fc81;p=thirdparty%2Fapache%2Fhttpd.git mod_proxy_balancer: Force workers into PROXY_WORKER_IN_ERROR when configured statuses are found PR: 48939 Backports: 930125, 930254, 962972, 987359 Submitted by: Daniel Ruggeri Reviewed by: trawick, niq, wrowe git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1005571 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index ceb90943c33..d23bc8f8152 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@  -*- coding: utf-8 -*- Changes with Apache 2.2.17 + *) Proxy balancer: support setting error status according to HTTP response + code from a backend. PR 48939. [Daniel Ruggeri ] + *) mod_authnz_ldap: If AuthLDAPCharsetConfig is set, also convert the password to UTF-8. PR 45318. [Johannes Müller , Stefan Fritsch] diff --git a/STATUS b/STATUS index 2c5d3ec2684..8f70385116e 100644 --- a/STATUS +++ b/STATUS @@ -87,21 +87,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_proxy_balancer: Force workers into PROXY_WORKER_IN_ERROR when configured - statuses are found - PR: 48939 - Trunk patches: http://svn.apache.org/viewvc?rev=930125&view=rev - http://svn.apache.org/viewvc?rev=930254&view=rev - http://svn.apache.org/viewvc?rev=962972&view=rev - http://svn.apache.org/viewvc?rev=987359&view=rev - 2.2.x patch: https://issues.apache.org/bugzilla/attachment.cgi?id=25923 - plus this CHANGES entry: - *) Proxy balancer: support setting error status according to HTTP response - code from a backend. PR 48939. [Daniel Ruggeri ] - Submitted by: Daniel Ruggeri - +1: trawick, wrowe - niq: +1 to the 2.2.x patch, but why r951900 and r987379 in trunk patches? - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/docs/manual/mod/mod_proxy.xml b/docs/manual/mod/mod_proxy.xml index 44015d93db4..815e18ae34c 100644 --- a/docs/manual/mod/mod_proxy.xml +++ b/docs/manual/mod/mod_proxy.xml @@ -979,6 +979,12 @@ expressions Balancer timeout in seconds. If set this will be the maximum time to wait for a free worker. Default is not to wait. + failonstatus + - + A single or comma-separated list of HTTP status codes. If set this will + force the worker into error state when the backend returns any status code + in the list. Worker recovery behaves the same as other worker errors. +

A sample balancer setup

diff --git a/include/ap_mmn.h b/include/ap_mmn.h index eef610ab671..ba1ca0bfe6a 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -139,6 +139,7 @@ * 20051115.23 (2.2.12) Add ap_open_piped_log_ex API, with cmdtype option, * and conditional cmdtype member of piped_log struct * 20051115.24 (2.2.15) Add forward member to proxy_conn_rec + * 20051115.25 (2.2.17) Add errstatuses member to proxy_balancer */ #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */ @@ -146,7 +147,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20051115 #endif -#define MODULE_MAGIC_NUMBER_MINOR 24 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 25 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 6a370563fb8..1efe95ce4d0 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -365,6 +365,28 @@ static const char *set_balancer_param(proxy_server_conf *conf, else return "scolonpathdelim must be On|Off"; } + else if (!strcasecmp(key, "failonstatus")) { + char *val_split; + char *status; + char *tok_state; + + val_split = apr_pstrdup(p, val); + + balancer->errstatuses = apr_array_make(p, 1, sizeof(int)); + + status = apr_strtok(val_split, ", ", &tok_state); + while (status != NULL) { + ival = atoi(status); + if (ap_is_HTTP_VALID_RESPONSE(ival)) { + *(int *)apr_array_push(balancer->errstatuses) = ival; + } + else { + return "failonstatus must be one or more HTTP response codes"; + } + status = apr_strtok(NULL, ", ", &tok_state); + } + + } else { return "unknown Balancer parameter"; } diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 358248f1353..4a4bf17bd1d 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -386,6 +386,8 @@ struct proxy_balancer { #endif void *context; /* general purpose storage */ int scolonsep; /* true if ';' seps sticky session paths */ + + apr_array_header_t *errstatuses; /* statuses to force members into error */ }; struct proxy_balancer_method { diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index e5a010dbd8b..90f3d086edd 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -591,7 +591,6 @@ static int proxy_balancer_post_request(proxy_worker *worker, proxy_server_conf *conf) { -#if 0 apr_status_t rv; if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) { @@ -600,8 +599,20 @@ static int proxy_balancer_post_request(proxy_worker *worker, balancer->name); return HTTP_INTERNAL_SERVER_ERROR; } - /* TODO: placeholder for post_request actions - */ + if (!apr_is_empty_array(balancer->errstatuses)) { + int i; + for (i = 0; i < balancer->errstatuses->nelts; i++) { + int val = ((int *)balancer->errstatuses->elts)[i]; + if (r->status == val) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, + "proxy: BALANCER: (%s). Forcing recovery for worker (%s), failonstatus %d", + balancer->name, worker->name, val); + worker->s->status |= PROXY_WORKER_IN_ERROR; + worker->s->error_time = apr_time_now(); + break; + } + } + } if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, @@ -611,8 +622,6 @@ static int proxy_balancer_post_request(proxy_worker *worker, ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy_balancer_post_request for (%s)", balancer->name); -#endif - if (worker && worker->s->busy) worker->s->busy--;