hyper_client_sockets/
connector.rs1use std::{
2 pin::Pin,
3 task::{Context, Poll},
4};
5
6use hyper_util::client::legacy::connect::{Connected, Connection};
7
8pub struct ConnectableIo<IO>(IO);
11
12impl<IO: hyper::rt::Write + hyper::rt::Read + Send + Unpin> hyper::rt::Write for ConnectableIo<IO> {
13 #[inline(always)]
14 fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, std::io::Error>> {
15 Pin::new(&mut self.get_mut().0).poll_write(cx, buf)
16 }
17
18 #[inline(always)]
19 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {
20 Pin::new(&mut self.get_mut().0).poll_flush(cx)
21 }
22
23 #[inline(always)]
24 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {
25 Pin::new(&mut self.get_mut().0).poll_shutdown(cx)
26 }
27}
28
29impl<IO: hyper::rt::Write + hyper::rt::Read + Send + Unpin> hyper::rt::Read for ConnectableIo<IO> {
30 #[inline(always)]
31 fn poll_read(
32 self: Pin<&mut Self>,
33 cx: &mut Context<'_>,
34 buf: hyper::rt::ReadBufCursor<'_>,
35 ) -> Poll<Result<(), std::io::Error>> {
36 Pin::new(&mut self.get_mut().0).poll_read(cx, buf)
37 }
38}
39
40impl<IO: hyper::rt::Write + hyper::rt::Read + Send + Unpin> Connection for ConnectableIo<IO> {
41 fn connected(&self) -> Connected {
42 Connected::new()
43 }
44}
45
46#[cfg(feature = "unix")]
47#[cfg_attr(docsrs, doc(cfg(feature = "unix")))]
48mod unix {
49 use std::{future::Future, marker::PhantomData, pin::Pin, task::Poll};
50
51 use http::Uri;
52
53 use crate::{uri::UnixUri, Backend};
54
55 use super::ConnectableIo;
56
57 #[derive(Debug, Clone)]
60 pub struct UnixConnector<B: Backend> {
61 marker: PhantomData<B>,
62 }
63
64 impl<B: Backend> UnixConnector<B> {
65 pub fn new() -> Self {
66 Self { marker: PhantomData }
67 }
68 }
69
70 impl<B: Backend> tower_service::Service<Uri> for UnixConnector<B> {
71 type Response = ConnectableIo<B::UnixIo>;
72
73 type Error = std::io::Error;
74
75 type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
76
77 #[inline(always)]
78 fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
79 Poll::Ready(Ok(()))
80 }
81
82 #[inline(always)]
83 fn call(&mut self, uri: Uri) -> Self::Future {
84 Box::pin(async move {
85 let socket_path = uri.parse_unix()?;
86 let io = B::connect_to_unix_socket(&socket_path).await?;
87 Ok(ConnectableIo(io))
88 })
89 }
90 }
91}
92
93#[cfg(feature = "unix")]
94#[cfg_attr(docsrs, doc(cfg(feature = "unix")))]
95pub use unix::UnixConnector;
96
97#[cfg(feature = "vsock")]
98#[cfg_attr(docsrs, doc(cfg(feature = "vsock")))]
99mod vsock {
100 use std::{future::Future, marker::PhantomData, pin::Pin, task::Poll};
101
102 use http::Uri;
103
104 use crate::{uri::VsockUri, Backend};
105
106 use super::ConnectableIo;
107
108 #[derive(Debug, Clone)]
111 pub struct VsockConnector<B: Backend> {
112 marker: PhantomData<B>,
113 }
114
115 impl<B: Backend> VsockConnector<B> {
116 pub fn new() -> Self {
117 Self { marker: PhantomData }
118 }
119 }
120
121 impl<B: Backend> tower_service::Service<Uri> for VsockConnector<B> {
122 type Response = ConnectableIo<B::VsockIo>;
123
124 type Error = std::io::Error;
125
126 type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
127
128 #[inline(always)]
129 fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
130 Poll::Ready(Ok(()))
131 }
132
133 #[inline(always)]
134 fn call(&mut self, uri: Uri) -> Self::Future {
135 Box::pin(async move {
136 let addr = uri.parse_vsock()?;
137 let io = B::connect_to_vsock_socket(addr).await?;
138 Ok(ConnectableIo(io))
139 })
140 }
141 }
142}
143
144#[cfg(feature = "vsock")]
145#[cfg_attr(docsrs, doc(cfg(feature = "vsock")))]
146pub use vsock::VsockConnector;
147
148#[cfg(feature = "firecracker")]
149#[cfg_attr(docsrs, doc(cfg(feature = "firecracker")))]
150mod firecracker {
151 use std::{future::Future, marker::PhantomData, pin::Pin, task::Poll};
152
153 use http::Uri;
154
155 use crate::{uri::FirecrackerUri, Backend};
156
157 use super::ConnectableIo;
158
159 #[derive(Debug, Clone)]
162 pub struct FirecrackerConnector<B: Backend> {
163 marker: PhantomData<B>,
164 }
165
166 impl<B: Backend> FirecrackerConnector<B> {
167 pub fn new() -> Self {
168 Self { marker: PhantomData }
169 }
170 }
171
172 impl<B: Backend> tower_service::Service<Uri> for FirecrackerConnector<B> {
173 type Response = ConnectableIo<B::FirecrackerIo>;
174
175 type Error = std::io::Error;
176
177 type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
178
179 #[inline(always)]
180 fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
181 Poll::Ready(Ok(()))
182 }
183
184 #[inline(always)]
185 fn call(&mut self, uri: Uri) -> Self::Future {
186 Box::pin(async move {
187 let (host_socket_path, guest_port) = uri.parse_firecracker()?;
188 let io = B::connect_to_firecracker_socket(&host_socket_path, guest_port).await?;
189 Ok(ConnectableIo(io))
190 })
191 }
192 }
193}
194
195#[cfg(feature = "firecracker")]
196#[cfg_attr(docsrs, doc(cfg(feature = "firecracker")))]
197pub use firecracker::FirecrackerConnector;