Nginx try_files instead of IFs to accomplish conditional logic

David Rahrer asked:

I’m trying to create Nginx vhost configs that will include the equivalent of the Apache htaccess rewrite rules for OpenCart. Here is the orignal:

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

As I understand it, this says that if the request is not a file, and it is not a directory, and does not contain a file with one of the above extensions, then rewrite according to the last line.

Here is what I am currently using in Nginx:

  location / {
    # This try_files directive is used to enable SEO-friendly URLs for OpenCart
    try_files $uri @opencart;

  location @opencart {
    rewrite ^/(.+)$ /index.php?_route_=$1 last;

This seems to work but I’m concerned that the check for those certain files is not there. Nothing I’ve been able to find suggests a way to duplicate that condition without using IFs. I’m also uncertain as to the reason for this part of the conditions, i.e. why those particular files matter.

My questions are:

  1. Is there a way to do this, i.e. write an Nginx equivalent to the condition concerning those file types without using IFs?

  2. Should the first location block of my Nginx example be changed to
    try_files $uri $uri/ @opencart; (adding the $uri/)

Thanks for any help.

My answer:

The purpose of that particular RewriteCond is to prevent requests for nonexistent static files being passed in to OpenCart.

You can do this with another location. For instance (off the top of my head, so it may need tweaking):

location ~ \.(ico|gif|jpg|jpeg|png|js|css)$ {
    try_files $uri =404;

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.