mini_server/
lib.rs

1use std::collections::HashMap;
2use std::io::{BufRead, Read, Write};
3use std::iter::zip;
4use std::net::{Ipv4Addr, SocketAddr, TcpListener, TcpStream};
5use std::sync::atomic::{AtomicBool, Ordering};
6use std::sync::Arc;
7
8#[macro_use]
9mod macros;
10pub mod worker;
11
12/// `CRLF` represents the Carriage Return (CR) and Line Feed (LF)
13/// characters combined ("\r\n"). It is commonly used as the
14/// end-of-line sequence in HTTP requests and responses.
15///
16/// `CRLF` is utilized to signify the end of a line in HTTP messages,
17/// ensuring compatibility with the HTTP protocol.
18///
19/// ```rust
20/// use mini_server::CRLF;
21///
22/// let http_line = format!("--- boundry{}{}", CRLF, CRLF);
23/// ```
24pub const CRLF: &str = "\r\n";
25
26/// `MAX_BUFFER` defines the maximum size, in bytes, for a request
27/// in your web server. Requests exceeding this size may be rejected or
28/// handled differently based on your server's implementation.
29///
30/// ## Determining the appropriate buffer size
31///
32/// Determining an appropriate value for `MAX_BUFFER` depends on several
33/// factors, including the typical size of requests the web server
34/// expects to handle, the available system resources, and the desired
35/// trade-off between memory usage and potential denial-of-service (DoS)
36/// protection.
37///
38/// Here are some considerations:
39///
40/// 1. Resource Constraints:
41///     Consider the available system memory. Setting MAX_BUFFER too high
42///     might lead to excessive memory usage, especially if the
43///     server handles a large number of concurrent requests.
44///
45/// 2. Denial-of-Service (DoS) Protection:
46///     A smaller MAX_BUFFER can provide a level of protection against
47///     certain types of DoS attacks that involve sending large,
48///     resource-consuming requests. However, it's essential to strike
49///     a balance to avoid false positives or impacting legitimate
50///     requests.
51///
52/// ## Note
53/// > The max_buffer is configurable when configurating a new server instance
54/// > It is only used in the [TcpServer]
55pub const MAX_BUFFER: usize = 16384;
56
57/// The `HTTPRequest` struct represents an HTTP request received by
58/// the web server. It encapsulates various components of an HTTP request,
59/// including the HTTP method, request path, headers, and body.
60#[derive(Debug, Clone)]
61pub struct HTTPRequest {
62    /// The HTTP method used in the request (e.g., GET, POST).
63    pub method: HTTPMethod,
64    /// The decoded path portion of the request URL.
65    pub path: String,
66    /// The raw, percent-encoded path from the request URL.
67    pub raw_path: String,
68    /// A collection of URL parameters parsed from the request.
69    pub params: URLSearchParams,
70    /// The version of the HTTP protocol used in the request (e.g., "1.1").
71    pub http_version: String,
72    /// A collection of HTTP headers included in the request.
73    pub headers: Headers,
74    /// The body of the HTTP request. (Note: Consider changing body to a sequence of bytes (***`Vec<u8>`***)
75    /// for more flexibility and efficiency.)
76    pub body: Vec<u8>,
77}
78
79impl Default for HTTPRequest {
80    fn default() -> Self {
81        Self {
82            method: HTTPMethod::GET,
83            path: String::from("/"),
84            raw_path: String::new(),
85            params: HashMap::new(),
86            http_version: String::from("1.1"),
87            headers: HashMap::new(),
88            body: Vec::new(),
89        }
90    }
91}
92
93/// The `URLSearchParams` type alias represents a collection of URL parameters parsed from an HTTP request's
94/// query string. It is implemented as a HashMap<String, String> where keys are parameter names, and values
95/// are parameter values.
96pub type URLSearchParams = HashMap<String, String>;
97
98/// The `Headers` type alias represents a collection of HTTP headers in key-value pairs. It is implemented
99/// as a HashMap<String, String>, where keys are header names, and values are header values.
100pub type Headers = HashMap<String, String>;
101
102/// The parse_path function takes a string representing an HTTP request path and extracts the path and URL
103/// parameters (if any) from it. It returns a tuple containing the path and a URLSearchParams
104/// `(HashMap<String, String>)` representing the parsed URL parameters.
105fn parse_path(data: &str) -> (String, URLSearchParams) {
106    let split_data = data.split_once('?');
107    if split_data.is_none() {
108        (data.into(), HashMap::new())
109    } else {
110        let (ph, pr) = split_data.unwrap();
111        let params: URLSearchParams = pr
112            .split('&')
113            .filter_map(|param| {
114                let mut parts = param.split('=');
115                let key = parts.next()?.to_string();
116                let value = parts.next()?.to_string();
117                Some((key, value))
118            })
119            .collect();
120
121        (ph.to_string(), params)
122    }
123}
124
125fn get_method(raw: Option<&str>) -> HTTPMethod {
126    if let Some(raw) = raw {
127        match raw {
128            "GET" => HTTPMethod::GET,
129            "HEAD" => HTTPMethod::HEAD,
130            "POST" => HTTPMethod::POST,
131            "PUT" => HTTPMethod::PUT,
132            "DELETE" => HTTPMethod::DELETE,
133            "CONNECT" => HTTPMethod::CONNECT,
134            "OPTIONS" => HTTPMethod::OPTIONS,
135            "TRACE" => HTTPMethod::TRACE,
136            "PATCH" => HTTPMethod::PATCH,
137            _ => HTTPMethod::GET,
138        }
139    } else {
140        HTTPMethod::GET
141    }
142}
143
144fn get_version(v: Option<u8>) -> String {
145    if let Some(v) = v {
146        if v == 1 {
147            return "1.1".into();
148        } else {
149            return "1.2".into();
150        }
151    } else {
152        "1.1".into()
153    }
154}
155
156/// The `HTTPResponse` struct represents an HTTP response that the web server can send to clients.
157/// It encapsulates various components of an HTTP response, including the response body, headers,
158/// status code, status text, and the HTTP version.
159///
160/// ```rust
161/// use mini_server::{HTTPResponse, Headers};
162///
163/// fn create_http_response() -> HTTPResponse {
164///     let mut headers = Headers::new();
165///     headers.insert("Content-Type".into(), "text/plain".into());
166///
167///     HTTPResponse {
168///         body: b"Hello, World!".to_vec(),
169///         headers,
170///         status: 200,
171///         status_text: "OK".to_string(),
172///         http_version: "1.1".to_string(),
173///     }
174/// }
175/// ```
176#[derive(Debug)]
177pub struct HTTPResponse {
178    /// The response body as a vector of bytes.
179    pub body: Vec<u8>,
180    /// A collection of HTTP headers included in the response.
181    pub headers: Headers,
182    ///  The HTTP status code indicating the outcome of the request.
183    pub status: u16,
184    /// The human-readable status text associated with the status code.
185    pub status_text: String,
186    /// The version of the HTTP protocol used for the response.
187    pub http_version: String,
188}
189
190fn default_headers() -> Headers {
191    let mut h = Headers::new();
192    h.insert("Server".into(), "miniserver".into());
193    h
194}
195
196impl Default for HTTPResponse {
197    fn default() -> Self {
198        HTTPResponse {
199            body: Vec::new(),
200            headers: default_headers(),
201            status: 200,
202            status_text: String::from("OK"),
203            http_version: String::from("1.1"),
204        }
205    }
206}
207
208response_from_for!(&[u8] => HTTPResponse);
209response_from_for!(Vec<u8> => HTTPResponse);
210response_from_for!(&str => HTTPResponse);
211response_from_for!(String => HTTPResponse);
212
213impl HTTPResponse {
214    /// Get a new HTTPResponse struct
215    pub fn new() -> Self {
216        HTTPResponse::default()
217    }
218
219    /// Allows updating the body of an HTTPResponse instance
220    /// with a new vector of bytes (`Vec<u8>`). Additionally, it automatically
221    /// updates the "Content-Length" header to reflect the length of the new body.
222    pub fn set_body(&mut self, body: Vec<u8>) {
223        self.body = body;
224        self.headers
225            .insert("Content-Length".to_string(), self.body.len().to_string());
226    }
227
228    /// Update the headers of an HTTPResponse instance with a new set of headers
229    /// provided as a Headers collection.
230    pub fn set_headers(&mut self, headers: Headers) {
231        for (key, value) in headers {
232            self.headers.insert(key, value);
233        }
234    }
235
236    /// Insert/Update the `HTTPResponse` header
237    pub fn set_header(&mut self, k: &str, v: &str) {
238        self.headers.insert(k.into(), v.into());
239    }
240
241    fn apply_status(&mut self, status: u16, text: &str) {
242        self.status = status;
243        self.status_text = text.to_string();
244    }
245
246    /// The set_status method allows setting the HTTP status code for an HTTPResponse instance.
247    /// It updates both the numeric status code (status) and the associated human-readable
248    /// status text.
249    pub fn set_status(&mut self, status: u16) {
250        match status {
251            100 => self.apply_status(status, "Continue"),
252            101 => self.apply_status(status, "Switching Protocols"),
253            102 => self.apply_status(status, "Processing"),
254            103 => self.apply_status(status, "Early Hints"),
255
256            200 => self.apply_status(status, "OK"),
257            201 => self.apply_status(status, "Created"),
258            202 => self.apply_status(status, "Accepted"),
259            203 => self.apply_status(status, "Non-Authoritative Information"),
260            204 => self.apply_status(status, "No Content"),
261            205 => self.apply_status(status, "Reset Content"),
262            206 => self.apply_status(status, "Partial Content"),
263            207 => self.apply_status(status, "Multi-Status"),
264            208 => self.apply_status(status, "Already Reported"),
265            226 => self.apply_status(status, "IM Used"),
266
267            300 => self.apply_status(status, "Multiple Choices"),
268            301 => self.apply_status(status, "Moved Permanently"),
269            302 => self.apply_status(status, "Found"),
270            303 => self.apply_status(status, "See Other"),
271            304 => self.apply_status(status, "Not Modified"),
272            305 => self.apply_status(status, "Use Proxy"),
273            306 => self.apply_status(status, "Switch Proxy"),
274            307 => self.apply_status(status, "Temporary Redirect"),
275            308 => self.apply_status(status, "Permanent Redirect"),
276
277            400 => self.apply_status(status, "Bad Request"),
278            401 => self.apply_status(status, "Unauthorized"),
279            402 => self.apply_status(status, "Payment Required"),
280            403 => self.apply_status(status, "Forbidden"),
281            404 => self.apply_status(status, "Not Found"),
282            405 => self.apply_status(status, "Method Not Allowed"),
283            406 => self.apply_status(status, "Not Acceptable"),
284            407 => self.apply_status(status, "Proxy Authentication Required"),
285            408 => self.apply_status(status, "Request Timeout"),
286            409 => self.apply_status(status, "Conflict"),
287            410 => self.apply_status(status, "Gone"),
288            411 => self.apply_status(status, "Length Required"),
289            412 => self.apply_status(status, "Precondition Failed"),
290            413 => self.apply_status(status, "Payload Too Large"),
291            414 => self.apply_status(status, "URI Too Long"),
292            415 => self.apply_status(status, "Unsupported Media Type"),
293            416 => self.apply_status(status, "Range Not Satisfiable"),
294            417 => self.apply_status(status, "Expectation Failed"),
295            418 => self.apply_status(status, "I'm a teapot"),
296            421 => self.apply_status(status, "Misdirected Request"),
297            422 => self.apply_status(status, "Unprocessable Entity"),
298            423 => self.apply_status(status, "Locked"),
299            424 => self.apply_status(status, "Failed Dependency"),
300            425 => self.apply_status(status, "Too Early"),
301            426 => self.apply_status(status, "Upgrade Required"),
302            428 => self.apply_status(status, "Precondition Required"),
303            429 => self.apply_status(status, "Too Many Requests"),
304            431 => self.apply_status(status, "Request Header Fields Too Large"),
305            451 => self.apply_status(status, "Unavailable For Legal Reasons"),
306
307            500 => self.apply_status(status, "Internal Server Error"),
308            501 => self.apply_status(status, "Not Implemented"),
309            502 => self.apply_status(status, "Bad Gateway"),
310            503 => self.apply_status(status, "Service Unavailable"),
311            504 => self.apply_status(status, "Gateway Timeout"),
312            505 => self.apply_status(status, "HTTP Version Not Supported"),
313            506 => self.apply_status(status, "Variant Also Negotiates"),
314            507 => self.apply_status(status, "Insufficient Storage"),
315            508 => self.apply_status(status, "Loop Detected"),
316            510 => self.apply_status(status, "Not Extended"),
317            511 => self.apply_status(status, "Network Authentication Required"),
318
319            _ => self.apply_status(500, "Internal Server Error"),
320        }
321    }
322
323    /// Set the HTTPResponse version (e.g. '1.1')
324    pub fn set_version(&mut self, version: String) {
325        self.http_version = version;
326    }
327
328    fn format_header(&self) -> String {
329        let mut headers = String::new();
330        for (key, value) in &self.headers {
331            headers.push_str(format!("{}: {}{}", key, value, CRLF).as_str());
332        }
333        headers
334    }
335
336    /// The raw method generates the raw representation of an HTTP response, including
337    /// the status line, headers, and body. It returns the
338    /// formatted HTTP response as a vector of bytes (`Vec<u8>`).
339    /// ```rust
340    /// use mini_server::HTTPResponse;
341    /// fn get_raw_response(response: &mut HTTPResponse) -> Vec<u8> {
342    ///     let raw_response = response.raw();
343    ///
344    ///     // Accessing the raw HTTP response
345    ///     println!("Raw Response: {:?}", raw_response);
346    ///     raw_response
347    /// }
348    /// ```
349    pub fn raw(&mut self) -> Vec<u8> {
350        let mut bytes = format!(
351            "HTTP/{version} {status} {status_text}{CRLF}{headers}{CRLF}",
352            version = self.http_version,
353            status = self.status,
354            status_text = self.status_text,
355            CRLF = CRLF,
356            headers = self.format_header(),
357        )
358        .as_bytes()
359        .to_vec();
360
361        bytes.extend(self.body.iter());
362
363        bytes
364    }
365}
366
367/// Get the value of a path dynamic variable
368/// ```rust
369/// use mini_server::*;
370/// let mut app = HTTPServer::new("localhost:4221");
371///
372/// app.get("/hello/@name/#age", |_, exprs| {
373///     let name = expand!(exprs, "name", PathExpr::String);
374///     let age = expand!(exprs, "age", PathExpr::Number);
375///
376///     format!("Hello {name}, you are {age}!").into()
377/// });
378/// ```
379#[macro_export]
380macro_rules! expand {
381    ($exprs: expr, $name: expr, $against: path) => {
382        match $exprs.get(&String::from($name)).unwrap() {
383            $against(value) => value,
384            _ => unreachable!(),
385        }
386    };
387}
388
389/// An hash map of `PathExpr`
390pub type PathMap = HashMap<String, PathExpr>;
391
392/// RequestHandler type is a function type that defines the signature for handling HTTP requests.
393/// It takes `HTTPRequest` and `HashMap<String, PathExpr>` as a parameter and returns an `HTTPResponse`
394pub struct RequestHandler(
395    Arc<Box<dyn Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static>>,
396);
397
398impl Clone for RequestHandler {
399    fn clone(&self) -> Self {
400        Self(self.0.clone())
401    }
402}
403
404/// EventHandler type is a function type that defines the signature for handling events triggered
405/// by HTTP requests. It takes references to an `HTTPRequest` and a mutable `HTTPResponse` as parameters.
406pub struct EventHandler(Arc<Box<dyn Fn(&HTTPRequest, &mut HTTPResponse) + Send + Sync + 'static>>);
407
408impl Clone for EventHandler {
409    fn clone(&self) -> Self {
410        Self(self.0.clone())
411    }
412}
413
414pub struct SimpleEventHandler(
415    Arc<Box<dyn Fn(&mut TcpStream, Request) -> Option<Response> + Send + Sync + 'static>>,
416);
417
418impl Clone for SimpleEventHandler {
419    fn clone(&self) -> Self {
420        Self(self.0.clone())
421    }
422}
423
424/// The SoftEventHandler type is a function type that defines the signature for handling soft events,
425/// typically without specific request or response parameters.
426pub struct SoftEventHandler(Arc<Box<dyn Fn() + Send + Sync + 'static>>);
427
428impl Clone for SoftEventHandler {
429    fn clone(&self) -> Self {
430        Self(self.0.clone())
431    }
432}
433
434pub struct ErrorEventHandler(Arc<Box<dyn Fn(RunError) + Send + Sync + 'static>>);
435
436impl Clone for ErrorEventHandler {
437    fn clone(&self) -> Self {
438        Self(self.0.clone())
439    }
440}
441/// The HTTPMethod enum represents the HTTP methods that can be used in HTTP requests.
442/// Each variant corresponds to a standard HTTP method.
443#[derive(Debug, PartialEq, Clone)]
444pub enum HTTPMethod {
445    /// Used to establish a network connection to a resource.
446    CONNECT,
447    /// Requests that a resource be removed.
448    DELETE,
449    /// Requests a representation of a resource.
450    GET,
451    /// Requests the headers of a resource without the body.
452    HEAD,
453    /// Describes the communication options for the target resource.
454    OPTIONS,
455    /// Applies partial modifications to a resource.
456    PATCH,
457    /// Submits data to be processed to a specified resource.
458    POST,
459    /// Updates a resource or creates a new resource if it does not exist.
460    PUT,
461    /// Performs a message loop-back test along the path to the target resource.
462    TRACE,
463}
464
465/// A path expression represent a dynamic variable of a path
466#[derive(Debug, Clone)]
467pub enum PathExpr {
468    String(String),
469    Number(i32),
470}
471
472pub struct Path {
473    pub expr: String,
474    pub handler: RequestHandler,
475    pub method: HTTPMethod,
476}
477
478impl Clone for Path {
479    fn clone(&self) -> Self {
480        Self {
481            expr: self.expr.clone(),
482            handler: self.handler.clone(),
483            method: self.method.clone(),
484        }
485    }
486}
487
488impl PartialEq for Path {
489    fn eq(&self, other: &Self) -> bool {
490        self.r#match(other.expr.clone()) && self.method == other.method
491    }
492}
493
494pub struct Listener {
495    handler: EventHandler,
496}
497
498impl Clone for Listener {
499    fn clone(&self) -> Self {
500        Self {
501            handler: self.handler.clone(),
502        }
503    }
504}
505
506pub struct SoftListener {
507    handler: SoftEventHandler,
508}
509
510impl Clone for SoftListener {
511    fn clone(&self) -> Self {
512        Self {
513            handler: self.handler.clone(),
514        }
515    }
516}
517
518pub struct ErrorListener {
519    handler: ErrorEventHandler,
520}
521
522impl Clone for ErrorListener {
523    fn clone(&self) -> Self {
524        Self {
525            handler: self.handler.clone(),
526        }
527    }
528}
529
530impl Path {
531    pub fn new<T>(expr: &str, handler: T, method: HTTPMethod) -> Self
532    where
533        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
534    {
535        Path {
536            expr: expr.to_string(),
537            handler: RequestHandler(Arc::new(Box::new(handler))),
538            method,
539        }
540    }
541
542    fn parse(&self, expr: String) -> PathMap {
543        let mut exprs = PathMap::new();
544        if self.r#match(expr.clone()) {
545            let other_part: Vec<_> = expr.split('/').filter(|x| !x.is_empty()).collect();
546            let self_part: Vec<_> = self.expr.split('/').filter(|x| !x.is_empty()).collect();
547
548            for (o_chunck, s_chunck) in zip(other_part, self_part) {
549                if s_chunck.starts_with('#') {
550                    let name = s_chunck.strip_prefix('#').unwrap().to_string();
551                    let value = o_chunck.parse::<i32>().unwrap();
552                    exprs.insert(name, PathExpr::Number(value));
553                } else if s_chunck.starts_with('@') {
554                    let name = s_chunck.strip_prefix('@').unwrap().to_string();
555                    let value = o_chunck.to_string();
556                    exprs.insert(name, PathExpr::String(value));
557                } else {
558                    continue;
559                }
560            }
561        }
562
563        exprs
564    }
565
566    fn r#match(&self, expr: String) -> bool {
567        if expr == self.expr {
568            true
569        } else {
570            let other_part: Vec<_> = expr.split('/').filter(|x| !x.is_empty()).collect();
571            let self_part: Vec<_> = self.expr.split('/').filter(|x| !x.is_empty()).collect();
572
573            if other_part.len() != self_part.len() {
574                false
575            } else {
576                for (o_chunck, s_chunck) in zip(other_part, self_part) {
577                    if s_chunck.starts_with('#') {
578                        if o_chunck.parse::<i32>().is_ok() {
579                            continue;
580                        } else {
581                            return false;
582                        }
583                    } else if s_chunck.starts_with('@') {
584                        continue;
585                    } else if o_chunck != s_chunck {
586                        return false;
587                    }
588                }
589
590                true
591            }
592        }
593    }
594
595    fn handle_request(&self, request: HTTPRequest) -> HTTPResponse {
596        let exprs = self.parse(request.path.clone());
597        (self.handler.0)(request, exprs)
598    }
599}
600
601impl Listener {
602    pub fn new<T>(handler: T) -> Self
603    where
604        T: Fn(&HTTPRequest, &mut HTTPResponse) + Send + Sync + 'static,
605    {
606        Listener {
607            handler: EventHandler(Arc::new(Box::new(handler))),
608        }
609    }
610
611    pub fn notify(&self, req: &HTTPRequest, res: &mut HTTPResponse) {
612        (self.handler.0)(req, res)
613    }
614}
615
616impl SoftListener {
617    pub fn new<T>(handler: T) -> Self
618    where
619        T: Fn() + Send + Sync + 'static,
620    {
621        SoftListener {
622            handler: SoftEventHandler(Arc::new(Box::new(handler))),
623        }
624    }
625
626    pub fn notify(&self) {
627        (self.handler.0)()
628    }
629}
630
631impl ErrorListener {
632    pub fn new<T>(handler: T) -> Self
633    where
634        T: Fn(RunError) + Send + Sync + 'static,
635    {
636        Self {
637            handler: ErrorEventHandler(Arc::new(Box::new(handler))),
638        }
639    }
640
641    pub fn notify(&self, error: RunError) {
642        (self.handler.0)(error)
643    }
644}
645
646pub trait Server<U, V> {
647    fn handle_request(&self, stream: U, req: V);
648    fn run(&self);
649}
650
651/// `Vec<u8>`
652pub type Request = Vec<u8>;
653/// `Vec<u8>`
654pub type Response = Vec<u8>;
655
656/// This struct provide a simple http server
657/// that handle many of the use cases
658///
659/// ## Example
660///
661/// ```rust
662/// use mini_server::*;
663///
664/// let mut app = HTTPServer::default();
665///
666/// app.get("/", |_, _| {
667///     "Hello World!".into()
668/// });
669///
670/// ```
671///
672/// ## Path
673///
674/// The path is an expression that can contains dynamic variables.
675/// - Basic paths: `/`, `/this/is/a/path`, ...
676/// - Dynamic path: `/this/is/a/@varibale`, `/this/is/another/#variable`
677///
678/// `#` and `@` are prefixes for dynamic values. `#` for denoting numbers
679/// and `@` for strings
680pub struct HTTPServer {
681    pub addr: Vec<SocketAddr>,
682    pub paths: Vec<Path>,
683    pub listeners: Vec<Listener>,
684    pub on_ready: Option<SoftListener>,
685    pub on_shutdown: Option<SoftListener>, // TODO: Implement on_shutdown
686    pub on_error: Option<ErrorListener>,
687    pub thread_pool: worker::ThreadPool,
688    pub should_shutdown: ShutdownWrapper,
689}
690
691pub struct ShutdownWrapper(AtomicBool);
692
693impl Default for HTTPServer {
694    fn default() -> Self {
695        Self {
696            addr: vec![SocketAddr::new(
697                std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
698                4221,
699            )],
700            paths: vec![],
701            listeners: vec![],
702            on_ready: None,
703            on_shutdown: None,
704            on_error: None,
705            thread_pool: worker::ThreadPool::new(14),
706            should_shutdown: ShutdownWrapper(AtomicBool::new(false)),
707        }
708    }
709}
710
711impl Clone for HTTPServer {
712    fn clone(&self) -> Self {
713        let new_should_shutdown = self.should_shutdown.0.load(Ordering::Relaxed);
714
715        Self {
716            addr: self.addr.clone(),
717            paths: self.paths.clone(),
718            listeners: self.listeners.clone(),
719            on_ready: self.on_ready.clone(),
720            on_shutdown: self.on_shutdown.clone(),
721            on_error: self.on_error.clone(),
722            thread_pool: worker::EMPTY_POOL,
723            should_shutdown: ShutdownWrapper(AtomicBool::new(new_should_shutdown)),
724        }
725    }
726}
727
728pub enum RunError {
729    CannotBindToAddr(Vec<SocketAddr>),
730}
731
732impl std::fmt::Display for RunError {
733    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
734        match self {
735            RunError::CannotBindToAddr(addr) => {
736                write!(f, "Unable to bind to those addresses: {addr:?}")
737            }
738        }
739    }
740}
741
742impl Server<&mut TcpStream, HTTPRequest> for HTTPServer {
743    fn handle_request(&self, stream: &mut TcpStream, req: HTTPRequest) {
744        let mut handled = false;
745        for path in &self.paths {
746            if path.method == req.method && path.r#match(req.path.clone()) {
747                let mut response = path.handle_request(req.clone());
748                for listener in &self.listeners {
749                    listener.notify(&req, &mut response);
750                }
751                let _ = stream.write(response.raw().as_slice());
752                handled = true;
753                break;
754            }
755        }
756        if !handled {
757            let mut response = HTTPResponse::default();
758            response.set_status(404);
759
760            let data: String = format!(
761                "Unreachable path `{:?} - {}`. Resource NOT FOUND",
762                req.method, req.path
763            );
764
765            let data_bytes: Vec<u8> = data.into_bytes();
766            response.set_body(data_bytes);
767            for listener in &self.listeners {
768                listener.notify(&req, &mut response);
769            }
770            let _ = stream.write(response.raw().as_slice());
771        }
772    }
773
774    fn run(&self) {
775        if let Ok(listener) = TcpListener::bind(self.addr.as_slice()) {
776            if let Some(ready_fn) = &self.on_ready {
777                ready_fn.notify();
778            }
779
780            for stream in listener.incoming() {
781                match stream {
782                    Ok(stream) => {
783                        let self_clone = Arc::new(self.clone());
784                        self.thread_pool.execute(move || {
785                            let s = self_clone.clone();
786                            let mut st = stream;
787                            s.handle_connection(&mut st);
788                        });
789                    }
790                    Err(e) => {
791                        eprintln!("{e}")
792                    }
793                }
794            }
795        } else {
796            if let Some(onerror) = &self.on_error {
797                onerror.notify(RunError::CannotBindToAddr(self.addr.clone()));
798            }
799        }
800    }
801}
802
803impl HTTPServer {
804    pub fn new<A>(addr: A) -> Self
805    where
806        A: std::net::ToSocketAddrs,
807    {
808        Self {
809            addr: addr.to_socket_addrs().unwrap().collect(),
810            paths: Vec::new(),
811            listeners: Vec::new(),
812            on_ready: None,
813            on_shutdown: None,
814            on_error: None,
815            thread_pool: worker::ThreadPool::new(14),
816            should_shutdown: ShutdownWrapper(AtomicBool::new(false)),
817        }
818    }
819
820    pub fn on_ready<T>(&mut self, handler: T)
821    where
822        T: Fn() + Send + Sync + 'static,
823    {
824        self.on_ready = Some(SoftListener::new(handler));
825    }
826
827    pub fn shutdown(&self) {
828        self.should_shutdown.0.store(true, Ordering::Relaxed)
829    }
830
831    pub fn on_shutdown<T>(&mut self, handler: T)
832    where
833        T: Fn() + Send + Sync + 'static,
834    {
835        self.on_shutdown = Some(SoftListener::new(handler));
836    }
837
838    pub fn on_error<T>(&mut self, handler: T)
839    where
840        T: Fn(RunError) + Send + Sync + 'static,
841    {
842        self.on_error = Some(ErrorListener::new(handler));
843    }
844
845    fn add_path(&mut self, path: Path) {
846        let path_name = path.expr.clone();
847        if !self.paths.contains(&path) {
848            self.paths.push(path);
849        } else {
850            eprintln!(
851                "..warn `{}` path redefinition is not allowed. Only the first definition matter",
852                path_name
853            );
854        }
855    }
856
857    fn handle_connection(&self, stream: &mut TcpStream) {
858        match stream.try_clone() {
859            Ok(s) => {
860                let mut reader = std::io::BufReader::new(s);
861                let mut head = String::new();
862                'read_req_head: loop {
863                    let mut temp = String::new();
864                    let _ = reader.read_line(&mut temp);
865
866                    if temp.trim().is_empty() {
867                        break 'read_req_head;
868                    } else {
869                        head.push_str(&temp);
870                    }
871                }
872
873                let mut headers = [httparse::EMPTY_HEADER; 16];
874                let mut req = httparse::Request::new(&mut headers);
875                let is_complete = req.parse(&head.as_bytes()).unwrap().is_complete();
876                let raw_path = match req.path {
877                    Some(p) => p.to_string(),
878                    None => String::from("/"),
879                };
880                let (path, params) = parse_path(&raw_path);
881
882                let mut parsed_headers: HashMap<String, String> = HashMap::new();
883                for field in req.headers {
884                    parsed_headers.insert(
885                        field.name.to_lowercase(),
886                        String::from_utf8(field.value.to_vec()).unwrap(),
887                    );
888                }
889
890                let body_len: Option<usize> =
891                    if let Some(len) = parsed_headers.get("content-length") {
892                        Some(len.parse().unwrap())
893                    } else {
894                        None
895                    };
896
897                let method = get_method(req.method);
898
899                if let Some(body_size) = body_len {
900                    let mut body_buf = vec![0; body_size];
901                    let _ = reader.read_exact(&mut body_buf);
902                    if is_complete {
903                        self.handle_request(
904                            stream,
905                            HTTPRequest {
906                                method,
907                                path,
908                                raw_path,
909                                params,
910                                http_version: if req.version.unwrap() == 1 {
911                                    "1.1".into()
912                                } else {
913                                    "1.2".into()
914                                },
915                                headers: parsed_headers,
916                                body: body_buf,
917                            },
918                        );
919                    };
920                } else {
921                    let request = HTTPRequest {
922                        method,
923                        path,
924                        raw_path,
925                        params,
926                        http_version: get_version(req.version),
927                        headers: parsed_headers,
928                        body: vec![],
929                    };
930                    self.handle_request(stream, request);
931                }
932            }
933            Err(e) => {
934                eprintln!("{e}");
935            }
936        }
937    }
938
939    pub fn connect<T>(&mut self, path: &'static str, handler: T)
940    where
941        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
942    {
943        self.add_path(Path::new(path, handler, HTTPMethod::CONNECT));
944    }
945
946    pub fn delete<T>(&mut self, path: &'static str, handler: T)
947    where
948        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
949    {
950        self.add_path(Path::new(path, handler, HTTPMethod::DELETE));
951    }
952
953    pub fn get<T>(&mut self, path: &'static str, handler: T)
954    where
955        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
956    {
957        self.add_path(Path::new(path, handler, HTTPMethod::GET));
958    }
959
960    pub fn head<T>(&mut self, path: &'static str, handler: T)
961    where
962        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
963    {
964        self.add_path(Path::new(path, handler, HTTPMethod::HEAD));
965    }
966
967    pub fn options<T>(&mut self, path: &'static str, handler: T)
968    where
969        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
970    {
971        self.add_path(Path::new(path, handler, HTTPMethod::OPTIONS));
972    }
973
974    pub fn patch<T>(&mut self, path: &'static str, handler: T)
975    where
976        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
977    {
978        self.add_path(Path::new(path, handler, HTTPMethod::PATCH));
979    }
980
981    pub fn post<T>(&mut self, path: &'static str, handler: T)
982    where
983        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
984    {
985        self.add_path(Path::new(path, handler, HTTPMethod::POST));
986    }
987
988    pub fn put<T>(&mut self, path: &'static str, handler: T)
989    where
990        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
991    {
992        self.add_path(Path::new(path, handler, HTTPMethod::PUT));
993    }
994
995    pub fn trace<T>(&mut self, path: &'static str, handler: T)
996    where
997        T: Fn(HTTPRequest, PathMap) -> HTTPResponse + Send + Sync + 'static,
998    {
999        self.add_path(Path::new(path, handler, HTTPMethod::TRACE));
1000    }
1001
1002    pub fn on_any<T>(&mut self, handler: T)
1003    where
1004        T: Fn(&HTTPRequest, &mut HTTPResponse) + Send + Sync + 'static,
1005    {
1006        self.listeners.push(Listener::new(handler));
1007    }
1008}
1009
1010pub struct TcpServer {
1011    pub addr: Vec<SocketAddr>,
1012    listeners: Vec<SimpleEventHandler>,
1013    on_ready: Option<SoftListener>,
1014    on_shutdown: Option<SoftListener>, // TODO: Implement on_shutdown
1015    max_buffer: Option<usize>,
1016}
1017
1018impl Default for TcpServer {
1019    fn default() -> Self {
1020        Self {
1021            addr: vec![SocketAddr::new(
1022                std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
1023                4221,
1024            )],
1025            listeners: vec![],
1026            on_ready: None,
1027            on_shutdown: None,
1028            max_buffer: None,
1029        }
1030    }
1031}
1032
1033impl Server<&mut TcpStream, Request> for TcpServer {
1034    fn handle_request(&self, stream: &mut TcpStream, req: Request) {
1035        for listener in &self.listeners {
1036            if let Some(response) = listener.0(stream, req.clone()) {
1037                let _ = stream.write(&response);
1038            }
1039        }
1040    }
1041
1042    fn run(&self) {
1043        let listener = TcpListener::bind(self.addr.as_slice()).unwrap();
1044        if let Some(ready_fn) = &self.on_ready {
1045            ready_fn.notify();
1046        }
1047
1048        for stream in listener.incoming() {
1049            let mut max_buffer = MAX_BUFFER;
1050            if let Some(mxb) = self.max_buffer {
1051                max_buffer = mxb;
1052            }
1053            match stream {
1054                Ok(mut stream) => {
1055                    let mut data = vec![0; max_buffer];
1056                    let _ = stream.read(&mut data);
1057                    self.handle_request(&mut stream, data);
1058                }
1059                Err(e) => {
1060                    eprintln!("{e}")
1061                }
1062            }
1063        }
1064    }
1065}
1066
1067impl TcpServer {
1068    pub fn new<A>(addr: A) -> Self
1069    where
1070        A: std::net::ToSocketAddrs,
1071    {
1072        Self {
1073            addr: addr.to_socket_addrs().unwrap().collect(),
1074            on_ready: None,
1075            listeners: Vec::new(),
1076            on_shutdown: None,
1077            max_buffer: None,
1078        }
1079    }
1080
1081    pub fn on_ready<T>(&mut self, handler: T)
1082    where
1083        T: Fn() + Send + Sync + 'static,
1084    {
1085        self.on_ready = Some(SoftListener::new(handler));
1086    }
1087
1088    pub fn on_shutdown<T>(&mut self, handler: T)
1089    where
1090        T: Fn() + Send + Sync + 'static,
1091    {
1092        self.on_shutdown = Some(SoftListener::new(handler));
1093    }
1094
1095    pub fn set_buffer_to(&mut self, size: usize) {
1096        self.max_buffer = Some(size);
1097    }
1098}