There are two levels of "HTTP": a more abstract, upper, layer with the HTTP semantic (e.g. PUT
resource r1
), and a lower layer where that semantic is encoded. Think of these two as, respectively, the application layer of HTTP, and the network layer of HTTP.
The application layer can be completely unaware of whether the semantic HTTP request PUT r1
has arrived in HTTP/1.1 or HTTP/2 format.
On the other hand, the same semantic, PUT r1
, is encoded differently in HTTP/1.1 (textual) vs HTTP/2 (binary) by the network layer.
The referenced section of the specification should be interpreted in the first sentence as referring to the application layer: "as in HTTP/1.1 header names should compared case insensitively".
This means that if an application is asked "is header ACCEPT
present?", the application should look at the header names in a case insensitive fashion (or be sure that the implementation provides such feature), and return true
if Accept
or accept
is present.
The second sentence should be interpreted as referring to the network layer: a compliant HTTP/2 implementation MUST send the headers over the network lowercase, because that is how HTTP/2 encodes header names to be sent over the wire.
Nothing forbids a compliant HTTP/2 implementation to receive content-length: 128
(lowercase), but then convert this header into Content-Length: 128
when it makes it available to the application - for example for maximum compatibility with HTTP/1.1 where the header has uppercase first letters (for example to be printed on screen).