Mercurial > hg > nginx
comparison src/http/modules/ngx_http_proxy_module.c @ 4358:94b995c7c614 stable-1.0
Merge of r4275, r4276, r4278, r4279:
Fixes for proxy_set_header, fastcgi/scgi/uwsgi_param inheritance:
*) 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.
*) Fixed proxy_set_header inheritance with proxy_set_body.
*) Separate functions to merge fastcgi/scgi/uwsgi params.
No functional changes.
*) Fixed fastcgi/scgi/uwsgi_param inheritance. The following problems were
fixed:
1. Directive fastcgi_cache affected headers sent to backends in unrelated
servers / locations (see ticket #45).
2. If-Unmodified-Since, If-Match and If-Range headers were sent to
backends if fastcgi_cache was used.
3. Cache-related headers were sent to backends if there were no
fastcgi_param directives and fastcgi_cache was used at server level.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 14 Dec 2011 15:13:25 +0000 |
parents | 88369902edb1 |
children | fd40c9ef750d |
comparison
equal
deleted
inserted
replaced
4357:efd515ace6bb | 4358:94b995c7c614 |
---|---|
1720 ngx_http_proxy_loc_conf_t *prev = parent; | 1720 ngx_http_proxy_loc_conf_t *prev = parent; |
1721 ngx_http_proxy_loc_conf_t *conf = child; | 1721 ngx_http_proxy_loc_conf_t *conf = child; |
1722 | 1722 |
1723 u_char *p; | 1723 u_char *p; |
1724 size_t size; | 1724 size_t size; |
1725 ngx_keyval_t *s; | |
1726 ngx_hash_init_t hash; | 1725 ngx_hash_init_t hash; |
1727 ngx_http_core_loc_conf_t *clcf; | 1726 ngx_http_core_loc_conf_t *clcf; |
1728 ngx_http_proxy_redirect_t *pr; | 1727 ngx_http_proxy_redirect_t *pr; |
1729 ngx_http_script_compile_t sc; | 1728 ngx_http_script_compile_t sc; |
1730 | 1729 |
2065 sc.complete_values = 1; | 2064 sc.complete_values = 1; |
2066 | 2065 |
2067 if (ngx_http_script_compile(&sc) != NGX_OK) { | 2066 if (ngx_http_script_compile(&sc) != NGX_OK) { |
2068 return NGX_CONF_ERROR; | 2067 return NGX_CONF_ERROR; |
2069 } | 2068 } |
2070 | |
2071 if (conf->headers_source == NULL) { | |
2072 conf->headers_source = ngx_array_create(cf->pool, 4, | |
2073 sizeof(ngx_keyval_t)); | |
2074 if (conf->headers_source == NULL) { | |
2075 return NGX_CONF_ERROR; | |
2076 } | |
2077 } | |
2078 | |
2079 s = ngx_array_push(conf->headers_source); | |
2080 if (s == NULL) { | |
2081 return NGX_CONF_ERROR; | |
2082 } | |
2083 | |
2084 ngx_str_set(&s->key, "Content-Length"); | |
2085 ngx_str_set(&s->value, "$proxy_internal_body_length"); | |
2086 } | 2069 } |
2087 | 2070 |
2088 if (ngx_http_proxy_merge_headers(cf, conf, prev) != NGX_OK) { | 2071 if (ngx_http_proxy_merge_headers(cf, conf, prev) != NGX_OK) { |
2089 return NGX_CONF_ERROR; | 2072 return NGX_CONF_ERROR; |
2090 } | 2073 } |
2099 { | 2082 { |
2100 u_char *p; | 2083 u_char *p; |
2101 size_t size; | 2084 size_t size; |
2102 uintptr_t *code; | 2085 uintptr_t *code; |
2103 ngx_uint_t i; | 2086 ngx_uint_t i; |
2104 ngx_array_t headers_names; | 2087 ngx_array_t headers_names, headers_merged; |
2105 ngx_keyval_t *src, *s, *h; | 2088 ngx_keyval_t *src, *s, *h; |
2106 ngx_hash_key_t *hk; | 2089 ngx_hash_key_t *hk; |
2107 ngx_hash_init_t hash; | 2090 ngx_hash_init_t hash; |
2108 ngx_http_script_compile_t sc; | 2091 ngx_http_script_compile_t sc; |
2109 ngx_http_script_copy_code_t *copy; | 2092 ngx_http_script_copy_code_t *copy; |
2115 conf->headers_set_hash = prev->headers_set_hash; | 2098 conf->headers_set_hash = prev->headers_set_hash; |
2116 conf->headers_source = prev->headers_source; | 2099 conf->headers_source = prev->headers_source; |
2117 } | 2100 } |
2118 | 2101 |
2119 if (conf->headers_set_hash.buckets | 2102 if (conf->headers_set_hash.buckets |
2103 && ((conf->body_source.data == NULL) | |
2104 == (prev->body_source.data == NULL)) | |
2120 #if (NGX_HTTP_CACHE) | 2105 #if (NGX_HTTP_CACHE) |
2121 && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) | 2106 && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) |
2122 #endif | 2107 #endif |
2123 ) | 2108 ) |
2124 { | 2109 { |
2130 != NGX_OK) | 2115 != NGX_OK) |
2131 { | 2116 { |
2132 return NGX_ERROR; | 2117 return NGX_ERROR; |
2133 } | 2118 } |
2134 | 2119 |
2120 if (ngx_array_init(&headers_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t)) | |
2121 != NGX_OK) | |
2122 { | |
2123 return NGX_ERROR; | |
2124 } | |
2125 | |
2135 if (conf->headers_source == NULL) { | 2126 if (conf->headers_source == NULL) { |
2136 conf->headers_source = ngx_array_create(cf->pool, 4, | 2127 conf->headers_source = ngx_array_create(cf->pool, 4, |
2137 sizeof(ngx_keyval_t)); | 2128 sizeof(ngx_keyval_t)); |
2138 if (conf->headers_source == NULL) { | 2129 if (conf->headers_source == NULL) { |
2139 return NGX_ERROR; | 2130 return NGX_ERROR; |
2149 if (conf->headers_set == NULL) { | 2140 if (conf->headers_set == NULL) { |
2150 return NGX_ERROR; | 2141 return NGX_ERROR; |
2151 } | 2142 } |
2152 | 2143 |
2153 | 2144 |
2154 src = conf->headers_source->elts; | |
2155 | |
2156 #if (NGX_HTTP_CACHE) | 2145 #if (NGX_HTTP_CACHE) |
2157 | 2146 |
2158 h = conf->upstream.cache ? ngx_http_proxy_cache_headers: | 2147 h = conf->upstream.cache ? ngx_http_proxy_cache_headers: |
2159 ngx_http_proxy_headers; | 2148 ngx_http_proxy_headers; |
2160 #else | 2149 #else |
2161 | 2150 |
2162 h = ngx_http_proxy_headers; | 2151 h = ngx_http_proxy_headers; |
2163 | 2152 |
2164 #endif | 2153 #endif |
2165 | 2154 |
2155 src = conf->headers_source->elts; | |
2156 for (i = 0; i < conf->headers_source->nelts; i++) { | |
2157 | |
2158 s = ngx_array_push(&headers_merged); | |
2159 if (s == NULL) { | |
2160 return NGX_ERROR; | |
2161 } | |
2162 | |
2163 *s = src[i]; | |
2164 } | |
2165 | |
2166 while (h->key.len) { | 2166 while (h->key.len) { |
2167 | 2167 |
2168 for (i = 0; i < conf->headers_source->nelts; i++) { | 2168 src = headers_merged.elts; |
2169 for (i = 0; i < headers_merged.nelts; i++) { | |
2169 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { | 2170 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { |
2170 goto next; | 2171 goto next; |
2171 } | 2172 } |
2172 } | 2173 } |
2173 | 2174 |
2174 s = ngx_array_push(conf->headers_source); | 2175 s = ngx_array_push(&headers_merged); |
2175 if (s == NULL) { | 2176 if (s == NULL) { |
2176 return NGX_ERROR; | 2177 return NGX_ERROR; |
2177 } | 2178 } |
2178 | 2179 |
2179 *s = *h; | 2180 *s = *h; |
2180 | 2181 |
2181 src = conf->headers_source->elts; | |
2182 | |
2183 next: | 2182 next: |
2184 | 2183 |
2185 h++; | 2184 h++; |
2186 } | 2185 } |
2187 | 2186 |
2188 | 2187 if (conf->body_source.data) { |
2189 src = conf->headers_source->elts; | 2188 s = ngx_array_push(&headers_merged); |
2190 for (i = 0; i < conf->headers_source->nelts; i++) { | 2189 if (s == NULL) { |
2190 return NGX_ERROR; | |
2191 } | |
2192 | |
2193 ngx_str_set(&s->key, "Content-Length"); | |
2194 ngx_str_set(&s->value, "$proxy_internal_body_length"); | |
2195 } | |
2196 | |
2197 | |
2198 src = headers_merged.elts; | |
2199 for (i = 0; i < headers_merged.nelts; i++) { | |
2191 | 2200 |
2192 hk = ngx_array_push(&headers_names); | 2201 hk = ngx_array_push(&headers_names); |
2193 if (hk == NULL) { | 2202 if (hk == NULL) { |
2194 return NGX_ERROR; | 2203 return NGX_ERROR; |
2195 } | 2204 } |