Serving default error pages with 'proxy_intercept_errors on'

Hello,

I’m running nginx v1.4.1 on OpenBSD 5.4 and I’d like to use
‘proxy_intercept_errors on’ directive without providing my own error
pages. In other words, instead of forwarding page content from the
backend server, just use the error pages that nginx generates by
default.

This isn’t supported normally, however the following configuration
seems to achieve the desired result (though you have to list the error
codes explicitly):

error_page 403 404 … @error;
location @error { return 444; }

I didn’t actually know what this would do until I tried it. I assume
that when a matching error code is received from the backend server,
nginx closes the proxy connection without reading the body and creates
a new internal request to @error, which is immediately closed without
a response. Thus, there is no body to send to the client, so it falls
back to the default behavior.

The question is whether this behavior is an accident and may change in
a future version, or if it’s an acceptable way of intercepting errors
without providing custom error pages?

  • Max

Hello!

On Fri, Dec 27, 2013 at 03:47:51PM -0500, Maxim K. wrote:

codes explicitly):

error_page 403 404 … @error;
location @error { return 444; }

I didn’t actually know what this would do until I tried it. I assume
that when a matching error code is received from the backend server,
nginx closes the proxy connection without reading the body and creates
a new internal request to @error, which is immediately closed without
a response. Thus, there is no body to send to the client, so it falls
back to the default behavior.

Not really.

What you see works because currently “return <4xx>” doesn’t
override error code previously set, thus for 404 error code
originally returned by a proxied server

location @error { return 4xx; }

is effectively equivalent to

location @error { return 404; }

which is documented to return “status code of the last occurred
error”, see Module ngx_http_core_module.

The question is whether this behavior is an accident and may change in
a future version, or if it’s an acceptable way of intercepting errors
without providing custom error pages?

I wouldn’t recommend relaying on this. Current behaviour of
“return”, which effectively uses previous error code set, is
somewhat questionable, and may change in the future.


Maxim D.
http://nginx.org/

On Sat, Dec 28, 2013 at 7:19 AM, Maxim D. [email protected]
wrote:

default.
nginx closes the proxy connection without reading the body and creates
location @error { return 4xx; }

is effectively equivalent to

location @error { return 404; }

which is documented to return “status code of the last occurred
error”, see Module ngx_http_core_module.

I thought that the original error code is returned because I’m not
using ‘=[response]’ syntax in the error_page directive. You’re saying
that ‘return’ may, at some point in the future, change the original
status code even though I’m not using ‘error_page 403 404 = @error
(with the equal sign)?

Is there any other way of getting nginx to return the default error
pages in this situation?

Hello!

On Sat, Dec 28, 2013 at 09:59:02AM -0500, Maxim K. wrote:

backend server, just use the error pages that nginx generates by
that when a matching error code is received from the backend server,

using ‘=[response]’ syntax in the error_page directive. You’re saying
that ‘return’ may, at some point in the future, change the original
status code even though I’m not using ‘error_page 403 404 = @error
(with the equal sign)?

As already pointed out, the documentation of the error_page
directive says (Module ngx_http_core_module):

: If uri processing leads to an error, the status code of the last
: occurred error is returned to the client.

To illustrate this, consider the following configuration:

 error_page 403 /no.such.file.html;

If at some point 403 error happens, request is redirected to
“/no.such.file.html”. If it exists, the file will be returned to
a client with the 403 status code. But if it doesn’t exists, the
404 error will be generated, and it will be returned to the
client.

Currently, this is not what “return 404” will do - instead, it
will preserve original error code. But the difference with
non-existant static file is obviously wrong.

Is there any other way of getting nginx to return the default error
pages in this situation?

Bulletproof way would be to use “return ” for each
you want to intercept.


Maxim D.
http://nginx.org/