[PATCH 1 of 5] Fixed proxy_set_header inheritance with proxy_cache (ticket #45)

Maxim Dounin mdounin at mdounin.ru
Fri Nov 11 00:08:01 UTC 2011


# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1320965910 -10800
# Node ID 3a36355f93db9030e7a39427a9e68cc1b6431044
# Parent  bec017127243c9287255589ed25ccf913e0d9a3e
Fixed proxy_set_header inheritance with proxy_cache (ticket #45).

Headers cleared with cache enabled (If-Modified-Since etc.) might be cleared
in unrelated servers/locations without proxy_cache enabled if proxy_cache was
used in some server/location.

Example config which triggered the problem:

    proxy_set_header X-Test "test";
    server { location /1 { proxy_cache name; proxy_pass ... } }
    server { location /2 { proxy_pass ... } }

Another one:

    server {
        proxy_cache name;
        location /1 { proxy_pass ... }
        location /2 { proxy_cache off; proxy_pass ... }
    }

In both cases If-Modified-Since header wasn't sent to backend in location /2.

Fix is to not modify conf->headers_source, but instead merge user-supplied
headers from conf->headers_source and default headers (either cache or not)
into separate headers_merged array.

diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -2875,7 +2875,7 @@ ngx_http_proxy_merge_headers(ngx_conf_t 
     size_t                        size;
     uintptr_t                    *code;
     ngx_uint_t                    i;
-    ngx_array_t                   headers_names;
+    ngx_array_t                   headers_names, headers_merged;
     ngx_keyval_t                 *src, *s, *h;
     ngx_hash_key_t               *hk;
     ngx_hash_init_t               hash;
@@ -2906,6 +2906,12 @@ ngx_http_proxy_merge_headers(ngx_conf_t 
         return NGX_ERROR;
     }
 
+    if (ngx_array_init(&headers_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
     if (conf->headers_source == NULL) {
         conf->headers_source = ngx_array_create(cf->pool, 4,
                                                 sizeof(ngx_keyval_t));
@@ -2925,8 +2931,6 @@ ngx_http_proxy_merge_headers(ngx_conf_t 
     }
 
 
-    src = conf->headers_source->elts;
-
 #if (NGX_HTTP_CACHE)
 
     h = conf->upstream.cache ? ngx_http_proxy_cache_headers:
@@ -2937,31 +2941,41 @@ ngx_http_proxy_merge_headers(ngx_conf_t 
 
 #endif
 
+    src = conf->headers_source->elts;
+    for (i = 0; i < conf->headers_source->nelts; i++) {
+
+        s = ngx_array_push(&headers_merged);
+        if (s == NULL) {
+            return NGX_ERROR;
+        }
+
+        *s = src[i];
+    }
+
     while (h->key.len) {
 
-        for (i = 0; i < conf->headers_source->nelts; i++) {
+        src = headers_merged.elts;
+        for (i = 0; i < headers_merged.nelts; i++) {
             if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
                 goto next;
             }
         }
 
-        s = ngx_array_push(conf->headers_source);
+        s = ngx_array_push(&headers_merged);
         if (s == NULL) {
             return NGX_ERROR;
         }
 
         *s = *h;
 
-        src = conf->headers_source->elts;
-
     next:
 
         h++;
     }
 
 
-    src = conf->headers_source->elts;
-    for (i = 0; i < conf->headers_source->nelts; i++) {
+    src = headers_merged.elts;
+    for (i = 0; i < headers_merged.nelts; i++) {
 
         hk = ngx_array_push(&headers_names);
         if (hk == NULL) {



More information about the nginx-devel mailing list