use crate::{ builder::ServerBuilder, config::ServerConfig, middleware::{Middleware, MiddlewareResult}, }; use http1::Builder; use http_body_util::Full; use hyper::{body::Incoming, server::conn::http1, service::service_fn, Request, Response}; use hyper_util::rt::TokioIo; use log::error; use std::{convert::Infallible, future::Future, net::SocketAddr, sync::Arc}; use tokio::{net::TcpListener, spawn}; use tokio_util::bytes::Bytes; pub struct Server { pub config: Arc, pub middlewares: Arc>>, } impl Server { pub fn builder() -> ServerBuilder { ServerBuilder { config: ServerConfig::default(), middlewares: vec![], } } pub async fn run(self, handler: F) where F: Fn(Request) -> Fut + Send + Sync + 'static, Fut: Future>, Infallible>> + Send, { let addr: SocketAddr = format!("{}:{}", self.config.ip, self.config.port) .parse() .expect("Invalid IP or port"); let listener = TcpListener::bind(addr) .await .expect("Failed to bind to address"); let handler = Arc::new(handler); let shared_middlewares = self.middlewares; loop { let (tcp, client_addr) = match listener.accept().await { Ok(conn) => conn, Err(e) => { error!("Accept error: {}", e); continue; } }; let io = TokioIo::new(tcp); let mws = Arc::clone(&shared_middlewares); let h = Arc::clone(&handler); let client_ip = client_addr.ip(); spawn(async move { let conn = Builder::new().serve_connection( io, service_fn(move |mut req| { let mws = Arc::clone(&mws); let h = Arc::clone(&h); async move { req.extensions_mut().insert(client_ip); for mw in mws.iter() { match mw.run(req).await { MiddlewareResult::Continue(next_req) => req = next_req, MiddlewareResult::Respond(res) => return Ok(res), } } h(req).await } }), ); if let Err(err) = conn.await { error!("Error serving connection: {:?}", err); } }); } } }