use eyre::{Context, Result};
use std::time::Duration;
use tonic::transport::{Channel, ClientTlsConfig};
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
pub async fn create_channel(url: &str) -> Result<Channel> {
let is_https = url.starts_with("https://");
let endpoint = Channel::from_shared(url.to_string())
.wrap_err_with(|| format!("Invalid gRPC URL: {}", url))?
.timeout(DEFAULT_TIMEOUT)
.connect_timeout(Duration::from_secs(10))
.http2_keep_alive_interval(Duration::from_secs(10))
.keep_alive_timeout(Duration::from_secs(20))
.keep_alive_while_idle(true);
let endpoint = if is_https {
let tls_config = ClientTlsConfig::new().with_native_roots();
endpoint
.tls_config(tls_config)
.wrap_err("Failed to configure TLS")?
} else {
endpoint
};
endpoint
.connect()
.await
.wrap_err_with(|| format!("Failed to connect to gRPC server at {}", url))
}
#[cfg(test)]
mod tests {
#[test]
fn test_https_detection() {
assert!("https://example.com:50051".starts_with("https://"));
assert!("https://grpc.cvm-demo.aspens.xyz:50051".starts_with("https://"));
assert!(!"http://localhost:50051".starts_with("https://"));
assert!(!"http://127.0.0.1:50051".starts_with("https://"));
}
}