use std::{ fmt::Display, io::{BufRead, BufReader, Read, Write}, net::TcpListener }; use anyhow::Result; use thiserror::Error; #[derive(Clone, Debug, Error)] enum E { #[error("Invalid request data found during parsing")] InvalidRequest, } fn main() -> Result<()> { let listener = TcpListener::bind("127.0.0.1:4221").unwrap(); for stream in listener.incoming() { match stream { Ok(mut stream) => { let buf_reader = BufReader::new(&mut stream); let mut data = buf_reader .lines() .map(|result| result.unwrap()) .take_while(|line| !line.is_empty()); let (_method, path, _ver) = { let start_line = data.next().ok_or(E::InvalidRequest)?; // should be 500; let mut parts = start_line.split_whitespace().map(ToOwned::to_owned); let method = parts.next().ok_or(E::InvalidRequest)?; let path = parts.next().ok_or(E::InvalidRequest)?; let ver = parts.next().ok_or(E::InvalidRequest)?; (method, path, ver) }; let code = match path.as_str() { "/" => "200 OK", _ => "404 Not Found", }; println!("accepted new connection"); let resp = create_response_simple(code); let _ = stream.write(&resp); let _ = stream.flush(); } Err(e) => { println!("error: {}", e); } } } Ok(()) } fn create_response_simple (code: T) -> Vec where T: Display { format!("HTTP/1.1 {code}\r\n\r\n").into() }