diff --git a/tonic/Cargo.toml b/tonic/Cargo.toml index 27768924c..3c219add5 100644 --- a/tonic/Cargo.toml +++ b/tonic/Cargo.toml @@ -24,7 +24,8 @@ codegen = ["dep:async-trait"] gzip = ["dep:flate2"] deflate = ["dep:flate2"] zstd = ["dep:zstd"] -default = ["router", "transport", "codegen", "prost"] +default = ["router", "transport", "codegen", "prost", "user-agent"] +user-agent = [] prost = ["dep:prost"] _tls-any = ["dep:tokio-rustls", "dep:tokio", "tokio?/rt", "tokio?/macros"] # Internal. Please choose one of `tls-ring` or `tls-aws-lc` tls-ring = ["_tls-any", "tokio-rustls/ring"] diff --git a/tonic/src/transport/channel/endpoint.rs b/tonic/src/transport/channel/endpoint.rs index f5c386899..dcde51a1b 100644 --- a/tonic/src/transport/channel/endpoint.rs +++ b/tonic/src/transport/channel/endpoint.rs @@ -1,19 +1,25 @@ +use std::{fmt, future::Future, net::IpAddr, pin::Pin, str, str::FromStr, time::Duration}; + +use bytes::Bytes; +use http::uri::Uri; +#[cfg(feature = "user-agent")] +use http::HeaderValue; +use hyper::rt; +use hyper_util::client::legacy::connect::HttpConnector; +use tower_service::Service; + #[cfg(feature = "_tls-any")] use super::service::TlsConnector; -use super::service::{self, Executor, SharedExec}; -use super::uds_connector::UdsConnector; -use super::Channel; #[cfg(feature = "_tls-any")] use super::ClientTlsConfig; +use super::{ + service::{self, Executor, SharedExec}, + uds_connector::UdsConnector, + Channel, +}; #[cfg(feature = "_tls-any")] use crate::transport::error; use crate::transport::Error; -use bytes::Bytes; -use http::{uri::Uri, HeaderValue}; -use hyper::rt; -use hyper_util::client::legacy::connect::HttpConnector; -use std::{fmt, future::Future, net::IpAddr, pin::Pin, str, str::FromStr, time::Duration}; -use tower_service::Service; #[derive(Clone, PartialEq, Eq, Hash)] pub(crate) enum EndpointType { @@ -29,6 +35,7 @@ pub struct Endpoint { pub(crate) uri: EndpointType, fallback_uri: Uri, pub(crate) origin: Option, + #[cfg(feature = "user-agent")] pub(crate) user_agent: Option, pub(crate) timeout: Option, pub(crate) concurrency_limit: Option, @@ -76,6 +83,7 @@ impl Endpoint { uri: EndpointType::Uri(uri.clone()), fallback_uri: uri, origin: None, + #[cfg(feature = "user-agent")] user_agent: None, concurrency_limit: None, rate_limit: None, @@ -105,6 +113,7 @@ impl Endpoint { uri: EndpointType::Uds(uds_filepath.to_string()), fallback_uri: Uri::from_static("http://tonic"), origin: None, + #[cfg(feature = "user-agent")] user_agent: None, concurrency_limit: None, rate_limit: None, @@ -185,6 +194,7 @@ impl Endpoint { /// builder.user_agent("Greeter").expect("Greeter should be a valid header value"); /// // user-agent: "Greeter tonic/x.x.x" /// ``` + #[cfg(feature = "user-agent")] pub fn user_agent(self, user_agent: T) -> Result where T: TryInto, diff --git a/tonic/src/transport/channel/service/connection.rs b/tonic/src/transport/channel/service/connection.rs index c4ce9408e..1cbea2c62 100644 --- a/tonic/src/transport/channel/service/connection.rs +++ b/tonic/src/transport/channel/service/connection.rs @@ -1,25 +1,28 @@ -use super::{AddOrigin, Reconnect, SharedExec, UserAgent}; -use crate::{ - body::Body, - transport::{channel::BoxFuture, service::GrpcTimeout, Endpoint}, -}; -use http::{Request, Response, Uri}; -use hyper::rt; -use hyper::{client::conn::http2::Builder, rt::Executor}; -use hyper_util::rt::TokioTimer; use std::{ fmt, task::{Context, Poll}, }; -use tower::load::Load; + +use http::{Request, Response, Uri}; +use hyper::{client::conn::http2::Builder, rt, rt::Executor}; +use hyper_util::rt::TokioTimer; use tower::{ layer::Layer, limit::{concurrency::ConcurrencyLimitLayer, rate::RateLimitLayer}, + load::Load, util::BoxService, ServiceBuilder, ServiceExt, }; use tower_service::Service; +#[cfg(feature = "user-agent")] +use super::UserAgent; +use super::{AddOrigin, Reconnect, SharedExec}; +use crate::{ + body::Body, + transport::{channel::BoxFuture, service::GrpcTimeout, Endpoint}, +}; + pub(crate) struct Connection { inner: BoxService, Response, crate::BoxError>, } @@ -55,13 +58,16 @@ impl Connection { settings.max_header_list_size(val); } - let stack = ServiceBuilder::new() - .layer_fn(|s| { - let origin = endpoint.origin.as_ref().unwrap_or(endpoint.uri()).clone(); + let stack = ServiceBuilder::new().layer_fn(|s| { + let origin = endpoint.origin.as_ref().unwrap_or(endpoint.uri()).clone(); + + AddOrigin::new(s, origin) + }); + + #[cfg(feature = "user-agent")] + let stack = stack.layer_fn(|s| UserAgent::new(s, endpoint.user_agent.clone())); - AddOrigin::new(s, origin) - }) - .layer_fn(|s| UserAgent::new(s, endpoint.user_agent.clone())) + let stack = stack .layer_fn(|s| GrpcTimeout::new(s, endpoint.timeout)) .option_layer(endpoint.concurrency_limit.map(ConcurrencyLimitLayer::new)) .option_layer(endpoint.rate_limit.map(|(l, d)| RateLimitLayer::new(l, d))) diff --git a/tonic/src/transport/channel/service/mod.rs b/tonic/src/transport/channel/service/mod.rs index e4306f033..a57d871a4 100644 --- a/tonic/src/transport/channel/service/mod.rs +++ b/tonic/src/transport/channel/service/mod.rs @@ -1,7 +1,9 @@ mod add_origin; use self::add_origin::AddOrigin; +#[cfg(feature = "user-agent")] mod user_agent; +#[cfg(feature = "user-agent")] use self::user_agent::UserAgent; mod reconnect; diff --git a/tonic/src/transport/error.rs b/tonic/src/transport/error.rs index 31b317521..5170e6d73 100644 --- a/tonic/src/transport/error.rs +++ b/tonic/src/transport/error.rs @@ -17,7 +17,7 @@ pub(crate) enum Kind { Transport, #[cfg(feature = "channel")] InvalidUri, - #[cfg(feature = "channel")] + #[cfg(all(feature = "channel", feature = "user-agent"))] InvalidUserAgent, #[cfg(all(feature = "_tls-any", feature = "channel"))] InvalidTlsConfigForUds, @@ -44,7 +44,7 @@ impl Error { Error::new(Kind::InvalidUri) } - #[cfg(feature = "channel")] + #[cfg(all(feature = "channel", feature = "user-agent"))] pub(crate) fn new_invalid_user_agent() -> Self { Error::new(Kind::InvalidUserAgent) } @@ -54,7 +54,7 @@ impl Error { Kind::Transport => "transport error", #[cfg(feature = "channel")] Kind::InvalidUri => "invalid URI", - #[cfg(feature = "channel")] + #[cfg(all(feature = "channel", feature = "user-agent"))] Kind::InvalidUserAgent => "user agent is not a valid header value", #[cfg(all(feature = "_tls-any", feature = "channel"))] Kind::InvalidTlsConfigForUds => "cannot apply TLS config for unix domain socket",