--- docs/manual/mod/mod_proxy.xml (revision 1438130) +++ docs/manual/mod/mod_proxy.xml (working copy) @@ -1015,6 +1015,15 @@ set to Off. Available with Apache HTTP Server 2.2.23 and later. + failonbadgateway + Off + If set to On, forces a backend worker into error state + if there's a communication failure with it (eg: timeout, invalid status + line, etc.). Worker recovery behaves the same as other worker errors. + Defaults to Off to retain the original behaviour of + returning a HTTP_BAD_GATEWAY response to the client. + Available with Apache HTTP Server 2.2.24 and later. +

A sample balancer setup

--- CHANGES (revision 1438130) +++ CHANGES (working copy) @@ -4,6 +4,10 @@ *) mod_ssl: Add new directive SSLCompression to disable TLS-level compression. PR 53219. [Björn Jacke , Stefan Fritsch] + *) mod_proxy: Add the failonbadgateway parameter that determines if a + communications error with a backend should result in that backend being + marked as in error. [Brian Kroth] + Changes with Apache 2.2.23 *) SECURITY: CVE-2012-0883 (cve.mitre.org) --- modules/proxy/proxy_util.c (revision 1438130) +++ modules/proxy/proxy_util.c (working copy) @@ -1315,6 +1315,7 @@ (*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_worker)); (*balancer)->forcerecovery = 1; + (*balancer)->failonbadgateway = 0; /* XXX Is this a right place to create mutex */ #if APR_HAS_THREADS if (apr_thread_mutex_create(&((*balancer)->mutex), --- modules/proxy/mod_proxy.c (revision 1438130) +++ modules/proxy/mod_proxy.c (working copy) @@ -395,6 +395,14 @@ else return "forcerecovery must be On|Off"; } + else if (!strcasecmp(key, "failonbadgateway")) { + if (!strcasecmp(val, "on")) + balancer->failonbadgateway = 1; + else if (!strcasecmp(val, "off")) + balancer->failonbadgateway = 0; + else + return "failonbadgateway must be On|Off"; + } else { return "unknown Balancer parameter"; } @@ -1053,6 +1061,34 @@ worker->s->error_time = apr_time_now(); } } + else if (access_status == HTTP_BAD_GATEWAY) { + /* Backend had a communications error (eg: timeout, protocol + * violation, etc.) + * + * This is provided for the case where the backend connects (or + * keep-alives are in use), but fails to respond in a timely manner + * or is having some other sort of difficulties that prevent it + * from returning useful data. In that case, we may wish to no + * longer use that backend. It should be noted that failonstatus + * doesn't cover this case since here the backend may return no + * status line or a corrupt one resulting in nothing to match on. + * + * This could instead be implemented, for instance, in + * mod_proxy_http.c:ap_proxy_http_process_response():1412, but this + * is a bit more general and should apply to all backend + * communication failures (at least from what I've seen looking + * through the code). + * + * DONE: Make this behavior dependent upon a configuration setting + * for the balacner (eg: failonbadgateway). + * 2013-02-01 + * bpkroth + */ + if (balancer && balancer->failonbadgateway) { + worker->s->status |= PROXY_WORKER_IN_ERROR; + worker->s->error_time = apr_time_now(); + } + } else { /* Unrecoverable error. * Return the origin status code to the client. --- modules/proxy/mod_proxy.h (revision 1438130) +++ modules/proxy/mod_proxy.h (working copy) @@ -389,6 +389,7 @@ apr_array_header_t *errstatuses; /* statuses to force members into error */ int forcerecovery; /* Force recovery if all workers are in error state */ + int failonbadgateway; /* Force members into error on communications failure */ }; struct proxy_balancer_method { --- include/ap_mmn.h (revision 1438130) +++ include/ap_mmn.h (working copy) @@ -149,6 +149,7 @@ * 20051115.29 (2.2.21) add max_ranges to core_dir_config * 20051115.30 (2.2.21) add ap_set_accept_ranges() * 20051115.31 (2.2.23) Add forcerecovery to proxy_balancer_shared struct + * 20051115.32 (2.2.24) Add failonbadgateway to proxy_balancer_shared struct */ #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */ @@ -156,7 +157,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20051115 #endif -#define MODULE_MAGIC_NUMBER_MINOR 31 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 32 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a