fp_server 2.0.5

A basic HTTP Server lib
Documentation
mod handler;
mod request;
mod response;
mod request_builder;
mod receiver;
mod parser;
mod serializer;

use receiver::Receiver;
use parser::HTTPRequestParser;
use serializer::HTTPResponseSerializer;

use std::io::Write;
use std::net::{TcpListener, TcpStream};
use std::collections::HashMap;

pub use request::*;
pub use response::HTTPResponse;
pub use handler::HTTPRequestHandler;
pub struct HTTPServer {
    listener: TcpListener,
    handlers: HashMap<HTTPMethod, Option<Box<dyn HTTPRequestHandler>>>
}

impl HTTPServer {
    pub fn new<A>(
        address: A
    ) -> Result<Self, HTTPServerError>
        where A: std::net::ToSocketAddrs
    {
        let listener = TcpListener::bind(address)
            .map_err(|_| {HTTPServerError::AddressBindFailure})?;    

        let mut handlers = HashMap::new();

        handlers.insert(HTTPMethod::CONNECT, None);
        handlers.insert(HTTPMethod::DELETE, None);
        handlers.insert(HTTPMethod::GET, None);
        handlers.insert(HTTPMethod::HEAD, None);
        handlers.insert(HTTPMethod::OPTIONS, None);
        handlers.insert(HTTPMethod::PATCH, None);
        handlers.insert(HTTPMethod::POST, None);
        handlers.insert(HTTPMethod::PUT, None);
        handlers.insert(HTTPMethod::TRACE, None);

        Ok(Self {
            listener,
            handlers
        })
    }

    pub fn run(&self) {
        std::thread::scope(|t| {
            self.listener.incoming().for_each(|res| {
                if let Ok(stream) = res {
                    t.spawn(|| {self.handle_connection(stream)});
                }
            });
        });
    }

    pub fn set_handler(
        &mut self,
        method: HTTPMethod,
        handler: Option<Box<dyn HTTPRequestHandler>>
    ) {
        self.handlers.insert(method, handler);
    }

    fn handle_connection(&self, mut stream: TcpStream) -> Option<()> {
        let receiver = Receiver::new();
        let parser = HTTPRequestParser::new();
        let serializer = HTTPResponseSerializer::new();

        let request_bytes = receiver.receive(&mut stream)?;
        let request = parser.parse(&request_bytes)?;
        let response = if let Some(handler) = self.handlers.get(&request.get_method()) {
            if let Some(handler) = handler {
                handler.run(request)
            }
            else {
                HTTPResponse::new("Unimplemented", 501, &[])
            }
        } else {
            println!("Invalid Request Method!");
            HTTPResponse::new("Invalid Request Method!", 400, &[])
        };
        let bytes = serializer.serialize(response);
        stream.write(&bytes).ok().map(|_| {})
    }
}

#[derive(Debug)]
pub enum HTTPServerError {
    AddressBindFailure
}