2011-05-08 97 views
4
<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响应没有为mod_headers设置apache的自定义头

如何获得头到304响应期间设置?

+0

远投,但你找到了一个解决方案? – juan 2013-07-23 15:43:42

+0

http://stackoverflow.com/questions/17812347/how-to-add-a-custom-header-despite-a-rewriterule-redirecting-to-304 – juan 2013-07-23 15:48:11

回答

1

阿帕奇明确禁止在符合HTTP规范304响应修改所述响应标头。这种类型的响应的名称是“未修改”。您可以使用Apache的过滤器体系结构,通过编写自定义模块或使用mod_perl来修改此行为,但这很可能是错误的。

7

根据目前的HTTP规范,一个304 Not Modified响应不应该返回实体头(除了少数特定的例外)。从section 10.3.5 of RFC 2616报价:

如果有条件的习惯强大的缓存验证,响应不应该包含其他实体头。 否则(即,条件GET使用弱验证器),响应绝不能包含其他实体头;这可以防止缓存的实体和更新的标题之间的不一致。

不幸的是所有的扩展标头是classified as entity headers

然而,展望未来,在旨在取代2616选秀HTTPbis规范,规则更为宽松。从section 4.1 of the Conditional Requests spec引述:

由于304响应的目标是最小化的信息传送 当接收者已经具有一个或多个高速缓存的表示,一个 发送者不应生​​成比 以上除非列出的字段其它表示的元数据所述元数据存在用于指导缓存更新的目的 。

因此,如果您设置的自定义标题不会被归类为表示元数据,那么我希望在新规则下被认为是合法的。

这就是说,无论什么是写在这些规范,你还是要处理一下Apache可以支持。根据我在源代码中看到的,在304响应中仍然不支持自定义标头。

其中头被过滤的地方是在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 ),上述标题的列表是通过(其它让比一些自动生成的标题,如:日期服务器)唯一的。从我所看到的情况来看,似乎并没有一种简单的方法来钩入这些代码来改变行为。

的底线是,这仍然是不可能的Apache在当前时间。至少有one bug report请求支持其他头文件,但这是专门用于CORS头文件的。然而,如果运气好的话,这可能会鼓励他们更加开放地支持自定义标题。

但是,直到出现这种情况,唯一的解决办法,我可以建议是给自己打补丁的服务器。如果你不想从源代码重建,你甚至可以直接修补二进制文件。例如,如果你只需要支持一个或两个新的标题,您可以取代一些你不太可能使用(例如设置-COOKIE2,这是过时反正)现有的头。

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

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

相关问题