HTTP/2 的 RFC 中有一个令人困惑的术语,我希望它更清晰。
根据 RFC https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2
就像在HTTP/1.x中一样,标头字段名称是ASCII的字符串。 以不区分大小写的方式进行比较的字符。然而 标头字段名称必须在其之前转换为小写 以 HTTP/2 编码。包含大写标头的请求或响应 字段名称必须被视为格式不正确
这似乎概述了两个相互矛盾的想法
- 标头字段名称在 HTTP/2 中不区分大小写
- 如果接收或发送的字段不是小写的,则请求/响应格式不正确。
如果包含非小写标头的请求或响应无效,如何将其视为不区分大小写?
"HTTP"有两个级别:一个更抽象的上层,具有HTTP语义(例如PUT
资源r1
(,以及对该语义进行编码的较低层。将这两者分别视为HTTP的应用层和HTTP的网络层。
应用层可能完全不知道语义 HTTP 请求PUT r1
是以 HTTP/1.1 还是 HTTP/2 格式到达的。
另一方面,相同的语义PUT r1
在 HTTP/1.1(文本(与 HTTP/2(二进制(中由网络层以不同的方式编码。
规范的引用部分应在第一句话中解释为指代应用层:"如在 HTTP/1.1 中,标头名称应不区分大小写地进行比较"。
这意味着,如果询问应用程序"标头ACCEPT
是否存在?",应用程序应以不区分大小写的方式查看标头名称(或确保实现提供此类功能(,并在存在Accept
或accept
时返回true
。
第二句话应该解释为指网络层:兼容的HTTP/2实现必须通过网络小写发送标头,因为这是HTTP/2编码标头名称的方式。
没有什么禁止兼容的 HTTP/2 实现接收content-length: 128
(小写(,但是当它可供应用程序使用时,将此标头转换为Content-Length: 128
- 例如,为了与 HTTP/1.1 的最大兼容性,其中标头具有大写首字母(例如打印在屏幕上(。
这是一个错误,或者至少是一个不必要的混乱规范。
标头名称必须不区分大小写,但这无关紧要,因为它们仅传输或接收小写。
即在RFC中,"内容长度"是指标题"内容长度"。
RFC 7540 已被 RFC 9113 淘汰,它简单地指出:
构造 HTTP/2 消息时,字段名称必须转换为小写。
https://www.rfc-editor.org/rfc/rfc9113#section-8.2
散文现在使用小写标题名称。