Rewrite "break" directive - a strange behavior

andrea.mandolo nginx-forum at nginx.us
Fri Apr 5 09:38:22 UTC 2013


Hi,

I'd like to report a strange behaviour of REWRITE "break" directives inside
a "location" block, when it is used a SET directive subsequently.

Now, i quote a little example, with a basic Nginx configuration that
simulate the issue.

#####  /etc/nginx/nginx.conf  ##########
worker_processes auto;
pid /var/run/nginx.pid;

events {
        worker_connections 2048;
}
http {
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
		
        upstream media_server {
                server 127.0.0.1:1935; ### Our media server}
        }

	include /etc/nginx/sites-enabled/example.conf;
}
############## END ##########################

Example server block:
#####  /etc/nginx/sites-enabled/example.conf  ##########

server {
	listen 0.0.0.0:80;
	server_name _;

	set $cache_max_age "600";
	set $cache_crossdomain "2";

	location ~* "/crossdomain\.xml$" {
		rewrite ^/pippo/(.*) /$1 break;
		set $cache_max_age "$cache_crossdomain";
		proxy_pass http://media_server;
	}

	add_header Test-Cache-Control "max-age=$cache_max_age";
}
############### END #########################

I expect the response to a request ( performed via WGET for example ) to
"http://localhost/pippo/crossdomain.xml"
contains the HEADER "Test-Cache-Control: max-age=2"

Instead, i get a wrong answer with HEADER  "Test-Cache-Control:
max-age=600",
as if the variable "$cache_max_age" is not re-setted with the new value
"2".

This is a WGET example.
######### START #############################
[root ~]# wget -S -O - http://localhost/pippo/crossdomain.xml
--2013-04-04 09:05:11--  http://localhost/pippo/crossdomain.xml
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Server: nginx/1.2.6
  Date: Thu, 04 Apr 2013 09:05:11 GMT
  Content-Type: text/xml
  Content-Length: 250
  Connection: keep-alive
  Cache-Control: no-cache
  Test-Cache-Control: max-age=600
Length: 250 [text/xml]
Saving to: `STDOUT'

 0% [                                                                       
                                                                            
                 ] 0           --.-K/s              <?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
        <allow-access-from domain="*" />
        <site-control permitted-cross-domain-policies="all"/>
</cross-domain-policy>
100%[=====================================================================================================================================================================>]
250         --.-K/s   in 0s

2013-04-04 09:05:11 (21.1 MB/s) - written to stdout [250/250]
######### END ########################

I tried to move the SET directive before REWRITE "break" and everything
works.
####### START ##########
	location ~* "/crossdomain\.xml$" {
		set $cache_max_age "$cache_crossdomain";
		rewrite ^/pippo/(.*) /$1 break;
		proxy_pass http://media_server;
	}
###### END ###########

Example request, after moving the SET directive ( "Test-Cache-Control:
max-age=2" is NOW correct )
########## START #########################
[root ~]# wget -S -O - http://localhost/pippo/crossdomain.xml
--2013-04-04 09:12:37--  http://localhost/pippo/crossdomain.xml
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Server: nginx/1.2.6
  Date: Thu, 04 Apr 2013 09:12:37 GMT
  Content-Type: text/xml
  Content-Length: 250
  Connection: keep-alive
  Cache-Control: no-cache
  Test-Cache-Control: max-age=2
Length: 250 [text/xml]
Saving to: `STDOUT'

 0% [                                                                       
                                                                            
                 ] 0           --.-K/s              <?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
        <allow-access-from domain="*" />
        <site-control permitted-cross-domain-policies="all"/>
</cross-domain-policy>
100%[=====================================================================================================================================================================>]
250         --.-K/s   in 0s

2013-04-04 09:12:37 (15.9 MB/s) - written to stdout [250/250]
############# END ######################


I searched inside the official documentation:
- REWRITE "break" descriptions say:
-- http://wiki.nginx.org/HttpRewriteModule#rewrite
--- "completes processing of current rewrite directives and non-rewrite
processing continues within the current location block only."
-- http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite
--- "stops processing the current set of ngx_http_rewrite_module
directives."

I haven't found anything that justifies this behaviour.

Maybe, the set directive is considerated an "ngx_http_rewrite_module
directive" ?
or, is this a potential issue ?

Thanks in advance for your support !!

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,238128,238128#msg-238128



More information about the nginx mailing list