0

How do I force nginx to serve a custom 404 page while responding with a 404 header, without changing the address of the browser so the user can easily retype?

set $allowed 0; #(updated after comments)
error_page  404  /404page.html; #(updated after first answer, forgot to mention)

    location = /authreq.html {
    if ($allowed = 0){
#   return 307 $scheme://$host/404page.html ; #works but should be 404
#   return 404 "shows this message"; #does not redirect when inserting url instead of message
# rewrite ^ /404page.html break; #serves 404page.html and doesn't change browseraddress which is good, but sends a response header 200
# return 404 # invokes error_page directive with header 200 

    }
}

The whole configuration:

server {

    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;
    server_name www.fellowshipmedia.eu;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.php index.html index.htm;
    error_page   404  =  /404page.html;
    set $allowed 0;

    location = /authreq.html {
        if ($allowed = 0){
           # return 307 $scheme://$host/404page.html ; #works but should be 404
           # return 404 "shows this message"; #does not redirect when inserting url instead of message
           return 404; #
           # rewrite ^ /404page.html break; #serves 404page.html and doesn't change browseraddress which is good, but sends a response header 200
        }
    }



}
C.A. Vuyk
  • 632
  • 10
  • 18
  • Do you have multiple if blocks ? How do you set the allowed var ? Post the whole configuration. – Xavier Lucas Oct 25 '14 at 12:58
  • Just added my testsite and the condition always set to 0 as it is in the configuration. – C.A. Vuyk Oct 25 '14 at 13:18
  • Post your whole configuration as requested. – Xavier Lucas Oct 25 '14 at 14:17
  • What's the last if block for ? Also how are you testing it ? With your browser ? Try in a private session with cleaned cache or with `curl` directly because browser caches response headers. – Xavier Lucas Oct 25 '14 at 14:39
  • Last block may be omitted, it removes double slashes. Did you try the testsite and have you noticed it response header is a 200? This doesn't come from my browsers cache. Also tried with private session and cleaned cache. – C.A. Vuyk Oct 25 '14 at 15:00
  • Very strange, at your last comment I tried an other browser that never visited the site to make sure there's no caching. Still responding with 200. I do not know about curl. With httpfox and with chrome developers it shows a response header 200. – C.A. Vuyk Oct 25 '14 at 15:07
  • In fact it was the wrong domain. I get a 302 redirecting to the previous domain I was testing on. `http://www.fellowshipmedia.eu/authreq.html` => `http://www.vuyk.eu/geentoegang.html` – Xavier Lucas Oct 25 '14 at 15:17
  • The nameserver that gives you the response is stale! More than 3 weeks ago I changed the nameservers from a protected environment with this redirect to the current nameserver. Please try with the IP: http://178.62.141.76/authreq.html – C.A. Vuyk Oct 26 '14 at 19:30
  • after testing and finding the solution I removed my testsite and posted the solution. – C.A. Vuyk Apr 05 '15 at 06:49

2 Answers2

2

Wouldn't the error_page directive do this for you you?

For example something like this:

server {
...   
  error_page  404  /404page.html;
...
  location = /authreq.html {
    if ($allowed = 0){
      return 404;
    }
  }
}
thla
  • 36
  • 2
  • Tested this, this gives a header 200... Forgot to mention in the question that the error_page directive was used already. – C.A. Vuyk Oct 25 '14 at 09:30
  • Ok, thanks for the update. This setup seems to work for me(On 1.6.2), though obviously without your custom code. So from a basic level it appears to work, have you tried it without the conditional? – thla Oct 25 '14 at 10:03
  • @C.A.Vuyk I have just tried this configuration on a clean nginx 1.6.2 install. It seems to work fine (Chrome as a test browser), can you provide more of your server configuration block please? – plasmid87 Oct 25 '14 at 10:10
  • There's no custom code, just a few simple testpages, I added them as an update in the question. When trying to reach authreq.html, it should give a 404 header but it keeps giving 200. – C.A. Vuyk Oct 25 '14 at 13:20
  • @thla what response header do you generate in your setup? – C.A. Vuyk Oct 25 '14 at 13:23
2

Simply doing the following will not return a 404 header but a 200:

    server {
...   
  error_page  404  /404page.html;
...
  location = /authreq.html {
    if ($allowed = 0){
      return 404;
    }
  }
}

To invoke a 404 header and serve a custom 404 page without changing the browsers' addressbar address you should add '404' in the error_page directive like so:

    error_page   404  =404  /404page.html;
C.A. Vuyk
  • 632
  • 10
  • 18