我们的云设置如下:
User Request -> Perlbal (SSL unwrapping) -> Squid (Caching) -> Apache -> HTTP Response
我们在某些页面上支持 SSL,但在其他页面上不支持。由于 perlbal 会解开 SSL,因此 perlbal 层以外的所有内容都仅处理未加密 HTTP 上的请求,但它会添加一个X-Forwarded-Proto
标头,以便应用程序知道是否使用了 SSL。
如果请求通过 HTTP 到达应用程序(Apache),当该特定页面需要 SSL 时,它会重定向到 HTTPS。
当对安全资源的请求到达我们的应用程序时,如果应用程序发送Cache-Control: public
,squid 会正确缓存该内容。问题是,如果用户随后尝试访问缓存后的该资源的 HTTP 版本,squid 会将其处理为缓存命中并通过 HTTP 返回缓存的资源,而实际上我们需要将其视为缓存未命中,因为 X-Forwarded-Proto 与原始请求不匹配。
这是怎么做到的?我们的应用程序发送:
Vary: X-Forwarded-Proto,Accept-Encoding
我很难找到有关此问题的任何文章/文档,而这个 Vary 标头似乎是其他人建议的,但它不起作用。无论 X-Forwarded-Proto 标头是否指示 SSL,Squid 都会提供缓存内容。
答案1
天啊。
由于历史原因,我们在 .htaccess 中有这样的内容:
BrowserMatch "MSIE" brokenvary=1
BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
BrowserMatch "Opera" !brokenvary
SetEnvIf brokenvary 1 force-no-vary
猜猜 IE 6 用户访问我们的网站后,squid 缓存会发生什么。Vary 标头被删除。缓存策略被破坏。
去他妈的 IE。删除它是个好主意。现在一切都正常了。