mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
mod_proxy: follow up to r1750392.
Avoid double checking the connection in ap_proxy_connect_backend() when ap_proxy_check_backend() says it is up and good to go. This can be done by moving the PROXY_WORKER_IS_USABLE() check in ap_proxy_check_backend(), since it is called by ap_proxy_connect_backend(), and not calling the latter if the former succeeded (for the modules using it). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1750474 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -980,8 +980,11 @@ PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,
|
|||||||
* @param conn acquired connection
|
* @param conn acquired connection
|
||||||
* @param s current server record
|
* @param s current server record
|
||||||
* @param expect_empty whether to check for empty (no data available) or not
|
* @param expect_empty whether to check for empty (no data available) or not
|
||||||
* @return APR_SUCCESS or error status (APR_ENOTEMPTY if expect_empty
|
* @return APR_SUCCESS or,
|
||||||
* is set but the connection is not empty)
|
* APR_ENOTSOCK: not connected,
|
||||||
|
* APR_NOTFOUND: worker in error state (unusable),
|
||||||
|
* APR_ENOTEMPTY: expect_empty set but the connection has data,
|
||||||
|
* other: connection closed/aborted (remotely)
|
||||||
*/
|
*/
|
||||||
PROXY_DECLARE(apr_status_t) ap_proxy_check_backend(const char *proxy_function,
|
PROXY_DECLARE(apr_status_t) ap_proxy_check_backend(const char *proxy_function,
|
||||||
proxy_conn_rec *conn,
|
proxy_conn_rec *conn,
|
||||||
|
@@ -783,8 +783,8 @@ static int proxy_ajp_handler(request_rec *r, proxy_worker *worker,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Step Two: Make the Connection */
|
/* Step Two: Make the Connection */
|
||||||
ap_proxy_check_backend(scheme, backend, r->server, 1);
|
if (ap_proxy_check_backend(scheme, backend, r->server, 1) &&
|
||||||
if (ap_proxy_connect_backend(scheme, backend, worker, r->server)) {
|
ap_proxy_connect_backend(scheme, backend, worker, r->server)) {
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00896)
|
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00896)
|
||||||
"failed to make connection to backend: %s",
|
"failed to make connection to backend: %s",
|
||||||
backend->hostname);
|
backend->hostname);
|
||||||
|
@@ -935,12 +935,14 @@ static int proxy_fcgi_handler(request_rec *r, proxy_worker *worker,
|
|||||||
*/
|
*/
|
||||||
backend->close = 1;
|
backend->close = 1;
|
||||||
if (worker->s->disablereuse_set && !worker->s->disablereuse) {
|
if (worker->s->disablereuse_set && !worker->s->disablereuse) {
|
||||||
ap_proxy_check_backend(FCGI_SCHEME, backend, r->server, 1);
|
|
||||||
backend->close = 0;
|
backend->close = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step Two: Make the Connection */
|
/* Step Two: Make the Connection */
|
||||||
if (ap_proxy_connect_backend(FCGI_SCHEME, backend, worker, r->server)) {
|
if ((backend->close || ap_proxy_check_backend(FCGI_SCHEME, backend,
|
||||||
|
r->server, 1)) &&
|
||||||
|
ap_proxy_connect_backend(FCGI_SCHEME, backend, worker,
|
||||||
|
r->server)) {
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01079)
|
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01079)
|
||||||
"failed to make connection to backend: %s",
|
"failed to make connection to backend: %s",
|
||||||
backend->hostname);
|
backend->hostname);
|
||||||
|
@@ -2069,8 +2069,9 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Step Two: Make the Connection */
|
/* Step Two: Make the Connection */
|
||||||
ap_proxy_check_backend(proxy_function, backend, r->server, 1);
|
if (ap_proxy_check_backend(proxy_function, backend, r->server, 1) &&
|
||||||
if (ap_proxy_connect_backend(proxy_function, backend, worker, r->server)) {
|
ap_proxy_connect_backend(proxy_function, backend, worker,
|
||||||
|
r->server)) {
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01114)
|
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01114)
|
||||||
"HTTP: failed to make connection to backend: %s",
|
"HTTP: failed to make connection to backend: %s",
|
||||||
backend->hostname);
|
backend->hostname);
|
||||||
|
@@ -2704,43 +2704,49 @@ PROXY_DECLARE(apr_status_t) ap_proxy_check_backend(const char *proxy_function,
|
|||||||
server_rec *s,
|
server_rec *s,
|
||||||
int expect_empty)
|
int expect_empty)
|
||||||
{
|
{
|
||||||
apr_status_t rv;
|
apr_status_t rv = APR_SUCCESS;
|
||||||
|
proxy_worker *worker = conn->worker;
|
||||||
|
|
||||||
if (!conn->sock) {
|
if (!PROXY_WORKER_IS_USABLE(worker)) {
|
||||||
return APR_ENOTSOCK;
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
rv = APR_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
else if (!conn->sock) {
|
||||||
if (conn->connection) {
|
rv = APR_ENOTSOCK;
|
||||||
|
}
|
||||||
|
else if (conn->connection) {
|
||||||
conn_rec *c = conn->connection;
|
conn_rec *c = conn->connection;
|
||||||
rv = ap_get_brigade(c->input_filters, conn->tmp_bb,
|
rv = ap_get_brigade(c->input_filters, conn->tmp_bb,
|
||||||
AP_MODE_SPECULATIVE, APR_NONBLOCK_READ, 1);
|
AP_MODE_SPECULATIVE, APR_NONBLOCK_READ, 1);
|
||||||
if (rv == APR_SUCCESS && expect_empty) {
|
if (APR_STATUS_IS_EAGAIN(rv)) {
|
||||||
|
rv = APR_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (rv == APR_SUCCESS && expect_empty) {
|
||||||
apr_off_t len = 0;
|
apr_off_t len = 0;
|
||||||
apr_brigade_length(conn->tmp_bb, 0, &len);
|
apr_brigade_length(conn->tmp_bb, 0, &len);
|
||||||
if (len) {
|
if (len) {
|
||||||
rv = APR_ENOTEMPTY;
|
rv = APR_ENOTEMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (APR_STATUS_IS_EAGAIN(rv)) {
|
|
||||||
rv = APR_SUCCESS;
|
|
||||||
}
|
|
||||||
apr_brigade_cleanup(conn->tmp_bb);
|
apr_brigade_cleanup(conn->tmp_bb);
|
||||||
}
|
}
|
||||||
else if (ap_proxy_is_socket_connected(conn->sock)) {
|
else if (!ap_proxy_is_socket_connected(conn->sock)) {
|
||||||
rv = APR_SUCCESS;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rv = APR_EPIPE;
|
rv = APR_EPIPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv != APR_SUCCESS) {
|
if (rv != APR_SUCCESS && rv != APR_ENOTSOCK) {
|
||||||
/* This clears conn->scpool (and associated data), so backup and
|
/* This clears conn->scpool (and associated data), so backup and
|
||||||
* restore any ssl_hostname for this connection set earlier by
|
* restore any ssl_hostname for this connection set earlier by
|
||||||
* ap_proxy_determine_connection().
|
* ap_proxy_determine_connection().
|
||||||
*/
|
*/
|
||||||
char ssl_hostname[PROXY_WORKER_RFC1035_NAME_SIZE];
|
char ssl_hostname[PROXY_WORKER_RFC1035_NAME_SIZE];
|
||||||
if (!conn->ssl_hostname || PROXY_STRNCPY(ssl_hostname,
|
if (rv == APR_NOTFOUND
|
||||||
conn->ssl_hostname)) {
|
|| !conn->ssl_hostname
|
||||||
|
|| PROXY_STRNCPY(ssl_hostname, conn->ssl_hostname)) {
|
||||||
ssl_hostname[0] = '\0';
|
ssl_hostname[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2761,6 +2767,36 @@ PROXY_DECLARE(apr_status_t) ap_proxy_check_backend(const char *proxy_function,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rv != APR_NOTFOUND) {
|
||||||
|
/*
|
||||||
|
* 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 (rv != APR_SUCCESS && rv != APR_ENOTEMPTY) {
|
||||||
|
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 rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2770,7 +2806,6 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
|
|||||||
server_rec *s)
|
server_rec *s)
|
||||||
{
|
{
|
||||||
apr_status_t rv;
|
apr_status_t rv;
|
||||||
int connected;
|
|
||||||
int loglevel;
|
int loglevel;
|
||||||
apr_sockaddr_t *backend_addr = conn->addr;
|
apr_sockaddr_t *backend_addr = conn->addr;
|
||||||
/* the local address to use for the outgoing connection */
|
/* the local address to use for the outgoing connection */
|
||||||
@@ -2780,9 +2815,12 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
|
|||||||
proxy_server_conf *conf =
|
proxy_server_conf *conf =
|
||||||
(proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
|
(proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
|
||||||
|
|
||||||
connected = (ap_proxy_check_backend(proxy_function, conn,
|
rv = ap_proxy_check_backend(proxy_function, conn, s, 0);
|
||||||
s, 0) == APR_SUCCESS);
|
if (rv == APR_NOTFOUND) {
|
||||||
while ((backend_addr || conn->uds_path) && !connected) {
|
return DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rv != APR_SUCCESS && (backend_addr || conn->uds_path)) {
|
||||||
#if APR_HAVE_SYS_UN_H
|
#if APR_HAVE_SYS_UN_H
|
||||||
if (conn->uds_path)
|
if (conn->uds_path)
|
||||||
{
|
{
|
||||||
@@ -2954,50 +2992,9 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
connected = 1;
|
return rv == APR_SUCCESS ? OK : DECLINED;
|
||||||
}
|
|
||||||
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 {
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static apr_status_t connection_shutdown(void *theconn)
|
static apr_status_t connection_shutdown(void *theconn)
|
||||||
|
Reference in New Issue
Block a user