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}