# Rewrite "break" directive - a strange behavior

**URL:** <https://www.ruby-forum.com/t/rewrite-break-directive-a-strange-behavior/227986>\
**Category:** NGINX\
**Created:** [April 5, 2013, 11:38am UTC](https://www.ruby-forum.com/t/rewrite-break-directive-a-strange-behavior/227986 "2013-04-05T11:38:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![andrea.mandolo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f0a364/32.png) [@andrea.mandolo](https://www.ruby-forum.com/u/andrea.mandolo)\
**Post date:** [April 5, 2013, 11:38am UTC](https://www.ruby-forum.com/t/rewrite-break-directive-a-strange-behavior/227986/1 "2013-04-05T11:38:54Z")

</div>

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](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](http://localhost/pippo/crossdomain.xml)  
–2013-04-04 09:05:11-- [http://localhost/pippo/crossdomain.xml](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”?\>

 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](http://localhost/pippo/crossdomain.xml)  
–2013-04-04 09:12:37-- [http://localhost/pippo/crossdomain.xml](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”?\>

 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:  
– [Module ngx\_http\_rewrite\_module](http://wiki.nginx.org/HttpRewriteModule#rewrite)  
— “completes processing of current rewrite directives and non-rewrite  
processing continues within the current location block only.”  
– [Module ngx\_http\_rewrite\_module](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:

> **[Rewrite "break" directive - a strange behavior](https://forum.nginx.org/read.php?2,238128,238128#msg-238128)**
>
> 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...

---

<div class="post-metadata">

**Author:** ![andrea.mandolo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f0a364/32.png) [@andrea.mandolo](https://www.ruby-forum.com/u/andrea.mandolo)\
**Post date:** [April 5, 2013, 11:43am UTC](https://www.ruby-forum.com/t/rewrite-break-directive-a-strange-behavior/227986/2 "2013-04-05T11:43:00Z")

</div>

Sorry, i forgot to post Nginx version and build details.

NGINX\_VERSION=“1.2.6”

##### CONFIGURE command used to build

./configure --conf-path=/etc/nginx/nginx.conf --prefix=/etc/nginx  
–error-log-path=/var/log/nginx/error.log   
–http-client-body-temp-path=/var/lib/nginx/body  
–http-fastcgi-temp-path=/var/lib/nginx/fastcgi   
–http-log-path=/var/log/nginx/access.log  
–http-proxy-temp-path=/var/lib/nginx/proxy   
–http-scgi-temp-path=/var/lib/nginx/scgi  
–http-uwsgi-temp-path=/var/lib/nginx/uwsgi   
–lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid  
–without-mail\_pop3\_module   
–without-mail\_imap\_module --without-mail\_smtp\_module --with-debug  
–with-rtsig\_module --with-file-aio   
–with-http\_realip\_module --with-http\_addition\_module  
–with-http\_sub\_module --with-http\_random\_index\_module   
–with-http\_secure\_link\_module --with-http\_dav\_module  
–with-http\_gzip\_static\_module --with-http\_random\_index\_module   
–add-module=modules/lua-nginx-module   
–add-module=modules/nginx-push-stream-module  
–add-module=modules/chunkin-nginx-module   
–add-module=modules/nginx-upload-progress-module  
–add-module=modules/substitutions4nginx-read-only   
–add-module=modules/echo-nginx-module  
–add-module=modules/ngx\_devel\_kit  
–add-module=modules/headers-more-nginx-module   
–add-module=modules/nginx\_upload\_module-2.2.0  
–with-pcre=modules/pcre-8.32  
–with-zlib=modules/zlib-1.2.7   
–with-http\_ssl\_module --with-openssl=modules/openssl-1.0.1c  
–with-http\_xslt\_module --with-ipv6   
–with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl   
–with-cc-opt=-Wno-error  
####################################################

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

---

<div class="post-metadata">

**Author:** ![andrea.mandolo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f0a364/32.png) [@andrea.mandolo](https://www.ruby-forum.com/u/andrea.mandolo)\
**Post date:** [April 5, 2013, 11:58am UTC](https://www.ruby-forum.com/t/rewrite-break-directive-a-strange-behavior/227986/3 "2013-04-05T11:58:46Z")

</div>

Hello!

On Fri, Apr 05, 2013 at 05:38:22AM -0400, andrea.mandolo wrote:

> 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.

[…]

> ```
> 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](http://localhost/pippo/crossdomain.xml)”  
> contains the HEADER “Test-Cache-Control: max-age=2”

This is wrong expectation. As “rewrite … break” stops  
processing of rewrite module directives, and “set” is the rewrite  
module directive, the

```
set $cache_max_age "$cache_crossdomain";

```

is never executed due to break. The add\_header configured  
uses previously computed value of the $cache\_max\_age variable,  
i.e. “600”.

The confusion likely comes from the fact that rewrite module  
directives are imperative, in contrast to other parts of the nginx  
config, which is declarative.

Reading docs here (in particular, preface and internal  
implementation sections) should be helpfull to understand how it  
works:

> **[Module ngx\_http\_rewrite\_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)**

> 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 expected behviour.

If you want “set …” to be executed, you have two basic options:

1. Don’t use “rewrite … break” but use “break” after rewrite  
module directives, i.e.

2. Just switch order of “rewrite” and “break” directives in your  
config:

[…]

> Maybe, the set directive is considerated an “ngx\_http\_rewrite\_module  
> directive” ?  
> or, is this a potential issue ?

The “set” directive _is_ rewrite module directive.

> **[Module ngx\_http\_rewrite\_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#set)**
>
> The ngx\_http\_rewrite\_module module is used to change request URI using PCRE regular expressions, return redirects, and conditionally select configurations.

–  
Maxim D.

> **[nginx: donation](http://nginx.org/en/donation.html)**

---

<div class="post-metadata">

**Author:** ![andrea.mandolo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f0a364/32.png) [@andrea.mandolo](https://www.ruby-forum.com/u/andrea.mandolo)\
**Post date:** [April 5, 2013, 2:35pm UTC](https://www.ruby-forum.com/t/rewrite-break-directive-a-strange-behavior/227986/4 "2013-04-05T14:35:26Z")

</div>

Thank you very much for the immediate answer !! 🙂

Just reading this documentation  
(“[Module ngx\_http\_rewrite\_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite)”)  
i had the suspect that “set” is a rewrite module`s directive.

But, in this other documentation  
(“[Module ngx\_http\_rewrite\_module](http://wiki.nginx.org/HttpRewriteModule#rewrite)”) i was a little in  
confusion.

The first documentation  
([Module ngx\_http\_rewrite\_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite)) is  
certainly more helpful to understand this behaviour.

Thanks again!

Posted at Nginx Forum:

> **[Re: Rewrite "break" directive - a strange behavior](https://forum.nginx.org/read.php?2,238128,238140#msg-238140)**
>
> 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...
