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<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<io::Result<()>> {
35        if !self.get_pre_read_data().is_empty() {
36            let len: usize = 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, 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, 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<(), io::Error>>` - The poll outcome carrying any flush error.
75    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
76        Pin::new(self.get_mut_inner()).poll_flush(cx)
77    }
78
79    /// Shuts down the inner stream through the proxy tunnel.
80    ///
81    /// # Arguments
82    ///
83    /// - `Pin<&mut Self>` - A pinned mutable reference to the tunnel stream.
84    /// - `&mut Context<'_>` - The task context used to register the shutdown interest.
85    ///
86    /// # Returns
87    ///
88    /// - `Poll<Result<(), io::Error>>` - The poll outcome carrying any shutdown error.
89    fn poll_shutdown(
90        mut self: Pin<&mut Self>,
91        cx: &mut Context<'_>,
92    ) -> Poll<Result<(), io::Error>> {
93        Pin::new(self.get_mut_inner()).poll_shutdown(cx)
94    }
95}
96
97impl Unpin for ProxyTunnelStream {}
98
99impl SyncProxyTunnelStream {
100    /// Creates a synchronous proxy tunnel stream.
101    ///
102    /// # Arguments
103    ///
104    /// - `BoxReadWrite` - The boxed inner stream carrying the tunneled bytes.
105    /// - `Vec<u8>` - The data already read from the proxy during the handshake.
106    pub(crate) fn new(stream: BoxReadWrite, pre_read_data: Vec<u8>) -> Self {
107        Self {
108            inner: stream,
109            pre_read_data,
110        }
111    }
112}
113
114impl Read for SyncProxyTunnelStream {
115    /// Reads the pre-read handshake data before delegating to the inner stream.
116    ///
117    /// # Arguments
118    ///
119    /// - `&mut [u8]` - The buffer that receives the read bytes.
120    ///
121    /// # Returns
122    ///
123    /// - `io::Result<usize>` - The read outcome carrying the number of bytes read or any error.
124    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
125        if !self.get_pre_read_data().is_empty() {
126            let len: usize = cmp::min(self.get_pre_read_data().len(), buf.len());
127            buf[..len].copy_from_slice(&self.get_pre_read_data()[..len]);
128            self.get_mut_pre_read_data().drain(..len);
129            return Ok(len);
130        }
131        self.get_mut_inner().read(buf)
132    }
133}
134
135impl Write for SyncProxyTunnelStream {
136    /// Writes bytes to the inner stream through the proxy tunnel.
137    ///
138    /// # Arguments
139    ///
140    /// - `&[u8]` - The buffer of bytes to write.
141    ///
142    /// # Returns
143    ///
144    /// - `io::Result<usize>` - The write outcome carrying the number of bytes written or any error.
145    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
146        self.get_mut_inner().write(buf)
147    }
148
149    /// Flushes the inner stream through the proxy tunnel.
150    ///
151    /// # Returns
152    ///
153    /// - `io::Result<()>` - The flush outcome carrying any flush error.
154    fn flush(&mut self) -> io::Result<()> {
155        self.get_mut_inner().flush()
156    }
157}
158
159impl Proxy {
160    /// Creates a plain HTTP proxy.
161    ///
162    /// # Arguments
163    ///
164    /// - `H` - The proxy host, converted to a string slice.
165    /// - `u16` - The proxy port.
166    pub fn http<H: AsRef<str>>(host: H, port: u16) -> Self {
167        Self::new(ProxyType::Http, host, port)
168    }
169
170    /// Creates an HTTPS (TLS-wrapped) proxy.
171    ///
172    /// # Arguments
173    ///
174    /// - `H` - The proxy host, converted to a string slice.
175    /// - `u16` - The proxy port.
176    pub fn https<H: AsRef<str>>(host: H, port: u16) -> Self {
177        Self::new(ProxyType::Https, host, port)
178    }
179
180    /// Creates a SOCKS5 proxy.
181    ///
182    /// # Arguments
183    ///
184    /// - `H` - The proxy host, converted to a string slice.
185    /// - `u16` - The proxy port.
186    pub fn socks5<H: AsRef<str>>(host: H, port: u16) -> Self {
187        Self::new(ProxyType::Socks5, host, port)
188    }
189
190    /// Attaches a username and password to this proxy.
191    ///
192    /// # Arguments
193    ///
194    /// - `U` - The proxy username, converted to a string slice.
195    /// - `P` - The proxy password, converted to a string slice.
196    pub fn auth<U: AsRef<str>, P: AsRef<str>>(mut self, username: U, password: P) -> Self {
197        self.set_username(Some(username.as_ref().to_owned()));
198        self.set_password(Some(password.as_ref().to_owned()));
199        self
200    }
201
202    /// Creates a proxy of the given type for a host and port.
203    ///
204    /// # Arguments
205    ///
206    /// - `ProxyType` - The protocol used to reach the proxy.
207    /// - `H` - The proxy host, converted to a string slice.
208    /// - `u16` - The proxy port.
209    fn new<H: AsRef<str>>(proxy_type: ProxyType, host: H, port: u16) -> Self {
210        Self {
211            proxy_type,
212            host: host.as_ref().to_owned(),
213            port,
214            username: None,
215            password: None,
216        }
217    }
218}