Question

We have a cloud setup like this:

User Request -> Perlbal (SSL unwrapping) -> Squid (Caching) -> Apache -> HTTP Response

We support SSL on some pages, and not on others. Everything beyond the perlbal layer only process requests over unencrypted HTTP since perlbal unwraps the SSL, but it does add an X-Forwarded-Proto header so that the application knows if SSL was used or not.

If a request hits the application (Apache) over HTTP, when that particular page requires SSL it redirects to HTTPS.

When a request for a secure resource reaches our application, and if the application sends Cache-Control: public, squid caches that content correctly. The problem is that if the user then tries to access the HTTP version of that resource once it's cached, squid processes it as a cache HIT and returns the cached resource over HTTP, when in fact we need it to consider it a cache MISS because X-Forwarded-Proto does not match the original request.

How is this done? Our application sends:

Vary: X-Forwarded-Proto,Accept-Encoding

I'm having a hard time finding any articles/documentation on this and this Vary header seems to be what other people suggest, but it is not working. Squid serves the cached content regardless of the X-Forwarded-Proto header indicating SSL or otherwise.

Was it helpful?

Solution

OMFG.

We had this in our .htaccess for historical reasons:

BrowserMatch "MSIE" brokenvary=1
BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
BrowserMatch "Opera" !brokenvary
SetEnvIf brokenvary 1 force-no-vary

Three guesses what happens to the squid cache once an IE 6 user visits our site. Vary header removed. Caching strategy broken.

Screw IE. Removing this was a good move. Everything working now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top