我喜欢mod_header
根据请求是通过 IPV4 还是 IPV6 发送来在 Apache 服务器的 HTTP 响应中添加自定义标头(使用),如下所示:
<If "%{IPV6} == 'on'">
Header always setifempty notice "you are using IPV6, keep up the good work"
</If>
<Else>
<If "%{IPV6} == 'off'">
Header always setifempty notice "expr=it's %{TIME_YEAR} and you're still using IPV4, (snarky comment redacted)"
</If>
<Else>
Header always setifempty notice "????how did you do that????"
</Else>
</Else>
在我决定启用之前,它一直运行良好mod_cache
现在它正在缓存我的自定义标头,这可能会导致不必要的行为,例如将 IPV4 标头传递给 IPV6 访问者,反之亦然。例如,收到 IPV4 请求,缓存响应,然后收到 IPV6 请求,并从缓存中提供响应,但它不会重新检查自定义标头逻辑
我希望保持mod_cache
启用状态,但前提是我能找到一种方法使其与我的自定义标题和平共处。
我的mod_cache
配置:
CacheSocache "shmcb:cache(2147483648)"
CacheEnable socache /
运行 Apache/2.4.52
更新,我还添加了,CacheQuickHandler off
因为我认为这是必要的,尽管它本身并没有完成工作。我认为过滤器链顺序可能需要调整,但我真的不明白如何调整。
答案1
我最终是如何解决这个问题的:
首先,必须关闭 Cache Quick Handler
CacheQuickHandler off
这会将缓存从过滤器链的开头移到结尾
其次,我们需要缓存模块(它只关心请求标头)来区分 IPV4 和 IPV6 连接,因此我们让 Apache 为此添加了一个请求标头:
<If "%{IPV6} == 'on'">
RequestHeader set is-ipv6 "YES"
Header always setifempty notice "(message redacted)"
</If>
<Else>
<If "%{IPV6} == 'off'">
RequestHeader set is-ipv6 "NO"
Header always setifempty notice "(message redacted)"
</If>
<Else>
RequestHeader set is-ipv6 "WTF"
Header always setifempty notice "(message redacted)"
</Else>
</Else>
第三,我们需要告诉代理模块,具有不同is-ipv6
标头的请求应该分别缓存
我已经有一个像这样的 Vary 标头设置:
Header append Vary Accept-Encoding env=!dont-vary
所以我把它改成了这样:
Header append Vary "Accept-Encoding, is-ipv6" env=!dont-vary
这解决了所有已知问题
请注意,这会在一定程度上降低缓存性能,因为相同的 IPV4 和 IPV6 请求必须分别缓存。