I have a weird scenario with this rewrite rule:
RewriteCond img/$2/$3/$4/$1 -f
RewriteRule ^img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\.\w+)$ img/$2/$3/$4/$1 [L]
The directory structure for this is (simplified):
var/
images/
..
www/
.htaccess
img -> /var/images
In other words, images are stored outside the webroot in a general data-storage area and are linked into the webroot's img
directory via a symbolic link. Image names are hashes. For efficiency, they're stored in a three-level deep directory hierarchy. For example:
0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg
is stored at
images/0a80/8e34/edaa/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg
The rewrite rule simply rewrites the file name into the nested directory structure.
Now, the weird thing is that the RewriteCond
works fine on my local systems but fails on a test server. The Apache debug log explicitly says that the "-f
pattern doesn't match" for this condition. If I simply remove this condition the rewrite rule works fine and the image is served.
What could cause -f
to fail for files which clearly exist?
FollowSymLinks
is allowed. Apache version 2.2.22-6ubuntu2 installed via apt and hardly modified. Works on a local install of Apache 2.2.23 (via homebrew). Couldn't see any significant changes between the two versions that should cause this.
Some more possibly significant details about the actual directory structure:
$ ls -l /var/www/myapp/current
[snip] /var/www/myapp/current -> /var/www/myapp/releases/20130418090750
$ ls -la /var/www/myapp/current/webroot
[snip]
[snip] .htaccess
[snip] img -> /usr/local/var/myapp/images
The Apache webroot is configured as:
DocumentRoot /var/www/myapp/current/webroot
If I write the RewriteCond
as:
RewriteCond /usr/local/var/myapp/images/$2/$3/$4/$1 -f
it works. I would prefer not to hardcode absolute paths though if at all avoidable.
May Apache be confused by the several levels of symlinks?