What is Apache's equivalent of Nginx's try_files?

In Nginx there is try_files, a config directive that "checks for the existence of files in order, and returns the first file that is found". I find it very neat to do this

location ~* \.(gif|jpe?g|css|js)$ {
    try_files $uri 404;
}

which is a safe way of directly serving static files, without bothering the web frameworks. How can I do the same thing in Apache?


Solution 1:

I commonly see this done with mod_rewrite:

 RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
 RewriteRule ^/(.*)$ balancer://app_cluster%{REQUEST_URI} [P,QSA,L]

It means "If a file does not exist on the file system, then proxy it through my mod_proxy_balancer cluster." Otherwise, if the file exists on the file system, it is simply served up by Apache relative to the defined DocumentRoot in your virtualhost.

But that's not my favorite way, mostly because it would require a stat system call per request.

With mod_proxy, you can use ProxyPassMatch if you have a new enough version of Apache (see documentation). Such as:

ProxyPassMatch \.(gif|jpe?g|css|js)$ !

Which uses the ! to indicate Apache should not proxy requests matching that regular expression.

If you are using an older version of Apache, you will have the ProxyPass directive available to you, but it only matches URI prefixes (this is my current preferred method):

ProxyPass /images !
ProxyPass /stylesheets !

Of course, if you must do regular expression matching as you mentioned above, then you can simply modify the mod_rewrite rule I posted at the top to negate a match against the %{REQUEST_URI}.

Hope that helps!