Is this how variable (set $var) inheritance works?

António P. P. Almeida appa at perusio.net
Sat Feb 4 03:22:32 UTC 2012


On 4 Fev 2012 02h53 WET, edho at myconan.net wrote:

> On Sat, Feb 4, 2012 at 8:15 AM, Max <nginxyz at mail.ru> wrote:
>>
>> This feature/bug is especially confusing when you use variables
>> inside root and alias directives, because the nested location
>> blocks will inherit the root and alias contents (unless
>> specifically set), which will have any uninitialized inherited
>> variable names replaced with "", so "/home/$variable/abc/$dir/"
>> would become "/home//abc//".
>>
>
> At least this makes nested location useless for cases like this.
> Instead of one regex with captures (and then use nested location), I
> had to do this instead:
>
> location /~ {
> location ~ ^/~([^/]+)/(.+\.php)$ {
> alias /home/$1/public_html/$2;
> if (!-f $request_filename) { return 404; }
> include fastcgi_params;
> fastcgi_param SCRIPT_FILENAME $request_filename;
> fastcgi_pass 127.0.0.1:9000;
> }
> location ~ ^/~([^/]+)(|/.*)$ {
> alias /home/$1/public_html/$2;
> index index.html;
> }
> }

The thing is that there is a server level rewrite phase and a location
level rewrite phase. And since you can have only *one and only one*
location everything at the location rewrite phase that happens before
a redirect/rewrite gets lost. Why? 

Because you enter a configuration find phase again and after that a
rewrite phase again on the location it was redirected to.

The server level rewrite only happens once in each vhost hence the
values of user variables set there are preserved.

That's my understanding of it, at least.

--- appa



> Or use map (and since it's currently impossible to do non-simple
> regex capture, I had to use two maps):
>
> map $uri $user {
> ~^/~(?P<user1>[^/]+)(|/.*)$ $user1;
> }
> map $uri $file {
> ~^/~[^/]+(?P<file1>|/.*)$ $file1;
> }
> server {
> ...
> location /~ {
> location ~ ^ {
> alias /home/$user/public_html/$file;
> location ~ \.php$ {
> include fastcgi_params;
> fastcgi_param SCRIPT_FILENAME $request_filename;
> fastcgi_pass 127.0.0.1:9000;
> }
> }
> }
> }



More information about the nginx mailing list