Welcome! Log In Create A New Profile

Advanced

Re: Rewrite "break" directive - a strange behavior

Maxim Dounin
April 05, 2013 06:00AM
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.

[...]

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

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:

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.

rewrite ...
set ...
break;

proxy_pass ...

2) Just switch order of "rewrite" and "break" directives in your
config:

set ...
rewrite ... break;

proxy_pass ...

[...]

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

The "set" directive _is_ rewrite module directive.

http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#set

--
Maxim Dounin
http://nginx.org/en/donation.html

_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Subject Author Posted

Rewrite "break" directive - a strange behavior

andrea.mandolo April 05, 2013 05:38AM

Re: Rewrite "break" directive - a strange behavior

andrea.mandolo April 05, 2013 05:42AM

Re: Rewrite "break" directive - a strange behavior

Maxim Dounin April 05, 2013 06:00AM

Re: Rewrite "break" directive - a strange behavior

andrea.mandolo April 05, 2013 08:35AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 108
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready