Apache caching based on cookie

apache-2.2mod-cache

I'm trying to put mod_cache in front of my application server to cache "public" requests but not requests from logged-in users. For various reasons using alternate subdomains or paths isn't a viable option for me. I have the basics set up as:

# Expiry and cache-control
SetEnvIf Cookie "NOCACHE" no-cache
Header set Cache-Control "no-cache" env=no-cache
RequestHeader set X-FW-NoCache "on" env=no-cache
ExpiresActive On
ExpiresDefault "access plus 1 days"
#ExpiresByType text/html "now"
CacheEnable disk /
CacheRoot /var/cache/apache
CacheIgnoreHeaders Set-Cookie
#CacheIgnoreCacheControl on
#CacheIgnoreNoLastMod on
RewriteEngine On

# Search Engine Safe URL rewrite
# Redirect Coldfusion requests to index.cfm
# matches /file.mp4 but not /file:name.mp4 (ie; is a real file)
RewriteCond %{REQUEST_FILENAME} !/[^/:]+\.[^/:]{2,5}$
RewriteRule (.*) /index.cfm$1 [PT,L]

So if Apache sees the NOCACHE cookie it will always pass the request to the application server, even if it has it in cache. It mostly works but there's one issue that's causing me some grief.

If you visit the page without the cookie you will get a cached version with a future expiry date. If you then set the cookie and go back to that page the request is not sent because the browser has its own cached copy with a future expiry date.

How do I modify this so the browser always makes a request and the cache sends a 304 or cached copy WITHOUT asking the application server to reprocess it? In other words how do I tell the mem_cache to cache the file but not the client and downstream proxies?

I tried using ExpiresByType text/html "now" but then the cache wont cache it at all – even when CacheIgnoreCacheControl is on.

I also played around with CacheIgnoreNoLastMod but didn't have any luck finding a solution.

Best Answer

Usually you would do this by simply setting Expires = -1 but in this case this disables the caching layer. The CacheIgnoreNoLastMod appears to only ignore the no-cache and no-store headers and not Expires. I would try using the no-cache header like:

Header merge Cache-Control no-cache env=CGI

with the CacheIgnoreNoLastMod (see mod_headers for more details on setting headers). The w3 Headers page is a good resource to understanding HTTP headers. Make sure you understand the cache control headers in particular as this will help you understand what the system is doing and how to get it to do what you want.

For debugging purposes I would start with mod_cache disabled and load pages using Chrome/Firefox to inspect the HTTP headers to ensure you are getting what you want. Make sure to force a page reload when reloading (shift/ctrl reload, I always forget which one).

Related Topic