Mala
Mala

Reputation: 14803

.htaccess mod_rewrite: enabling caching via checking if file exists

I am implementing a caching system for dynamically generated images. The script is called via /img/type/param1/param2.png, where multiple types are possible and the number of parameters are variable. The script generates the image and dumps it to disk.

I would like .htaccess rules, which when requesting the image generation script:

  1. checks to see if a cached file exists
  2. if so, mod_rewrite to the cached file
  3. if not, don't do anything so that the script runs

What I have so far is a slightly modified logic:

  1. mod_rewrite to where the cached file would be
  2. check to see if the file exists
  3. if not, mod_rewrite the request back again

If there's a better way to do this, I'd love to hear it. In any case, the relevant part of my .htaccess file:

RewriteRule ^img/(type1|type2)/(.*)$ /images/cache/$1/$2

RewriteCond /^(.*)$ !-f
RewriteRule images/cache/(.*) /img/$1

This doesn't seem to work quite right. To debug it, I inserted the following after the first RewriteRule (the target page just dumps its input):

RewriteRule ^(.*)$ /htaccess.php?url=$1 [END]

As a result, I get:

Array
(
    [url] => /images/cache/a/l/300.png/a/l/300.png
)

I don't understand why $2 contains l/300.png/a/l/300.png instead of just l/300.png.

If I change first RewriteRule to include an [L], I get the expected result. However, I experience the exact same "double-matching" issue on the second RewriteRule which reverts the request back into the non-cache version. However, adding [L] to this second RewriteRule:

RewriteRule ^img/(type1|type2)/(.*)$ /images/cache/$1/$2 [L]

RewriteCond /^(.*)$ !-f
RewriteRule images/cache/(.*) /img/$1 [L]

yields an Internal Server Error.

What am I doing wrong, and how do I fix this issue?

Upvotes: 1

Views: 1742

Answers (1)

Jon Lin
Jon Lin

Reputation: 143856

The first logic that you have is what you want to be doing, that bypasses the possible looping issues. You just need to extract the relevant bits from the %{REQUEST_URI} then backreference them using % references. So for example:

RewriteCond %{REQUEST_URI} ^/img/(.*)$
RewriteCond %{DOCUMENT_ROOT}/images/cache/%1 -f
RewriteRule ^img/(.*)$ /images/cache/$1 [L]

or using the regex patterns that you had:

RewriteCond %{REQUEST_URI} ^/img/(type1|type2)/(.*)$
RewriteCond %{DOCUMENT_ROOT}/images/cache/%1/%2 -f
RewriteRule ^img/(.*)$ /images/cache/$1 [L]

Upvotes: 2

Related Questions