1 // Copyright (c) 2025 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 #![cfg(all(
15 feature = "async",
16 feature = "tokio_base",
17 feature = "http1_1",
18 not(feature = "__tls")
19 ))]
20
21 mod common;
22
23 use std::convert::Infallible;
24 use std::io;
25 use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
26
27 use ylong_http_client::async_impl::{Body, Client, Request, Resolver, SocketFuture};
28
29 use crate::common::init_test_work_runtime;
30
server_fn( _req: hyper::Request<hyper::Body>, ) -> Result<hyper::Response<hyper::Body>, Infallible>31 async fn server_fn(
32 _req: hyper::Request<hyper::Body>,
33 ) -> Result<hyper::Response<hyper::Body>, Infallible> {
34 let response = hyper::Response::builder()
35 .status(hyper::StatusCode::OK)
36 .body(hyper::Body::empty())
37 .expect("build hyper response failed");
38 Ok(response)
39 }
40
41 macro_rules! dns_test {
42 (
43 Ipv4;
44 Success;
45 $resolver: ident
46 ) => {
47 define_service_handle!(HTTP;);
48 let rt = init_test_work_runtime(4);
49 let (tx, rx) = std::sync::mpsc::channel();
50
51 rt.block_on(async move {
52 let mut handle = start_http_server!(HTTP; server_fn);
53 handle
54 .server_start
55 .recv()
56 .await
57 .expect("recv server start msg failed !");
58 tx.send(handle)
59 .expect("send Handle out the server coroutine failed !");
60 });
61
62 let mut handle = rx.recv().expect("recv Handle failed !");
63
64 let client = Client::builder()
65 .dns_resolver($resolver)
66 .build()
67 .expect("Build Client failed.");
68
69 let request = Request::builder()
70 .url(format!("localhost:{}", handle.port).as_str())
71 .body(Body::empty())
72 .expect("Client build Request failed.");
73
74 rt.block_on(async move {
75 let response = client.request(request).await;
76 assert!(response.is_ok());
77
78 handle
79 .client_shutdown
80 .send(())
81 .await
82 .expect("send client shutdown");
83 handle
84 .server_shutdown
85 .recv()
86 .await
87 .expect("server shutdown");
88 })
89 };
90 (
91 Ipv6;
92 Success;
93 $resolver: ident
94 ) => {
95 define_service_handle!(HTTP;);
96 let rt = init_test_work_runtime(4);
97 let (tx, rx) = std::sync::mpsc::channel();
98
99 rt.block_on(async move {
100 let mut handle = start_http_server!(HTTP; Ipv6; server_fn);
101 handle
102 .server_start
103 .recv()
104 .await
105 .expect("recv server start msg failed !");
106 tx.send(handle)
107 .expect("send Handle out the server coroutine failed !");
108 });
109
110 let mut handle = rx.recv().expect("recv Handle failed !");
111
112 let client = Client::builder()
113 .dns_resolver($resolver)
114 .build()
115 .expect("Build Client failed.");
116
117 let request = Request::builder()
118 .url(format!("localhost:{}", handle.port).as_str())
119 .body(Body::empty())
120 .expect("Client build Request failed.");
121
122 rt.block_on(async move {
123 let response = client.request(request).await;
124 assert!(response.is_ok());
125
126 handle
127 .client_shutdown
128 .send(())
129 .await
130 .expect("send client shutdown");
131 handle
132 .server_shutdown
133 .recv()
134 .await
135 .expect("server shutdown");
136 })
137 };
138 (
139 Ipv4;
140 Fail;
141 $resolver: ident
142 ) => {
143 define_service_handle!(HTTP;);
144 let rt = init_test_work_runtime(4);
145 let (tx, rx) = std::sync::mpsc::channel();
146
147 rt.block_on(async move {
148 let mut handle = start_http_server!(HTTP; server_fn);
149 handle
150 .server_start
151 .recv()
152 .await
153 .expect("recv server start msg failed !");
154 tx.send(handle)
155 .expect("send Handle out the server coroutine failed !");
156 });
157
158 let mut handle = rx.recv().expect("recv Handle failed !");
159
160 let client = Client::builder()
161 .dns_resolver($resolver)
162 .build()
163 .expect("Build Client failed.");
164
165 let request = Request::builder()
166 .url(format!("localhost:{}", handle.port).as_str())
167 .body(Body::empty())
168 .expect("Client build Request failed.");
169
170 rt.block_on(async move {
171 let response = client.request(request).await;
172 assert!(response.is_err());
173
174 handle
175 .client_shutdown
176 .send(())
177 .await
178 .expect("send client shutdown");
179 handle
180 .server_shutdown
181 .recv()
182 .await
183 .expect("server shutdown");
184 })
185 };
186 (
187 Ipv6;
188 Fail;
189 $resolver: ident
190 ) => {
191 define_service_handle!(HTTP;);
192 let rt = init_test_work_runtime(4);
193 let (tx, rx) = std::sync::mpsc::channel();
194
195 rt.block_on(async move {
196 let mut handle = start_http_server!(HTTP; Ipv6; server_fn);
197 handle
198 .server_start
199 .recv()
200 .await
201 .expect("recv server start msg failed !");
202 tx.send(handle)
203 .expect("send Handle out the server coroutine failed !");
204 });
205
206 let mut handle = rx.recv().expect("recv Handle failed !");
207
208 let client = Client::builder()
209 .dns_resolver($resolver)
210 .build()
211 .expect("Build Client failed.");
212
213 let request = Request::builder()
214 .url(format!("localhost:{}", handle.port).as_str())
215 .body(Body::empty())
216 .expect("Client build Request failed.");
217
218 rt.block_on(async move {
219 let response = client.request(request).await;
220 assert!(response.is_err());
221
222 handle
223 .client_shutdown
224 .send(())
225 .await
226 .expect("send client shutdown");
227 handle
228 .server_shutdown
229 .recv()
230 .await
231 .expect("server shutdown");
232 })
233 };
234 }
235
236 #[test]
sdv_client_request_dns_resolver_ipv4()237 fn sdv_client_request_dns_resolver_ipv4() {
238 struct ExampleDnsResolver;
239 impl Resolver for ExampleDnsResolver {
240 fn resolve(&self, authority: &str) -> SocketFuture {
241 let port = authority.trim_start_matches("localhost:").to_string();
242 Box::pin(async move {
243 if port.is_empty() {
244 Err(io::Error::new(io::ErrorKind::Other, "").into())
245 } else {
246 let ip = Ipv4Addr::new(127, 0, 0, 1);
247 let addr = SocketAddr::from((ip, port.parse().unwrap()));
248 let addrs = vec![addr];
249 Ok(Box::new(addrs.into_iter())
250 as Box<dyn Iterator<Item = SocketAddr> + Sync + Send>)
251 }
252 })
253 }
254 }
255 dns_test!(Ipv4; Success; ExampleDnsResolver);
256 }
257
258 #[test]
sdv_client_request_dns_resolver_ipv6()259 fn sdv_client_request_dns_resolver_ipv6() {
260 struct ExampleDnsResolver;
261 impl Resolver for ExampleDnsResolver {
262 fn resolve(&self, authority: &str) -> SocketFuture {
263 let port = authority.trim_start_matches("localhost:").to_string();
264 Box::pin(async move {
265 if port.is_empty() {
266 Err(io::Error::new(io::ErrorKind::Other, "").into())
267 } else {
268 let ip = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
269 let addr = SocketAddr::from((ip, port.parse().unwrap()));
270 let addrs = vec![addr];
271 Ok(Box::new(addrs.into_iter())
272 as Box<dyn Iterator<Item = SocketAddr> + Sync + Send>)
273 }
274 })
275 }
276 }
277 dns_test!(Ipv6; Success; ExampleDnsResolver);
278 }
279
280 #[test]
sdv_client_request_dns_resolver_ipv4_invalid()281 fn sdv_client_request_dns_resolver_ipv4_invalid() {
282 struct ExampleDnsResolver;
283 impl Resolver for ExampleDnsResolver {
284 fn resolve(&self, authority: &str) -> SocketFuture {
285 let port = authority.trim_start_matches("localhost:").to_string();
286 Box::pin(async move {
287 if port.is_empty() {
288 Err(io::Error::new(io::ErrorKind::Other, "").into())
289 } else {
290 let ip = Ipv4Addr::new(127, 0, 0, 2);
291 let addr = SocketAddr::from((ip, port.parse().unwrap()));
292 let addrs = vec![addr];
293 Ok(Box::new(addrs.into_iter())
294 as Box<dyn Iterator<Item = SocketAddr> + Sync + Send>)
295 }
296 })
297 }
298 }
299 dns_test!(Ipv4; Fail; ExampleDnsResolver);
300 }
301
302 #[test]
sdv_client_request_dns_resolver_ipv6_invalid()303 fn sdv_client_request_dns_resolver_ipv6_invalid() {
304 struct ExampleDnsResolver;
305 impl Resolver for ExampleDnsResolver {
306 fn resolve(&self, authority: &str) -> SocketFuture {
307 let port = authority.trim_start_matches("localhost:").to_string();
308 Box::pin(async move {
309 if port.is_empty() {
310 Err(io::Error::new(io::ErrorKind::Other, "").into())
311 } else {
312 let ip = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 2);
313 let addr = SocketAddr::from((ip, port.parse().unwrap()));
314 let addrs = vec![addr];
315 Ok(Box::new(addrs.into_iter())
316 as Box<dyn Iterator<Item = SocketAddr> + Sync + Send>)
317 }
318 })
319 }
320 }
321 dns_test!(Ipv6; Fail; ExampleDnsResolver);
322 }
323
324 #[test]
sdv_client_request_dns_resolver_ipv4_multiple1()325 fn sdv_client_request_dns_resolver_ipv4_multiple1() {
326 struct ExampleDnsResolver;
327 impl Resolver for ExampleDnsResolver {
328 fn resolve(&self, authority: &str) -> SocketFuture {
329 let port = authority.trim_start_matches("localhost:").to_string();
330 Box::pin(async move {
331 if port.is_empty() {
332 Err(io::Error::new(io::ErrorKind::Other, "").into())
333 } else {
334 let ip1 = Ipv4Addr::new(127, 0, 0, 1);
335 let addr1 = SocketAddr::from((ip1, port.parse().unwrap()));
336 let ip2 = Ipv4Addr::new(127, 0, 0, 2);
337 let addr2 = SocketAddr::from((ip2, port.parse().unwrap()));
338 let addrs = vec![addr1, addr2];
339 Ok(Box::new(addrs.into_iter())
340 as Box<dyn Iterator<Item = SocketAddr> + Sync + Send>)
341 }
342 })
343 }
344 }
345 dns_test!(Ipv4; Success; ExampleDnsResolver);
346 }
347
348 #[test]
sdv_client_request_dns_resolver_ipv6_multiple1()349 fn sdv_client_request_dns_resolver_ipv6_multiple1() {
350 struct ExampleDnsResolver;
351 impl Resolver for ExampleDnsResolver {
352 fn resolve(&self, authority: &str) -> SocketFuture {
353 let port = authority.trim_start_matches("localhost:").to_string();
354 Box::pin(async move {
355 if port.is_empty() {
356 Err(io::Error::new(io::ErrorKind::Other, "").into())
357 } else {
358 let ip1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
359 let addr1 = SocketAddr::from((ip1, port.parse().unwrap()));
360 let ip2 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 2);
361 let addr2 = SocketAddr::from((ip2, port.parse().unwrap()));
362 let addrs = vec![addr1, addr2];
363 Ok(Box::new(addrs.into_iter())
364 as Box<dyn Iterator<Item = SocketAddr> + Sync + Send>)
365 }
366 })
367 }
368 }
369 dns_test!(Ipv6; Success; ExampleDnsResolver);
370 }
371
372 #[test]
sdv_client_request_dns_resolver_ipv4_multiple2()373 fn sdv_client_request_dns_resolver_ipv4_multiple2() {
374 struct ExampleDnsResolver;
375 impl Resolver for ExampleDnsResolver {
376 fn resolve(&self, authority: &str) -> SocketFuture {
377 let port = authority.to_string();
378 Box::pin(async move {
379 if port.is_empty() {
380 Err(io::Error::new(io::ErrorKind::Other, "").into())
381 } else {
382 let (port1, port2) = port.split_once(':').unwrap();
383 let ip1 = Ipv4Addr::new(127, 0, 0, 1);
384 let addr1 = SocketAddr::from((ip1, port1.parse().unwrap()));
385 let ip2 = Ipv4Addr::new(127, 0, 0, 1);
386 let addr2 = SocketAddr::from((ip2, port2.parse().unwrap()));
387 let addrs = vec![addr1, addr2];
388 Ok(Box::new(addrs.into_iter())
389 as Box<dyn Iterator<Item = SocketAddr> + Sync + Send>)
390 }
391 })
392 }
393 }
394 define_service_handle!( HTTP ; );
395 let rt = init_test_work_runtime(4);
396 let (mut handle1, mut handle2) = rt.block_on(async move {
397 let mut handle1 = start_http_server!( HTTP ; server_fn );
398 let mut handle2 = start_http_server!( HTTP ; server_fn );
399 handle1
400 .server_start
401 .recv()
402 .await
403 .expect("recv server start msg failed !");
404 handle2
405 .server_start
406 .recv()
407 .await
408 .expect("recv server start msg failed !");
409 (handle1, handle2)
410 });
411 let client = Client::builder()
412 .dns_resolver(ExampleDnsResolver)
413 .build()
414 .expect("Build Client failed.");
415 let request = Request::builder()
416 .url(format!("{}:{}", handle1.port, handle2.port).as_str())
417 .body(Body::empty())
418 .expect("Client build Request failed.");
419 rt.block_on(async move {
420 let response = client.request(request).await;
421 assert!(response.is_ok());
422
423 handle1
424 .client_shutdown
425 .send(())
426 .await
427 .expect("send client shutdown");
428 handle1
429 .server_shutdown
430 .recv()
431 .await
432 .expect("server shutdown");
433 handle2
434 .client_shutdown
435 .send(())
436 .await
437 .expect("send client shutdown");
438 handle2
439 .server_shutdown
440 .recv()
441 .await
442 .expect("server shutdown");
443 })
444 }
445
446 #[test]
sdv_client_request_dns_resolver_ipv6_multiple2()447 fn sdv_client_request_dns_resolver_ipv6_multiple2() {
448 struct ExampleDnsResolver;
449 impl Resolver for ExampleDnsResolver {
450 fn resolve(&self, authority: &str) -> SocketFuture {
451 let port = authority.to_string();
452 Box::pin(async move {
453 if port.is_empty() {
454 Err(io::Error::new(io::ErrorKind::Other, "").into())
455 } else {
456 let (port1, port2) = port.split_once(':').unwrap();
457 let ip1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
458 let addr1 = SocketAddr::from((ip1, port1.parse().unwrap()));
459 let ip2 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
460 let addr2 = SocketAddr::from((ip2, port2.parse().unwrap()));
461 let addrs = vec![addr1, addr2];
462 Ok(Box::new(addrs.into_iter())
463 as Box<dyn Iterator<Item = SocketAddr> + Sync + Send>)
464 }
465 })
466 }
467 }
468 define_service_handle!( HTTP ; );
469 let rt = init_test_work_runtime(4);
470 let (mut handle1, mut handle2) = rt.block_on(async move {
471 let mut handle1 = start_http_server!( HTTP ; Ipv6; server_fn );
472 let mut handle2 = start_http_server!( HTTP ; Ipv6; server_fn );
473 handle1
474 .server_start
475 .recv()
476 .await
477 .expect("recv server start msg failed !");
478 handle2
479 .server_start
480 .recv()
481 .await
482 .expect("recv server start msg failed !");
483 (handle1, handle2)
484 });
485 let client = Client::builder()
486 .dns_resolver(ExampleDnsResolver)
487 .build()
488 .expect("Build Client failed.");
489 let request = Request::builder()
490 .url(format!("{}:{}", handle1.port, handle2.port).as_str())
491 .body(Body::empty())
492 .expect("Client build Request failed.");
493 rt.block_on(async move {
494 let response = client.request(request).await;
495 assert!(response.is_ok());
496
497 handle1
498 .client_shutdown
499 .send(())
500 .await
501 .expect("send client shutdown");
502 handle1
503 .server_shutdown
504 .recv()
505 .await
506 .expect("server shutdown");
507 handle2
508 .client_shutdown
509 .send(())
510 .await
511 .expect("send client shutdown");
512 handle2
513 .server_shutdown
514 .recv()
515 .await
516 .expect("server shutdown");
517 })
518 }
519
520 #[test]
sdv_client_request_dns_resolver_ipv4_ipv6()521 fn sdv_client_request_dns_resolver_ipv4_ipv6() {
522 struct ExampleDnsResolver;
523 impl Resolver for ExampleDnsResolver {
524 fn resolve(&self, authority: &str) -> SocketFuture {
525 let port = authority.to_string();
526 Box::pin(async move {
527 if port.is_empty() {
528 Err(io::Error::new(io::ErrorKind::Other, "").into())
529 } else {
530 let (port1, port2) = port.split_once(':').unwrap();
531 let ip1 = Ipv4Addr::new(0, 0, 0, 1);
532 let addr1 = SocketAddr::from((ip1, port1.parse().unwrap()));
533 let ip2 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
534 let addr2 = SocketAddr::from((ip2, port2.parse().unwrap()));
535 let addrs = vec![addr1, addr2];
536 Ok(Box::new(addrs.into_iter())
537 as Box<dyn Iterator<Item = SocketAddr> + Sync + Send>)
538 }
539 })
540 }
541 }
542 define_service_handle!( HTTP ; );
543 let rt = init_test_work_runtime(4);
544 let (mut handle1, mut handle2) = rt.block_on(async move {
545 let mut handle1 = start_http_server!( HTTP ; server_fn );
546 let mut handle2 = start_http_server!( HTTP ; Ipv6; server_fn );
547 handle1
548 .server_start
549 .recv()
550 .await
551 .expect("recv server start msg failed !");
552 handle2
553 .server_start
554 .recv()
555 .await
556 .expect("recv server start msg failed !");
557 (handle1, handle2)
558 });
559 let client = Client::builder()
560 .dns_resolver(ExampleDnsResolver)
561 .build()
562 .expect("Build Client failed.");
563 let request = Request::builder()
564 .url(format!("{}:{}", handle1.port, handle2.port).as_str())
565 .body(Body::empty())
566 .expect("Client build Request failed.");
567 rt.block_on(async move {
568 let response = client.request(request).await;
569 assert!(response.is_ok());
570
571 handle1
572 .client_shutdown
573 .send(())
574 .await
575 .expect("send client shutdown");
576 handle1
577 .server_shutdown
578 .recv()
579 .await
580 .expect("server shutdown");
581 handle2
582 .client_shutdown
583 .send(())
584 .await
585 .expect("send client shutdown");
586 handle2
587 .server_shutdown
588 .recv()
589 .await
590 .expect("server shutdown");
591 })
592 }
593