try_files and a nested location regexp

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

try_files and a nested location regexp

vedranf
I could not figure out why try_files in a nested location defined with a
regexp does not work in nginx/1.4.6 under Ubuntu 14.04.  Consider the
following config:

server {
        listen 8080 default_server;
        root /usr/share/nginx/html;
        autoindex on;

        location /x/ {
                alias /test/;
                location ~ ^/x/test {
                        try_files $uri =404;
                }
        }
}

With /test containing publically readable file test.html and directory
test_dir  this does not works as expected. While localhost:/x/ properly
lists directory context of /test and localhost:/x/test_dir/ is reported as
404 not found , nginx also reported as 404 not found localhost:/x/test.html
even if the file exists.

Now, if replace the regexp with a simple prefix so the location reads:

        location /x/ {
                alias /test/;
                location /x/test {
                        try_files $uri =404;
                }
        }

then everything work. That is, both localhost:/x/ and localhost:/x/test.html
are accessible and only localhost:/x/test_dir/ is 404 not found.

So what is wrong with the usage of try_files in the initial regexp-based
location config?

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,254033,254033#msg-254033

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

Sergey Kandaurov
On Oct 16, 2014, at 1:38 PM, igorb <[hidden email]> wrote:
> [...]
> So what is wrong with the usage of try_files in the initial regexp-based
> location config?

That is because a location defined with a regular expression has no fixed
length to make a replacement in try_files, which is what alias do.

--
Sergey Kandaurov

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

vedranf
I tried to add explicit alias to the regexp location:

server {
        listen 8080 default_server;
        root /usr/share/nginx/html;
        autoindex on;

        location /x/ {
                alias /test/;
        }

        location ~ ^/x/(test.*)$ {
                alias /test/$1;
                try_files $uri =404;
        }
}

However that still gives 404 for localhost/x/test.html . Does that mean that
try_files cannot be used at all in a regexp location defined with an alias,
it only works if the location uses the root directive?

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,254033,254035#msg-254035

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

Edho Arief-2
On Thu, Oct 16, 2014 at 8:09 PM, igorb <[hidden email]> wrote:

> I tried to add explicit alias to the regexp location:
>
> server {
>         listen 8080 default_server;
>         root /usr/share/nginx/html;
>         autoindex on;
>
>         location /x/ {
>                 alias /test/;
>         }
>
>         location ~ ^/x/(test.*)$ {
>                 alias /test/$1;
>                 try_files $uri =404;
>         }
> }
>
> However that still gives 404 for localhost/x/test.html . Does that mean that
> try_files cannot be used at all in a regexp location defined with an alias,
> it only works if the location uses the root directive?
>

Why don't just use the alias in try_files?

    try_files /test/$1 =404;

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

vedranf
I tried that, but it still does not work. The following config as before
still gives 404 for localhost/x/test.html :

server {
        listen 8080 default_server;
        root /usr/share/nginx/html;
        autoindex on;

        location /x/ {
                alias /test/;
        }

        location ~ ^/x/(test.*)$ {
                alias /test/$1;
                try_files /test/$1 =404;
        #       try_files $uri =404;
        }
}

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,254033,254037#msg-254037

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

Francis Daly
In reply to this post by vedranf
On Thu, Oct 16, 2014 at 07:09:44AM -0400, igorb wrote:

Hi there,

>         location ~ ^/x/(test.*)$ {
>                 alias /test/$1;
>                 try_files $uri =404;
>         }

> However that still gives 404 for localhost/x/test.html . Does that mean that
> try_files cannot be used at all in a regexp location defined with an alias,
> it only works if the location uses the root directive?

try_files puts its "file" argument after $document_root, and looks for
a file on the filesystem with that combined name.

alias-with-regex sets $document_root to the value given.

So if you want try_files and alias-with-regex, you want something like

  try_files "" =404

But that specific use of try_files is probably not very useful, since
it is mostly the same as having no try_files at all -- I guess it is a
simplified version of what you really want, so it is useful as an example.

        f
--
Francis Daly        [hidden email]

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

Edho Arief-2
In reply to this post by vedranf
On Thu, Oct 16, 2014 at 8:25 PM, igorb <[hidden email]> wrote:

> I tried that, but it still does not work. The following config as before
> still gives 404 for localhost/x/test.html :
>
> server {
>         listen 8080 default_server;
>         root /usr/share/nginx/html;
>         autoindex on;
>
>         location /x/ {
>                 alias /test/;
>         }
>
>         location ~ ^/x/(test.*)$ {
>                 alias /test/$1;
>                 try_files /test/$1 =404;
>         #       try_files $uri =404;
>         }
> }
>

