preventing rewrite loops with "index"
Marcus Clyne
ngx.eugaia at gmail.com
Mon Jan 25 09:58:18 MSK 2010
Hi,
Maxim Dounin wrote:
> Hello!
>
> On Sun, Jan 24, 2010 at 10:45:32PM +0100, Piotr Sikora wrote:
>
>
>>> 2. Note "internal" in location /users/. It means "only visible
>>> for internal redirects", so even user called "users" should be
>>> correctly processed by the first location.
>>>
>> Actually, this isn't true. Any attempt to access internal location
>> results in 404 response.
>>
>> You can verify this with very simple configuration:
>>
>> server {
>> listen 8000;
>> location / { return 500; }
>> location /x { internal; return 500; }
>> }
>>
>> Accessing /x will result in 404 response.
>>
The example is obviously correct, but it doesn't truly explain the
reason for getting the 404 for accessing /users/xxx URLs (even though
the result is almost the same). The reason is to do with the order that
locations are handled, specifically that ^~ locations are handled before
~* and ~ ones, and if they match, then the regex ones aren't tested. If
you try to access the URL /users/xxx, it will therefore match the second
location given by ^~, and return 404 because it's an internal location.
Therefore, trying access anything under a user named 'users' will fail
(though the URL /users on its own is ok, because that will match the
regex location and not the ^~ location).
Using location /users in the original locations will result in an
internal server error, because the regex will be caught before the
/users location each time the URL is checked, creating an infinite loop.
>
> True, I was wrong here. Actually I wasn't sure and that's why I
> used "should". :)
>
>
>> This is a bug and it's somewhere on my TODO list.
>>
>
> Strictly - it's not bug, it's just how internal locations work
> now. But I agree it's a probably good idea to change semantics
> and make them just invisible for external requests.
>
I was under the impression that the way internal requests currently work
was a consciously-chosen decision, and was considered a feature. It's a
useful one IMHO. Surely if you want to make a location fully
'invisible' (i.e. both internally and externally), you can just add the
directive 'return 404;' to the location.
Marcus.
More information about the nginx
mailing list