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}