preventing rewrite loops with "index"

Dennis J. dennisml at
Sat Jan 23 04:47:12 MSK 2010

On 01/22/2010 04:01 PM, Igor Sysoev wrote:
> On Fri, Jan 22, 2010 at 03:06:47PM +0100, Dennis J. wrote:
>> Hi,
>> So with my first rewrite issue solved I now move closer towards the real
>> configuration and run into a problem with the index directive.
>> My location looks like this:
>> location ~* ^/(([A-Za-z])([A-Za-z0-9])([A-Za-z0-9])[^/]*)(/.*)?$ {
>>       root /web;
>>       set $site_path /users/$2/$3/$4/$1/htdocs;
>>       set $real_uri $5;
>>       rewrite .* $site_path$real_uri break;
>> }
>> When I request "/test/index.html" the location matches and gets properly
>> rewritten into a hashed form "/users/t/e/s/test/index.html". Then the root
>> get prefixed resulting in the path "/web/users/t/e/s/test/index.html" which
>> get correctly delivered by nginx. So far so good.
>> The problem happens when I request "/test/" instead which should deliver
>> the same index.html through the index directive. That doesn't happen though.
>> Looking at the log what seems to happen is that nginx sees that
>> "/web/users/t/e/s/test/" is a directory and issues a new request with the
>> uri "/web/users/t/e/s/test/index.html". This however matches the above
>> location again resulting in another rewrite that ends with a completely
>> broken path and a 404.
>> How can I get that the correct index processing for the first correctly
>> rewritten path without triggering another round of location processing
>> messing things up?
>   location ~* ^/(([A-Za-z])([A-Za-z0-9])([A-Za-z0-9])[^/]*)(/.*)?$ {
>       alias  /web/users/$2/$3/$4/$1/htdocs$5;
>   }

This works as intended, thanks!
When I try to add a referrer check though I run into trouble. Adding the 
following after the alias directive makes nginx return a 404 instead of 

             if ($request_uri ~ zip) {

The log says that nginx cannot find the file "/web/users/////htdocs". When 
I change the ~ into a = then nginx returns index.html correctly.
What I'm trying to get at is something similar to this:

valid_referers none;
if ($request_uri ~* \.(mpg|zip|avi)$) {
   if ($invalid_referer) {
     return 405;

I noticed that nested if's are not possible so I'm not sure how to handle 
such a case where multiple conditions have to be satisfied (name must match 
and $invalid_referer must be set). But right now I'm wondering why changing 
the "=" into "~" above suddenly results in a 404 and the captured variables 
all beeing empty.


More information about the nginx mailing list