HTTP/2 区分大小写在 RFC 中看似矛盾

Seeming contradiction in RFC for HTTP/2 case sensitivity

HTTP/2 的 RFC 中有一些令人困惑的术语,我希望更清楚一些。

根据 RFC https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2

Just as in HTTP/1.x, header field names are strings of ASCII characters that are compared in a case-insensitive fashion. However, header field names MUST be converted to lowercase prior to their encoding in HTTP/2. A request or response containing uppercase header field names MUST be treated as malformed

这似乎概括了两个相互矛盾的想法

如果包含non-lowercaseheaders的请求或响应是无效的,怎么会被认为是case-insensitive?

"HTTP" 有两个级别:一个更抽象的上层,具有 HTTP 语义(例如 PUT 资源 r1 ), 以及对该语义进行编码的较低层。把这两者分别看成是HTTP的应用层,和HTTP的网络层。

应用层可以完全不知道语义HTTP请求PUT r1是HTTP/1.1还是HTTP/2格式到达
另一方面,相同的语义 PUT r1 在 HTTP/1.1(文本)和 HTTP/2(二进制)中由网络层编码不同。

规范的引用部分应在第一句中解释为引用应用层:"as in HTTP/1.1 header names should compared case insensitively"。
这意味着如果应用程序被询问 "is header ACCEPT present?",应用程序应该以不区分大小写的方式查看 header 名称(或确保实现提供此类功能),并且 return true 如果存在 Acceptaccept

第二句话应解释为指的是网络层:兼容的 HTTP/2 实现必须通过网络小写发送 header,因为这就是 HTTP/2 编码 header 要通过网络发送的名称。

没有什么可以禁止兼容的 HTTP/2 实现接收 content-length: 128(小写),但是当它对应用程序可用时,然后将此 header 转换为 Content-Length: 128 -例如,为了最大程度地兼容 HTTP/1.1,其中 header 的首字母大写(例如要打印在屏幕上)。