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.
This commit is contained in:
parent
e0ce48cd7d
commit
6f4903c804
|
@ -2875,7 +2875,7 @@ ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
|
|||
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 *cf, ngx_http_proxy_loc_conf_t *conf,
|
|||
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 *cf, ngx_http_proxy_loc_conf_t *conf,
|
|||
}
|
||||
|
||||
|
||||
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 *cf, ngx_http_proxy_loc_conf_t *conf,
|
|||
|
||||
#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) {
|
||||
|
|
Loading…
Reference in New Issue