ErrorWriter.IsSupported is overly strict
Currently ErrorWriter.IsSupported uses the currently supported codecs (provided in the form of handler options) to compute all of the possible content-types that the server would support. However, this is not necessary. There are only four protocol types, and the actual registered codecs aren't necessary in order to classify them:
- If the content-type is
application/grpcor starts withapplication/grpc+then it's a gRPC request. - If the content-type is
application/grpc-webor starts withapplication/grpc-web+then it's a gRPC-Web request. - If the content-type starts with
application/connect+then it's a Connect streaming request. - Lastly, if the content-type starts with
application/and matches none of the above OR it has aConnect-Protocol-Version: 1header OR it uses a GET HTTP method and includes aconnect=v1query param then it's a Connect unary request. - Only when none of the above apply should the request be un-classifiable and
IsSupportedreturn false.
In all of the above cases, the actual supported codecs are irrelevant because, once classified as above, an error can be correctly written (error formats are codec-agnostic).
Addressing this would also enable error handling that more closely resembles gRPC. In gRPC servers, if the content-type is not a gRPC content-type (i.e. it is not application/grpc and does not start with application/grpc+) then the server sends back a 415 HTTP status code, which clients will then classify as an unknown error. If it's a gRPC content-type, but not a supported codec, the server sends back a gRPC error (HTTP status code 200, error code and message in HTTP trailers) with a code of "internal". So with the above logic, when the content-type is not supported, an ErrorWriter could be used to write an RPC internal error and a 415 HTTP status code only used if the ErrorWriter reports that the request is unsupported.