use std::sync::Arc; use tokio::{net::TcpStream, io::{AsyncWriteExt, AsyncReadExt}}; use crate::{http::{header::Header, response::Response, request::Request}, script::Config}; async fn send_response(mut socket: TcpStream, code: u16, body: String) { let mut res = Response::new(); res.headers.put(Header::new("Content-Type", "text/plain")); res.status = code; res.body = Some(body); let res_str = res.deserialize(); let _ = socket.write(res_str.as_bytes()).await; } pub async fn handle_connection(mut socket: TcpStream, config: Arc) { let mut buf = [0; 1204]; let n: usize = match socket.read(&mut buf).await { Ok(n) if n == 0 => return, Ok(n) => n as usize, Err(e) => { eprintln!("failed to read from socket; err = {:?}", e); return } }; let str = String::from_utf8_lossy(&buf[0..n]); let Some(req) = Request::serialize(&str) else { return }; let Some(script) = config.get(&req.method, &req.uri.route) else { send_response(socket, 405, "Method Not Allowed".to_owned()).await; return }; match script.run(req.body.as_ref()) { Ok(res) => { let res_str = res.deserialize(); let _ = socket.write(res_str.as_bytes()).await; }, Err(err) => { println!("{err}"); send_response(socket, 500, format!("{err}")).await; }, } }