3

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.

SpliFF
  • 394
  • 2
  • 7
  • 24

1 Answers1

3

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).

uesp
  • 3,384
  • 1
  • 17
  • 16
  • Thanks. I'm trying experiments along these lines using Cache-Control `no-store` or `must-revalidate` with `CacheIgnoreCacheControl` or `CacheStoreNoStore`. Depending on the combination I get results close to what I want but with a few side effects (for example no-store will always cause a 200 response rather than 304 even if the client would otherwise match the cache). I haven't experimented with CacheIgnoreNoLastMod yet. – SpliFF Apr 29 '11 at 15:07
  • Thanks for the response. I tried various combinations of those headers and manual header tweaks. I got close but I was still getting undesirable side-effects and the complexity was getting too high. In the end I settled for a simpler approach of redirecting logins to subdomains with different cache rules to the main `www` domain. – SpliFF Sep 15 '11 at 23:27