View | Details | Raw Unified | Return to bug 39673
Collapse All | Expand All

(-)modules/proxy/proxy_util.c (-23 / +70 lines)
Lines 1333-1338 static void init_conn_pool(apr_pool_t *p, proxy_wo Link Here
1333
    worker->cp = cp;
1333
    worker->cp = cp;
1334
}
1334
}
1335
1335
1336
static void socket_cleanup(proxy_conn_rec *conn)
1337
{
1338
    conn->sock = NULL;
1339
    conn->connection = NULL;
1340
    apr_pool_clear(conn->scpool);
1341
}
1342
1336
static apr_status_t connection_cleanup(void *theconn)
1343
static apr_status_t connection_cleanup(void *theconn)
1337
{
1344
{
1338
    proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
1345
    proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
Lines 1351-1362 static apr_status_t connection_cleanup(void *theco Link Here
1351
        conn->r = NULL;
1358
        conn->r = NULL;
1352
    }
1359
    }
1353
1360
1354
    /* Sanity check: Did we already return the pooled connection? */
1361
    /* If the connection was not acquired from the reslist, it was from the
1362
     * optional function ap_proxy_acquire_connection_ex (1for1 connection),
1363
     * so it will be closed/freed with the client's connection pool.
1364
     *
1365
     * <sigh>
1366
     * The flag 'inreslist' has been hijacked (to preserve the 2.4.x API), it
1367
     * was originally used here to check a double-release of the connection,
1368
     * being unset when acquired and set when released (below).
1369
     *
1370
     * The check was broken (per se) since nothing can help when the same
1371
     * connection is released twice, the reslist might have destroy it the
1372
     * first time or else given it to another thread before the second time,
1373
     * it could also work sometimes...
1374
     *
1375
     * The flag is now misnamed, but still set/unset in the same place, so its
1376
     * value really is 0 here when the connection comes from the reslist (and
1377
     * should be put back there) and 1 when it comes from an optional call to
1378
     * ap_proxy_acquire_connection_ex (and must not hit the reslist now), hence
1379
     * the test below is misleading but valid...
1380
     * </sigh>
1381
     */
1355
    if (conn->inreslist) {
1382
    if (conn->inreslist) {
1356
        ap_log_perror(APLOG_MARK, APLOG_ERR, 0, conn->pool, APLOGNO(00923)
1383
        if (conn->close) {
1357
                      "Pooled connection 0x%pp for worker %s has been"
1384
            socket_cleanup(conn);
1358
                      " already returned to the connection pool.", conn,
1385
        }
1359
                      worker->s->name);
1360
        return APR_SUCCESS;
1386
        return APR_SUCCESS;
1361
    }
1387
    }
1362
1388
Lines 1384-1396 static apr_status_t connection_cleanup(void *theco Link Here
1384
    return APR_SUCCESS;
1410
    return APR_SUCCESS;
1385
}
1411
}
1386
1412
1387
static void socket_cleanup(proxy_conn_rec *conn)
1388
{
1389
    conn->sock = NULL;
1390
    conn->connection = NULL;
1391
    apr_pool_clear(conn->scpool);
1392
}
1393
1394
PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn,
1413
PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn,
1395
                                                            request_rec *r)
1414
                                                            request_rec *r)
1396
{
1415
{
Lines 1975-1987 PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr Link Here
1975
    return connected ? 0 : 1;
1994
    return connected ? 0 : 1;
1976
}
1995
}
1977
1996
1978
PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
1997
static int ap_proxy_acquire_connection_ex(const char *proxy_function,
1979
                                               proxy_conn_rec **conn,
1998
                                          proxy_conn_rec **conn,
1980
                                               proxy_worker *worker,
1999
                                          proxy_worker *worker,
1981
                                               server_rec *s)
2000
                                          server_rec *s,
2001
                                          conn_rec *c)
