簡體   English   中英

304響應沒有為mod_headers設置apache的自定義標頭

[英]304 response does not set custom header for apache with mod_headers

<VirtualHost *:80>
    ServerAdmin webmaster@dev.dom.com
    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響應中仍然不支持自定義標頭。

過濾標頭的位置在文件/modules/http/http_filters.cap_http_header_filter函數中:

更具體地說,這段代碼:

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)時,上面的標題列表是唯一允許通過的標題(除了一些自動生成的標題,如DateServer )。 從我所看到的,似乎沒有一種簡單的方法來掛鈎這段代碼來改變行為。

最重要的是,目前在Apache中仍然無法做到這一點。 至少有一個錯誤報告請求支持其他標頭,但這是專門針對CORS標頭的。 但幸運的是,這可能會鼓勵他們更加開放地支持自定義標題。

但在此之前,我建議的唯一解決方案是自己修補服務器。 如果您不想從源代碼重建,您甚至可以直接修補二進制文件。 例如,如果您只需要支持一個或兩個新標頭,則可以替換一些您不太可能使用的現有標頭(例如, Set-Cookie2 ,無論如何都已過時)。

只需在Apache bin目錄中搜索要替換的標題名稱(在Windows上,您應該在libhttpd.dll中找到它們)。 然后使用二進制編輯器將空終止字符串替換為新的標題名稱(當然,它需要與您要替換的標題長度相同或更短)。

我不知道其他操作系統,但我已經在Windows上測試了它,它似乎確實有效。 這顯然是一個可怕的黑客,但如果你非常絕望,你可能會認為這是一個選擇。

Apache明確禁止修改304響應中的響應頭以符合http規范。 此類響應的名稱是“未修改”。 您可以使用Apache的過濾器體系結構,編寫自定義模塊或使用mod_perl來修改此行為,但這很可能是錯誤的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM