Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Poor man's reverse proxy: caching using mod_rewrite

I am pretty sure somebody already solved this problem somehow. Long story short I want to cache GET requests to my PHP script. The script saves the content into the file at /cache/{uri}/index.{type}/index.{type}. Headers are set by an .htaccess file in the same directory, e.g. RequestHeader set Content-type "application/json;charset=utf-8".

Here what it looks like:

{webroot}/
    .htaccess
    cache/
        caching/
            test/
                index.json/
                    .htaccess
                    index.json
    index.php

Contents of {webroot}/.htaccess:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /

# Append ".html", if there is no extension...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !\.\w+$
RewriteRule ^(.*?)$ /$1.html [L]

# ...and redirect to cache directory ("/cache")
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*?)\.(\w+)$ /cache/$1/index.$2/index.$2 [L]
</IfModule>

Contents of {webroot}/cache/.htaccess:

<IfModule mod_rewrite.c>
RewriteEngine on

# If no file found, redirect back to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) /index.php?/$1 [L]
</IfModule>

Contents of {webroot}/cache/caching/test/index.json/.htaccess:

<IfModule mod_rewrite.c>
RewriteEngine on

# Cache till 5th May, 2012
RewriteCond %{TIME} >20120518194510
RewriteRule ^(.*) /index.php?/$1 [L]

RequestHeader set Content-type "application/json;charset=utf-8" 
</IfModule>

Now for http://localhost/caching/test.json the cached version is served. However, the problem is that the file is accessible directly via http://localhost/cache/caching/test/index.json/index.json and I cannot figure out how to prevent access to it by either throwing an error page or redirecting to index.php or any other way.

Sage advice is very welcome, because I barely know what I am doing.

share|improve this question

1 Answer 1

up vote 0 down vote accepted

Squash any requests to the cache directory that don't have an environment variable stating that they were properly redirected by the root.

Change your rule in the root .htaccess, to tag all redirecting requests with an environment variable saying that they're allowed internal redirects, instead of direct access:

RewriteRule ^(.*?)\.(\w+)$ /cache/$1/index.$2/index.$2 [L,ENV=FROM_ROOT:1]

The tricky part is that the environment variables get renamed for an internal redirect. So, add something like this to the index.json/.htaccess:

RewriteCond %{ENV:REDIRECT_FROM_ROOT} !1
RewriteRule ^(.*) /index.php?/$1 [L]
share|improve this answer
    
Works like a charm. Thanks! –  chromice Apr 19 '12 at 17:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.