Opened 13 years ago

Closed 13 years ago

Last modified 13 years ago

#45 closed defect (fixed)

Некорректная обработка директив конфига

Reported by: www.google.com/accounts/o8/id?id=AItOawlwT8QHCr6aIRPa7TBcWiTsPv_AUE1MzkM Owned by: Maxim Dounin
Priority: minor Milestone:
Component: other Version: 0.8.x
Keywords: proxy_cache cache if-modified-since if-none-match last-modified etag Cc:
uname -a: Darwin amIMac.local 10.5.0 Darwin Kernel Version 10.5.0: Fri Nov 5 23:19:13 PDT 2010; root:xnu-1504.9.17~1/RELEASE_X86_64 x86_64
nginx -V: configure arguments: --prefix=/opt/local --with-cc-opt='-I/opt/local/include -O2' --with-ld-opt=-L/opt/local/lib --conf-path=/opt/local/etc/nginx/nginx.conf --error-log-path=/opt/local/var/log/nginx/error.log --http-log-path=/opt/local/var/log/nginx/access.log --pid-path=/opt/local/var/run/nginx/nginx.pid --lock-path=/opt/local/var/run/nginx/nginx.lock --http-client-body-temp-path=/opt/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/opt/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/opt/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/opt/local/var/run/nginx/uwsgi_temp

Description

Если в конфиге несколько вирт. хостов, и хотя бы для одного из них включено кэширование (директивой proxy_cache), то при проксировании запросов заголовки, управляющие кэшированием (If-Modified-Since, If-None-Match), не передаются бэкэнду для других хостов (может быть, и локэйшн тоже) даже если те не должны кэшироваться nginx. Попытка ручной установки заголовков приводит к 404 ошибке.

Пример, на котором баг вопроизводится (опускаю не относящиеся к теме настройки):

http {
	proxy_set_header		Host				$host;
	proxy_set_header		X-Real-IP			$remote_addr;
	proxy_set_header		X-Forwarded-For 	$proxy_add_x_forwarded_for;
	proxy_cache_path		/opt/local/var/run/nginx/cache/images levels=1 keys_zone=images:1h max_size=1m;

	server {
		location / {
			proxy_pass		http://apache;
			proxy_cache 		images;
			proxy_cache_valid 	200 301 302 304 1h;
			proxy_hide_header 	"Set-Cookie";
			proxy_ignore_headers "Cache-Control" "Expires";
		}
	}
	server {
		location ~* \.jpg$ {
			proxy_pass		http://apache;
			#backend will never get if-modified-since headers
		}
	}
}

Change History (5)

comment:1 by Maxim Dounin, 13 years ago

Owner: changed from somebody to Maxim Dounin
Status: newassigned

Nice catch, thanks.

comment:2 by Maxim Dounin, 13 years ago

Patch series which fixes this is available for review here:
http://mailman.nginx.org/pipermail/nginx-devel/2011-November/001426.html

comment:3 by Maxim Dounin, 13 years ago

In [4275/nginx]:

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.

comment:4 by Maxim Dounin, 13 years ago

Resolution: fixed
Status: assignedclosed

Committed, thanks.

comment:5 by Maxim Dounin, 13 years ago

In [4359/nginx]:

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).
  1. If-Unmodified-Since, If-Match and If-Range headers were sent to backends if fastcgi_cache was used.
  1. Cache-related headers were sent to backends if there were no fastcgi_param directives and fastcgi_cache was used at server level.
Note: See TracTickets for help on using tickets.