1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use std::io;
use std::net::{TcpListener, TcpStream};

use anyhow::Error;
use fehler::throws;
use log::{debug, info};
use threadpool::ThreadPool;

use crate::http_handler::{handle, Response};

#[throws]
fn handle_stream(stream: TcpStream) -> Response {
    let mut out = stream.try_clone()?;
    let mut reader = io::BufReader::new(stream);
    handle(&mut reader, &mut out)?
}

fn uber_handle_stream(stream: io::Result<TcpStream>) {
    match stream {
        Ok(stream) => {
            let addr = stream.peer_addr().unwrap();
            debug!("Accepted connection: {}", addr);

            let res = handle_stream(stream);
            match res {
                Ok(response) => info!("{} {}", addr, response.status()),
                Err(e) => info!("An error happened while handling request {}", e),
            }
        }
        Err(e) => {
            info!("Connection failed: {}", e);
        }
    }
}

pub fn run(listener: TcpListener, pool: ThreadPool) {
    info!(
        "Running server on {} with {} threads",
        listener.local_addr().unwrap(),
        pool.max_count()
    );
    for stream in listener.incoming() {
        pool.execute(move || {
            uber_handle_stream(stream);
        });
    }
}