tonic/transport/channel/
uds_connector.rs1use std::future::Future;
2use std::pin::Pin;
3use std::task::{Context, Poll};
4
5use http::Uri;
6use hyper_util::rt::TokioIo;
7
8use tower::Service;
9
10use crate::status::ConnectError;
11
12#[cfg(not(target_os = "windows"))]
13use tokio::net::UnixStream;
14
15#[cfg(not(target_os = "windows"))]
16async fn connect_uds(uds_path: String) -> Result<UnixStream, ConnectError> {
17 UnixStream::connect(uds_path)
18 .await
19 .map_err(|err| ConnectError(From::from(err)))
20}
21
22#[cfg(target_os = "windows")]
25#[allow(dead_code)]
26type UnixStream = tokio::io::DuplexStream;
27
28#[cfg(target_os = "windows")]
29async fn connect_uds(_uds_path: String) -> Result<UnixStream, ConnectError> {
30 Err(ConnectError(
31 "uds connections are not allowed on windows".into(),
32 ))
33}
34
35pub(crate) struct UdsConnector {
36 uds_filepath: String,
37}
38
39impl UdsConnector {
40 pub(crate) fn new(uds_filepath: &str) -> Self {
41 UdsConnector {
42 uds_filepath: uds_filepath.to_string(),
43 }
44 }
45}
46
47impl Service<Uri> for UdsConnector {
48 type Response = TokioIo<UnixStream>;
49 type Error = ConnectError;
50 type Future = UdsConnecting;
51
52 fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
53 Poll::Ready(Ok(()))
54 }
55
56 fn call(&mut self, _: Uri) -> Self::Future {
57 let uds_path = self.uds_filepath.clone();
58 let fut = async move {
59 let stream = connect_uds(uds_path).await?;
60 Ok(TokioIo::new(stream))
61 };
62 UdsConnecting {
63 inner: Box::pin(fut),
64 }
65 }
66}
67
68type ConnectResult = Result<TokioIo<UnixStream>, ConnectError>;
69
70pub(crate) struct UdsConnecting {
71 inner: Pin<Box<dyn Future<Output = ConnectResult> + Send>>,
72}
73
74impl Future for UdsConnecting {
75 type Output = ConnectResult;
76
77 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
78 self.get_mut().inner.as_mut().poll(cx)
79 }
80}