Skip to main content

http_request/request/proxy/
impl.rs

1use super::*;
2
3impl ProxyTunnelStream {
4    /// Creates an asynchronous proxy tunnel stream.
5    ///
6    /// # Arguments
7    ///
8    /// - `BoxAsyncReadWrite` - The boxed inner stream carrying the tunneled bytes.
9    /// - `Vec<u8>` - The data already read from the proxy during the handshake.
10    pub(crate) fn new(stream: BoxAsyncReadWrite, pre_read_data: Vec<u8>) -> Self {
11        Self {
12            inner: stream,
13            pre_read_data,
14        }
15    }
16}
17
18impl AsyncRead for ProxyTunnelStream {
19    /// Reads the pre-read handshake data before delegating to the inner stream.
20    ///
21    /// # Arguments
22    ///
23    /// - `Pin<&mut Self>` - A pinned mutable reference to the tunnel stream.
24    /// - `&mut Context<'_>` - The task context used to register the read interest.
25    /// - `&mut ReadBuf<'_>` - The buffer that receives the read bytes.
26    ///
27    /// # Returns
28    ///
29    /// - `Poll<std::io::Result<()>>` - The poll outcome carrying any read error.
30    fn poll_read(
31        mut self: Pin<&mut Self>,
32        cx: &mut Context<'_>,
33        buf: &mut ReadBuf<'_>,
34    ) -> Poll<std::io::Result<()>> {
35        if !self.get_pre_read_data().is_empty() {
36            let len: usize = std::cmp::min(self.get_pre_read_data().len(), buf.remaining());
37            buf.put_slice(&self.get_pre_read_data()[..len]);
38            self.get_mut_pre_read_data().drain(..len);
39            return Poll::Ready(Ok(()));
40        }
41        Pin::new(self.get_mut_inner()).poll_read(cx, buf)
42    }
43}
44
45impl AsyncWrite for ProxyTunnelStream {
46    /// Writes bytes to the inner stream through the proxy tunnel.
47    ///
48    /// # Arguments
49    ///
50    /// - `Pin<&mut Self>` - A pinned mutable reference to the tunnel stream.
51    /// - `&mut Context<'_>` - The task context used to register the write interest.
52    /// - `&[u8]` - The buffer of bytes to write.
53    ///
54    /// # Returns
55    ///
56    /// - `Poll<Result<usize, std::io::Error>>` - The poll outcome carrying the written byte count or any error.
57    fn poll_write(
58        mut self: Pin<&mut Self>,
59        cx: &mut Context<'_>,
60        buf: &[u8],
61    ) -> Poll<Result<usize, std::io::Error>> {
62        Pin::new(self.get_mut_inner()).poll_write(cx, buf)
63    }
64
65    /// Flushes the inner stream through the proxy tunnel.
66    ///
67    /// # Arguments
68    ///
69    /// - `Pin<&mut Self>` - A pinned mutable reference to the tunnel stream.
70    /// - `&mut Context<'_>` - The task context used to register the flush interest.
71    ///
72    /// # Returns
73    ///
74    /// - `Poll<Result<(), std::io::Error>>` - The poll outcome carrying any flush error.
75    fn poll_flush(
76        mut self: Pin<&mut Self>,
77        cx: &mut Context<'_>,
78    ) -> Poll<Result<(), std::io::Error>> {
79        Pin::new(self.get_mut_inner()).poll_flush(cx)
80    }
81
82    /// Shuts down the inner stream through the proxy tunnel.
83    ///
84    /// # Arguments
85    ///
86    /// - `Pin<&mut Self>` - A pinned mutable reference to the tunnel stream.
87    /// - `&mut Context<'_>` - The task context used to register the shutdown interest.
88    ///
89    /// # Returns
90    ///
91    /// - `Poll<Result<(), std::io::Error>>` - The poll outcome carrying any shutdown error.
92    fn poll_shutdown(
93        mut self: Pin<&mut Self>,
94        cx: &mut Context<'_>,
95    ) -> Poll<Result<(), std::io::Error>> {
96        Pin::new(self.get_mut_inner()).poll_shutdown(cx)
97    }
98}
99
100impl Unpin for ProxyTunnelStream {}
101
102impl SyncProxyTunnelStream {
103    /// Creates a synchronous proxy tunnel stream.
104    ///
105    /// # Arguments
106    ///
107    /// - `BoxReadWrite` - The boxed inner stream carrying the tunneled bytes.
108    /// - `Vec<u8>` - The data already read from the proxy during the handshake.
109    pub(crate) fn new(stream: BoxReadWrite, pre_read_data: Vec<u8>) -> Self {
110        Self {
111            inner: stream,
112            pre_read_data,
113        }
114    }
115}
116
117impl Read for SyncProxyTunnelStream {
118    /// Reads the pre-read handshake data before delegating to the inner stream.
119    ///
120    /// # Arguments
121    ///
122    /// - `&mut [u8]` - The buffer that receives the read bytes.
123    ///
124    /// # Returns
125    ///
126    /// - `std::io::Result<usize>` - The read outcome carrying the number of bytes read or any error.
127    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
128        if !self.get_pre_read_data().is_empty() {
129            let len: usize = std::cmp::min(self.get_pre_read_data().len(), buf.len());
130            buf[..len].copy_from_slice(&self.get_pre_read_data()[..len]);
131            self.get_mut_pre_read_data().drain(..len);
132            return Ok(len);
133        }
134        self.get_mut_inner().read(buf)
135    }
136}
137
138impl Write for SyncProxyTunnelStream {
139    /// Writes bytes to the inner stream through the proxy tunnel.
140    ///
141    /// # Arguments
142    ///
143    /// - `&[u8]` - The buffer of bytes to write.
144    ///
145    /// # Returns
146    ///
147    /// - `std::io::Result<usize>` - The write outcome carrying the number of bytes written or any error.
148    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
149        self.get_mut_inner().write(buf)
150    }
151
152    /// Flushes the inner stream through the proxy tunnel.
153    ///
154    /// # Returns
155    ///
156    /// - `std::io::Result<()>` - The flush outcome carrying any flush error.
157    fn flush(&mut self) -> std::io::Result<()> {
158        self.get_mut_inner().flush()
159    }
160}
161
162impl Proxy {
163    /// Creates a plain HTTP proxy.
164    ///
165    /// # Arguments
166    ///
167    /// - `H` - The proxy host, converted to a string slice.
168    /// - `u16` - The proxy port.
169    pub fn http<H: AsRef<str>>(host: H, port: u16) -> Self {
170        Self::new(ProxyType::Http, host, port)
171    }
172
173    /// Creates an HTTPS (TLS-wrapped) proxy.
174    ///
175    /// # Arguments
176    ///
177    /// - `H` - The proxy host, converted to a string slice.
178    /// - `u16` - The proxy port.
179    pub fn https<H: AsRef<str>>(host: H, port: u16) -> Self {
180        Self::new(ProxyType::Https, host, port)
181    }
182
183    /// Creates a SOCKS5 proxy.
184    ///
185    /// # Arguments
186    ///
187    /// - `H` - The proxy host, converted to a string slice.
188    /// - `u16` - The proxy port.
189    pub fn socks5<H: AsRef<str>>(host: H, port: u16) -> Self {
190        Self::new(ProxyType::Socks5, host, port)
191    }
192
193    /// Attaches a username and password to this proxy.
194    ///
195    /// # Arguments
196    ///
197    /// - `U` - The proxy username, converted to a string slice.
198    /// - `P` - The proxy password, converted to a string slice.
199    pub fn auth<U: AsRef<str>, P: AsRef<str>>(mut self, username: U, password: P) -> Self {
200        self.set_username(Some(username.as_ref().to_owned()));
201        self.set_password(Some(password.as_ref().to_owned()));
202        self
203    }
204
205    /// Creates a proxy of the given type for a host and port.
206    ///
207    /// # Arguments
208    ///
209    /// - `ProxyType` - The protocol used to reach the proxy.
210    /// - `H` - The proxy host, converted to a string slice.
211    /// - `u16` - The proxy port.
212    fn new<H: AsRef<str>>(proxy_type: ProxyType, host: H, port: u16) -> Self {
213        Self {
214            proxy_type,
215            host: host.as_ref().to_owned(),
216            port,
217            username: None,
218            password: None,
219        }
220    }
221}