Spec clarification about multi-value custom metadata -> HTTP/2 headers

200 views
Skip to first unread message

Peter Wiese

unread,
Apr 14, 2022, 7:13:41 PM4/14/22
to grpc.io
I have 2 questions:

Given the following set of custom metadata added via some client SDK, Grpc-Core, Grpc-Go, grpc-dotnet

key1: foo
key1: bar

Is it required that these map to separate HTTP/2 headers?

key1: foo
key1: bar

Or is it allowable to map those metadata items to a single HTTP/2 header with a comma-separate value?

key1: foo,bar

Per the gRPC over HTTP/2 spec https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests

I read that as either form is acceptable. If that is true my other question is if a gRPC server receives headers in either form are they semantically the same?


------
Context
------

A grpc-dotnet client (which replaces the wrapper over Grpc.Core) turns multiple metadata items into a single HTTP/2 header and a grpc-dotnet server reads it back as a single header with a comma-separated value (as a string).

grpc-go sees multiple headers as individual metadata items, but it sees a single header with a comma-separated value as a single metadata item.

I'm trying to figure out if grpc-dotnet is doing the wrong thing here. Its doing something different but I can't say if its bad or not.

Akshay Shah

unread,
Apr 20, 2022, 12:39:15 PM4/20/22
to grpc.io
I'm also curious about this - I recently ran into this behavior in grpc-go.

Eric Anderson

unread,
Apr 25, 2022, 3:21:57 PM4/25/22
to Peter Wiese, grpc.io
On Thu, Apr 14, 2022 at 4:13 PM Peter Wiese <peter...@gmail.com> wrote:
Per the gRPC over HTTP/2 spec https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests

I read that as either form is acceptable. If that is true my other question is if a gRPC server receives headers in either form are they semantically the same?

I'm a bit confused what wasn't explained by this about Custom-Metadata; it seems you saw it:
Duplicate header names may have their values joined with "," as the delimiter and be considered semantically equivalent.

So yes, they are semantically the same. This is actually an HTTP-ism exposed in gRPC, so the HTTP spec talks about this if you care.

A grpc-dotnet client (which replaces the wrapper over Grpc.Core) turns multiple metadata items into a single HTTP/2 header and a grpc-dotnet server reads it back as a single header with a comma-separated value (as a string).

That's okay. Note that it would not be okay to split on ',' within the API; that can only be done with knowledge about that specific header's format. (E.g., maybe it supports commas in double quotes like CSV, or allows backslashes before commas to escape, or maybe it isn't multi-valued at all)

Note that proxies can also perform this transformation, so every language may see the combined form.

I think it would be quite fair to only support single-valued headers within a gRPC API for non-binary headers. It is much easier to use and less prone to buggy usage.
Reply all
Reply to author
Forward
0 new messages