Welcome! Log In Create A New Profile

Advanced

allow `error_page 200` to avoid the need for a teapot

Posted by illwieckz 
allow `error_page 200` to avoid the need for a teapot
June 27, 2019 07:01PM
Currently (NGINX 1.10.3), if I do `return 200` and `error_code 200` to branch to some location, I get that error:

```
[emerg] value "200" must be between 300 and 599
```

I made a workaround using a teapot. I'm explaining myself:

In the past we had our website available on both HTTP and HTTPs, and the website domain name was www.unvanquished.net, but we now switched to HTTPs only (with a redirect from HTTP to HTTPs) and switched the domain name to unvanquished.net (with a redirect from www prefix).

But, we have some software out there that fetches http://www.unvanquished.net/?json=get_recent_posts
This page now redirects to https://unvanquished.net/?json=get_recent_posts instead but the bad thing is that the software does not handle redirects so it fails to fetch the data. Basically it's like using curl without -L option.

Since the data is fetched using a GET query on a non-specific location I can't use a location block. I have to use the `if` instruction which is evil according to https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ which says “The only 100% safe things which may be done inside if in a location context are: return ...; rewrite ... last;”.

So, since rewrite was not an option (client does not handle redirects) I had to use return. Since all pages but the one we talk about are redirected with a 301 redirect I had the idea to return the 200 HTTP code and tell NGINX to use a special location block when 200 is raised.

But then I got the “[emerg] value "200" must be between 300 and 599” error. So I used another error code instead, and to be sure to not use an error code that may be raised by the server without having to serve a file, I used the 418 “I'm a teapot” error code. I also used some trick to be sure the client get the 200 code in fine.

This is an abstract of the NGINX configuration file:

```
# Serve the website itself
server {
listen 443 ssl;
listen [::]:443 ssl;

server_name unvanquished.net;

root /path/to/the/website;

index index.php index.html index.htm default.html default.htm;

# more specific configuration
# php-fpm stuff etc.
}

# Redirect HTTP to HTTPs
server {
listen 80;
listen [::]:80;

server_name unvanquished.net;

location / {
rewrite ^(.*)$ https://unvanquished.net$1 permanent;
}
}

# Redirect www.unvanquished.net to unvanquished.net
server {
listen 80;
listen 443 ssl;
listen [::]:80;
listen [::]:443 ssl;

server_name www.unvanquished.net;

location / {
# updater does not support redirect
# but we now redirect HTTP to HTTPs
# and www.server_name to server_name
# by default, so we have to serve
# this content with a teapot
if ($arg_json = get_recent_posts) {
return 418;
}

rewrite ^(.*)$ https://unvanquished.net$1 permanent;
}

error_page 418 =200 @teapot;

location @teapot {
proxy_set_header Host unvanquished.net;
proxy_pass https://localhost:443;
}
}

```

Note that I used a proxy_pass on this NGINX instance as a hack to not have to duplicate the complex configuration the website has (php stuff etc.) but it would have worked if I duplicated the website config instead of that proxy hack.

It's ugly, but it works. Thanks to the =200 syntax the returned error code is 200 even if I use the 418 to branch to that given location. Our software was able to fetch the content even with a 418 error code but I used the =200 syntax to be sure to return 200 and be compliant with HTTP protocol.

Why can't we use 200-299 codes in NGINX? In my case it would have been legit.

Thanks to RFC 2324 I was able to not hijack an error code NGINX would legitimately use, and used a teapot instead.
Re: allow `error_page 200` to avoid the need for a teapot
August 28, 2019 08:59AM
Have you tried internal redirections instead?
You may end up with a custom handler in Javascript for the old www... domain and the legacy use case, but everything else could be using external redirections.

Cheers,
--j.
Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 95
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready