Discussion: Why HTTP2 pseudo headers such as :authory are removed from Metadata
davidfiala opened this issue · 2 comments
I'm curious to learn more about the reasons behind removing HTTP2 pseudo headers from being exposed as gRPC Metadata members on server call handlers. In my case, I'm specifically interested in exposing at least :authority
header to server call handlers.
My rationale for at least being interestd in exposing :authority
is that servers may need to behave differently based on what DNS hostname the caller reached them from or from whatever authority a reverse proxy like Envoy may have told a server to behave as. I believe there are important use cases for this, such as a health check ensuring that it returns the right code based on whether the server's ID matches the DNS hostname (authority) that the caller thinks it is reaching.
Related
- grpc-go has the same behavior on pseudo headers: https://github.com/grpc/grpc-go/blob/24e90243755430b73804d2bf13f0abcfa19361e5/internal/metadata/metadata.go#L112
- The commit that removes/prevents HTTP2 pseudo headers from making it in to gRPC metadata: 0c606f4
- (less related) Discussion on setting
:authority
on client calls: #104
Unfortunately I couldn't quite figure out the reason behind why pseudo headers are cleared out. But it does seem to exist in multiple gRPC languages.
I'd love to see if steps can be taken to expose :authority
. Maybe :path
too. I don't think they necessarily need to be in the Metadata object if there are reasons against it though. And I can easily imagine that some users' tests may be brittle enough that the sudden inclusion of such headers may break them.
Would this need to be a gRPC proposal to make such a change that exposes these pseudo headers potentially?
First, some good news: there is work in progress to make the contents of the :authority
header available to server interceptors (see grpc/proposal#433), and I can probably extend that to the call objects that the handlers get. The :path
header uniquely determines what handler is called, so you can infer that from in the handler, and that information is also passed to server interceptors.
As for the reasoning, I would say that it mainly comes from the gRPC over HTTP2 protocol spec. Specifically, the "Custom-Metadata" production rule describes the request and response headers that are defined by the application, as opposed to headers defined and handled by the library. That is what the Metadata
class in this library is supposed to correspond to.
In version 1.11.x, server call objects have a getHost
method, which returns the contents of the :authority
header. They also already had the getPath
method, which returns the contents of the :path
header.