web: make HTTP field names case-insensitive (#32364)

I'm opening this PR to (hopefully!) stimulate a discussion. In brief,
I'd like to amend the gRPC-Web protocol docs to encourage
implementations to follow HTTP semantics and compare HTTP field names
case-insensitively.

The gRPC-Web specification is a nicely-designed way for proxies to
expose standard HTTP/2 gRPC servers to clients using less
tightly-controlled HTTP stacks, such as web browsers. To serve that
goal, it seems valuable to have the gRPC-Web specification follow [RFC
9110 (HTTP
Semantics)](https://www.rfc-editor.org/rfc/rfc9110.html#name-field-names).
Like previous RFCs, 9110 specifies that "field names are
case-insensitive." However, the current gRPC-Web specification requires
that servers and proxies "use lower-case header/trailer names" on the
wire. In principle, mandating casing on the wire is normal for HTTP/2
and fine (if unusual) for HTTP/1.1; however, it encourages
implementations to violate HTTP semantics and require lower-case names
when _reading_ headers and trailers.

I'd like to loosen the gRPC-Web specification to permit any casing on
the wire for HTTP/1.1. I'd also like to emphasize that gRPC-Web
implementations ought to follow standard HTTP semantics when _reading_
fields and compare names case-insensitively. Implementations that can't
treat names case-insensitively without breaking backward compatibility
should instead normalize field names to lowercase. Among the
Google-maintained gRPC implementations, at least `grpc-go` and
`grpc-java` already compare names case-insensitively (even though
they're HTTP/2-only). `grpc-dart` does the opposite and compares names
case-sensitively. `grpc-web` is sometimes case-insensitive (when reading
`grpc-status` and `grpc-message` from trailers-only responses) and
sometimes case-sensitive (when hand-parsing a block of length-prefixed
trailers).

The proposed amendment does not affect the correctness of Envoy (which
may continue to use lower-case field names). It partially affects
`grpc-web`, which would require a small patch to always normalize names.
(Both patched and unpatched versions of `grpc-web` would work with
Envoy.) `grpc-dart` would need to either begin treating field names
case-insensitively or normalize names, depending on what's possible in
Dart without breaking backward compatibility.

Relates to https://github.com/improbable-eng/grpc-web/issues/228,
https://github.com/bufbuild/connect-go/issues/453/, and
https://github.com/grpc/grpc-dart/issues/594.
pull/30788/head^2
Akshay Shah 2 years ago committed by GitHub
parent 8fc8fa3fee
commit 58ea2e00fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      doc/PROTOCOL-WEB.md

@ -48,7 +48,8 @@ Content-Type
HTTP wire protocols
1. support any HTTP/*, with no dependency on HTTP/2 specific framing
2. use lower-case header/trailer names
2. header names may be upper- or mixed-case over HTTP/1.1, but trailers encoded in
the last length-prefixed message must always use lower-case names.
3. use EOF (end of body) to close the stream
---

Loading…
Cancel
Save