1982
{
2002
{
1983
    apr_status_t rv;
2003
    apr_status_t rv;
2004
    int one4one = 0;
1984
2005
2006
    *conn = NULL;
2007
1985
    if (!PROXY_WORKER_IS_USABLE(worker)) {
2008
    if (!PROXY_WORKER_IS_USABLE(worker)) {
1986
        /* Retry the worker */
2009
        /* Retry the worker */
1987
        ap_proxy_retry_worker(proxy_function, worker, s);
2010
        ap_proxy_retry_worker(proxy_function, worker, s);
Lines 1994-1999 PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr Link Here
1994
        }
2017
        }
1995
    }
2018
    }
1996
2019
2020
    if (c && worker->s->is_address_reusable && !worker->s->disablereuse) {
2021
        *conn = (proxy_conn_rec *)ap_get_module_config(c->conn_config,
2022
                                                       &proxy_module);
2023
        if (!*conn) {
2024
            connection_constructor((void **)conn, worker, c->pool);
2025
            ap_set_module_config(c->conn_config, &proxy_module, *conn);
2026
        }
2027
        rv = APR_SUCCESS;
2028
        one4one = 1;
2029
    }
2030
    else
1997
    if (worker->s->hmax && worker->cp->res) {
2031
    if (worker->s->hmax && worker->cp->res) {
1998
        rv = apr_reslist_acquire(worker->cp->res, (void **)conn);
2032
        rv = apr_reslist_acquire(worker->cp->res, (void **)conn);
1999
    }
2033
    }
Lines 2011-2038 PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr Link Here
2011
2045
2012
    if (rv != APR_SUCCESS) {
2046
    if (rv != APR_SUCCESS) {
2013
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00941)
2047
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00941)
2014
                     "%s: failed to acquire connection for (%s)",
2048
                     "%s: failed to acquire %sconnection for (%s)",
2015
                     proxy_function, worker->s->hostname);
2049
                     proxy_function, one4one ? "1for1 " : "",
2050
                     worker->s->hostname);
2016
        return HTTP_SERVICE_UNAVAILABLE;
2051
        return HTTP_SERVICE_UNAVAILABLE;
2017
    }
2052
    }
2018
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00942)
2053
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00942)
2019
                 "%s: has acquired connection for (%s)",
2054
                 "%s: has acquired %sconnection for (%s)",
2020
                 proxy_function, worker->s->hostname);
2055
                 proxy_function, one4one ? "1for1 " : "",
2056
                 worker->s->hostname);
2021
2057
2022
    (*conn)->worker = worker;
2058
    (*conn)->worker = worker;
2023
    (*conn)->close  = 0;
2059
    (*conn)->close  = 0;
2024
    (*conn)->inreslist = 0;
2060
    (*conn)->inreslist = one4one;
2025
2061
2026
    return OK;
2062
    return OK;
2027
}
2063
}
2028
2064
2065
PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
2066
                                               proxy_conn_rec **conn,
2067
                                               proxy_worker *worker,
2068
                                               server_rec *s)
2069
{
2070
    return ap_proxy_acquire_connection_ex(proxy_function, conn, worker, s,
2071
                                          NULL);
2072
}
2073
2029
PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,
2074
PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,
2030
                                               proxy_conn_rec *conn,
2075
                                               proxy_conn_rec *conn,
2031
                                               server_rec *s)
2076
                                               server_rec *s)
2032
{
2077
{
2033
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00943)
2078
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00943)
2034
                "%s: has released connection for (%s)",
2079
                 "%s: has released %sconnection for (%s)",
2035
                proxy_function, conn->worker->s->hostname);
2080
                 proxy_function, conn->inreslist ? "1for1 " : "",
2081
                 conn->worker->s->hostname);
2036
    connection_cleanup(conn);
2082
    connection_cleanup(conn);
2037
2083
2038
    return OK;
2084
    return OK;
Lines 3217-3220 void proxy_util_register_hooks(apr_pool_t *p) Link Here
3217
{
3263
{
3218
    APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker);
3264
    APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker);
3219
    APR_REGISTER_OPTIONAL_FN(ap_proxy_clear_connection);
3265
    APR_REGISTER_OPTIONAL_FN(ap_proxy_clear_connection);
3266
    APR_REGISTER_OPTIONAL_FN(ap_proxy_acquire_connection_ex);