Have you tried removing the alias?

location ~ ^/x/(test.*)$ {
  try_files /test/$1 =404;
}

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

vedranf
In reply to this post by Francis Daly
Thanks, try_files "" =404 works indeed as long as the regexp location block
contains the necessary alias. I.e. the original example modified like in:

server {
  listen 8080 default_server;
  root /usr/share/nginx/html;
  autoindex on;

  location /x/ {
    alias /test/;
    location ~ ^/x/test {
      try_files "" =404;
    }
  }
}

does not work, while the following one with an extra alias works nicely:

server {
  listen 8080 default_server;
  root /usr/share/nginx/html;
  autoindex on;

  location /x/ {
    alias /test/;
    location ~ ^/x/(test.*) {
      alias /test/$1;
      try_files "" =404;
    }
  }
}

P.S.

This is indeed a very simplified config. However, even in this form it is
useful as it reports directories matching ^/x/test as not found even with
autoindex on inherited from the server context.

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,254033,254042#msg-254042

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

vedranf
In reply to this post by Edho Arief-2
That does not work either. What works is try_files "" =404 together with an
explicit alias as Francis Daly described in another post.

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,254033,254043#msg-254043

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

Francis Daly
In reply to this post by vedranf
On Thu, Oct 16, 2014 at 07:55:48AM -0400, igorb wrote:

Hi there,

> Thanks, try_files "" =404 works indeed as long as the regexp location block
> contains the necessary alias.

That sounds correct.

"alias" sets $document_root. try_files concatenates $document_root with
its "file" argument. (It does do more than that; those details might
matter depending on what precisely you want to do.)

So if you want to use try_files, you must make sure that $document_root
and the "file" argument combine to name the file that you want to check
the existence of.

>   location /x/ {
>     alias /test/;
>     location ~ ^/x/test {
>       try_files "" =404;
>     }
>   }

> does not work,

$document_root concatenated with "" is /test/, which is not a file,
so =404 is used.

> This is indeed a very simplified config. However, even in this form it is
> useful as it reports directories matching ^/x/test as not found even with
> autoindex on inherited from the server context.

If you want try_files to look for a directory instead of a file, you
have to configure it to do that.

        f
--
Francis Daly        [hidden email]

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

Edho Arief-2
In reply to this post by vedranf
On Thu, Oct 16, 2014 at 9:03 PM, igorb <[hidden email]> wrote:
> That does not work either. What works is try_files "" =404 together with an
> explicit alias as Francis Daly described in another post.
>

did you put it inside the aliased location block? That'd explain why
it doesn't work (as francis said, $document_root is overridden) unless
you add "root /test;" inside the block.

Seriously though, you better avoid using `alias` at all.

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

vedranf
In reply to this post by Francis Daly
Thanks again for detailed explanation. Now I almost grasped how try_files
works. "Almost" because I still do not see why the following does not work:

server {
listen 8080 default_server;
root /usr/share/nginx/html;
autoindex on;

location /x/ {
alias /test/;
location ~ ^/x/(test.*) {
try_files $1 =404;
}
}
}

For localhost/x/test.html $1 will be test.html. I suppose $document_root
should be /test/ as it was set with the alias in the outer location so
try_files should try to check for existing /test/test.html . However, nginx
still reports 404. Why it is so?

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,254033,254047#msg-254047

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: try_files and a nested location regexp

Francis Daly
On Thu, Oct 16, 2014 at 08:42:26AM -0400, igorb wrote:

Hi there,

> Thanks again for detailed explanation. Now I almost grasped how try_files
> works. "Almost" because I still do not see why the following does not work:

There is a defect which is involved here, and probably interferes:

http://trac.nginx.org/nginx/ticket/97

Anything involving try_files and alias may not do what you expect.

If you can specify what exactly you want, it may be possible to find a
configuration which does that using the current implementation of the
defect. Or it may not be.

You will probably be much happier investigating if you enable the
debug log.

> location /x/ {
> alias /test/;
> location ~ ^/x/(test.*) {
> try_files $1 =404;
> }
> }

> For localhost/x/test.html $1 will be test.html. I suppose $document_root
> should be /test/ as it was set with the alias in the outer location so
> try_files should try to check for existing /test/test.html . However, nginx
> still reports 404. Why it is so?

Can you tell whether the 404 is from the uri argument of try_files,
or the serve-from-filesystem handler?

Look in the debug log and you will see what happens.

Or: what do you see if you change try_files to end in =405?

The rest is "the details of what else try_files and alias do".

(try_files does see /test/test.html, but the serve-from-filesystem
handler does not try to serve that file.)

        f
--
Francis Daly        [hidden email]

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx