Understanding alias (used as rewrite)

Hi, I’m confused about the details of “alias” used as
a kind of rewrite (which should be more efficient as
I understand it, as long as its appropriately used).

I found I can do this:

location = /path/number/one.html {
alias /some/other/path/script.php;
include fastcgi.conf;
}

So I was confucsed why this not working:

location ^~ /my-long-prefix-goes-here {
alias /another/different/path/anotherscript.php;
include fastcgi.conf;
}

In other words, alias of exact location match does
a cheap “rewrite” perfectly. But now I want to match
addresses like:

/my-long-prefix-goes-here
/my-long-prefix-goes-herexxx
/my-long-prefix-goes-here/
/my-long-prefix-goes-here/filename

Only the first one works, the others are 404. Is
Nginx adding the tail end of the matched prefix
to the aliased location? I tried to make my alias:

alias /another/different/path/anotehrscript.php?;

so the stuff on the end turns into a query arg which
php can ignore. But that didn’t work.

I also tried to use regex to match the location:

location ~ ^/my-long-prefix-goes-here {

But now NONE of the addresses work - even the
exact match is 404. Why??

I found this was the only way to make it work:

root /another/different/path;
rewrite ^(.*)$ /anotehrscript.php break;

In this situation is rewrite the only solution?

On Mon, Jun 22, 2015 at 7:05 PM, E.B. [email protected] wrote:

I found this was the only way to make it work:

root /another/different/path;
rewrite ^(.*)$ /anotehrscript.php break;

In this situation is rewrite the only solution?

You’re probably looking for this

fastcgi_param SCRIPT_FILENAME /another/different/path/anotehrscript.php;

I found this was the only way to make it work:
fastcgi_param SCRIPT_FILENAME /another/different/path/anotehrscript.php;
Excellent point! Thanks you!
However, what if the alias was NOT to a php file? Is using
rewrite the only solution - alias not able to working? What
is alias doing to cause 404?

On Tue, Jun 23, 2015 at 5:32 AM, E.B. [email protected] wrote:

You’re probably looking for this

fastcgi_param SCRIPT_FILENAME /another/different/path/anotehrscript.php;

Excellent point! Thanks you!
However, what if the alias was NOT to a php file? Is using
rewrite the only solution - alias not able to working? What
is alias doing to cause 404?

This config works for me.

location ~ ^/test {
alias /data/public_html/somefile.php;
include fastcgi.conf;
fastcgi_pass 127.0.0.1:8900;
}

Check what your error log says to find out why it returns 404.

Also the question mark you put will become part of file name php look
for (it’ll look for ‘file.php?’ instead of ‘file.php’.

Thanks for your ongoing helps! I hope someone
can advise further

location ~ ^/test {
alias /data/public_html/somefile.php;

include fastcgi.conf;

fastcgi_pass 127.0.0.1:8900;

}

Yes, I had also got similar to work, but
only for the exact match uri-- the first
in my list of possible uris that must work:

/my-long-prefix-goes-here
/my-long-prefix-goes-herexxx
/my-long-prefix-goes-here/
/my-long-prefix-goes-here/filename

I still get 404 for the last 3. That’s why
I thinking it was adding the end of the original
uri to the alias redirect. but Im not sure.

(I used prefix match not regex match but I
now tried your version with regex and get same
result)

Check what your error log says to find out why it returns 404.

Im not getting anything in my log I dont know
why (access log shows the requested uri but
I cant find the file not found error). I checked
php log too and basic nginx error log. I have a
access and error log set for this domain. Is
that where the file not found error should be going?

Also the question mark you put will become part of file name php look
for (it’ll look for ‘file.php?’ instead of ‘file.php’.

I was using the ? to try and avoid unknown file
lookups because I thought the part of the uri
after the matching location prefix was being
added to the aliased location. I thought I could
pass it as a query string to PHP so I could ignore
it that way.

But you help clarify that it won’t work that way
so I understand partly why I am getting 404, thank
you.

Part of what is not clear is if/when alias will have
the rest of the uri after the match prefix added to
it?? The doc:

http://nginx.org/en/docs/http/ngx_http_core_module.html#alias

says nothing, but it begins to appear to me that if
you end the aliased location with / then it will have
the rest of the original uri added to it, but if you
don’t end the alias with / then it will be taken without
changes.

If that’s not right, can someone explain?

And if that is right, why isn’t it documented (a
simply and imporant key feature should have that
documentde!

On Tue, Jun 23, 2015 at 11:44:33PM -0700, E.B. wrote:

Hi there,

Thanks for your ongoing helps! I hope someone
can advise further

you seem to keep referring to “alias used as rewrite”. I do not know
what you mean by that.

Could you explain?

When you do, it may be that it becomes clear where your mental model of
what “alias” (or maybe “rewrite”) does, breaks down.

“alias” is, as you noted, documented at Module ngx_http_core_module. It is
used to identify a filename that should be used to handle the request.

In short: there are two relevant kinds of location: prefix and
regex. (“exact” is a special case of “prefix”.)

In a prefix location, the starting part of the request that matches the
“location” value is replaced with the “alias” value, and what results
becomes $request_filename. (There is more to it than that, but that
should be enough for now.)

In a regex location, the entire request is replaced with the “alias”
value, and what results becomes $request_filename.

In your example configs, if you replace the “include” line with
something
like

return 200 “location #1: request $request_uri → file
$request_filename\n”;

(change the #1 to something that will identify the location to you each
time), then you can use “curl” to make your various requests and see
the responses.

Does that show you how each configuration was used?

If $request_filename identifies a file that does exist, it will
probably be used; if it identifies a file that does not exist, there
will probably be an error. But it all depends on the configuration that
is not yet shown.

And “rewrite” does something different, documented at
Module ngx_http_rewrite_module; it involves uris, not filenames.

f

Francis D. [email protected]

On Wed, Jun 24, 2015 at 3:44 PM, E.B. [email protected] wrote:

is alias doing to cause 404?

I thinking it was adding the end of the original
uri to the alias redirect. but Im not sure.

you need the regexp-based alias (as in my example).

access and error log set for this domain. Is
it that way.

says nothing, but it begins to appear to me that if
you end the aliased location with / then it will have
the rest of the original uri added to it, but if you
don’t end the alias with / then it will be taken without
changes.

If that’s not right, can someone explain?

it depends on the type of locaton. If it’s regexp-based alias
(location ~ ^/some/(regexp)), the full path is replaced with whatever
in alias params but otherwise the trailing request uri (the one after
path specified in location) will be appended to the alias.

Yes, I had also got similar to work, but
uri to the alias redirect. but Im not sure.

you need the regexp-based alias (as in my example).

Well, in the very next sentence I told you I
already tried your regex version with no luck.

But with some helpful explaining from you
and Francis I understand better and also
found a bug. Next mail for more.

it depends on the type of locaton. If it’s regexp-based alias
(location ~ ^/some/(regexp)), the full path is replaced with whatever
in alias params but otherwise the trailing request uri (the one after
path specified in location) will be appended to the alias.

OK. It wasn’t working that way for me but
I discovered cuz of a config bug. So now
I understand this but WHY ISNT THIS DOCUMENTED?

First big appreciated to you and Edho
for helping!! Especially for things not
documented . :slight_smile:

you seem to keep referring to “alias used as rewrite”. I do not know
what you mean by that.

Could you explain?

Sure I wanted to take a prefix:

/my-long-base-path

and make sure all uris that match
that prefix are served to the same
file.

I got a rewrite to do that perfectly
but I see a lot of talk that rewrites
are what you used in apache and are
slow and not the nginx way of thinking.
and it make sense that because the
target file is fixed that avoiding
the rewrite engine will be faster just
pointing to a static aliased file.

I digress but hearing your opinion on
this is interesting to me.

“alias” is, as you noted, documented at Module ngx_http_core_module. It is
used to identify a filename that should be used to handle the request.

Im still wondering why the critical part
you kindly explaining below is not documented.
Isn’t this basic feature and important info
to know?

In short: there are two relevant kinds of location: prefix and
regex. (“exact” is a special case of “prefix”.)

In a prefix location, the starting part of the request that matches the
“location” value is replaced with the “alias” value, and what results
becomes $request_filename. (There is more to it than that, but that
should be enough for now.)

In a regex location, the entire request is replaced with the “alias”
value, and what results becomes $request_filename.

thanks. might have been causing less trouble
to the mailing list if this was known from the
docs. :slight_smile:

In your example configs, if you replace the “include” line with something
like

return 200 “location #1: request $request_uri → file $request_filename\n”;

this was so helpful it is amazing! removing
all guessworkd! this should be included in
the docs too! i am very thankful to you for this!

(change the #1 to something that will identify the location to you each
time), then you can use “curl” to make your various requests and see
the responses.

Does that show you how each configuration was used?

i discovered in the fastcgi conf file there
was a:
try_files $uri =404

so it overrided the alias and causeding
the problem. i guess this was a security
measure to prevent sneaking around the
filesystem for php requests. is there a
better way to effect same protection?
try_files $request_filename =404???

On Wed, Jun 24, 2015 at 05:19:52PM -0700, E.B. wrote:

Hi there,

Could you explain?

Sure I wanted to take a prefix:

/my-long-base-path

and make sure all uris that match
that prefix are served to the same
file.

For this mail thread, that’s probably fine. But for a general solution,
you’ll want to make sure that you are clear about what “served to the
same file” means.

If it is “serve a file from filesystem”, then alias and/or try_files may
be useful. If it is “send to an upstream such as via fastcgi_pass”,
then alias may not be needed at all.

this is interesting to me.
Generally, if I can avoid rewrite but achieve the same result simply,
that’s what I’d tend to do.

But without knowing what the original rewrite was doing, it was hard to
guess.

“alias” is, as you noted, documented at Module ngx_http_core_module. It is
used to identify a filename that should be used to handle the request.

Im still wondering why the critical part
you kindly explaining below is not documented.
Isn’t this basic feature and important info
to know?

My suspicion is that what is documented is clear enough to the writer;
and no reader had previously pointed out any problems.

(I think that my explanation does follow from the documented words;
but I can see how it may not be immediately obvious. So if the
nginx documentation team is reading: this thread has some suggested
alternate/additional words for the documentation of “alias”.)

i discovered in the fastcgi conf file there
was a:
try_files $uri =404

so it overrided the alias and causeding
the problem.

Yes; “alias” and “try_files” may not work together as you may
immediately
expect.

It doesn’t actually override the alias; but it does do (and fail)
a test that you probably do not want it to do.

(And that try_files line is part of “the configuration that is not yet
shown”. The “include” file could have almost anything in it which would
change the way that the configuration is understood.)

i guess this was a security
measure to prevent sneaking around the
filesystem for php requests.

I confess I’ve never been quite sure of the point of that line.

I can see what it does, and I think that it might be useful in some
limited circumstances which include “…and my php is configured badly
and I won’t change it…”; but I’ve tried to avoid those circumstances.

is there a
better way to effect same protection?

If you can specify what you consider the “same protection” to be,
then maybe.

And kudos for correct use of the verb “to effect” :wink:

try_files $request_filename =404???

That won’t do what you want because of how try_files handles its
not-last
arguments.

Possibly in this one specific case – so not in fastcgi.conf that is
included elsewhere –

try_files “” =404;

would do it. But you know that you are sending SCRIPT_FILENAME (or
whatever your fastcgi server honours) set to one specific filename only,
and you know that the matching file exists. So what is the test doing
that would be bad if it were not done?

Cheers,

f

Francis D. [email protected]

is there a
arguments.

Possibly in this one specific case – so not in fastcgi.conf that is
included elsewhere –

try_files “” =404;

would do it. But you know that you are sending SCRIPT_FILENAME (or
whatever your fastcgi server honours) set to one specific filename only,
and you know that the matching file exists. So what is the test doing
that would be bad if it were not done?

I read more about what the “security protection”
could have been aiming at and I think it was as
you suspect, coverage for bad php config. To answer
your last question, php in some cases could execute
some code hidden in a .gif file if the .php path
didn’t exist (“exmaple.org”)
so the test was trying to verify if test.php exists
or not. I thinking it’s not the best way to protect this.

Thanks for your kind helpful responsing!