From 9b18aa7854c03f99c1429ecd3f3e59c295589a70 Mon Sep 17 00:00:00 2001 From: Joe Dahlquist Date: Mon, 4 Jul 2022 01:12:40 -0700 Subject: [PATCH] Correctly identify gRPC requests in default `on_response` callback (#278) * use grpc status instead of html status in grpc-web on_response_trace * add changelog entry for pr#278 Co-authored-by: Joe Dahlquist --- tower-http/CHANGELOG.md | 4 +++- tower-http/src/trace/on_response.rs | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tower-http/CHANGELOG.md b/tower-http/CHANGELOG.md index 020c0d06..5ac55120 100644 --- a/tower-http/CHANGELOG.md +++ b/tower-http/CHANGELOG.md @@ -21,7 +21,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Fixed -- None. +- **trace:** Correctly identify gRPC requests in default `on_response` callback ([#278]) + +[#278]: https://github.com/tower-rs/tower-http/pull/278 # 0.3.4 (June 06, 2022) diff --git a/tower-http/src/trace/on_response.rs b/tower-http/src/trace/on_response.rs index 09f44e58..573de2e4 100644 --- a/tower-http/src/trace/on_response.rs +++ b/tower-http/src/trace/on_response.rs @@ -264,10 +264,23 @@ impl OnResponse for DefaultOnResponse { fn status(res: &Response) -> Option { use crate::classify::grpc_errors_as_failures::ParsedGrpcStatus; + // gRPC-over-HTTP2 uses the "application/grpc[+format]" content type, and gRPC-Web uses + // "application/grpc-web[+format]" or "application/grpc-web-text[+format]", where "format" is + // the message format, e.g. +proto, +json. + // + // So, valid grpc content types include (but are not limited to): + // - application/grpc + // - application/grpc+proto + // - application/grpc-web+proto + // - application/grpc-web-text+proto + // + // For simplicity, we simply check that the content type starts with "application/grpc". let is_grpc = res .headers() .get(http::header::CONTENT_TYPE) - .map_or(false, |value| value == "application/grpc"); + .map_or(false, |value| { + value.as_bytes().starts_with("application/grpc".as_bytes()) + }); if is_grpc { match crate::classify::grpc_errors_as_failures::classify_grpc_metadata(