gipinani
gipinani

Reputation: 14418

RpcException Metadata limitations

On grpc service side, I'm throwing RpcException with the following extension method:

public static class GrpcExceptionExtension 
{
    public static RpcException BuildRpcException(this Exception e)
    {
        var metadata = new Metadata
                    {
                        { "message", e.Message },
                    };
        return new RpcException(new Status(StatusCode.Internal, "Internal Exception"), metadata);
    }
}

After some headaches, I discovered that when a Metadata entry is set with a message containing certain characters, the RpcException cannot probably be serialized. So my StatusCode.Internal resulted in a Status(StatusCode="Unknown", Detail="Bad gRPC response. HTTP status code: 500")

I was wondering if there is an article / documentation where I can find what is allowed to be sent as Metadata.

Currently I had this message that didn't work:

Message = "Cannot insert the value NULL into column 'ColID', table 'XXX.dbo.TTT'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."

After removing \r and \n it worked.

Upvotes: 1

Views: 730

Answers (1)

Yuri Golobokov
Yuri Golobokov

Reputation: 1965

Please, take a look at

https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md

esp.

  • Custom-Metadata → Binary-Header / ASCII-Header
  • Binary-Header → {Header-Name "-bin" } {base64 encoded value}
  • ASCII-Header → Header-Name ASCII-Value
  • Header-Name → 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - .
  • ASCII-Value → 1*( %x20-%x7E ) ; space and printable ASCII

and

Custom-Metadata is an arbitrary set of key-value pairs defined by the application layer. Header names starting with "grpc-" but not listed here are reserved for future GRPC use and should not be used by applications as Custom-Metadata.

Note that HTTP2 does not allow arbitrary octet sequences for header values so binary header values must be encoded using Base64 as per https://tools.ietf.org/html/rfc4648#section-4. Implementations MUST accept padded and un-padded values and should emit un-padded values. Applications define binary headers by having their names end with "-bin". Runtime libraries use this suffix to detect binary headers and properly apply base64 encoding & decoding as headers are sent and received.

You can change the metadata key to, e.g., "message-bin" to allow for automatic base64 encode/decode to preserve all characters.

Upvotes: 1

Related Questions