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

(-)modules/proxy/proxy_util.c (-17 / +28 lines)
Lines 1351-1365 static apr_status_t connection_cleanup(void *theco Link Here
1351
        conn->r = NULL;
1351
        conn->r = NULL;
1352
    }
1352
    }
1353
1353
1354
    /* Sanity check: Did we already return the pooled connection? */
1355
    if (conn->inreslist) {
1356
        ap_log_perror(APLOG_MARK, APLOG_ERR, 0, conn->pool, APLOGNO(00923)
1357
                      "Pooled connection 0x%pp for worker %s has been"
1358
                      " already returned to the connection pool.", conn,
1359
                      worker->s->name);
1360
        return APR_SUCCESS;
1361
    }
1362
1363
    /* determine if the connection need to be closed */
1354
    /* determine if the connection need to be closed */
1364
    if (conn->close || !worker->s->is_address_reusable || worker->s->disablereuse) {
1355
    if (conn->close || !worker->s->is_address_reusable || worker->s->disablereuse) {
1365
        apr_pool_t *p = conn->pool;
1356
        apr_pool_t *p = conn->pool;
Lines 1371-1376 static apr_status_t connection_cleanup(void *theco Link Here
1371
        apr_pool_tag(conn->scpool, "proxy_conn_scpool");
1362
        apr_pool_tag(conn->scpool, "proxy_conn_scpool");
1372
    }
1363
    }
1373
1364
1365
    /*
1366
     * If the connection was not acquired from the reslist,
1367
     * that's an aside one and it's up to the owner to
1368
     * release it (or let it die with its pool).
1369
     */
1370
    if (conn->inreslist) {
1371
        return APR_SUCCESS;
1372
    }
1373
1374
    if (worker->s->hmax && worker->cp->res) {
1374
    if (worker->s->hmax && worker->cp->res) {
1375
        conn->inreslist = 1;
1375
        conn->inreslist = 1;
1376
        apr_reslist_release(worker->cp->res, (void *)conn);
1376
        apr_reslist_release(worker->cp->res, (void *)conn);
Lines 1426-1439 PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connectio Link Here
1426
    return APR_SUCCESS;
1426
    return APR_SUCCESS;
1427
}
1427
}
1428
1428
1429
/* reslist constructor */
1429
static apr_status_t ap_proxy_conn_create(proxy_conn_rec **pconn,
1430
static apr_status_t connection_constructor(void **resource, void *params,
1430
                                         proxy_worker *worker,
1431
                                           apr_pool_t *pool)
1431
                                         apr_pool_t *pool)
1432
{
1432
{
1433
    apr_pool_t *ctx;
1433
    apr_pool_t *ctx;
1434
    apr_pool_t *scpool;
1434
    apr_pool_t *scpool;
1435
    proxy_conn_rec *conn;
1435
    proxy_conn_rec *conn;
1436
    proxy_worker *worker = (proxy_worker *)params;
1437
1436
1438
    /*
1437
    /*
1439
     * Create the subpool for each connection
1438
     * Create the subpool for each connection
Lines 1452-1467 PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connectio Link Here
1452
    apr_pool_create(&scpool, ctx);
1451
    apr_pool_create(&scpool, ctx);
1453
    apr_pool_tag(scpool, "proxy_conn_scpool");
1452
    apr_pool_tag(scpool, "proxy_conn_scpool");
1454
    conn = apr_pcalloc(ctx, sizeof(proxy_conn_rec));
1453
    conn = apr_pcalloc(ctx, sizeof(proxy_conn_rec));
1455
1454
 
1456
    conn->pool   = ctx;
1455
    conn->pool   = ctx;
1457
    conn->scpool = scpool;
1456
    conn->scpool = scpool;
1458
    conn->worker = worker;
1457
    conn->worker = worker;
1459
    conn->inreslist = 1;
1458
    conn->inreslist = 1;
1460
    *resource = conn;
1461
1459
1460
    *pconn = conn;
1462
    return APR_SUCCESS;
1461
    return APR_SUCCESS;
1463
}
1462
}
1464
1463
1464
/* reslist constructor */
1465
static apr_status_t connection_constructor(void **resource, void *params,
1466
                                           apr_pool_t *pool)
1467
{
1468
    proxy_conn_rec *conn = NULL;
1469
    apr_status_t rv = ap_proxy_conn_create(&conn, params, pool);
1470
    *resource = conn;
1471
    return rv;
1472
}
1473
1465
/* reslist destructor */
1474
/* reslist destructor */
1466
static apr_status_t connection_destructor(void *resource, void *params,
1475
static apr_status_t connection_destructor(void *resource, void *params,
1467
                                          apr_pool_t *pool)
1476
                                          apr_pool_t *pool)
Lines 2031-2038 PROXY_DECLARE(int) ap_proxy_release_connection(con Link Here
2031
                                               server_rec *s)
2040
                                               server_rec *s)
2032
{
2041
{
2033
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00943)
2042
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00943)
2034
                "%s: has released connection for (%s)",
2043
                 "%s: has released %sconnection for (%s)",
2035
                proxy_function, conn->worker->s->hostname);
2044
                 proxy_function, conn->inreslist ? "aside " : "",
2045
                 conn->worker->s->hostname);
2036
    connection_cleanup(conn);
2046
    connection_cleanup(conn);
2037
2047
2038
    return OK;
2048
    return OK;
Lines 3217-3220 void proxy_util_register_hooks(apr_pool_t *p) Link Here
3217
{
3227
{
3218
    APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker);
3228
    APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker);
3219
    APR_REGISTER_OPTIONAL_FN(ap_proxy_clear_connection);
