Apache mod_header奇怪的行为

时间:2016-01-31 04:49:41

标签: apache .htaccess http-headers httpresponse mod-headers

############################
# FILES - CACHING: CONTROL #
############################

Header set Cache-Control "max-age=2592000, public"

<FilesMatch "\.(?:bmp|css|cur|gif|ico|jp(?:eg?|g)|js|png|svgz?|tiff?|webp)$">
    Header set Cache-Control "max-age=31536000, public"
</FilesMatch>

<FilesMatch "\.(?:html?|json|php|xml)$">
    Header set Cache-Control "max-age=0, must-revalidate, no-cache, no-store, post-check=0, pre-check=0, private"
</FilesMatch>

<FilesMatch "\.(?:atom|rdf|rss)$">
    Header set Cache-Control "max-age=3600, public"
</FilesMatch>

Header merge Cache-Control "no-transform"

这是我htacces的一个片段,我在其中处理Cache-Control标题。默认情况下,对于所有文件,它都设置为max-age=2592000, public。 在底部,我总是试图附加一个no-transform指令,但它根本不起作用。它......好吧它什么也没做。从未设置no-transform指令。我尝试用merge替换append,没有任何变化。

现在,这是我注意到的。如果我将第三个FilesMatch指令替换为:

<FilesMatch "\.(?:atom|rdf|rss)$">
    Header set Cache-Control "max-age=3600, public"
    Header merge Cache-Control "no-transform"
</FilesMatch>

有效。我网站的每个Feed文件都有no-transform指令。如果我将第一个代码段的最后一行更改为:

<FilesMatch "^.+$">
    Header merge Cache-Control "no-transform"
</FilesMatch>

嗯......它适用于所有文件。只是......为什么?!

我还注意到有关标题的另一个非常奇怪的行为。让我们说我想在连接上强制保持活力。我在htaccess文件中的某处插入了这个:

Header merge Connection "Keep-Alive"

这就是我在回复标题中得到的结果:

Connection: Keep-Alive, Keep-Alive

再次......为什么?!

1 个答案:

答案 0 :(得分:1)

我怀疑(虽然找不到任何支持此文档的文档,因为它不是100%清除此页面:https://httpd.apache.org/docs/2.4/sections.html),FilesMatch指令是在不在FileMatch中的指令之后处理的。

因此即使你这样写:

Header set Cache-Control "max-age=2592000, public"

<FilesMatch "\.(?:atom|rdf|rss)$">
    Header set Cache-Control "max-age=3600, public"
</FilesMatch>

Header merge Cache-Control "no-transform"

Apache像这样处理它:

Header set Cache-Control "max-age=2592000, public"

Header merge Cache-Control "no-transform"

<FilesMatch "\.(?:atom|rdf|rss)$">
    Header set Cache-Control "max-age=3600, public"
</FilesMatch>

这意味着“稍后”设置会覆盖先前的合并。如果您将FilesMatch中的“set”更改为“merge”,您应该会看到它有效,因为它将不再覆盖它。

虽然老实说我觉得这种编写配置的方式很难遵循。由于您将缓存控制头设置为四次,为什么不在四个set指令的每一个中同时设置no-transform?是的,它只是一点点重复,但更清晰,意味着你不会遇到这些订单问题!

您的第二个问题更容易从文档中解释:http://httpd.apache.org/docs/current/mod/mod_headers.html#header

  

合并 ...双引号中的值被视为与其他相同的未引用值不同

因此,如果价值是Keep-Alive并且你添加了“Keep-Alive”,那么你最终会得到“Keep-Alive Keep-Alive”。

顺便说一下,你应该尝试通过设置标题来启用Keep-Alives。虽然这对客户端起作用,但Apache还需要保持连接活动以便客户端连接,而不仅仅是通过设置此标头。因此客户端会认为连接正在保持活动状态,但事实上它并不会因为服务器无论如何都会关闭连接。您需要使用如下所示的配置进行设置(这也将为您设置必要的标题):

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5