From: Jim Jagielski Date: Mon, 12 Jan 2015 13:37:20 +0000 (+0000) Subject: Merge r1588527 from trunk: X-Git-Tag: 2.4.11~36 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e2a133cfb4ddad6107647516e00aa74ca3ccf15;p=apache Merge r1588527 from trunk: mod_proxy: Preserve original request headers even if they differ from the ones to be forwarded to the backend. PR 45387. Submitted by: ylavic Reviewed/backported by: jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1651082 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index a7757b6853..f64a05c617 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,10 @@ Changes with Apache 2.4.11 request headers earlier. Adds "MergeTrailers" directive to restore legacy behavior. [Edward Lu, Yann Ylavic, Joe Orton, Eric Covener] + *) mod_proxy: Preserve original request headers even if they differ + from the ones to be forwarded to the backend. PR 45387. + [Yann Ylavic] + *) mod_ssl: dump SSL IO/state for the write side of the connection(s), like reads (level TRACE4). [Yann Ylavic] diff --git a/STATUS b/STATUS index 4de2e7d181..ee7ab09b71 100644 --- a/STATUS +++ b/STATUS @@ -132,12 +132,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: 2.4.x patch: trunk works (module CHANGES) +1: ylavic, rjung, trawick - * mod_proxy: Preserve original request headers even if they differ - from the ones to be forwarded to the backend. PR 45387. - trunk patch: http://svn.apache.org/r1588527 - 2.4.x patch: trunk works (modulo CHANGES) - +1: ylavic, rjung, covener - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index a0b0650183..98a93dd282 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -749,14 +749,8 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r, if (!r->kept_body && r->main) { /* XXX: Why DON'T sub-requests use keepalives? */ p_conn->close = 1; - if (old_cl_val) { - old_cl_val = NULL; - apr_table_unset(r->headers_in, "Content-Length"); - } - if (old_te_val) { - old_te_val = NULL; - apr_table_unset(r->headers_in, "Transfer-Encoding"); - } + old_cl_val = NULL; + old_te_val = NULL; rb_method = RB_STREAM_CL; e = apr_bucket_eos_create(input_brigade->bucket_alloc); APR_BRIGADE_INSERT_TAIL(input_brigade, e); @@ -782,7 +776,6 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r, "client %s (%s) requested Transfer-Encoding " "chunked body with Content-Length (C-L ignored)", c->client_ip, c->remote_host ? c->remote_host: ""); - apr_table_unset(r->headers_in, "Content-Length"); old_cl_val = NULL; origin->keepalive = AP_CONN_CLOSE; p_conn->close = 1; diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 3e74ec9ce0..9d8265a293 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -3252,7 +3252,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, char *buf; const apr_array_header_t *headers_in_array; const apr_table_entry_t *headers_in; - apr_table_t *headers_in_copy; + apr_table_t *saved_headers_in; apr_bucket *e; int do_100_continue; conn_rec *origin = p_conn->connection; @@ -3324,6 +3324,21 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(header_brigade, e); + /* + * Save the original headers in here and restore them when leaving, since + * we will apply proxy purpose only modifications (eg. clearing hop-by-hop + * headers, add Via or X-Forwarded-* or Expect...), whereas the originals + * will be needed later to prepare the correct response and logging. + * + * Note: We need to take r->pool for apr_table_copy as the key / value + * pairs in r->headers_in have been created out of r->pool and + * p might be (and actually is) a longer living pool. + * This would trigger the bad pool ancestry abort in apr_table_copy if + * apr is compiled with APR_POOL_DEBUG. + */ + saved_headers_in = r->headers_in; + r->headers_in = apr_table_copy(r->pool, saved_headers_in); + /* handle Via */ if (conf->viaopt == via_block) { /* Block all outgoing Via: headers */ @@ -3422,21 +3437,10 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, } proxy_run_fixups(r); - /* - * Make a copy of the headers_in table before clearing the connection - * headers as we need the connection headers later in the http output - * filter to prepare the correct response headers. - * - * Note: We need to take r->pool for apr_table_copy as the key / value - * pairs in r->headers_in have been created out of r->pool and - * p might be (and actually is) a longer living pool. - * This would trigger the bad pool ancestry abort in apr_table_copy if - * apr is compiled with APR_POOL_DEBUG. - */ - headers_in_copy = apr_table_copy(r->pool, r->headers_in); - ap_proxy_clear_connection(r, headers_in_copy); + ap_proxy_clear_connection(r, r->headers_in); + /* send request headers */ - headers_in_array = apr_table_elts(headers_in_copy); + headers_in_array = apr_table_elts(r->headers_in); headers_in = (const apr_table_entry_t *) headers_in_array->elts; for (counter = 0; counter < headers_in_array->nelts; counter++) { if (headers_in[counter].key == NULL @@ -3498,6 +3502,11 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(header_brigade, e); } + + /* Restore the original headers in (see comment above), + * we won't modify them anymore. + */ + r->headers_in = saved_headers_in; return OK; }