Content-Type missing in responses triggered by interceptors returning Status
Bug Report
Services guarded by interceptors that return Err(Status::*) for any reason are missing Content-Type headers in the responses when queried with grpcurl.
Version
Tested on the main v0.6.1 release and the latest master branch
Platform
Linux plopear 5.14.16-arch1-1 x86_64 GNU/Linux
Crates
tonic
Description
TL;DR: Err(Status::*) responses are handled differently when they occur in Interceptors versus methods, leading grpcurl to complain that the content-type header is missing in Interceptor-generated responses.
Similar to #431, #700, and #759, but creating a new issue since this appears to be a broader case than a specific example not working (or represents a regression to the fix applied in #701).
I've created a repro of the issue here. This repro lets you configure different FAILURE_MODEs through environment variables: None means that there is no failure, Method means that the configured methods return a Status, and Interceptor means that the interceptor returns a Status. I'd expect Method and Interceptor failure modes to generate the exact same response, but they do not. Listed below are the tests I've run on each relevant failure mode.
Failure Mode: Method
Run command (in repro repo): RUST_LOG=info FAILURE_MODE=method cargo run
Query command: grpcurl -plaintext -import-path ./proto -proto health.proto [::]:50051 grpc.health.v1.Health/Check
Query response:
ERROR:
Code: Internal
Message: Failure within the Check method
Failure Mode: Interceptor
Run command (in repro repo): RUST_LOG=info FAILURE_MODE=interceptor cargo run
Query command: grpcurl -plaintext -import-path ./proto -proto health.proto [::]:50051 grpc.health.v1.Health/Check
Query response:
ERROR:
Code: Unknown
Message: OK: HTTP status code 200; transport: missing content-type field
The first is behaving as expected, the second is not.
Next Steps:
I'll do a bit more digging to see how these requests are different, and I suspect that a fix like #701 will be in order. But want to make sure that this is floated as a possible regression on all interceptors, rather than those used in a particular example.
Following up on this: it appears that by the time wrapped service responses are mapped at this line, Method failure modes include content-type headers of application/grpc and Interceptor failure modes include the message payload, but not the content-type. Going to do a bit more digging to determine where that content-type header might be getting dropped (assuming it's generated properly in the first place), but that difference is enough to qualify this as a bug within tonic, I think, rather than a bug with grpcurl's implementation.