Changes with Apache 2.3.11
+ *) mod_proxy_http: Allocate the fake backend request from a child pool
+ of the backend connection, instead of misusing the pool of the frontend
+ request. Fixes a thread safety issue where buckets set aside in the
+ backend connection leak into other threads, and then disappear when
+ the frontend request is cleaned up, in turn causing corrupted buckets
+ to make other threads spin. [Graham Leggett]
+
*) mod_ssl: Change the format of the SSL_{CLIENT,SERVER}_{I,S}_DN variables
to be RFC 2253 compatible, convert non-ASCII characters to UTF8, and
escape other special characters with backslashes. The old format can
char buffer[HUGE_STRING_LEN];
const char *buf;
char keepchar;
- request_rec *rp;
apr_bucket *e;
apr_bucket_brigade *bb, *tmp_bb;
apr_bucket_brigade *pass_bb;
* filter chain
*/
- rp = ap_proxy_make_fake_req(origin, r);
+ backend->r = ap_proxy_make_fake_req(origin, r);
/* In case anyone needs to know, this is a fake request that is really a
* response.
*/
- rp->proxyreq = PROXYREQ_RESPONSE;
+ backend->r->proxyreq = PROXYREQ_RESPONSE;
tmp_bb = apr_brigade_create(p, c->bucket_alloc);
do {
apr_status_t rc;
apr_brigade_cleanup(bb);
- rc = ap_proxygetline(tmp_bb, buffer, sizeof(buffer), rp, 0, &len);
+ rc = ap_proxygetline(tmp_bb, buffer, sizeof(buffer), backend->r, 0, &len);
if (len == 0) {
/* handle one potential stray CRLF */
- rc = ap_proxygetline(tmp_bb, buffer, sizeof(buffer), rp, 0, &len);
+ rc = ap_proxygetline(tmp_bb, buffer, sizeof(buffer), backend->r, 0, &len);
}
if (len <= 0) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r,
"Set-Cookie", NULL);
/* shove the headers direct into r->headers_out */
- ap_proxy_read_headers(r, rp, buffer, sizeof(buffer), origin,
+ ap_proxy_read_headers(r, backend->r, buffer, sizeof(buffer), origin,
&pread_len);
if (r->headers_out == NULL) {
ap_set_content_type(r, apr_pstrdup(p, buf));
}
if (!ap_is_HTTP_INFO(proxy_status)) {
- ap_proxy_pre_http_request(origin, rp);
+ ap_proxy_pre_http_request(origin, backend->r);
}
/* Clear hop-by-hop headers */
if (!r->header_only && /* not HEAD request */
(proxy_status != HTTP_NO_CONTENT) && /* not 204 */
(proxy_status != HTTP_NOT_MODIFIED)) { /* not 304 */
- ap_discard_request_body(rp);
+ ap_discard_request_body(backend->r);
}
return proxy_status;
}
* TE, so that they are preserved accordingly for
* ap_http_filter to know where to end.
*/
- rp->headers_in = apr_table_copy(r->pool, r->headers_out);
+ backend->r->headers_in = apr_table_copy(backend->r->pool, r->headers_out);
/*
* Restore Transfer-Encoding header from response if we saved
* one before and there is none left. We need it for the
* ap_http_filter. See above.
*/
- if (te && !apr_table_get(rp->headers_in, "Transfer-Encoding")) {
- apr_table_add(rp->headers_in, "Transfer-Encoding", te);
+ if (te && !apr_table_get(backend->r->headers_in, "Transfer-Encoding")) {
+ apr_table_add(backend->r->headers_in, "Transfer-Encoding", te);
}
apr_table_unset(r->headers_out,"Transfer-Encoding");
apr_off_t readbytes;
apr_status_t rv;
- rv = ap_get_brigade(rp->input_filters, bb,
+ rv = ap_get_brigade(backend->r->input_filters, bb,
AP_MODE_READBYTES, mode,
conf->io_buffer_size);
PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r)
{
- request_rec *rp = apr_pcalloc(r->pool, sizeof(*r));
+ apr_pool_t *pool;
+
+ apr_pool_create(&pool, c->pool);
+
+ request_rec *rp = apr_pcalloc(pool, sizeof(*r));
- rp->pool = r->pool;
+ rp->pool = pool;
rp->status = HTTP_OK;
- rp->headers_in = apr_table_make(r->pool, 50);
- rp->subprocess_env = apr_table_make(r->pool, 50);
- rp->headers_out = apr_table_make(r->pool, 12);
- rp->err_headers_out = apr_table_make(r->pool, 5);
- rp->notes = apr_table_make(r->pool, 5);
+ rp->headers_in = apr_table_make(pool, 50);
+ rp->subprocess_env = apr_table_make(pool, 50);
+ rp->headers_out = apr_table_make(pool, 12);
+ rp->err_headers_out = apr_table_make(pool, 5);
+ rp->notes = apr_table_make(pool, 5);
rp->server = r->server;
rp->proxyreq = r->proxyreq;
rp->proto_output_filters = c->output_filters;
rp->proto_input_filters = c->input_filters;
- rp->request_config = ap_create_request_config(r->pool);
+ rp->request_config = ap_create_request_config(pool);
proxy_run_create_req(r, rp);
return rp;
return APR_SUCCESS;
}
+ if (conn->r) {
+ apr_pool_destroy(conn->r->pool);
+ conn->r = NULL;
+ }
+
#if APR_HAS_THREADS
/* Sanity check: Did we already return the pooled connection? */
if (conn->inreslist) {