diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index 5a1a46169..d3d054d15 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -10,5 +10,7 @@ protox = "0.9" prettyplease = "0.2" quote = "1" syn = "2" -tempfile = "3.8.0" -tonic-prost-build = {path = "../tonic-prost-build", default-features = false, features = ["cleanup-markdown"]} +tempfile = "3.27" +tonic-prost-build = { path = "../tonic-prost-build", default-features = false, features = [ + "cleanup-markdown", +] } diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 622fcd97d..47c51d168 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -254,31 +254,81 @@ path = "src/codec_buffers/client.rs" [features] gcp = ["dep:prost-types", "tonic/tls-ring"] -routeguide = ["dep:async-stream", "dep:tokio-stream", "dep:rand", "dep:serde", "dep:serde_json"] +routeguide = [ + "dep:async-stream", + "dep:tokio-stream", + "dep:rand", + "dep:serde", + "dep:serde_json", +] reflection = ["dep:tonic-reflection"] autoreload = ["dep:tokio-stream", "tokio-stream?/net", "dep:listenfd"] health = ["dep:tonic-health"] -grpc-web = ["dep:tonic-web", "dep:bytes", "dep:http", "dep:hyper", "dep:hyper-util", "dep:tracing-subscriber", "dep:tower", "dep:tower-http", "tower-http?/cors"] +grpc-web = [ + "dep:tonic-web", + "dep:bytes", + "dep:http", + "dep:hyper", + "dep:hyper-util", + "dep:tracing-subscriber", + "dep:tower", + "dep:tower-http", + "tower-http?/cors", +] tracing = ["dep:tracing", "dep:tracing-subscriber"] -uds = ["dep:tokio-stream", "tokio-stream?/net", "dep:tower", "dep:hyper", "dep:hyper-util"] +uds = [ + "dep:tokio-stream", + "tokio-stream?/net", + "dep:tower", + "dep:hyper", + "dep:hyper-util", +] streaming = ["dep:tokio-stream", "dep:h2"] mock = ["dep:tokio-stream", "dep:tower", "dep:hyper-util"] json-codec = ["dep:serde", "dep:serde_json", "dep:bytes"] compression = ["tonic/gzip"] tls = ["tonic/tls-ring"] -tls-rustls = ["dep:http", "dep:hyper", "dep:hyper-util", "dep:hyper-rustls", "dep:tower", "tower-http/util", "tower-http/add-extension", "dep:tokio-rustls"] +tls-rustls = [ + "dep:http", + "dep:hyper", + "dep:hyper-util", + "dep:hyper-rustls", + "dep:tower", + "tower-http/util", + "tower-http/add-extension", + "dep:tokio-rustls", +] tls-client-auth = ["tonic/tls-ring"] types = ["dep:tonic-types"] h2c = ["dep:hyper", "dep:tower", "dep:http", "dep:hyper-util"] cancellation = ["dep:tokio-util"] -full = ["gcp", "routeguide", "reflection", "autoreload", "health", "grpc-web", "tracing", "uds", "streaming", "mock", "json-codec", "compression", "tls", "tls-rustls", "tls-client-auth", "types", "cancellation", "h2c"] +full = [ + "gcp", + "routeguide", + "reflection", + "autoreload", + "health", + "grpc-web", + "tracing", + "uds", + "streaming", + "mock", + "json-codec", + "compression", + "tls", + "tls-rustls", + "tls-client-auth", + "types", + "cancellation", + "h2c", +] tower = ["dep:tower", "dep:http"] default = ["full"] [dependencies] # Common dependencies -tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] } +tokio = { version = "1.52", features = ["rt-multi-thread", "macros"] } prost = "0.14" tonic = { path = "../tonic" } tonic-prost = { path = "../tonic-prost" } @@ -289,22 +339,32 @@ tonic-reflection = { path = "../tonic-reflection", optional = true } tonic-types = { path = "../tonic-types", optional = true } async-stream = { version = "0.3", optional = true } tokio-stream = { version = "0.1", optional = true } -tokio-util = { version = "0.7.8", optional = true } +tokio-util = { version = "0.7", optional = true } tower = { version = "0.5", optional = true } -rand = { version = "0.9", optional = true } +rand = { version = "0.10", optional = true } serde = { version = "1.0", features = ["derive"], optional = true } serde_json = { version = "1.0", optional = true } -tracing = { version = "0.1.16", optional = true } -tracing-subscriber = { version = "0.3", features = ["tracing-log", "fmt"], optional = true } +tracing = { version = "0.1", optional = true } +tracing-subscriber = { version = "0.3", features = [ + "tracing-log", + "fmt", +], optional = true } prost-types = { version = "0.14", optional = true } http = { version = "1", optional = true } hyper = { version = "1", optional = true } -hyper-util = { version = "0.1.4", optional = true } +hyper-util = { version = "0.1", optional = true } listenfd = { version = "1.0", optional = true } bytes = { version = "1", optional = true } h2 = { version = "0.4", optional = true } -tokio-rustls = { version = "0.26.1", optional = true, features = ["ring", "tls12"], default-features = false } -hyper-rustls = { version = "0.27.0", features = ["http2", "ring", "tls12"], optional = true, default-features = false } +tokio-rustls = { version = "0.26", optional = true, features = [ + "ring", + "tls12", +], default-features = false } +hyper-rustls = { version = "0.27", features = [ + "http2", + "ring", + "tls12", +], optional = true, default-features = false } tower-http = { version = "0.6", optional = true } [build-dependencies] diff --git a/examples/src/health/server.rs b/examples/src/health/server.rs index 374b2d8da..3fb885b54 100644 --- a/examples/src/health/server.rs +++ b/examples/src/health/server.rs @@ -35,7 +35,7 @@ async fn twiddle_service_status(reporter: HealthReporter) { iter += 1; tokio::time::sleep(Duration::from_secs(1)).await; - if iter % 2 == 0 { + if iter.is_multiple_of(2) { reporter.set_serving::>().await; } else { reporter.set_not_serving::>().await; diff --git a/examples/src/routeguide/client.rs b/examples/src/routeguide/client.rs index 3d9a75273..c3bd33c5f 100644 --- a/examples/src/routeguide/client.rs +++ b/examples/src/routeguide/client.rs @@ -1,7 +1,7 @@ use std::error::Error; use std::time::Duration; -use rand::Rng; +use rand::RngExt; use rand::rngs::ThreadRng; use tokio::time; use tonic::Request; diff --git a/grpc-protobuf-build/Cargo.toml b/grpc-protobuf-build/Cargo.toml index 833e581c1..007886231 100644 --- a/grpc-protobuf-build/Cargo.toml +++ b/grpc-protobuf-build/Cargo.toml @@ -8,9 +8,9 @@ publish = false rust-version = { workspace = true } [dependencies] -prettyplease = "0.2.35" +prettyplease = "0.2" protobuf-codegen = { version = "4.34.0-release" } -syn = "2.0.104" +syn = "2.0" [build-dependencies] cmake = "0.1" diff --git a/grpc/Cargo.toml b/grpc/Cargo.toml index 9188537a5..fdb35200c 100644 --- a/grpc/Cargo.toml +++ b/grpc/Cargo.toml @@ -33,7 +33,6 @@ _runtime-tokio = [ tower = ["_runtime-tokio"] tls-rustls = [ "dep:rustls", - "dep:rustls-pemfile", "dep:rustls-pki-types", "dep:tokio-rustls", "dep:rustls-platform-verifier", @@ -42,51 +41,48 @@ tls-rustls = [ [dependencies] base64 = "0.22" -bytes = "1.10.1" -hickory-resolver = { version = "0.25.1", optional = true } -http = "1.1.0" +bytes = "1.11" +hickory-resolver = { version = "0.26", optional = true } +http = "1.4" http-body = "1.0.1" -hyper = { version = "1.6.0", features = ["client", "http2"] } +hyper = { version = "1.9", features = ["client", "http2"] } itoa = "1.0" -parking_lot = "0.12.4" -pin-project-lite = "0.2.16" -rand = "0.9" +parking_lot = "0.12" +pin-project-lite = "0.2" +rand = "0.10" rustls = { version = "0.23", optional = true, default-features = false, features = [ "tls12", "logging", "std", ] } -rustls-pemfile = { version = "2.1", optional = true, default-features = false, features = [ - "std", -] } -rustls-pki-types = { version = "1.8", optional = true, default-features = false } -rustls-platform-verifier = { version = "0.6", optional = true, default-features = false } -rustls-webpki = { version = "0.102", optional = true, default-features = false } -serde = { version = "1.0.219", features = ["derive"] } -serde_json = "1.0.140" +rustls-pki-types = { version = "1.14", optional = true, default-features = false } +rustls-platform-verifier = { version = "0.7", optional = true, default-features = false } +rustls-webpki = { version = "0.103", optional = true, default-features = false } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" socket2 = { version = "0.6", optional = true } -tokio = { version = "1.37.0", features = ["sync", "macros"] } +tokio = { version = "1.52", features = ["sync", "macros"] } tokio-rustls = { version = "0.26", optional = true, default-features = false } -tokio-stream = { version = "0.1.17", default-features = false } +tokio-stream = { version = "0.1", default-features = false } tonic = { version = "0.14.0", path = "../tonic", default-features = false, features = [ "codegen", ] } -tower = { version = "0.5.2", features = [ +tower = { version = "0.5", features = [ "limit", "util", "buffer", ], optional = true } tower-service = "0.3.3" trait-variant = "0.1.2" -url = "2.5.0" +url = "2.5" [dev-dependencies] async-stream = "0.3.6" -criterion = "0.5" -hickory-server = "0.25.2" -prost = "0.14.0" +criterion = "0.8" +hickory-server = "0.26" +prost = "0.14" rustls = { version = "0.23", default-features = false, features = ["ring"] } -tempfile = "3.26" +tempfile = "3.27" tonic = { version = "0.14.0", path = "../tonic", default-features = false, features = [ "server", "router", diff --git a/grpc/benches/metadata.rs b/grpc/benches/metadata.rs index 658bc4714..a87a581b6 100644 --- a/grpc/benches/metadata.rs +++ b/grpc/benches/metadata.rs @@ -23,12 +23,12 @@ */ use criterion::Criterion; -use criterion::black_box; use criterion::criterion_group; use criterion::criterion_main; use grpc::metadata::MetadataKey; use grpc::metadata::MetadataMap; use grpc::metadata::MetadataValue; +use std::hint::black_box; use tonic::metadata::MetadataMap as TonicMetadataMap; fn bench_metadata_map_insert(c: &mut Criterion) { diff --git a/grpc/src/client/name_resolution/backoff.rs b/grpc/src/client/name_resolution/backoff.rs index b703e377a..6a75e4291 100644 --- a/grpc/src/client/name_resolution/backoff.rs +++ b/grpc/src/client/name_resolution/backoff.rs @@ -24,7 +24,7 @@ use std::time::Duration; -use rand::Rng; +use rand::RngExt; #[derive(Clone)] pub(crate) struct BackoffConfig { diff --git a/grpc/src/credentials/rustls/client/test.rs b/grpc/src/credentials/rustls/client/test.rs index 2accf9aaa..b93099008 100644 --- a/grpc/src/credentials/rustls/client/test.rs +++ b/grpc/src/credentials/rustls/client/test.rs @@ -32,6 +32,7 @@ use rustls::ServerConfig; use rustls::crypto::ring; use rustls_pki_types::CertificateDer; use rustls_pki_types::PrivateKeyDer; +use rustls_pki_types::pem::PemObject; use tempfile::NamedTempFile; use tokio::io::AsyncReadExt; use tokio::io::AsyncWriteExt; @@ -489,7 +490,7 @@ fn mtls_server_config() -> ServerConfig { let file = std::fs::File::open(client_ca_path).expect("cannot open client CA file"); let mut reader = std::io::BufReader::new(file); let mut root_store = rustls::RootCertStore::empty(); - for cert in rustls_pemfile::certs(&mut reader) { + for cert in CertificateDer::pem_reader_iter(&mut reader) { root_store.add(cert.unwrap()).unwrap(); } @@ -516,7 +517,7 @@ fn load_certs(filename: &str) -> Vec> { let path = test_certs_path().join(filename); let file = std::fs::File::open(path).expect("cannot open certificate file"); let mut reader = std::io::BufReader::new(file); - rustls_pemfile::certs(&mut reader) + CertificateDer::pem_reader_iter(&mut reader) .map(|result| result.unwrap()) .collect() } @@ -525,15 +526,7 @@ fn load_private_key(filename: &str) -> PrivateKeyDer<'static> { let path = test_certs_path().join(filename); let file = std::fs::File::open(path).expect("cannot open private key file"); let mut reader = std::io::BufReader::new(file); - loop { - match rustls_pemfile::read_one(&mut reader).expect("cannot read private key") { - Some(rustls_pemfile::Item::Pkcs1Key(key)) => return key.into(), - Some(rustls_pemfile::Item::Pkcs8Key(key)) => return key.into(), - Some(rustls_pemfile::Item::Sec1Key(key)) => return key.into(), - None => panic!("no keys found"), - _ => {} - } - } + PrivateKeyDer::from_pem_reader(&mut reader).expect("cannot read private key") } fn load_root_certs(filename: &str) -> RootCertificates { diff --git a/grpc/src/credentials/rustls/mod.rs b/grpc/src/credentials/rustls/mod.rs index 67885c42d..9134dd72f 100644 --- a/grpc/src/credentials/rustls/mod.rs +++ b/grpc/src/credentials/rustls/mod.rs @@ -22,11 +22,10 @@ * */ -use std::io::BufReader; - use rustls::crypto::CryptoProvider; use rustls::pki_types::PrivateKeyDer; use rustls_pki_types::CertificateDer; +use rustls_pki_types::pem::PemObject; use tokio::sync::watch; use crate::credentials::ProtocolInfo; @@ -154,21 +153,11 @@ fn sanitize_crypto_provider(mut crypto_provider: CryptoProvider) -> Result Result>, String> { - let mut reader = BufReader::new(pem); - rustls_pemfile::certs(&mut reader) + CertificateDer::pem_slice_iter(pem) .map(|result| result.map_err(|e| e.to_string())) .collect() } fn parse_key(pem: &[u8]) -> Result, String> { - let mut reader = BufReader::new(pem); - loop { - match rustls_pemfile::read_one(&mut reader).map_err(|e| e.to_string())? { - Some(rustls_pemfile::Item::Pkcs1Key(key)) => return Ok(key.into()), - Some(rustls_pemfile::Item::Pkcs8Key(key)) => return Ok(key.into()), - Some(rustls_pemfile::Item::Sec1Key(key)) => return Ok(key.into()), - None => return Err("no private key found".to_string()), - _ => continue, - } - } + PrivateKeyDer::from_pem_slice(pem).map_err(|e| e.to_string()) } diff --git a/grpc/src/credentials/rustls/server/test.rs b/grpc/src/credentials/rustls/server/test.rs index 14f1d4c5d..b8ba2688d 100644 --- a/grpc/src/credentials/rustls/server/test.rs +++ b/grpc/src/credentials/rustls/server/test.rs @@ -29,6 +29,7 @@ use std::sync::Once; use rustls::HandshakeKind; use rustls::crypto::ring; use rustls_pki_types::ServerName; +use rustls_pki_types::pem::PemObject; use tempfile::NamedTempFile; use tokio::io::AsyncReadExt; use tokio::io::AsyncWriteExt; @@ -675,7 +676,7 @@ fn load_certs(filename: &str) -> Vec> let path = test_certs_path().join(filename); let file = std::fs::File::open(path).expect("cannot open certificate file"); let mut reader = std::io::BufReader::new(file); - rustls_pemfile::certs(&mut reader) + rustls_pki_types::CertificateDer::pem_reader_iter(&mut reader) .map(|result| result.unwrap()) .collect() } @@ -684,15 +685,7 @@ fn load_private_key(filename: &str) -> rustls_pki_types::PrivateKeyDer<'static> let path = test_certs_path().join(filename); let file = std::fs::File::open(path).expect("cannot open private key file"); let mut reader = std::io::BufReader::new(file); - loop { - match rustls_pemfile::read_one(&mut reader).expect("cannot read private key") { - Some(rustls_pemfile::Item::Pkcs1Key(key)) => return key.into(), - Some(rustls_pemfile::Item::Pkcs8Key(key)) => return key.into(), - Some(rustls_pemfile::Item::Sec1Key(key)) => return key.into(), - None => panic!("no keys found"), - _ => {} - } - } + rustls_pki_types::PrivateKeyDer::from_pem_reader(&mut reader).expect("cannot read private key") } fn load_root_certs(filename: &str) -> RootCertificates { diff --git a/grpc/src/rt/tokio/hickory_resolver.rs b/grpc/src/rt/tokio/hickory_resolver.rs index 0c2ad6119..5c1d233a0 100644 --- a/grpc/src/rt/tokio/hickory_resolver.rs +++ b/grpc/src/rt/tokio/hickory_resolver.rs @@ -25,11 +25,13 @@ use std::net::IpAddr; use hickory_resolver::TokioResolver; +use hickory_resolver::config::ConnectionConfig; use hickory_resolver::config::LookupIpStrategy; -use hickory_resolver::config::NameServerConfigGroup; +use hickory_resolver::config::NameServerConfig; use hickory_resolver::config::ResolverConfig; use hickory_resolver::config::ResolverOpts; -use hickory_resolver::name_server::TokioConnectionProvider; +use hickory_resolver::net::runtime::TokioRuntimeProvider; +use hickory_resolver::proto::rr::RData; use crate::rt::ResolverOptions; use crate::rt::{self}; @@ -58,13 +60,19 @@ impl rt::DnsResolver for DnsResolver { .txt_lookup(name) .await .map_err(|err| err.to_string())? + .answers() .iter() - .map(|txt_record| { - txt_record - .iter() - .map(|bytes| String::from_utf8_lossy(bytes).into_owned()) - .collect::>() - .join("") + .filter_map(|record| { + if let RData::TXT(txt) = &record.data { + Some( + txt.txt_data + .iter() + .map(|bytes| String::from_utf8_lossy(bytes).into_owned()) + .collect::(), + ) + } else { + None + } }) .collect(); Ok(response) @@ -74,21 +82,23 @@ impl rt::DnsResolver for DnsResolver { impl DnsResolver { pub(super) fn new(opts: ResolverOptions) -> Result { let builder = if let Some(server_addr) = opts.server_addr { - let provider = TokioConnectionProvider::default(); - let name_servers = NameServerConfigGroup::from_ips_clear( - &[server_addr.ip()], - server_addr.port(), - true, - ); - let config = ResolverConfig::from_parts(None, vec![], name_servers); - TokioResolver::builder_with_config(config, provider) + let mut udp = ConnectionConfig::udp(); + udp.port = server_addr.port(); + let mut tcp = ConnectionConfig::tcp(); + tcp.port = server_addr.port(); + let name_server = NameServerConfig::new(server_addr.ip(), true, vec![udp, tcp]); + let config = ResolverConfig::from_parts(None, vec![], vec![name_server]); + TokioResolver::builder_with_config(config, TokioRuntimeProvider::default()) } else { TokioResolver::builder_tokio().map_err(|err| err.to_string())? }; let mut resolver_opts = ResolverOpts::default(); resolver_opts.ip_strategy = LookupIpStrategy::Ipv4AndIpv6; Ok(DnsResolver { - resolver: builder.with_options(resolver_opts).build(), + resolver: builder + .with_options(resolver_opts) + .build() + .map_err(|err| err.to_string())?, }) } } @@ -99,16 +109,17 @@ mod tests { use std::net::SocketAddr; use std::sync::Arc; - use hickory_resolver::Name; - use hickory_server::ServerFuture; - use hickory_server::authority::Catalog; - use hickory_server::authority::ZoneType; + use hickory_resolver::proto::rr::Name; + use hickory_server::Server; use hickory_server::proto::rr::LowerName; use hickory_server::proto::rr::RData; use hickory_server::proto::rr::Record; use hickory_server::proto::rr::rdata::A; use hickory_server::proto::rr::rdata::TXT; - use hickory_server::store::in_memory::InMemoryAuthority; + use hickory_server::store::in_memory::InMemoryZoneHandler; + use hickory_server::zone_handler::AxfrPolicy; + use hickory_server::zone_handler::Catalog; + use hickory_server::zone_handler::ZoneType; use tokio::net::UdpSocket; use tokio::sync::oneshot; use tokio::task::JoinHandle; @@ -214,8 +225,11 @@ mod tests { /// read from the returned struct. async fn start_in_memory_dns_server(host: &str, records: Vec) -> FakeDns { // Create a simple A record for `test.local.` - let authority = - InMemoryAuthority::empty(Name::from_ascii(host).unwrap(), ZoneType::Primary, false); + let authority: InMemoryZoneHandler = InMemoryZoneHandler::empty( + Name::from_ascii(host).unwrap(), + ZoneType::Primary, + AxfrPolicy::Deny, + ); for record in records { authority.upsert(record, 0).await; @@ -227,7 +241,7 @@ mod tests { vec![Arc::new(authority)], ); - let mut server = ServerFuture::new(catalog); + let mut server = Server::new(catalog); let socket = UdpSocket::bind("127.0.0.1:0").await.unwrap(); let addr = socket.local_addr().unwrap(); diff --git a/interop/Cargo.toml b/interop/Cargo.toml index 83dfb2043..3af648c49 100644 --- a/interop/Cargo.toml +++ b/interop/Cargo.toml @@ -15,27 +15,27 @@ path = "src/bin/server.rs" [dependencies] async-stream = "0.3" -strum = {version = "0.27", features = ["derive"]} -pico-args = {version = "0.5", features = ["eq-separator"]} +strum = { version = "0.28", features = ["derive"] } +pico-args = { version = "0.5", features = ["eq-separator"] } console = "0.16" http = "1" http-body-util = "0.1" prost = "0.14" -tokio = {version = "1.0", features = ["rt-multi-thread", "time", "macros"]} +tokio = { version = "1.52", features = ["rt-multi-thread", "time", "macros"] } tokio-stream = "0.1" -tonic = {path = "../tonic", features = ["tls-ring"]} -tonic-prost = {path = "../tonic-prost"} +tonic = { path = "../tonic", features = ["tls-ring"] } +tonic-prost = { path = "../tonic-prost" } tower = "0.5" -tracing-subscriber = {version = "0.3"} -grpc = {path = "../grpc"} +tracing-subscriber = { version = "0.3" } +grpc = { path = "../grpc" } # TODO: Remove once the protobuf-codegen crate supports configuring the path to # the protobuf crate used in the generated message code, instead of defaulting # to `::protobuf`. protobuf = { version = "4.34.0-release" } -tonic-protobuf = {path = "../tonic-protobuf"} -grpc-protobuf = {path = "../grpc-protobuf"} +tonic-protobuf = { path = "../tonic-protobuf" } +grpc-protobuf = { path = "../grpc-protobuf" } rustls = { version = "0.23", default-features = false, features = ["ring"] } [build-dependencies] -tonic-prost-build = {path = "../tonic-prost-build"} -grpc-protobuf-build = {path = "../grpc-protobuf-build"} +tonic-prost-build = { path = "../tonic-prost-build" } +grpc-protobuf-build = { path = "../grpc-protobuf-build" } diff --git a/interop/build.rs b/interop/build.rs index 1e2ea4057..d6277f881 100644 --- a/interop/build.rs +++ b/interop/build.rs @@ -4,7 +4,7 @@ fn main() { eprintln!("{}", grpc_protobuf_build::protoc()); let path = std::env::var("PATH").unwrap_or_default(); unsafe { - std::env::set_var("PATH", format!("{}:{}", path, grpc_protobuf_build::bin())); + std::env::set_var("PATH", format!("{}:{}", grpc_protobuf_build::bin(), path)); } tonic_prost_build::compile_protos(proto).unwrap(); diff --git a/protoc-gen-rust-grpc/CMakeLists.txt b/protoc-gen-rust-grpc/CMakeLists.txt index 6ccbdc551..a967995e9 100644 --- a/protoc-gen-rust-grpc/CMakeLists.txt +++ b/protoc-gen-rust-grpc/CMakeLists.txt @@ -27,7 +27,7 @@ fetch_protobuf(${PROTOBUF_VERSION}) # Download and configure abseil # Abseil version that's compatible with protobuf -set(ABSEIL_VERSION "20240722.0") +set(ABSEIL_VERSION "20260107.0") set(ABSEIL_URL "https://github.com/abseil/abseil-cpp/archive/refs/tags/${ABSEIL_VERSION}.tar.gz") message(STATUS "Downloading abseil-cpp ${ABSEIL_VERSION}") @@ -35,7 +35,7 @@ message(STATUS "Downloading abseil-cpp ${ABSEIL_VERSION}") FetchContent_Declare( absl URL ${ABSEIL_URL} - URL_HASH SHA256=f50e5ac311a81382da7fa75b97310e4b9006474f9560ac46f54a9967f07d4ae3 + URL_HASH SHA256=4c124408da902be896a2f368042729655709db5e3004ec99f57e3e14439bc1b2 DOWNLOAD_EXTRACT_TIMESTAMP TRUE ) @@ -67,6 +67,11 @@ target_link_libraries(protoc-gen-rust-grpc absl::flat_hash_map absl::strings absl::string_view + absl::status + absl::statusor + absl::log + absl::log_internal_message + absl::log_internal_check_op ) # Include directories @@ -110,7 +115,7 @@ install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/${PROTOC_OUTPUT_NAME} message(STATUS "") message(STATUS "protoc-gen-rust-grpc configuration summary:") message(STATUS " Protobuf version: ${PROTOBUF_VERSION}") -message(STATUS " Abseil version: ${ABSEIL_VERSION}") +message(STATUS " Abseil version: ${ABSEIL_VERSION} (matches protobuf ${PROTOBUF_VERSION} internal abseil)") message(STATUS " Build type: ${CMAKE_BUILD_TYPE}") message(STATUS " C++ standard: ${CMAKE_CXX_STANDARD}") message(STATUS " Output directory: ${CMAKE_BINARY_DIR}/bin") diff --git a/tests/compression/Cargo.toml b/tests/compression/Cargo.toml index b6a57a3cf..0cab8c4da 100644 --- a/tests/compression/Cargo.toml +++ b/tests/compression/Cargo.toml @@ -10,15 +10,18 @@ http = "1" http-body = "1" http-body-util = "0.1" hyper-util = "0.1" -paste = "1.0.12" -pin-project = "1.0" +pastey = "0.2" +pin-project = "1.1" prost = "0.14" -tokio = {version = "1.0", features = ["macros", "rt-multi-thread", "net"]} +tokio = { version = "1.52", features = ["macros", "rt-multi-thread", "net"] } tokio-stream = "0.1" -tonic = {path = "../../tonic", features = ["gzip", "deflate", "zstd"]} -tonic-prost = {path = "../../tonic-prost"} +tonic = { path = "../../tonic", features = ["gzip", "deflate", "zstd"] } +tonic-prost = { path = "../../tonic-prost" } tower = "0.5" -tower-http = {version = "0.6", features = ["map-response-body", "map-request-body"]} +tower-http = { version = "0.6", features = [ + "map-response-body", + "map-request-body", +] } [build-dependencies] -tonic-prost-build = {path = "../../tonic-prost-build" } +tonic-prost-build = { path = "../../tonic-prost-build" } diff --git a/tests/compression/src/util.rs b/tests/compression/src/util.rs index 095e32290..06923592b 100644 --- a/tests/compression/src/util.rs +++ b/tests/compression/src/util.rs @@ -20,7 +20,7 @@ use tower_http::map_request_body::MapRequestBodyLayer; macro_rules! parametrized_tests { ($fn_name:ident, $($test_name:ident: $input:expr),+ $(,)?) => { - paste::paste! { + pastey::paste! { $( #[tokio::test(flavor = "multi_thread")] async fn [<$fn_name _ $test_name>]() { diff --git a/tests/default_stubs/Cargo.toml b/tests/default_stubs/Cargo.toml index ffa09cfbe..76caf1cd3 100644 --- a/tests/default_stubs/Cargo.toml +++ b/tests/default_stubs/Cargo.toml @@ -5,13 +5,13 @@ license = "MIT" name = "default_stubs" [dependencies] -tokio = {version = "1.0", features = ["macros", "rt-multi-thread", "net"]} -tokio-stream = {version = "0.1", features = ["net"]} -tonic = {path = "../../tonic"} -tonic-prost = {path = "../../tonic-prost"} +tokio = { version = "1.52", features = ["macros", "rt-multi-thread", "net"] } +tokio-stream = { version = "0.1", features = ["net"] } +tonic = { path = "../../tonic" } +tonic-prost = { path = "../../tonic-prost" } [dev-dependencies] -tempfile = "3.20" +tempfile = "3.27" [build-dependencies] -tonic-prost-build = {path = "../../tonic-prost-build" } +tonic-prost-build = { path = "../../tonic-prost-build" } diff --git a/tests/integration_tests/Cargo.toml b/tests/integration_tests/Cargo.toml index ee9fed9e6..6daa8a55a 100644 --- a/tests/integration_tests/Cargo.toml +++ b/tests/integration_tests/Cargo.toml @@ -7,23 +7,28 @@ name = "integration-tests" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bytes = "1.0" +bytes = "1.11" prost = "0.14" -tokio = {version = "1.0", features = ["macros", "rt-multi-thread", "net", "sync"]} -tonic = {path = "../../tonic"} -tonic-prost = {path = "../../tonic-prost"} -tracing-subscriber = {version = "0.3"} +tokio = { version = "1.52", features = [ + "macros", + "rt-multi-thread", + "net", + "sync", +] } +tonic = { path = "../../tonic", features = ["tls-native-roots"] } +tonic-prost = { path = "../../tonic-prost" } +tracing-subscriber = { version = "0.3" } [dev-dependencies] h2 = "0.4" http = "1" http-body = "1" hyper-util = "0.1" -rustls = {version = "0.23", features = ["ring"]} -tokio-stream = {version = "0.1.5", features = ["net"]} +rustls = { version = "0.23", features = ["ring"] } +tokio-stream = { version = "0.1", features = ["net"] } tower = "0.5" tower-http = { version = "0.6", features = ["set-header", "trace"] } tower-service = "0.3" [build-dependencies] -tonic-prost-build = {path = "../../tonic-prost-build"} +tonic-prost-build = { path = "../../tonic-prost-build" } diff --git a/tests/integration_tests/tests/max_message_size.rs b/tests/integration_tests/tests/max_message_size.rs index de6c91f90..5802e8c80 100644 --- a/tests/integration_tests/tests/max_message_size.rs +++ b/tests/integration_tests/tests/max_message_size.rs @@ -243,11 +243,10 @@ fn assert_test_case(case: TestCase) { match (case.expected_code, res) { (Some(_), Ok(())) => panic!("Expected failure, but got success"), - (Some(code), Err(status)) => { - if status.code() != code { - panic!("Expected failure, got failure but wrong code, got: {status:?}") - } + (Some(code), Err(status)) if status.code() != code => { + panic!("Expected failure, got failure but wrong code, got: {status:?}") } + (Some(_), Err(_)) => (), (None, Err(status)) => panic!("Expected success, but got failure, got: {status:?}"), diff --git a/tests/web/Cargo.toml b/tests/web/Cargo.toml index edef9fa2b..dc9b799bb 100644 --- a/tests/web/Cargo.toml +++ b/tests/web/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT" [dependencies] base64 = "0.22" -bytes = "1.0" +bytes = "1.11" http-body-util = "0.1" hyper = "1" hyper-util = "0.1" diff --git a/tonic-build/src/lib.rs b/tonic-build/src/lib.rs index e03ec917d..d31fe18f9 100644 --- a/tonic-build/src/lib.rs +++ b/tonic-build/src/lib.rs @@ -268,10 +268,10 @@ fn naive_snake_case(name: &str) -> String { while let Some(x) = it.next() { s.push(x.to_ascii_lowercase()); - if let Some(y) = it.peek() { - if y.is_uppercase() { - s.push('_'); - } + if let Some(y) = it.peek() + && y.is_uppercase() + { + s.push('_'); } } diff --git a/tonic-health/Cargo.toml b/tonic-health/Cargo.toml index 6a96fed24..e6c64082f 100644 --- a/tonic-health/Cargo.toml +++ b/tonic-health/Cargo.toml @@ -16,30 +16,34 @@ rust-version = { workspace = true } [dependencies] prost = "0.14" -tokio = {version = "1.0", features = ["sync"]} -tokio-stream = {version = "0.1", default-features = false, features = ["sync"]} -tonic = { version = "0.14.0", path = "../tonic", default-features = false, features = ["codegen"] } +tokio = { version = "1.52", features = ["sync"] } +tokio-stream = { version = "0.1", default-features = false, features = [ + "sync", +] } +tonic = { version = "0.14.0", path = "../tonic", default-features = false, features = [ + "codegen", +] } tonic-prost = { version = "0.14.0", path = "../tonic-prost", default-features = false } [dev-dependencies] -tokio = {version = "1.0", features = ["rt-multi-thread", "macros"]} -prost-types = "0.14.0" +tokio = { version = "1.52", features = ["rt-multi-thread", "macros"] } +prost-types = "0.14" [lints] workspace = true [package.metadata.cargo_check_external_types] allowed_external_types = [ - "tonic::*", + "tonic::*", - # major released - "bytes::*", - "http::*", - "http_body::*", + # major released + "bytes::*", + "http::*", + "http_body::*", - # not major released - "prost::*", + # not major released + "prost::*", - "futures_core::stream::Stream", - "tower_service::Service", + "futures_core::stream::Stream", + "tower_service::Service", ] diff --git a/tonic-prost-build/Cargo.toml b/tonic-prost-build/Cargo.toml index 4a8ec9187..8cd170972 100644 --- a/tonic-prost-build/Cargo.toml +++ b/tonic-prost-build/Cargo.toml @@ -8,7 +8,11 @@ repository = "https://github.com/hyperium/tonic" homepage = "https://github.com/hyperium/tonic" description = "Prost build integration for tonic" readme = "README.md" -categories = ["development-tools::build-utils", "network-programming", "asynchronous"] +categories = [ + "development-tools::build-utils", + "network-programming", + "asynchronous", +] keywords = ["rpc", "grpc", "prost", "protobuf", "tonic"] rust-version = { workspace = true } @@ -25,14 +29,10 @@ prettyplease = { version = "0.2" } proc-macro2 = "1.0" quote = "1.0" syn = "2.0" -tempfile = "3.0" +tempfile = "3.27" [dev-dependencies] tonic = { version = "0.14.0", path = "../tonic", default-features = false } [package.metadata.cargo_check_external_types] -allowed_external_types = [ - "tonic_build::*", - "prost_build::*", - "prost_types::*" -] +allowed_external_types = ["tonic_build::*", "prost_build::*", "prost_types::*"] diff --git a/tonic-prost/src/codec.rs b/tonic-prost/src/codec.rs index f25bb6d43..7767218b8 100644 --- a/tonic-prost/src/codec.rs +++ b/tonic-prost/src/codec.rs @@ -380,7 +380,7 @@ mod tests { cx: &mut Context<'_>, ) -> Poll, Self::Error>>> { // every other call to poll_data returns data - let should_send = self.count % 2 == 0; + let should_send = self.count.is_multiple_of(2); let data_len = self.data.len(); let partial_len = self.partial_len; let count = self.count; diff --git a/tonic-reflection/Cargo.toml b/tonic-reflection/Cargo.toml index e295db1fd..c5d2ca19a 100644 --- a/tonic-reflection/Cargo.toml +++ b/tonic-reflection/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = [ - "James Nugent ", - "Samani G. Gikandi ", + "James Nugent ", + "Samani G. Gikandi ", ] categories = ["network-programming", "asynchronous"] description = """ @@ -26,32 +26,36 @@ default = ["server"] [dependencies] prost = "0.14" -prost-types = {version = "0.14", optional = true} -tokio = { version = "1.0", features = ["sync", "rt"], optional = true } -tokio-stream = {version = "0.1", default-features = false, optional = true } -tonic = { version = "0.14.0", path = "../tonic", default-features = false, features = ["codegen"] } +prost-types = { version = "0.14", optional = true } +tokio = { version = "1.52", features = ["sync", "rt"], optional = true } +tokio-stream = { version = "0.1", default-features = false, optional = true } +tonic = { version = "0.14.0", path = "../tonic", default-features = false, features = [ + "codegen", +] } tonic-prost = { version = "0.14.0", path = "../tonic-prost", default-features = false } [dev-dependencies] -tokio-stream = {version = "0.1", default-features = false, features = ["net"]} -tonic = { version = "0.14.0", path = "../tonic", default-features = false, features = ["transport"] } +tokio-stream = { version = "0.1", default-features = false, features = ["net"] } +tonic = { version = "0.14.0", path = "../tonic", default-features = false, features = [ + "transport", +] } [lints] workspace = true [package.metadata.cargo_check_external_types] allowed_external_types = [ - "tonic::*", + "tonic::*", - # major released - "bytes::*", - "http::*", - "http_body::*", + # major released + "bytes::*", + "http::*", + "http_body::*", - # not major released - "prost::*", - "prost_types::*", + # not major released + "prost::*", + "prost_types::*", - "futures_core::stream::Stream", - "tower_service::Service", + "futures_core::stream::Stream", + "tower_service::Service", ] diff --git a/tonic-types/src/richer_error/mod.rs b/tonic-types/src/richer_error/mod.rs index 91e6d0eea..5609d155d 100644 --- a/tonic-types/src/richer_error/mod.rs +++ b/tonic-types/src/richer_error/mod.rs @@ -851,10 +851,10 @@ impl RpcStatusExt for pb::Status { fn get_details_retry_info(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == RetryInfo::TYPE_URL { - if let Ok(detail) = RetryInfo::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == RetryInfo::TYPE_URL + && let Ok(detail) = RetryInfo::from_any_ref(any) + { + return Some(detail); } } @@ -863,10 +863,10 @@ impl RpcStatusExt for pb::Status { fn get_details_debug_info(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == DebugInfo::TYPE_URL { - if let Ok(detail) = DebugInfo::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == DebugInfo::TYPE_URL + && let Ok(detail) = DebugInfo::from_any_ref(any) + { + return Some(detail); } } @@ -875,10 +875,10 @@ impl RpcStatusExt for pb::Status { fn get_details_quota_failure(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == QuotaFailure::TYPE_URL { - if let Ok(detail) = QuotaFailure::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == QuotaFailure::TYPE_URL + && let Ok(detail) = QuotaFailure::from_any_ref(any) + { + return Some(detail); } } @@ -887,10 +887,10 @@ impl RpcStatusExt for pb::Status { fn get_details_error_info(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == ErrorInfo::TYPE_URL { - if let Ok(detail) = ErrorInfo::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == ErrorInfo::TYPE_URL + && let Ok(detail) = ErrorInfo::from_any_ref(any) + { + return Some(detail); } } @@ -899,10 +899,10 @@ impl RpcStatusExt for pb::Status { fn get_details_precondition_failure(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == PreconditionFailure::TYPE_URL { - if let Ok(detail) = PreconditionFailure::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == PreconditionFailure::TYPE_URL + && let Ok(detail) = PreconditionFailure::from_any_ref(any) + { + return Some(detail); } } @@ -911,10 +911,10 @@ impl RpcStatusExt for pb::Status { fn get_details_bad_request(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == BadRequest::TYPE_URL { - if let Ok(detail) = BadRequest::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == BadRequest::TYPE_URL + && let Ok(detail) = BadRequest::from_any_ref(any) + { + return Some(detail); } } @@ -923,10 +923,10 @@ impl RpcStatusExt for pb::Status { fn get_details_request_info(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == RequestInfo::TYPE_URL { - if let Ok(detail) = RequestInfo::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == RequestInfo::TYPE_URL + && let Ok(detail) = RequestInfo::from_any_ref(any) + { + return Some(detail); } } @@ -935,10 +935,10 @@ impl RpcStatusExt for pb::Status { fn get_details_resource_info(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == ResourceInfo::TYPE_URL { - if let Ok(detail) = ResourceInfo::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == ResourceInfo::TYPE_URL + && let Ok(detail) = ResourceInfo::from_any_ref(any) + { + return Some(detail); } } @@ -947,10 +947,10 @@ impl RpcStatusExt for pb::Status { fn get_details_help(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == Help::TYPE_URL { - if let Ok(detail) = Help::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == Help::TYPE_URL + && let Ok(detail) = Help::from_any_ref(any) + { + return Some(detail); } } @@ -959,10 +959,10 @@ impl RpcStatusExt for pb::Status { fn get_details_localized_message(&self) -> Option { for any in self.details.iter() { - if any.type_url.as_str() == LocalizedMessage::TYPE_URL { - if let Ok(detail) = LocalizedMessage::from_any_ref(any) { - return Some(detail); - } + if any.type_url.as_str() == LocalizedMessage::TYPE_URL + && let Ok(detail) = LocalizedMessage::from_any_ref(any) + { + return Some(detail); } } diff --git a/tonic-xds/Cargo.toml b/tonic-xds/Cargo.toml index bf93d0223..3b96f2d86 100644 --- a/tonic-xds/Cargo.toml +++ b/tonic-xds/Cargo.toml @@ -9,7 +9,7 @@ authors = [ "Ankur Mittal ", "Jeff Jiang ", "Lucio Franco ", - "Yutao Ma " + "Yutao Ma ", ] categories = ["web-programming", "network-programming", "asynchronous"] description = """ @@ -25,12 +25,15 @@ tonic = "0.14" http = "1" http-body = "1" pin-project-lite = "0.2" -tower = { version = "0.5", default-features = false, features = ["discover", "retry"] } +tower = { version = "0.5", default-features = false, features = [ + "discover", + "retry", +] } arc-swap = "1" dashmap = "6.1" -thiserror = "2.0.17" +thiserror = "2.0" url = "2.5.8" -futures-core = "0.3.31" +futures-core = "0.3" futures-util = "0.3" bytes = "1" xds-client = { version = "0.1.0-alpha.1", path = "../xds-client" } @@ -45,7 +48,7 @@ tokio = { version = "1", features = ["sync", "time"] } fastrand = "2" tokio-stream = "0.1" tokio-util = "0.7" -backoff = "0.4" +backon = { version = "1.6", default-features = false, features = ["std"] } shared_http_body = "0.1" tonic-prost = { version = "0.14", optional = true } @@ -53,9 +56,16 @@ tonic-prost = { version = "0.14", optional = true } workspace = true [dev-dependencies] -xds-client = { version = "0.1.0-alpha.1", path = "../xds-client", features = ["test-util"] } -tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "test-util"] } -tonic = { version = "0.14", features = [ "server", "channel", "tls-ring" ] } +xds-client = { version = "0.1.0-alpha.1", path = "../xds-client", features = [ + "test-util", +] } +tokio = { version = "1", features = [ + "rt-multi-thread", + "macros", + "net", + "test-util", +] } +tonic = { version = "0.14", features = ["server", "channel", "tls-ring"] } tonic-prost = "0.14" tonic-prost-build = "0.14" async-stream = "0.3" diff --git a/tonic-xds/examples/xds_server.rs b/tonic-xds/examples/xds_server.rs index c4232e59a..624f9e425 100644 --- a/tonic-xds/examples/xds_server.rs +++ b/tonic-xds/examples/xds_server.rs @@ -104,7 +104,7 @@ impl Snapshot { api_listener: Some(ApiListener { api_listener: Some(Any { type_url: TYPE_HCM.to_string(), - value: hcm.encode_to_vec().into(), + value: hcm.encode_to_vec(), }), }), ..Default::default() diff --git a/tonic-xds/src/client/retry.rs b/tonic-xds/src/client/retry.rs index c8f7c8c6d..1e1b1b0b8 100644 --- a/tonic-xds/src/client/retry.rs +++ b/tonic-xds/src/client/retry.rs @@ -7,8 +7,9 @@ use std::task::{Context, Poll}; use std::time::Duration; use arc_swap::ArcSwap; -use backoff::ExponentialBackoffBuilder; -use backoff::backoff::Backoff; +use backon::BackoffBuilder; +use backon::ExponentialBackoff; +use backon::ExponentialBuilder; use http::{Request, Response}; use http_body::Body; use shared_http_body::{SharedBody, SharedBodyExt}; @@ -184,14 +185,14 @@ impl Default for GrpcRetryPolicyConfig { /// gRPC header for tracking retry attempts per the gRPC spec. const GRPC_PREVIOUS_RPC_ATTEMPTS: &str = "grpc-previous-rpc-attempts"; -/// Create a [`backoff::ExponentialBackoff`] from a [`GrpcRetryBackoffConfig`]. -fn make_backoff(config: &GrpcRetryBackoffConfig) -> backoff::ExponentialBackoff { - ExponentialBackoffBuilder::default() - .with_initial_interval(config.base_interval) - .with_max_interval(config.max_interval) - .with_multiplier(config.backoff_multiplier) - .with_randomization_factor(0.2) - .with_max_elapsed_time(None) +/// Create an [`ExponentialBackoff`] iterator from a [`GrpcRetryBackoffConfig`]. +fn make_backoff(config: &GrpcRetryBackoffConfig) -> ExponentialBackoff { + ExponentialBuilder::default() + .with_min_delay(config.base_interval) + .with_max_delay(config.max_interval) + .with_factor(config.backoff_multiplier as f32) + .with_jitter() + .without_max_times() .build() } @@ -203,15 +204,26 @@ fn make_backoff(config: &GrpcRetryBackoffConfig) -> backoff::ExponentialBackoff /// Implements [`tower::retry::Policy`]. Tower's `Retry` service clones the policy /// for each request, so `backoff` and `attempts` track per-request retry state /// while the shared config is read from `ArcSwap` on each retry decision. -#[derive(Clone, Debug)] +#[derive(Debug)] pub(crate) struct GrpcRetryPolicy { config: Arc>, /// Backoff state for the current request, created from config on first retry. - backoff: Option, + backoff: Option, /// Number of retry attempts made so far for the current request. attempts: u32, } +impl Clone for GrpcRetryPolicy { + fn clone(&self) -> Self { + Self { + config: self.config.clone(), + // Each cloned policy gets a fresh backoff — it's per-request state. + backoff: None, + attempts: 0, + } + } +} + impl GrpcRetryPolicy { /// Create a new retry policy with the given configuration. pub(crate) fn new(config: GrpcRetryPolicyConfig) -> Self { @@ -237,9 +249,7 @@ impl GrpcRetryPolicy { let backoff = self .backoff .get_or_insert_with(|| make_backoff(backoff_config)); - backoff - .next_backoff() - .unwrap_or(backoff_config.max_interval) + backoff.next().unwrap_or(backoff_config.max_interval) } } diff --git a/tonic-xds/src/xds/resource/cluster.rs b/tonic-xds/src/xds/resource/cluster.rs index 295c30cf8..5b6acac5d 100644 --- a/tonic-xds/src/xds/resource/cluster.rs +++ b/tonic-xds/src/xds/resource/cluster.rs @@ -156,7 +156,9 @@ mod tests { #[test] fn test_all_resources_required() { - assert!(ClusterResource::ALL_RESOURCES_REQUIRED_IN_SOTW); + const { + assert!(ClusterResource::ALL_RESOURCES_REQUIRED_IN_SOTW); + } } #[test] diff --git a/tonic-xds/src/xds/resource/endpoints.rs b/tonic-xds/src/xds/resource/endpoints.rs index 6aee0ce74..1d6e2a40c 100644 --- a/tonic-xds/src/xds/resource/endpoints.rs +++ b/tonic-xds/src/xds/resource/endpoints.rs @@ -259,7 +259,9 @@ mod tests { fn test_eds_allows_partial_responses_in_sotw() { // EDS resources are per-cluster, so SotW responses may contain only a subset. // Unlike LDS/CDS which require all resources in every SotW response. - assert!(!EndpointsResource::ALL_RESOURCES_REQUIRED_IN_SOTW); + const { + assert!(!EndpointsResource::ALL_RESOURCES_REQUIRED_IN_SOTW); + } } #[test] diff --git a/tonic-xds/src/xds/resource/listener.rs b/tonic-xds/src/xds/resource/listener.rs index 7e8eb7173..d3edbe0df 100644 --- a/tonic-xds/src/xds/resource/listener.rs +++ b/tonic-xds/src/xds/resource/listener.rs @@ -118,7 +118,7 @@ mod tests { }; let hcm_any = Any { type_url: "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager".to_string(), - value: hcm.encode_to_vec().into(), + value: hcm.encode_to_vec(), }; Listener { name: name.to_string(), @@ -182,7 +182,9 @@ mod tests { #[test] fn test_all_resources_required() { - assert!(ListenerResource::ALL_RESOURCES_REQUIRED_IN_SOTW); + const { + assert!(ListenerResource::ALL_RESOURCES_REQUIRED_IN_SOTW); + } } #[test] @@ -223,7 +225,7 @@ mod tests { }; let hcm_any = Any { type_url: "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager".to_string(), - value: hcm.encode_to_vec().into(), + value: hcm.encode_to_vec(), }; let listener = Listener { name: "inline-listener".to_string(), diff --git a/tonic-xds/src/xds/resource/route_config.rs b/tonic-xds/src/xds/resource/route_config.rs index 2e95aadfe..75f681bc2 100644 --- a/tonic-xds/src/xds/resource/route_config.rs +++ b/tonic-xds/src/xds/resource/route_config.rs @@ -571,7 +571,9 @@ mod tests { #[test] fn test_not_all_resources_required() { - assert!(!RouteConfigResource::ALL_RESOURCES_REQUIRED_IN_SOTW); + const { + assert!(!RouteConfigResource::ALL_RESOURCES_REQUIRED_IN_SOTW); + } } #[test] diff --git a/tonic/Cargo.toml b/tonic/Cargo.toml index 099d2ac1b..eea08b9cb 100644 --- a/tonic/Cargo.toml +++ b/tonic/Cargo.toml @@ -16,7 +16,7 @@ license = "MIT" readme = "../README.md" repository = "https://github.com/hyperium/tonic" version = "0.14.5" -rust-version = {workspace = true} +rust-version = { workspace = true } exclude = ["benches-disabled"] [features] @@ -25,28 +25,51 @@ gzip = ["dep:flate2"] deflate = ["dep:flate2"] zstd = ["dep:zstd"] default = ["router", "transport", "codegen"] -_tls-any = ["dep:tokio", "tokio?/rt", "tokio?/macros", "tls-connect-info"] # Internal. Please choose one of `tls-ring` or `tls-aws-lc` +_tls-any = [ + "dep:tokio", + "tokio?/rt", + "tokio?/macros", + "tls-connect-info", +] # Internal. Please choose one of `tls-ring` or `tls-aws-lc` tls-ring = ["_tls-any", "tokio-rustls/ring"] tls-aws-lc = ["_tls-any", "tokio-rustls/aws-lc-rs"] tls-native-roots = ["_tls-any", "channel", "dep:rustls-native-certs"] -tls-webpki-roots = ["_tls-any","channel", "dep:webpki-roots"] +tls-webpki-roots = ["_tls-any", "channel", "dep:webpki-roots"] tls-connect-info = ["dep:tokio-rustls"] router = ["dep:axum", "dep:tower", "tower?/util"] server = [ - "dep:h2", - "dep:hyper", "hyper?/server", - "dep:hyper-util", "hyper-util?/service", "hyper-util?/server-auto", - "dep:socket2", - "dep:tokio", "tokio?/macros", "tokio?/net", "tokio?/time", - "tokio-stream/net", - "dep:tower", "tower?/util", "tower?/limit", "tower?/load-shed", + "dep:h2", + "dep:hyper", + "hyper?/server", + "dep:hyper-util", + "hyper-util?/service", + "hyper-util?/server-auto", + "dep:socket2", + "dep:tokio", + "tokio?/macros", + "tokio?/net", + "tokio?/time", + "tokio-stream/net", + "dep:tower", + "tower?/util", + "tower?/limit", + "tower?/load-shed", ] channel = [ - "dep:hyper", "hyper?/client", - "dep:hyper-util", "hyper-util?/client-legacy", - "dep:tower", "tower?/balance", "tower?/buffer", "tower?/discover", "tower?/limit", "tower?/load-shed", "tower?/util", - "dep:tokio", "tokio?/time", - "dep:hyper-timeout", + "dep:hyper", + "hyper?/client", + "dep:hyper-util", + "hyper-util?/client-legacy", + "dep:tower", + "tower?/balance", + "tower?/buffer", + "tower?/discover", + "tower?/limit", + "tower?/load-shed", + "tower?/util", + "dep:tokio", + "tokio?/time", + "dep:hyper-timeout", ] transport = ["server", "channel"] @@ -56,51 +79,58 @@ transport = ["server", "channel"] [dependencies] base64 = "0.22" -bytes = "1.0" -http = "1.1.0" +bytes = "1.11" +http = "1.4" tracing = "0.1" http-body = "1" http-body-util = "0.1" -percent-encoding = "2.1" -pin-project = "1.0.11" +percent-encoding = "2.3" +pin-project = "1.1" tower-layer = "0.3" tower-service = "0.3" -tokio-stream = {version = "0.1.16", default-features = false} +tokio-stream = { version = "0.1", default-features = false } # codegen -async-trait = {version = "0.1.13", optional = true} +async-trait = { version = "0.1", optional = true } # transport -h2 = {version = "0.4", optional = true} -hyper = {version = "1", features = ["http1", "http2"], optional = true} -hyper-util = { version = "0.1.11", features = ["tokio"], optional = true } +h2 = { version = "0.4", optional = true } +hyper = { version = "1", features = ["http1", "http2"], optional = true } +hyper-util = { version = "0.1", features = ["tokio"], optional = true } socket2 = { version = "0.6", optional = true, features = ["all"] } -tokio = {version = "1", default-features = false, optional = true} -tower = {version = "0.5", default-features = false, optional = true} -axum = {version = "0.8", default-features = false, optional = true} +tokio = { version = "1", default-features = false, optional = true } +tower = { version = "0.5", default-features = false, optional = true } +axum = { version = "0.8", default-features = false, optional = true } # rustls rustls-native-certs = { version = "0.8", optional = true } -tokio-rustls = { version = "0.26.1", default-features = false, features = ["logging", "tls12"], optional = true } +tokio-rustls = { version = "0.26", default-features = false, features = [ + "logging", + "tls12", +], optional = true } webpki-roots = { version = "1", optional = true } # compression -flate2 = {version = "1.0", optional = true} -zstd = { version = "0.13.0", optional = true } +flate2 = { version = "1.1", optional = true } +zstd = { version = "0.13", optional = true } # channel -hyper-timeout = {version = "0.5", optional = true} +hyper-timeout = { version = "0.5", optional = true } sync_wrapper = "1.0.2" [dev-dependencies] bencher = "0.1.5" -quickcheck = "1.0" -quickcheck_macros = "1.0" -static_assertions = "1.0" -tokio = {version = "1.0", features = ["rt-multi-thread", "macros", "test-util"]} -tower = {version = "0.5", features = ["load-shed", "timeout"]} +quickcheck = "1.1" +quickcheck_macros = "1.2" +static_assertions = "1.1" +tokio = { version = "1.52", features = [ + "rt-multi-thread", + "macros", + "test-util", +] } +tower = { version = "0.5", features = ["load-shed", "timeout"] } [lints] workspace = true @@ -110,28 +140,28 @@ all-features = true [package.metadata.cargo_check_external_types] allowed_external_types = [ - # major released - "bytes::*", - "tokio::*", - "http::*", - "http_body::*", - "hyper::*", - "rustls_pki_types::*", - - # not major released - "prost::*", - "tracing::*", - - "async_trait::async_trait", - "axum_core::body::Body", - "axum_core::response::into_response::IntoResponse", - "axum::routing::Router", - "futures_core::stream::Stream", - "h2::error::Error", - "tower_service::Service", - "tower_layer::Layer", - "tower_layer::stack::Stack", - "tower_layer::identity::Identity", + # major released + "bytes::*", + "tokio::*", + "http::*", + "http_body::*", + "hyper::*", + "rustls_pki_types::*", + + # not major released + "prost::*", + "tracing::*", + + "async_trait::async_trait", + "axum_core::body::Body", + "axum_core::response::into_response::IntoResponse", + "axum::routing::Router", + "futures_core::stream::Stream", + "h2::error::Error", + "tower_service::Service", + "tower_layer::Layer", + "tower_layer::stack::Stack", + "tower_layer::identity::Identity", ] [[bench]] diff --git a/tonic/src/codec/decode.rs b/tonic/src/codec/decode.rs index 4061303be..0455e3736 100644 --- a/tonic/src/codec/decode.rs +++ b/tonic/src/codec/decode.rs @@ -294,13 +294,13 @@ impl StreamingInner { } fn response(&mut self) -> Result<(), Status> { - if let Direction::Response(status) = self.direction { - if let Err(Some(e)) = crate::status::infer_grpc_status(self.trailers.as_ref(), status) { - // If the trailers contain a grpc-status, then we should return that as the error - // and otherwise stop the stream (by taking the error state) - self.trailers.take(); - return Err(e); - } + if let Direction::Response(status) = self.direction + && let Err(Some(e)) = crate::status::infer_grpc_status(self.trailers.as_ref(), status) + { + // If the trailers contain a grpc-status, then we should return that as the error + // and otherwise stop the stream (by taking the error state) + self.trailers.take(); + return Err(e); } Ok(()) } diff --git a/tonic/src/status.rs b/tonic/src/status.rs index eeceb32b4..1d35f3e0b 100644 --- a/tonic/src/status.rs +++ b/tonic/src/status.rs @@ -778,13 +778,13 @@ pub(crate) fn infer_grpc_status( trailers: Option<&HeaderMap>, status_code: http::StatusCode, ) -> Result<(), Option> { - if let Some(trailers) = trailers { - if let Some(status) = Status::from_header_map(trailers) { - if status.code() == Code::Ok { - return Ok(()); - } else { - return Err(status.into()); - } + if let Some(trailers) = trailers + && let Some(status) = Status::from_header_map(trailers) + { + if status.code() == Code::Ok { + return Ok(()); + } else { + return Err(status.into()); } } trace!("trailers missing grpc-status"); diff --git a/tonic/src/transport/channel/endpoint.rs b/tonic/src/transport/channel/endpoint.rs index 3f639c91a..72870aa1b 100644 --- a/tonic/src/transport/channel/endpoint.rs +++ b/tonic/src/transport/channel/endpoint.rs @@ -63,10 +63,11 @@ impl Endpoint { { let me = dst.try_into().map_err(|e| Error::from_source(e.into()))?; #[cfg(feature = "_tls-any")] - if let EndpointType::Uri(uri) = &me.uri { - if me.tls.is_none() && uri.scheme() == Some(&http::uri::Scheme::HTTPS) { - return me.tls_config(ClientTlsConfig::new().with_enabled_roots()); - } + if let EndpointType::Uri(uri) = &me.uri + && me.tls.is_none() + && uri.scheme() == Some(&http::uri::Scheme::HTTPS) + { + return me.tls_config(ClientTlsConfig::new().with_enabled_roots()); } Ok(me) } diff --git a/tonic/src/transport/server/incoming.rs b/tonic/src/transport/server/incoming.rs index 3eb06d76e..b2d396ab1 100644 --- a/tonic/src/transport/server/incoming.rs +++ b/tonic/src/transport/server/incoming.rs @@ -146,10 +146,10 @@ fn set_accepted_socket_options( nodelay: Option, keepalive: &Option, ) { - if let Some(nodelay) = nodelay { - if let Err(e) = stream.set_nodelay(nodelay) { - warn!("error trying to set TCP_NODELAY: {e}"); - } + if let Some(nodelay) = nodelay + && let Err(e) = stream.set_nodelay(nodelay) + { + warn!("error trying to set TCP_NODELAY: {e}"); } if let Some(keepalive) = keepalive { diff --git a/tonic/src/transport/server/io_stream.rs b/tonic/src/transport/server/io_stream.rs index 06e288290..3bdf19619 100644 --- a/tonic/src/transport/server/io_stream.rs +++ b/tonic/src/transport/server/io_stream.rs @@ -126,8 +126,8 @@ where fn handle_tcp_accept_error(e: impl Into) -> ControlFlow { let e = e.into(); tracing::debug!(error = %e, "accept loop error"); - if let Some(e) = e.downcast_ref::() { - if matches!( + if let Some(e) = e.downcast_ref::() + && matches!( e.kind(), io::ErrorKind::ConnectionAborted | io::ErrorKind::ConnectionReset @@ -135,9 +135,9 @@ fn handle_tcp_accept_error(e: impl Into) -> ControlFlow