I recently set up a rewrite to serve .webp
files in place of .jpg
files whenever possible. It seemed to be working correctly until today we noticed that a newly uploaded .jpg
image was returning a 404
even though the image was present. I did some checking and found that the server was rewriting the .jpg
URL to .webp
, and then getting a 404
because the .webp
hadn't been created yet.
I then moved the rule from vhost_ssl.conf over to .htaccess and did a bunch of tinkering until I found something that worked, then moved that solution back to vhost_ssl.conf. But I still don't understand why the original rewrite sometimes failed. Can anyone review and shed some light on the subject?
Original rewrite:
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
RewriteRule (.+)\.(?:jpe?g|png)$ $1.webp [NC,T=image/webp,E=webp,L]
Final rewrite:
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_URI} (.+)\.(?:jpe?g|png)$
RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
RewriteRule .* %1.webp [NC,T=image/webp,E=webp,L]
The only real difference between the two methods is that in the new method I check if the request URI matches jpeg/png before the rewrite condition that checks if the file exists. I think the new method is less efficient since the rewrite rule matches everything, but at least the condition above filters it, and it's in vhost_ssl.conf which is better than .htaccess.
Some other notes:
- During testing, I changed the original rewrite to a 301 redirect so I could see the file it thought it found. Sure enough, the file was the same as the .jpg file, just with a .webp extension - correct path and all (even though the .webp didn't really exist).
- Also during testing, I tried changing the rewrite condition to
RewriteCond %{DOCUMENT_ROOT}/%1.webp_asdfasdfasf -f
just to verify that it would in fact fail, and it did. So it knew that the completely bogus file didn't exist, but it still thought the .webp file did exist.