Hello!
On Wed, Mar 13, 2013 at 10:53 AM, Calin Don wrote:
>
> rewrite_by_lua_no_postpone on;
> server {
> set $foo '1';
> rewrite_by_lua 'ngx.var.foo = "2"';
> if ($foo = '1') { return 404; }
> if ($foo = '2') { return 503; }
> }
>
> And if I access an URL it returns 404 instead of 503.
>
The actual running order is like this:
ngx_rewrite's directives used in server blocks run at the "server
rewrite" phase in the Nginx core while rewrite_by_lua used in the
server blocks are just inherited by all the location blocks within the
current server {} and run in the "rewrite" phase.
For more details about Nginx's running phases, please refer to my
Nginx tutorials here:
http://openresty.org/download/agentzh-nginx-tutorials-en.html
So in this code snippet, your directives run in this order:
set $foo '1';
if ($foo = '1') { return 404; }
if ($foo = '2') { return 503; }
rewrite_by_lua 'ngx.var.foo = "2"';
No wonder you're getting 404 instead of 503 because your Lua code
actually runs after your "if" directives.
> If I rewrite the code like this:
>
> rewrite_by_lua_no_postpone on;
> server {
> set $foo '1';
> rewrite_by_lua 'ngx.var.foo = "2"';
>
> location / {
> if ($foo = '1') { return 404; }
> if ($foo = '2') { return 503; }
> }
> }
>
> It returns 503 as expected.
>
Here, your "set" directive used in the outer scope runs in the "server
rewrite" phase while your "if" directives and "rewrite_by_lua" run at
the "rewrite" phase, which is always running after the "server
rewrite" phase (though not directly after).
Because you turn on rewrite_by_lua_no_postpone, then in the "rewrite"
phase, your "rewrite_by_lua" directive always run before *all* the
ngx_rewrite module's directives.
Unlike the set_by_lua directive which is effectively injected into
ngx_rewrite's command sequence behind the scene, the "rewrite_by_lua"
directive cannot mix with ngx_rewrite's directives freely. When you
mix them, rewrite_by_lua always run before all the ngx_rewrite
directives when rewrite_by_lua_no_postpone is on, and after all the
ngx_rewrite directives otherwise.
> Can someone point the proper way of setting a variable from upstream which
> is "usable" (in if/rewrite/return context) at server block level?
>
It is (highly) recommended to stick with pure Lua to do all the
rewrites, internal redirections, and Nginx variable assignments
operations instead of mixing Lua with ngx_rewrite's directives. I
believe almost all the functionalities provided by ngx_rewrite are
implemented in ngx_lua's Lua API. Feel free to prove me wrong ;)
Best regards,
-agentzh