From: Nick Kew Date: Thu, 1 Apr 2010 22:48:38 +0000 (+0000) Subject: Proxy balancer: support setting error status according to X-Git-Tag: 2.3.6~268 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9c1c3f56d48751f3445f83dc53a756abbccd43d5;p=thirdparty%2Fapache%2Fhttpd.git Proxy balancer: support setting error status according to HTTP response code from a backend. PR 48939 [Daniel Ruggeri ] git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@930125 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index af2920d0e44..833fda02c65 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,10 @@ Changes with Apache 2.3.7 processing is completed, avoiding orphaned callback pointers. [Brett Gervasoni , Jeff Trawick] + *) Proxy balancer: support setting error status according to + HTTP response code from a backend. + PR 48939 [Daniel Ruggeri ] + *) htcacheclean: Introduce the ability to clean specific URLs from the cache, if provided as an optional parameter on the command line. [Graham Leggett] diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index cb5336f2022..92975c4c995 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -381,6 +381,27 @@ static const char *set_balancer_param(proxy_server_conf *conf, else return "scolonpathdelim must be On|Off"; } + else if (!strcasecmp(key, "erroronstatus")) { + char valSplit[strlen(val)+1]; + char *status; + char *tok_state; + + strcpy(valSplit, val); + balancer->errstatuses = apr_array_make(p, 1, sizeof(int)); + + status = apr_strtok(valSplit, ", ", &tok_state); + while (status != NULL) { + ival = atoi(status); + if (ap_is_HTTP_VALID_RESPONSE(ival)) { + *(int*)apr_array_push(balancer->errstatuses) = ival; + } + else { + return "erroronstatus must be one or more HTTP response code"; + } + 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 adf1376367c..f5452700fe0 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -373,6 +373,7 @@ struct proxy_balancer { void *context; /* general purpose storage */ const char *sticky_path; /* URL sticky session identifier */ 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 03ed92288b2..1258f003a12 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -600,7 +600,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) { @@ -609,8 +608,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_NOTICE, rv, r->server, + "Detected ErrorOnState (%d) for member (%s). Forcing worker into error state.", val, worker->name); + 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, @@ -620,8 +631,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--;