httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Yann Ylavic <ylavic....@gmail.com>
Subject Re: mod_proxy duplicated its headers on next balancer's worker or 100-continue ping retries
Date Fri, 04 Apr 2014 16:44:19 GMT
Here is the patch not polluted by working collisions or gotos :

Index: modules/proxy/mod_proxy_wstunnel.c
===================================================================
--- modules/proxy/mod_proxy_wstunnel.c    (revision 1584652)
+++ modules/proxy/mod_proxy_wstunnel.c    (working copy)
@@ -320,15 +320,26 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p
     apr_socket_t *client_socket = ap_get_conn_socket(c);
     ws_baton_t *baton = apr_pcalloc(r->pool, sizeof(ws_baton_t));
     apr_socket_t *sockets[3] = {NULL, NULL, NULL};
+    apr_table_t *saved_headers_in;
     int status;

     header_brigade = apr_brigade_create(p, backconn->bucket_alloc);

     ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "sending request");

+    /*
+     * Save the original headers in before ap_proxy_create_hdrbrgd() and
+     * restore them after, since it will apply proxy purpose only modifications
+     * (eg. cleanup hop-by-hop headers, add Via or X-Forwarded-*...), whereas
+     * the original headers may be needed later to prepare the correct response
+     * or logging.
+     */
+    saved_headers_in = r->headers_in;
+    r->headers_in = apr_table_copy(r->pool, saved_headers_in);
     rv = ap_proxy_create_hdrbrgd(p, header_brigade, r, conn,
                                  worker, conf, uri, url, server_portstr,
                                  &old_cl_val, &old_te_val);
+    r->headers_in = saved_headers_in;
     if (rv != OK) {
         return rv;
     }
Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c    (revision 1584652)
+++ modules/proxy/mod_proxy_http.c    (working copy)
@@ -717,6 +717,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_r
     apr_off_t bytes;
     int force10, rv;
     conn_rec *origin = p_conn->connection;
+    apr_table_t *saved_headers_in;

     if (apr_table_get(r->subprocess_env, "force-proxy-request-1.0")) {
         if (r->expecting_100) {
@@ -727,11 +728,21 @@ int ap_proxy_http_request(apr_pool_t *p, request_r
         force10 = 0;
     }

+    /*
+     * Save the original headers in here and restore them when leaving, since
+     * we will apply proxy purpose only modifications (eg. cleanup hop-by-hop
+     * headers, add Via or X-Forwarded-* or Expect...), whereas the original
+     * headers may be needed later to prepare the correct response or logging.
+     */
+    saved_headers_in = r->headers_in;
+    r->headers_in = apr_table_copy(r->pool, saved_headers_in);
+
     header_brigade = apr_brigade_create(p, bucket_alloc);
     rv = ap_proxy_create_hdrbrgd(p, header_brigade, r, p_conn,
                                  worker, conf, uri, url, server_portstr,
                                  &old_cl_val, &old_te_val);
     if (rv != OK) {
+        r->headers_in = saved_headers_in;
         return rv;
     }

@@ -775,6 +786,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_r
     if (old_te_val && strcasecmp(old_te_val, "chunked") != 0) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01093)
                       "%s Transfer-Encoding is not supported", old_te_val);
+        r->headers_in = saved_headers_in;
         return HTTP_INTERNAL_SERVER_ERROR;
     }

@@ -808,6 +820,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_r
                           " from %s (%s)",
                           p_conn->addr, p_conn->hostname ?
p_conn->hostname: "",
                           c->client_ip, c->remote_host ? c->remote_host: "");
+            r->headers_in = saved_headers_in;
             return HTTP_BAD_REQUEST;
         }

@@ -830,6 +843,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_r
                           " to %pI (%s) from %s (%s)",
                           p_conn->addr, p_conn->hostname ?
p_conn->hostname: "",
                           c->client_ip, c->remote_host ? c->remote_host: "");
+            r->headers_in = saved_headers_in;
             return HTTP_INTERNAL_SERVER_ERROR;
         }

@@ -963,6 +977,11 @@ skip_body:
         break;
     }

+    /* Restore the original headers in (see comment above),
+     * we won't modify them anymore.
+     */
+    r->headers_in = saved_headers_in;
+
     if (rv != OK) {
         /* apr_status_t value has been logged in lower level method */
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01097)
Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c    (revision 1584652)
+++ modules/proxy/proxy_util.c    (working copy)
@@ -3203,7 +3203,6 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
     char *buf;
     const apr_array_header_t *headers_in_array;
     const apr_table_entry_t *headers_in;
-    apr_table_t *headers_in_copy;
     apr_bucket *e;
     int do_100_continue;
     conn_rec *origin = p_conn->connection;
@@ -3363,21 +3362,10 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
     }

     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
[EOS]

Mime
View raw message