304 响应未使用 mod_headers 设置 apache 的自定义标头

2023-12-05

<VirtualHost *:80>
    ServerAdmin [email protected]
    DocumentRoot "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs"
    ServerName dev.dom.com
    ServerAlias dev.dom.com
    ErrorLog "logs/dev.dom.com-error.log"
    CustomLog "logs/dev.dom.com-access.log" common
    PassEnv CLUSTER
    Header always set X-Cluster "%{CLUSTER}e"
</VirtualHost>

这是我的配置。我有一个环境变量,它告诉我所在的集群,它作为“X-Cluster”中的标头传递。这对 200 或 404 响应返回良好,但 304 Not Modified 响应永远不会返回标头,即使它返回其他适当的 Apache 标头。

如何在 304 响应期间设置标头?


根据当前的 HTTP 规范,304 Not Modified响应不应返回实体标头(除了一些特定的例外)。引用自RFC 2616 第 10.3.5 节:

如果条件 GET 使用强缓存验证器,则响应不应包含其他实体标头。 否则(即,条件 GET 使用弱验证器),响应不得包含其他实体标头;这可以防止缓存的实体主体和更新的标头之间出现不一致。

不幸的是所有扩展头都是分类为实体标题.

然而,展望未来,在旨在取代 RFC 2616 的 HTTPbis 规范草案中,规则要宽松得多。引用自条件请求规范第 4.1 节:

由于 304 响应的目标是最大限度地减少信息传输 当接收者已经拥有一个或多个缓存表示时, 发送者不应该生成除 上面列出的字段,除非所述元数据的存在是为了 指导缓存更新。

因此,如果您设置的自定义标头不会被分类为表示元数据,那么我希望根据新规则将其视为合法。

也就是说,无论这些规范中写了什么,您仍然必须处理 Apache 可以支持的内容。从我在源代码中看到的情况来看,304 响应中仍然不支持自定义标头。

过滤header的地方是在ap_http_header_filter文件中的函数/modules/http/http_filters.c:

更具体地说,这段代码:

if (r->status == HTTP_NOT_MODIFIED) {
    apr_table_do((int (*)(void *, const char *, const char *)) form_header_field,
                 (void *) &h, r->headers_out,
                 "Connection",
                 "Keep-Alive",
                 "ETag",
                 "Content-Location",
                 "Expires",
                 "Cache-Control",
                 "Vary",
                 "Warning",
                 "WWW-Authenticate",
                 "Proxy-Authenticate",
                 "Set-Cookie",
                 "Set-Cookie2",
                 NULL);
}

当返回“未修改”响应 (304) 时,上面的标头列表是唯一允许通过的标头(除了一些自动生成的标头,例如Date and Server)。据我所知,似乎没有一种简单的方法可以连接到这段代码来改变行为。

最重要的是,目前在 Apache 中这仍然是不可能的。至少有一份错误报告请求对其他标头的支持,但这是专门针对 CORS 标头的。不过,如果幸运的话,这可能会鼓励他们更加开放地支持自定义标头。

但在此之前,我可以建议的唯一解决方案是自己修补服务器。如果您不想从源代码重建,您甚至可以直接修补二进制文件。例如,如果您只需要支持一两个新标头,则可以替换一些您不太可能使用的现有标头(例如设置-Cookie2,无论如何它已经过时了)。

只需在 Apache bin 目录中搜索要替换的标头名称(在 Windows 上,您应该在libhttpd.dll)。然后使用二进制编辑器将空终止字符串替换为新的标头名称(当然,它需要与要替换的标头长度相同或更短)。

我不知道其他操作系统,但我在 Windows 上测试过它,它似乎确实有效。这显然是一个可怕的黑客攻击,但如果你足够绝望,你可能会认为这是一个选择。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

304 响应未使用 mod_headers 设置 apache 的自定义标头 的相关文章

随机推荐