francoisgib_webserver 1.0.3

HTTP Webserver
Documentation
#[cfg(test)]
mod tests {
    use std::str::FromStr;

    use chrono::Utc;

    use crate::{
        config::Config,
        http::{
            headers::{HeaderEntry, HttpHeader, HttpHeaderValue},
            methods::HttpMethod,
            requests::HttpRequest,
            responses::HttpResponse,
            status::HttpStatus,
        },
        server::HttpServer,
        tree::{EndpointType, HttpTree},
        utils::buffer::Buffer,
    };

    #[tokio::test]
    async fn test_handle_client() {
        use std::time::Duration;
        use tokio::io::{AsyncReadExt, AsyncWriteExt};
        use tokio::net::TcpStream;
        use tokio::time::sleep;

        fn hello_world_handler(_: &HttpRequest, response: &mut HttpResponse) -> Result<(), String> {
            let content_type_header = HeaderEntry::from_str("Content-Type: text/plain").unwrap();
            let content_length_header = HeaderEntry::from_str("Content-Length: 13").unwrap();

            response.headers.push(content_type_header);
            response.headers.push(content_length_header);
            response.status = HttpStatus::Ok;
            response.body = Buffer::from_str("Hello, World!").ok();

            Ok(())
        }

        let mut tree = HttpTree::default();
        tree.add_endpoint(
            "/hello",
            HttpMethod::GET,
            EndpointType::Handler(hello_world_handler),
        );

        let server = HttpServer::new(tree, Config::default());

        let mut expected_response: HttpResponse = server.get_default_response();
        expected_response
            .headers
            .push(HeaderEntry::from_str("Content-Type: text/plain").unwrap());
        expected_response
            .headers
            .push(HeaderEntry::from_str("Content-Length: 13").unwrap());

        expected_response.body = Buffer::from_str("Hello, World!").ok();

        let server_join = tokio::spawn(async move { server.async_start().await });
        sleep(Duration::from_millis(100)).await;

        let mut stream = TcpStream::connect("127.0.0.1:8080")
            .await
            .expect("Failed to connect to server");
        let buffer = "GET /hello HTTP/1.1\r\n\r\n";
        stream
            .write_all(buffer.as_bytes())
            .await
            .expect("Failed to write to stream");

        let mut response_buffer = [0; 1024];
        let bytes_read = stream
            .read(&mut response_buffer)
            .await
            .expect("Failed to read from stream");
        let response = String::from_utf8_lossy(&response_buffer[..bytes_read]);
        println!("vbytes   {}", bytes_read);

        let expected_response_date_header =
            expected_response.find_header(HttpHeader::Date).unwrap();
        expected_response_date_header.value = HttpHeaderValue::Date(Utc::now());

        assert_eq!(expected_response.to_string(), response);

        server_join.abort();
    }
}