1 // Copyright (c) 2023 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(feature = "async", feature = "http1_1", feature = "ylong_base"))]
15 
16 #[macro_use]
17 pub mod tcp_server;
18 
19 use ylong_http::body::async_impl::Body;
20 
21 use crate::tcp_server::{format_header_str, TcpHandle};
22 
23 /// SDV test cases for `async::Client`.
24 ///
25 /// # Brief
26 /// 1. Starts a hyper server acts as proxy with the tokio coroutine.
27 /// 2. Creates an async::Client.
28 /// 3. The client sends a request message.
29 /// 4. Verifies the received request on the server.
30 /// 5. The server sends a response message.
31 /// 6. Verifies the received response on the client.
32 /// 7. Shuts down the server.
33 #[test]
sdv_async_client_send_request()34 fn sdv_async_client_send_request() {
35     let mut handles_vec = vec![];
36 
37     start_tcp_server!(
38         ASYNC;
39         Proxy: true,
40         ServerNum: 1,
41         Handles: handles_vec,
42         Request: {
43             Method: "GET",
44             Version: "HTTP/1.1",
45             Path: "/data",
46             Header: "Content-Length", "6",
47             Header: "Accept", "*/*",
48             Body: "Hello!",
49         },
50         Response: {
51             Status: 201,
52             Version: "HTTP/1.1",
53             Header: "Content-Length", "11",
54             Body: "METHOD GET!",
55         },
56     );
57 
58     let handle = handles_vec.pop().expect("No more handles !");
59     let client = ylong_http_client::async_impl::Client::builder()
60         .proxy(
61             ylong_http_client::Proxy::http(
62                 format!("http://{}{}", handle.addr.as_str(), "/data").as_str(),
63             )
64             .build()
65             .expect("Http proxy build failed"),
66         )
67         .build()
68         .expect("Client build failed!");
69 
70     let shutdown_handle = ylong_runtime::spawn(async move {
71         {
72             let request = build_client_request!(
73                 Request: {
74                     Method: "GET",
75                     Path: "/data",
76                     Addr: handle.addr.as_str(),
77                     Header: "Content-Length", "6",
78                     Body: "Hello!",
79                 },
80             );
81 
82             let mut response = client.request(request).await.expect("Request send failed");
83 
84             assert_eq!(
85                 response.status().as_u16(),
86                 201,
87                 "Assert response status code failed"
88             );
89             assert_eq!(
90                 response.version().as_str(),
91                 "HTTP/1.1",
92                 "Assert response version failed"
93             );
94             assert_eq!(
95                 response
96                     .headers()
97                     .get("Content-Length")
98                     .unwrap_or_else(|| panic!(
99                         "Get response header \"{}\" failed",
100                         "Content-Length"
101                     ))
102                     .to_string()
103                     .unwrap_or_else(|_| panic!(
104                         "Convert response header \"{}\"into string failed",
105                         "Content-Length"
106                     )),
107                 "11",
108                 "Assert response header \"{}\" failed",
109                 "Content-Length",
110             );
111             let mut buf = [0u8; 4096];
112             let mut size = 0;
113             loop {
114                 let read = response
115                     .body_mut()
116                     .data(&mut buf[size..])
117                     .await
118                     .expect("Response body read failed");
119                 if read == 0 {
120                     break;
121                 }
122                 size += read;
123             }
124             assert_eq!(
125                 &buf[..size],
126                 "METHOD GET!".as_bytes(),
127                 "Assert response body failed"
128             );
129         }
130         handle
131             .server_shutdown
132             .recv()
133             .expect("server send order failed !");
134     });
135     ylong_runtime::block_on(shutdown_handle).expect("Runtime wait for server shutdown failed");
136 }
137