Location Alias not working

Francis Daly francis at daoine.org
Sun Aug 28 23:19:11 UTC 2016

On Sun, Aug 28, 2016 at 06:59:45PM +0200, İhsan Doğan wrote:
> On Saturday, 27 Aug 2016 21:50 +0100, Francis Daly wrote:

Hi there,

Edho Arief is correct; what you see is due to the "index" directive and
the subsequent "php" subrequest.

> > What specific test request do you make?
> GET /foo/ with curl:
> $ curl https://foo.bar.com/foo/
> > What file on the filesystem do you want nginx to return?
> UFS (FreeBSD).

My question was unclear.

What is the output you want to get, instead of the 404?

Do you want the content of the file /var/www/foo/index.html? Do you want
the php-processed output of the file /var/www/foo/index.php? Do you want
something else?

> > What does your error.log say about the 404 response?
> 2016/08/28 18:53:32 [error] 22231#0: *11704 open()
> "/usr/local/www/foo.bar.com404" failed (2: No such file or
> directory), client: 2a02:168:9800::50, server: foo.bar.com,
> request: "GET /foo/ HTTP/1.1", host: "foo.bar.com"

That is curious output. I do not understand how your config can lead to
that output.

>         server_name foo.bar.com;
>         root /usr/local/www/foo/bar;
>         index index.php index.html;

>         location / {

>         location ~ ^(.+?\.php)(/.*)?$ {
>                 try_files $1 = 404;

> 	location /foo/ {
> 		alias /var/www/foo/;
> 	}

The request for /foo/ is handled in the last location there. It's a
directory, so the "index" directive is checked, and the file "index.php"
exists, so there is an internal rewrite to /foo/index.php

(If the file index.php did not exist, nginx would check for the existence
of index.html, and then issue an internal rewrite to
/foo/index.html. /foo/index.html would be handled in the /foo/ location,
and would try to send the file /var/www/foo/index.html)

The request /foo/index.php is handled in the "~ php" location, which says
(in this case) "try_files /foo/index.php = 404"; the root directory here
is /usr/local/www/foo/bar

/usr/local/www/foo/bar/foo/index.php does not exist;
/usr/local/www/foo/bar= does not exist, so there is an internal rewrite
to the request 404.

The request 404 is not handled in any of your locations, so it uses the
implicit catch-all and looks for the file /usr/local/www/foo/bar404. Which
does not exist, and the error.log should show that.

A few things can be changed here:

* nginx does not act as you expect as regards the internal rewrite for
a directory-request. I suspect that nginx is not going to change on
that front.

* your "try_files" must end in an argument "=404" if you want it to
raise a 404 error. "= 404" is not the same; it *does* lead to a 404 in
your case, but only after more processing and for a different reason.

* top-level regex locations are usually unwise. One reason is that an
(implicit) internal rewrite may be processed in a location you did
not expect.

To fix things, you will want to decide how each request should be handled;
I suspect that the easiest will be if you start by moving the current
top-level regex locations to within other locations where possible.

Good luck with it,

Francis Daly        francis at daoine.org

More information about the nginx mailing list