diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 5c3e7e8b5..6d9064212 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -290,13 +290,13 @@ hyper-warp-multiplex = ["hyper-warp"] uds = ["tokio-stream/net", "dep:tower", "dep:hyper"] streaming = ["tokio-stream", "dep:h2"] mock = ["tokio-stream", "dep:tower"] -tower = ["dep:hyper", "dep:tower", "dep:http"] +tower = ["dep:hyper", "tower/timeout", "dep:http"] json-codec = ["dep:serde", "dep:serde_json", "dep:bytes"] compression = ["tonic/gzip"] tls = ["tonic/tls"] tls-rustls = ["dep:hyper", "dep:hyper-rustls", "dep:tower", "tower-http/util", "tower-http/add-extension", "dep:rustls-pemfile", "dep:tokio-rustls"] dynamic-load-balance = ["dep:tower"] -timeout = ["tokio/time", "dep:tower"] +timeout = ["tokio/time", "tower/timeout"] tls-client-auth = ["tonic/tls"] types = ["dep:tonic-types"] h2c = ["dep:hyper", "dep:tower", "dep:http"] diff --git a/tonic/Cargo.toml b/tonic/Cargo.toml index 013cc6e72..303cf2619 100644 --- a/tonic/Cargo.toml +++ b/tonic/Cargo.toml @@ -26,24 +26,26 @@ version = "0.10.2" codegen = ["dep:async-trait"] gzip = ["dep:flate2"] zstd = ["dep:zstd"] -default = ["transport", "codegen", "prost"] +default = ["channel", "codegen", "prost"] prost = ["dep:prost"] tls = ["dep:rustls-pemfile", "transport", "dep:tokio-rustls", "dep:rustls", "tokio/rt", "tokio/macros"] tls-roots = ["tls-roots-common", "dep:rustls-native-certs"] -tls-roots-common = ["tls"] +tls-roots-common = ["tls", "channel"] tls-webpki-roots = ["tls-roots-common", "dep:webpki-roots"] transport = [ "dep:async-stream", "dep:axum", - "channel", "dep:h2", - "dep:hyper", - "tokio/net", - "tokio/time", - "dep:tower", + "dep:hyper", "hyper?/server", + "tokio/net", "tokio/time", + "dep:tower", "tower?/util", "tower?/limit", +] +channel = [ + "transport", + "dep:hyper", "hyper?/client", + "dep:tower", "tower?/balance", "tower?/buffer", "tower?/discover", "tower?/load", "tower?/make", "dep:hyper-timeout", ] -channel = [] # [[bench]] # name = "bench_main" @@ -70,12 +72,14 @@ async-trait = {version = "0.1.13", optional = true} # transport h2 = {version = "0.3.17", optional = true} -hyper = {version = "0.14.26", features = ["full"], optional = true} -hyper-timeout = {version = "0.4", optional = true} +hyper = {version = "0.14.26", features = ["http1", "http2", "runtime", "stream"], optional = true} tokio-stream = "0.1" -tower = {version = "0.4.7", default-features = false, features = ["balance", "buffer", "discover", "limit", "load", "make", "timeout", "util"], optional = true} +tower = {version = "0.4.7", default-features = false, optional = true} axum = {version = "0.6.9", default_features = false, optional = true} +# channel +hyper-timeout = {version = "0.4", optional = true} + # rustls async-stream = { version = "0.3", optional = true } rustls-pemfile = { version = "1.0", optional = true } diff --git a/tonic/src/transport/error.rs b/tonic/src/transport/error.rs index d2a1c7bb2..92a910498 100644 --- a/tonic/src/transport/error.rs +++ b/tonic/src/transport/error.rs @@ -15,7 +15,9 @@ struct ErrorImpl { #[derive(Debug)] pub(crate) enum Kind { Transport, + #[cfg(feature = "channel")] InvalidUri, + #[cfg(feature = "channel")] InvalidUserAgent, } @@ -35,10 +37,12 @@ impl Error { Error::new(Kind::Transport).with(source) } + #[cfg(feature = "channel")] pub(crate) fn new_invalid_uri() -> Self { Error::new(Kind::InvalidUri) } + #[cfg(feature = "channel")] pub(crate) fn new_invalid_user_agent() -> Self { Error::new(Kind::InvalidUserAgent) } @@ -46,7 +50,9 @@ impl Error { fn description(&self) -> &str { match &self.inner.kind { Kind::Transport => "transport error", + #[cfg(feature = "channel")] Kind::InvalidUri => "invalid URI", + #[cfg(feature = "channel")] Kind::InvalidUserAgent => "user agent is not a valid header value", } } diff --git a/tonic/src/transport/mod.rs b/tonic/src/transport/mod.rs index a0435c797..9fdaab6ad 100644 --- a/tonic/src/transport/mod.rs +++ b/tonic/src/transport/mod.rs @@ -87,6 +87,7 @@ //! //! [rustls]: https://docs.rs/rustls/0.16.0/rustls/ +#[cfg(feature = "channel")] pub mod channel; pub mod server; @@ -110,10 +111,11 @@ pub use self::tls::Certificate; pub use axum::{body::BoxBody as AxumBoxBody, Router as AxumRouter}; pub use hyper::{Body, Uri}; +#[cfg(feature = "channel")] pub(crate) use self::service::executor::Executor; -#[cfg(feature = "tls")] -#[cfg_attr(docsrs, doc(cfg(feature = "tls")))] +#[cfg(all(feature = "channel", feature = "tls"))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "channel", feature = "tls"))))] pub use self::channel::ClientTlsConfig; #[cfg(feature = "tls")] #[cfg_attr(docsrs, doc(cfg(feature = "tls")))] @@ -122,4 +124,5 @@ pub use self::server::ServerTlsConfig; #[cfg_attr(docsrs, doc(cfg(feature = "tls")))] pub use self::tls::Identity; +#[cfg(feature = "channel")] type BoxFuture<'a, T> = std::pin::Pin + Send + 'a>>; diff --git a/tonic/src/transport/service/io.rs b/tonic/src/transport/service/io.rs index 2230b9b2e..865ea814f 100644 --- a/tonic/src/transport/service/io.rs +++ b/tonic/src/transport/service/io.rs @@ -1,4 +1,5 @@ use crate::transport::server::Connected; +#[cfg(feature = "channel")] use hyper::client::connect::{Connected as HyperConnected, Connection}; use std::io; use std::io::IoSlice; @@ -15,20 +16,24 @@ pub(in crate::transport) trait Io: impl Io for T where T: AsyncRead + AsyncWrite + Send + 'static {} +#[cfg(feature = "channel")] pub(crate) struct BoxedIo(Pin>); +#[cfg(feature = "channel")] impl BoxedIo { pub(in crate::transport) fn new(io: I) -> Self { BoxedIo(Box::pin(io)) } } +#[cfg(feature = "channel")] impl Connection for BoxedIo { fn connected(&self) -> HyperConnected { HyperConnected::new() } } +#[cfg(feature = "channel")] impl Connected for BoxedIo { type ConnectInfo = NoneConnectInfo; @@ -37,9 +42,11 @@ impl Connected for BoxedIo { } } +#[cfg(feature = "channel")] #[derive(Copy, Clone)] pub(crate) struct NoneConnectInfo; +#[cfg(feature = "channel")] impl AsyncRead for BoxedIo { fn poll_read( mut self: Pin<&mut Self>, @@ -50,6 +57,7 @@ impl AsyncRead for BoxedIo { } } +#[cfg(feature = "channel")] impl AsyncWrite for BoxedIo { fn poll_write( mut self: Pin<&mut Self>, diff --git a/tonic/src/transport/service/mod.rs b/tonic/src/transport/service/mod.rs index 69d850f10..3a51d6a90 100644 --- a/tonic/src/transport/service/mod.rs +++ b/tonic/src/transport/service/mod.rs @@ -1,26 +1,34 @@ +#[cfg(feature = "channel")] mod add_origin; +#[cfg(feature = "channel")] mod connection; +#[cfg(feature = "channel")] mod connector; +#[cfg(feature = "channel")] mod discover; +#[cfg(feature = "channel")] pub(crate) mod executor; pub(crate) mod grpc_timeout; mod io; +#[cfg(feature = "channel")] mod reconnect; mod router; #[cfg(feature = "tls")] mod tls; +#[cfg(feature = "channel")] mod user_agent; -pub(crate) use self::add_origin::AddOrigin; -pub(crate) use self::connection::Connection; -pub(crate) use self::connector::Connector; -pub(crate) use self::discover::DynamicServiceStream; -pub(crate) use self::executor::SharedExec; pub(crate) use self::grpc_timeout::GrpcTimeout; pub(crate) use self::io::ServerIo; #[cfg(feature = "tls")] -pub(crate) use self::tls::{TlsAcceptor, TlsConnector}; -pub(crate) use self::user_agent::UserAgent; +pub(crate) use self::tls::TlsAcceptor; +#[cfg(all(feature = "channel", feature = "tls"))] +pub(crate) use self::tls::TlsConnector; +#[cfg(feature = "channel")] +pub(crate) use self::{ + add_origin::AddOrigin, connection::Connection, connector::Connector, + discover::DynamicServiceStream, executor::SharedExec, user_agent::UserAgent, +}; pub use self::router::Routes; pub use self::router::RoutesBuilder; diff --git a/tonic/src/transport/service/tls.rs b/tonic/src/transport/service/tls.rs index f956132fb..c06d7a89e 100644 --- a/tonic/src/transport/service/tls.rs +++ b/tonic/src/transport/service/tls.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "channel")] use super::io::BoxedIo; use crate::transport::{ server::{Connected, TlsStream}, @@ -5,9 +6,14 @@ use crate::transport::{ }; use std::{fmt, sync::Arc}; use tokio::io::{AsyncRead, AsyncWrite}; +#[cfg(feature = "channel")] use tokio_rustls::{ - rustls::{ClientConfig, RootCertStore, ServerConfig, ServerName}, - TlsAcceptor as RustlsAcceptor, TlsConnector as RustlsConnector, + rustls::{ClientConfig, ServerName}, + TlsConnector as RustlsConnector, +}; +use tokio_rustls::{ + rustls::{RootCertStore, ServerConfig}, + TlsAcceptor as RustlsAcceptor, }; /// h2 alpn in plain format for rustls. @@ -15,17 +21,20 @@ const ALPN_H2: &str = "h2"; #[derive(Debug)] enum TlsError { + #[cfg(feature = "channel")] H2NotNegotiated, CertificateParseError, PrivateKeyParseError, } +#[cfg(feature = "channel")] #[derive(Clone)] pub(crate) struct TlsConnector { config: Arc, domain: Arc, } +#[cfg(feature = "channel")] impl TlsConnector { pub(crate) fn new( ca_cert: Option, @@ -67,6 +76,7 @@ impl TlsConnector { }) } + #[cfg(feature = "channel")] pub(crate) async fn connect(&self, io: I) -> Result where I: AsyncRead + AsyncWrite + Send + Unpin + 'static, @@ -90,6 +100,7 @@ impl TlsConnector { } } +#[cfg(feature = "channel")] impl fmt::Debug for TlsConnector { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TlsConnector").finish() @@ -154,6 +165,7 @@ impl fmt::Debug for TlsAcceptor { impl fmt::Display for TlsError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + #[cfg(feature = "channel")] TlsError::H2NotNegotiated => write!(f, "HTTP/2 was not negotiated."), TlsError::CertificateParseError => write!(f, "Error parsing TLS certificate."), TlsError::PrivateKeyParseError => write!(