HTTP 狀態程式碼表示錯誤或缺少主機標頭
是否有適合通過 SNI 或 HTTP Host 標頭髮送錯誤主機名(或根本沒有)的客戶端使用的 HTTP 狀態程式碼?
一個較老的問題首先解決了此類請求如何發生以及為什麼發生,以及如何在 Apache 中從技術上處理它們。然而,它沒有解決響應狀態程式碼的選擇。
過去,我實現了一個 HTTP 代理,它會發送狀態碼 502 和一個解釋錯誤消息產生原因的 html 頁面。我使用 502 的理由是,我主要會因為配置錯誤而看到它,這意味著代理無法找到合適的後端。實際上,簡單地看到完全偽造的主機名的頻率要高得多。
是否有另一個更合適且更清晰的狀態程式碼向客戶端表明此 IP 地址上的伺服器無法辨識通過 SNI 和/或 Host 標頭髮送的值?
在通過 SNI 發送的主機名與 HTTP Host 標頭不匹配的情況下,RFC 6066 沒有指定甚至推薦任何特定的 HTTP 錯誤。如果 SNI 主機名不是它為其提供服務的主機名,它確實建議伺服器中止 TLS 握手。從第 3 節開始:
如果伺服器理解 ClientHello 擴展但無法辨識伺服器名稱,則伺服器應該採取以下兩種操作之一:通過發送致命級別的 unrecognized_name(112) 警報中止握手或繼續握手。
由於這種格式錯誤的請求可以通過 TLS 握手並需要在 HTTP 中被拒絕,因此需要一個 HTTP 響應程式碼。在所有存在的那些中,只有一個真正適合這種情況:
400 (Bad Request) 狀態碼表示伺服器不能或不會處理請求,因為某些東西被認為是客戶端錯誤(例如,格式錯誤的請求語法、無效的請求消息幀或欺騙性請求路由)。
事實上,這是 RFC 7230 指定的響應。從第 5.4 節描述 Host 標頭:
伺服器必須以 400(Bad Request)狀態碼響應任何缺少 Host 頭欄位的 HTTP/1.1 請求消息以及包含多個 Host 頭欄位或具有無效欄位值的 Host 頭欄位的任何請求消息.
我強烈建議不要為此使用 502。它的語義表明伺服器端有問題,如果稍後嘗試,請求將成功。