3220
}
3267
}
(-)modules/proxy/mod_proxy_http.c (-2 / +28 lines)
Lines 17-22 Link Here
17
/* HTTP routines for Apache proxy */
17
/* HTTP routines for Apache proxy */
18
18
19
#include "mod_proxy.h"
19
#include "mod_proxy.h"
20
#include "proxy_util.h" /* ap_proxy_acquire_connection_ex() */
20
#include "ap_regex.h"
21
#include "ap_regex.h"
21
22
22
module AP_MODULE_DECLARE_DATA proxy_http_module;
23
module AP_MODULE_DECLARE_DATA proxy_http_module;
Lines 24-29 module AP_MODULE_DECLARE_DATA proxy_http_module; Link Here
24
static int (*ap_proxy_clear_connection_fn)(request_rec *r, apr_table_t *headers) =
25
static int (*ap_proxy_clear_connection_fn)(request_rec *r, apr_table_t *headers) =
25
        NULL;
26
        NULL;
26
27
28
static int (*ap_proxy_acquire_connection_ex_fn)(const char *proxy_function,
29
                                                proxy_conn_rec **conn,
30
                                                proxy_worker *worker,
31
                                                server_rec *s,
32
                                                conn_rec *c)
33
                                                = NULL;
34
27
static apr_status_t ap_proxy_http_cleanup(const char *scheme,
35
static apr_status_t ap_proxy_http_cleanup(const char *scheme,
28
                                          request_rec *r,
36
                                          request_rec *r,
29
                                          proxy_conn_rec *backend);
37
                                          proxy_conn_rec *backend);
Lines 1902-1910 static int proxy_http_handler(request_rec *r, prox Link Here
1902
1910
1903
1911
1904
    /* create space for state information */
1912
    /* create space for state information */
1905
    if ((status = ap_proxy_acquire_connection(proxy_function, &backend,
1913
    if (apr_table_get(r->subprocess_env, "proxy-1for1-connection")) {
1906
                                              worker, r->server)) != OK)
1914
        status = ap_proxy_acquire_connection_ex_fn(proxy_function, &backend,
1915
                                                   worker, r->server, c);
1916
    }
1917
    else {
1918
        status = ap_proxy_acquire_connection(proxy_function, &backend,
1919
                                             worker, r->server);
1920
    }
1921
    if (status != OK) {
1907
        goto cleanup;
1922
        goto cleanup;
1923
    }
1908
1924
1909
1925
1910
    backend->is_ssl = is_ssl;
1926
    backend->is_ssl = is_ssl;
Lines 2034-2039 static int proxy_http_post_config(apr_pool_t *pcon Link Here
2034
        }
2050
        }
2035
    }
2051
    }
2036
2052
2053
    if (!ap_proxy_acquire_connection_ex_fn) {
2054
        ap_proxy_acquire_connection_ex_fn =
2055
            APR_RETRIEVE_OPTIONAL_FN(ap_proxy_acquire_connection_ex);
2056
        if (!ap_proxy_acquire_connection_ex_fn) {
2057
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO()
2058
                         "mod_proxy must be loaded for mod_proxy_http");
2059
            return !OK;
2060
        }
2061
    }
2062
2037
    return OK;
2063
    return OK;
2038
}
2064
}
2039
2065
(-)modules/proxy/proxy_util.h (+8 lines)
Lines 40-45 PROXY_DECLARE_DATA extern const apr_strmatch_patte Link Here
40
 */
40
 */
41
void proxy_util_register_hooks(apr_pool_t *p);
41
void proxy_util_register_hooks(apr_pool_t *p);
42
42
43
/**
44
 * Optional function to acquire a backend connection attached to the client's one
45
 * when c is not NULL, otherwise it is ap_proxy_acquire_connection.
46
 */
47
APR_DECLARE_OPTIONAL_FN(int, ap_proxy_acquire_connection_ex,
48
		(const char *proxy_function, proxy_conn_rec **conn,
49
		 proxy_worker *worker, server_rec *s, conn_rec *c));
50
43
/** @} */
51
/** @} */
44
52
45
#endif /* PROXY_UTIL_H_ */
53
#endif /* PROXY_UTIL_H_ */

Return to bug 39673