// Copyright (c) 2023 Huawei Device Co., Ltd. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #![cfg(all(feature = "async", feature = "http1_1", feature = "ylong_base"))] #[macro_use] pub mod tcp_server; use ylong_http::body::async_impl::Body; use crate::tcp_server::{format_header_str, TcpHandle}; /// SDV test cases for `async::Client`. /// /// # Brief /// 1. Starts a hyper server acts as proxy with the tokio coroutine. /// 2. Creates an async::Client. /// 3. The client sends a request message. /// 4. Verifies the received request on the server. /// 5. The server sends a response message. /// 6. Verifies the received response on the client. /// 7. Shuts down the server. #[test] fn sdv_async_client_send_request() { let mut handles_vec = vec![]; start_tcp_server!( ASYNC; Proxy: true, ServerNum: 1, Handles: handles_vec, Request: { Method: "GET", Version: "HTTP/1.1", Path: "/data", Header: "Content-Length", "6", Header: "Accept", "*/*", Body: "Hello!", }, Response: { Status: 201, Version: "HTTP/1.1", Header: "Content-Length", "11", Body: "METHOD GET!", }, ); let handle = handles_vec.pop().expect("No more handles !"); let client = ylong_http_client::async_impl::Client::builder() .proxy( ylong_http_client::Proxy::http( format!("http://{}{}", handle.addr.as_str(), "/data").as_str(), ) .build() .expect("Http proxy build failed"), ) .build() .expect("Client build failed!"); let shutdown_handle = ylong_runtime::spawn(async move { { let request = build_client_request!( Request: { Method: "GET", Path: "/data", Addr: handle.addr.as_str(), Header: "Content-Length", "6", Body: "Hello!", }, ); let mut response = client.request(request).await.expect("Request send failed"); assert_eq!( response.status().as_u16(), 201, "Assert response status code failed" ); assert_eq!( response.version().as_str(), "HTTP/1.1", "Assert response version failed" ); assert_eq!( response .headers() .get("Content-Length") .unwrap_or_else(|| panic!( "Get response header \"{}\" failed", "Content-Length" )) .to_string() .unwrap_or_else(|_| panic!( "Convert response header \"{}\"into string failed", "Content-Length" )), "11", "Assert response header \"{}\" failed", "Content-Length", ); let mut buf = [0u8; 4096]; let mut size = 0; loop { let read = response .body_mut() .data(&mut buf[size..]) .await .expect("Response body read failed"); if read == 0 { break; } size += read; } assert_eq!( &buf[..size], "METHOD GET!".as_bytes(), "Assert response body failed" ); } handle .server_shutdown .recv() .expect("server send order failed !"); }); ylong_runtime::block_on(shutdown_handle).expect("Runtime wait for server shutdown failed"); }