3229
    APR_REGISTER_OPTIONAL_FN(ap_proxy_clear_connection);
3230
    APR_REGISTER_OPTIONAL_FN(ap_proxy_conn_create);
3220
}
3231
}
(-)modules/proxy/mod_proxy_http.c (-2 / +85 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_conn_create() */
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_conn_create_fn)(proxy_conn_rec **pconn,
29
                                      proxy_worker *worker,
30
                                      apr_pool_t *pool) = NULL;
31
32
static int (*ap_proxy_retry_worker_fn)(const char *proxy_function,
33
                                       proxy_worker *worker,
34
                                       server_rec *s) = NULL;
35
27
static apr_status_t ap_proxy_http_cleanup(const char *scheme,
36
static apr_status_t ap_proxy_http_cleanup(const char *scheme,
28
                                          request_rec *r,
37
                                          request_rec *r,
29
                                          proxy_conn_rec *backend);
38
                                          proxy_conn_rec *backend);
Lines 1837-1842 apr_status_t ap_proxy_http_cleanup(const char *sch Link Here
1837
    return OK;
1846
    return OK;
1838
}
1847
}
1839
1848
1849
static int proxy_http_acquire_1for1_connection(const char *proxy_function,
1850
                                               proxy_conn_rec **pconn,
1851
                                               proxy_worker *worker,
1852
                                               request_rec *r)
1853
{
1854
    conn_rec *c = r->connection;
1855
    server_rec *s = r->server;
1856
    proxy_conn_rec *conn;
1857
    apr_status_t rv;
1858
1859
    *pconn = NULL;
1860
1861
    if (!PROXY_WORKER_IS_USABLE(worker)) {
1862
        /* Retry the worker */
1863
        ap_proxy_retry_worker_fn(proxy_function, worker, s);
1864
1865
        if (!PROXY_WORKER_IS_USABLE(worker)) {
1866
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO()
1867
                         "%s: disabled 1for1 connection for (%s)",
1868
                         proxy_function, worker->s->hostname);
1869
            return HTTP_SERVICE_UNAVAILABLE;
1870
        }
1871
    }
1872
1873
    conn = (proxy_conn_rec *)ap_get_module_config(c->conn_config,
1874
                                                  &proxy_http_module);
1875
    if (!conn) {
1876
        rv = ap_proxy_conn_create_fn(&conn, worker, c->pool);
1877
        if (rv != APR_SUCCESS) {
1878
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO()
1879
                         "%s: failed to acquire 1for1 connection for (%s)",
1880
                         proxy_function, worker->s->hostname);
1881
            return HTTP_INTERNAL_SERVER_ERROR;
1882
        }
1883
1884
        ap_set_module_config(c->conn_config, &proxy_http_module, conn);
1885
    }
1886
1887
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO()
1888
                 "%s: has acquired 1for1 connection for (%s)",
1889
                 proxy_function, worker->s->hostname);
1890
    *pconn = conn;
1891
1892
    return OK;
1893
}
1894
1840
/*
1895
/*
1841
 * This handles http:// URLs, and other URLs using a remote proxy over http
1896
 * This handles http:// URLs, and other URLs using a remote proxy over http
1842
 * If proxyhost is NULL, then contact the server directly, otherwise
1897
 * If proxyhost is NULL, then contact the server directly, otherwise
Lines 1902-1910 static int proxy_http_handler(request_rec *r, prox Link Here
1902
1957
1903
1958
1904
    /* create space for state information */
1959
    /* create space for state information */
1905
    if ((status = ap_proxy_acquire_connection(proxy_function, &backend,
1960
    if (apr_table_get(r->subprocess_env, "proxy-1for1-connection")) {
1906
                                              worker, r->server)) != OK)
1961
        status = proxy_http_acquire_1for1_connection(proxy_function, &backend,
1962
                                                     worker, r);
1963
    }
1964
    else {
1965
        status = ap_proxy_acquire_connection(proxy_function, &backend, worker,
1966
                                             r->server);
1967
    }
1968
    if (status != OK) {
1907
        goto cleanup;
1969
        goto cleanup;
1970
    }
1908
1971
1909
1972
1910
    backend->is_ssl = is_ssl;
1973
    backend->is_ssl = is_ssl;
Lines 2034-2039 static int proxy_http_post_config(apr_pool_t *pcon Link Here
2034
        }
2097
        }
2035
    }
2098
    }
2036
2099
2100
    if (!ap_proxy_conn_create_fn) {
2101
        ap_proxy_conn_create_fn =
2102
            APR_RETRIEVE_OPTIONAL_FN(ap_proxy_conn_create);
2103
        if (!ap_proxy_conn_create_fn) {
2104
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO()
2105
                         "mod_proxy must be loaded for mod_proxy_http");
2106
            return !OK;
2107
        }
2108
    }
2109
2110
    if (!ap_proxy_retry_worker_fn) {
2111
        ap_proxy_retry_worker_fn =
2112
            APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker);
2113
        if (!ap_proxy_retry_worker_fn) {
2114
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO()
2115
                         "mod_proxy must be loaded for mod_proxy_http");
2116
            return !OK;
2117
        }
2118
    }
2119
2037
    return OK;
2120
    return OK;
2038
}
2121
}
2039
2122
(-)modules/proxy/proxy_util.h (+6 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 create a proxy connection (aside from the reslist).
45
 */
46
APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_proxy_conn_create,
47
        (proxy_conn_rec **pconn, proxy_worker *worker, apr_pool_t *pool));
48
43
/** @} */
49
/** @} */
44
50
45
#endif /* PROXY_UTIL_H_ */
51
#endif /* PROXY_UTIL_H_ */

Return to bug 39673