diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 2121892..6f904b2 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -2838,33 +2838,48 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, connected = 1; } - /* - * Put the entire worker to error state if - * the PROXY_WORKER_IGNORE_ERRORS flag is not set. - * Altrough some connections may be alive - * no further connections to the worker could be made - */ - if (!connected && PROXY_WORKER_IS_USABLE(worker) && - !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) { - worker->s->error_time = apr_time_now(); - worker->s->status |= PROXY_WORKER_IN_ERROR; - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00959) - "ap_proxy_connect_backend disabling worker for (%s) for %" - APR_TIME_T_FMT "s", - worker->s->hostname, apr_time_sec(worker->s->retry)); + + if (PROXY_WORKER_IS_USABLE(worker)) { + /* + * Put the entire worker to error state if + * the PROXY_WORKER_IGNORE_ERRORS flag is not set. + * Although some connections may be alive + * no further connections to the worker could be made + */ + if (!connected) { + if (!(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) { + worker->s->error_time = apr_time_now(); + worker->s->status |= PROXY_WORKER_IN_ERROR; + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00959) + "ap_proxy_connect_backend disabling worker for (%s) for %" + APR_TIME_T_FMT "s", + worker->s->hostname, apr_time_sec(worker->s->retry)); + } + } + else { + if (worker->s->retries) { + /* + * A worker came back. So here is where we need to + * either reset all params to initial conditions or + * apply some sort of aging + */ + } + worker->s->error_time = 0; + worker->s->retries = 0; + } + return connected ? OK : DECLINED; } else { - if (worker->s->retries) { - /* - * A worker came back. So here is where we need to - * either reset all params to initial conditions or - * apply some sort of aging - */ - } - worker->s->error_time = 0; - worker->s->retries = 0; + /* + * The worker is in error likely done by a different thread / process + * e.g. for a timeout or bad status. We should respect this and should + * not continue with a connection via this worker even if we got one. + */ + if (connected) { + socket_cleanup(conn); + } + return DECLINED; } - return connected ? OK : DECLINED; } PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,