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