Nginx – Redirect Non-Existent Files on HTTPS to HTTP with try_files

nginx

I've searched for the correct way to do this for a while.

On an https server when a non-existent file is requested redirect to the http server and request the same file.

eg.

https:// example.org/some_missing_file.html – redirect -> http:// example.org/some_missing_file.html

https:// example.org/existing_file.html – serve file

https:// example.org/SomeDir/missing_file – redirect -> http:// example.org/SomeDir/missing_file

https:// example.org/SomeMissingDir/ – redirect -> http:// example.org/SomeMissingDir/missing_file

This if based snippet works

listen 443 ssl;

#... more config

if (!-e $request_filename) {
    rewrite ^ http:// example.org$request_uri permanent;
    break;
}

But "if is evil" – http://wiki.nginx.org/IfIsEvil

So this is my attempt at a try_files version – which doesn't work.

   try_files $uri @redirect;

   location @redirect {
           rewrite ^ http:// example.org$request_uri permanent;
           break;
   }

I've tried numerous variations of this; proxy_redirects, return 302's – they fail to redirect or don't work when a file is in a subdir, or don't redirect the root if empty.

Does anyone have a bullet proof try_files based replacement?

(ps. spaces due to link checker not knowing about example.org!)

Best Answer

server {
    listen 443 ssl;

    root /path/to/documents;

    location / {
        try_files $uri @redirect; 
    }

    location @redirect {
        return 301 http://example.org$request_uri;
    }
}