use std::io::{ BufRead, BufReader, Read };
use std::net::TcpListener;
use std::sync::{ Arc, RwLock };
use std::time::Instant;
use crate::request::{ parse_path_params, Request };
use crate::response::Response;
use crate::workerpool::WorkerPool;
pub type Next<'a> = &'a mut dyn FnMut();
pub type Handler = dyn Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static;
pub type Middleware = dyn Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next) +
Send +
Sync +
'static;
#[derive(Clone)]
struct Route {
method: String,
path: String,
middleware: Vec<Arc<Middleware>>,
handler: Arc<Handler>,
}
pub struct Glote {
routes: Arc<RwLock<Vec<Route>>>,
middleware: Arc<RwLock<Vec<Arc<Middleware>>>>,
pool: WorkerPool,
static_path: Option<String>,
}
impl Glote {
pub fn new() -> Arc<Self> {
let num_cores = std::thread
::available_parallelism()
.map(|n| n.get())
.unwrap_or(1);
Arc::new(Self {
routes: Arc::new(RwLock::new(Vec::new())),
middleware: Arc::new(RwLock::new(Vec::new())),
pool: WorkerPool::new(num_cores * 4),
static_path: None,
})
}
pub fn set_warkers(&mut self, size: usize) {
self.pool = WorkerPool::new(size);
}
fn run_handlers(
&self,
req: Arc<RwLock<Request>>,
res: Arc<RwLock<Response>>,
middlewares: &[Arc<Middleware>],
final_handler: impl FnMut() + Send + 'static
) {
let req = Arc::clone(&req);
let res = Arc::clone(&res);
let middlewares = middlewares.to_vec();
let mut final_handler = Some(Box::new(final_handler) as Box<dyn FnMut()>);
for mw in middlewares.into_iter().rev() {
let req = req.clone();
let res = res.clone();
let mut next = final_handler.take().unwrap();
final_handler = Some(
Box::new(move || {
if !res.read().unwrap().is_stopped() {
mw(req.clone(), res.clone(), &mut next);
}
})
);
}
if let Some(mut chain) = final_handler {
if !res.read().unwrap().is_stopped() {
chain();
}
}
}
pub fn use_middleware<F>(&self, middleware: F)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next) + Send + Sync + 'static
{
let mut middlewares = self.middleware.write().unwrap();
middlewares.push(Arc::new(middleware));
}
pub fn static_file(&mut self, path: &str) {
self.static_path = Some(path.into());
}
pub fn listen(self: Arc<Self>, port: u16) {
let listener = TcpListener::bind(("127.0.0.1", port)).unwrap();
println!("\n---------------------\nServer running on port {}", port);
for stream in listener.incoming() {
let stream = match stream {
Ok(s) => s,
Err(e) => {
eprintln!("Connection failed: {}", e);
continue;
}
};
let routers_clone = {
let guard = self.routes.read().unwrap();
guard.clone()
};
let middleware_clone = {
let guard = self.middleware.read().unwrap();
guard.clone()
};
let _static_file = self.static_path.clone();
let this = self.clone();
self.pool.execute(move || {
let now = Instant::now();
let mut stream = stream;
let mut reader = BufReader::new(&mut stream);
let mut lines = Vec::new();
let mut buffer = String::new();
loop {
buffer.clear();
if reader.read_line(&mut buffer).unwrap() == 0 {
break;
}
let line = buffer.trim_end().to_string();
if line.is_empty() {
break;
}
lines.push(line);
}
let content_length = lines
.iter()
.find(|line| line.to_ascii_lowercase().starts_with("content-length:"))
.and_then(|line| line.split(": ").nth(1))
.and_then(|len| len.parse::<usize>().ok());
let mut body_lines = Vec::new();
if let Some(len) = content_length {
let mut buf = vec![0u8; len];
reader.read_exact(&mut buf).unwrap();
let body = String::from_utf8_lossy(&buf).to_string();
body_lines.extend(body.lines().map(|s| s.to_string()));
}
lines.push(String::new()); lines.extend(body_lines);
let req = Request::new(&lines);
let mut res_opt = Some(Arc::new(RwLock::new(Response::new(stream))));
let mut matched = false;
for route in routers_clone.into_iter() {
if route.method == req.method {
if let Some(params) = parse_path_params(&route.path, &req.path) {
let mut req_with_params = req.clone();
req_with_params.path_params = params;
let req_with_params = Arc::new(RwLock::new(req_with_params));
let combined_middleware: Vec<_> = middleware_clone
.iter()
.chain(route.middleware.iter())
.cloned()
.collect();
if let Some(res_actual) = res_opt.take() {
let req_for_handler = Arc::clone(&req_with_params);
let res_for_handler = Arc::clone(&res_actual);
this.run_handlers(
Arc::clone(&req_for_handler),
Arc::clone(&res_for_handler),
&combined_middleware,
{
let req_inner = req_for_handler.clone();
let res_inner = res_for_handler.clone();
move || {
(route.handler)(req_inner.clone(), res_inner.clone());
}
}
);
matched = true;
break;
}
}
}
}
let duration = now.elapsed();
if !matched {
if let Some(res) = res_opt {
let mut res = res.write().unwrap();
res.status(404);
res.send("404 Not Found");
}
println!("\x1b[31m{} {}: {:?}\x1b[0m ", req.method, req.path, duration);
} else {
println!("\x1b[32m{} {}: {:?}\x1b[0m ", req.method, req.path, duration);
}
});
}
}
pub fn get<F>(&self, path: &str, handler: F)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let empty_middleware: Vec<fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next)> = vec![];
self.get_with_middleware(path, empty_middleware, handler);
}
pub fn get_with_middleware<F>(
&self,
path: &str,
middleware: Vec<fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next)>,
handler: F
)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let wrapped: Vec<Arc<Middleware>> = middleware
.into_iter()
.map(|m| Arc::new(m) as Arc<Middleware>)
.collect();
self.get_with_middleware_run(path, wrapped, handler);
}
fn get_with_middleware_run<F>(&self, path: &str, middleware: Vec<Arc<Middleware>>, handler: F)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let route = Route {
method: "GET".to_string(),
path: path.to_string(),
middleware,
handler: Arc::new(handler),
};
self.routes.write().unwrap().push(route);
}
pub fn post<F>(&self, path: &str, handler: F)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let empty_middleware: Vec<fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next)> = vec![];
self.post_with_middleware(path, empty_middleware, handler);
}
pub fn post_with_middleware<F>(
&self,
path: &str,
middleware: Vec<fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next)>,
handler: F
)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let wrapped: Vec<Arc<Middleware>> = middleware
.into_iter()
.map(|m| Arc::new(m) as Arc<Middleware>)
.collect();
self.post_with_middleware_run(path, wrapped, handler);
}
fn post_with_middleware_run<F>(&self, path: &str, middleware: Vec<Arc<Middleware>>, handler: F)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let route = Route {
method: "POST".to_string(),
path: path.to_string(),
middleware,
handler: Arc::new(handler),
};
self.routes.write().unwrap().push(route);
}
pub fn put<F>(&self, path: &str, handler: F)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let empty_middleware: Vec<fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next)> = vec![];
self.put_with_middleware(path, empty_middleware, handler);
}
pub fn put_with_middleware<F>(
&self,
path: &str,
middleware: Vec<fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next)>,
handler: F
)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let wrapped: Vec<Arc<Middleware>> = middleware
.into_iter()
.map(|m| Arc::new(m) as Arc<Middleware>)
.collect();
self.put_with_middleware_run(path, wrapped, handler);
}
fn put_with_middleware_run<F>(&self, path: &str, middleware: Vec<Arc<Middleware>>, handler: F)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let route = Route {
method: "PUT".to_string(),
path: path.to_string(),
middleware,
handler: Arc::new(handler),
};
self.routes.write().unwrap().push(route);
}
pub fn delete<F>(&self, path: &str, handler: F)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let empty_middleware: Vec<fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next)> = vec![];
self.delete_with_middleware(path, empty_middleware, handler);
}
pub fn delete_with_middleware<F>(
&self,
path: &str,
middleware: Vec<fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>, Next)>,
handler: F
)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let wrapped: Vec<Arc<Middleware>> = middleware
.into_iter()
.map(|m| Arc::new(m) as Arc<Middleware>)
.collect();
self.delete_with_middleware_run(path, wrapped, handler);
}
fn delete_with_middleware_run<F>(
&self,
path: &str,
middleware: Vec<Arc<Middleware>>,
handler: F
)
where F: Fn(Arc<RwLock<Request>>, Arc<RwLock<Response>>) + Send + Sync + 'static
{
let route = Route {
method: "DELETE".to_string(),
path: path.to_string(),
middleware,
handler: Arc::new(handler),
};
self.routes.write().unwrap().push(route);
}
}