server_name '_' and custom error_page

Maxim Dounin mdounin at mdounin.ru
Fri Oct 29 15:03:31 MSD 2010


Hello!

On Fri, Oct 29, 2010 at 12:23:20PM +0200, Mark Bekkers wrote:

> Hi,
> 
> This is my first time post, hi everybody.
> 
> The reason of this post is that I found some Nginx behaviour that I
> don't understand.
> I would like to know if it's a bug or not.
> Version: nginx/0.8.52
> 
> I pointed all DNS requests to my Nginx server (using a CNAME wildcard).
> Every none matched server names are handled by the snippit below (a
> fallback server configuration)
> 
> server {
>         # CONFIG
>         server_name _;
> 
>         # SETTINGS
>         listen 80 default;
>         root /var/www/host/default/public;
>     access_log /var/www/home/log/nginx/default.access.log;
> 
>     error_page 404 /error_page/404.html;
>     location /error_page/ {alias /var/www/home/error_page/; allow
> all; internal;}
> 
>     }
> 
> 
> A request to kjhtgfcdh.example.com will be catched by the fallback
> configuration and then serves
> my custom defined 404 because the root directive points to an empy
> directory; thus no file is found.
> 
> This way I can inform clients (with a custom error_page) they are
> accessing the wrong host.
> 
> But this seemed wrong so I changed it to:
> 
> server {
>         # CONFIG
>         server_name _;
> 
>         # SETTINGS
>         listen 80 default;
>     access_log /var/www/home/log/nginx/default.access.log;
> 
>     error_page 404 /error_page/404.html;
>     location /error_page/ {alias /var/www/home/error_page/; allow
> all; internal;}
> 
>     return 404;
> 
>     }
> 
> This is almost the same, but it has no root directive and a return
> directive.
> This seems the way to do it because it skips the need to look for a
> file in the root and returns with a 404
> immediately, but it doesn't serve my custom error_page. It serves
> the nginx internal 404 document.
> 
> So I changed it to:
> 
> server {
>         # CONFIG
>         server_name _;
> 
>         # SETTINGS
>         listen 80 default;
>     access_log /var/www/home/log/nginx/default.access.log;
> 
>     error_page 404 /error_page/404.html;
>     location /error_page/ {alias /var/www/home/error_page/; allow
> all; internal;}
> 
>         location / {
>             return 404;
>         }
> 
>     }
> 
> Again no root directive but the return directive is wrapped in a
> location block and it DOES
> serve my custom error_page.
> 
> My questions:
> Did I found a bug? And if I did; what would be correct behaviour?
> And if I did not; what is the correct behaviour in this context?

Behaviour you see is correct.  By adding

    return 404;

at server{} level you instructed nginx to generate 404 on every 
server rewrite processing.  Server rewrites are processed on every 
internal redirect, including ones generated by error_page.  Thus 
something like this happens:

- ...initial request...
- server rewrites: generate 404
- error_page: redirect 404 to your custom /error_page/404.html 
  (and set flag "we've already done error_page redirection")
- server rewrites: generate 404
- error_page: wow, we've already done error_page redirection and 
  this resulted in another error, return default error page

Maxim Dounin



More information about the nginx mailing list