//! Server module for handling requests //! //! # A Complete Example //! //! ```rust //! use krustie::{ //! Server, //! Router, //! Request, //! Response, //! Middleware, //! StatusCode, //! json::{ get_string_from_json, json }, //! middleware::{ GzipEncoder, ServeStatic }, //! server::route_handler::HandlerResult, //! request::RequestBody, //! response::ContentType, //! }; //! //! let mut server = Server::create(); //! let krustie_middleware = AddHeader::new("Server", "Krustie"); //! let mut router = Router::new(); //! //! router.get("/", |_, res| { //! res.status(StatusCode::Ok).body( //! b"

Hello, World!

".to_vec(), //! ContentType::Html //! ); //! }); //! //! let mut sub_router = Router::new(); //! //! sub_router //! .get("/", |_, res| { //! let body = json!({"message": "Hello, World!"}); //! res.status(StatusCode::Ok).body_json(body); //! }) //! .post("/", post_req); //! //! router.use_router("/home", sub_router); //! //! server.use_handler(router); //! server.use_handler(krustie_middleware); //! server.use_handler(GzipEncoder); //! server.use_handler(ServeStatic::new("public")); //! //! // vvvvvv Uncommment to listen on //! // server.listen(8080); //! //! //! fn post_req(req: &Request, res: &mut Response) { //! match req.get_body() { //! RequestBody::Json(json) => { //! let key_result = json.get("server"); //! //! if get_string_from_json(key_result).unwrap() == "Krustie" { //! res.status(StatusCode::Ok).body_json(json!({"message": "Valid server"})); //! } else { //! res.status(StatusCode::try_from(201).unwrap()).body_json(json!({"error": "Invalid server"})); //! } //! }, //! _ => { //! res.status(StatusCode::BadRequest).body_json(json!({"error": "Invalid JSON"})); //! } //! } //! } //! //! #[derive(Clone)] //! struct AddHeader { //! key: String, //! value: String, //! } //! //! impl AddHeader { //! fn new(key: &str, value: &str) -> Self { //! Self { key: key.to_string(), value: value.to_string() } //! } //! } //! //! impl Middleware for AddHeader { //! fn middleware(&mut self, _: &Request, res: &mut Response) -> HandlerResult { //! res.set_header(&self.key, &self.value); //! HandlerResult::Next //! } //! } //! ``` use crate::{Request, Response, StatusCode}; use std::{ fmt::{Debug, Formatter}, io::Write, net::{TcpListener, TcpStream}, }; pub mod route_handler; pub mod testing; use route_handler::{HandlerResult, RouteHandler}; use std::thread; /// A server for handling requests /// /// # Example /// /// ```rust /// use krustie::{ Server, Router, StatusCode, response::ContentType, }; /// /// let mut server = Server::create(); /// let mut router = Router::new(); /// /// router.get("/", |_, res| { /// res.status(StatusCode::Ok) /// .body(b"Hello World!".to_vec(), ContentType::Text); /// }); /// /// server.use_handler(router); /// /// // server.listen(8080); /// ``` pub struct Server { route_handlers: Vec>, address: String, } impl Server { /// Creates a new server instance /// /// # Example /// /// ```rust /// use krustie::Server; /// /// let server = Server::create(); /// /// // vvvvvv Uncommment to listen on /// // server.listen(8080); /// ``` pub fn create() -> Self { Self { route_handlers: Vec::new(), address: String::from(""), } } /// Adds a middleware or a router to the server /// /// `Middleware` are functions that are executed before or after the request is handled by the server. /// They can be used to modify the request or response. /// /// `Router` is a collection of routes that can be used to handle requests. /// /// # Example /// /// ```rust /// use krustie::{ Server, Router, Response, StatusCode, Middleware, middleware::gzip::GzipEncoder }; /// /// let mut server = Server::create(); /// let mut router = Router::new(); /// /// /// server.use_handler(router); /// server.use_handler(GzipEncoder); /// ``` pub fn use_handler(&mut self, handler: impl RouteHandler + 'static) { self.route_handlers.push(Box::new(handler)); } fn handle_stream(&mut self, stream: &mut TcpStream) { let mut response = Response::default(); match Request::parse(stream) { Ok(request) => { for handler in &mut self.route_handlers { let result = handler.handle(&request, &mut response); if result == HandlerResult::End { break; } } } Err(err) => { response .status(StatusCode::BadRequest) .debug_msg(&err.to_string()); } } let response_stream: Vec = response.into(); match stream.write_all(&response_stream) { Ok(_) => {} Err(e) => { eprintln!("error: {}", e); } } } /// Listens for incoming requests on the specified IP and port /// /// # Example /// /// ```rust /// use krustie::Server; /// /// let mut server = Server::create(); /// /// // vvvvvv Uncommment to listen on /// // server.listen(8080); /// ``` pub fn listen(&self, port: u16) { Listener::listen(port, self.clone()); } } impl Clone for Server { fn clone(&self) -> Self { let route_handlers: Vec> = self.route_handlers.clone(); Self { route_handlers, address: self.address.clone(), } } } impl Debug for Server { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { write!(f, "Server {{ Address: {} }}", self.address) } } #[derive(Debug)] struct Listener {} impl Listener { fn listen(port: u16, handler: Server) { let address = format!("127.0.0.1:{}", port); let listener = TcpListener::bind(address).unwrap_or_else(|err| panic!("{}", err)); println!("Listening on http://localhost:{port}"); for stream_result in listener.incoming() { let mut stream = stream_result.unwrap_or_else(|err| { panic!("Error while listening: {}", err); }); let mut handler = handler.clone(); thread::spawn(move || { handler.handle_stream(&mut stream); }); } } }