http4r_core/
server.rs

1use std::net::{TcpListener, TcpStream};
2use std::thread;
3use std::io::{Write};
4use std::sync::{Arc};
5use crate::handler::Handler;
6use crate::headers::Headers;
7use crate::http_message::{HttpMessage, read_message_from_wire, MessageError, RequestOptions, Response, write_message_to_wire};
8use crate::http_message::Body::{BodyString};
9
10pub struct Server {
11    pub port: u16,
12    // options: ServerOptions,
13}
14
15pub struct ServerOptions {
16    pub threadpool_size: usize,
17    pub headers_size: usize,
18    pub trailers_size: usize,
19}
20
21impl Server where {
22    pub fn new(port: u16) -> Server {
23        Server {
24            port,
25            // options: options.unwrap_or(ServerOptions {
26            //     headers_size: 16384,
27            //     trailers_size: 16384,
28            //     threadpool_size: 10,
29            // })
30        }
31    }
32
33    pub fn start<F, H>(&mut self, fun: F, close_on_finish: bool)
34        where F: Fn() -> Result<H, String> + Send + Sync + 'static, H: Handler {
35        let listener = self.listen();
36        let handler = Arc::new(fun);
37
38        if close_on_finish {
39            thread::spawn(|| {
40                Self::handle_tcp_stream(listener, handler)
41            });
42        } else {
43            Self::handle_tcp_stream(listener, handler);
44        };
45    }
46
47    fn handle_tcp_stream<F, H>(listener: TcpListener, handler: Arc<F>)
48        where F: Fn() -> Result<H, String> + Send + Sync + 'static,
49              H: Handler {
50        for stream in listener.incoming() {
51            let h = handler.clone();
52            thread::spawn(move || {
53                Self::handle_request(h.clone(), stream.unwrap());
54            });
55        }
56    }
57
58    fn handle_request<F, H>(handler: Arc<F>, mut stream: TcpStream)
59        where F: Fn() -> Result<H, String> + Send + Sync + 'static, H: Handler {
60        let mut reader: &mut [u8] = &mut [0; 4096];
61        let mut chunks_writer = Vec::with_capacity(1048576);
62        let mut compress_writer = Vec::with_capacity(1048576);
63        let mut start_line_writer = Vec::with_capacity(16384);
64        let mut headers_writer = Vec::with_capacity(16384);
65        let mut trailers_writer = Vec::with_capacity(16384);
66
67        let result = read_message_from_wire(
68            stream.try_clone().unwrap(),
69            &mut reader,
70            &mut start_line_writer,
71            &mut headers_writer,
72            &mut chunks_writer,
73            &mut compress_writer,
74            &mut trailers_writer,
75        );
76
77        match result {
78            Err(MessageError::HeadersTooBig(msg))
79            | Err(MessageError::TrailersTooBig(msg))
80            | Err(MessageError::InvalidContentLength(msg))
81            | Err(MessageError::StartLineTooBig(msg))
82            | Err(MessageError::InvalidBoundaryDigit(msg))
83            => {
84                let response = Response::bad_request(Headers::empty(), BodyString(msg.as_str()));
85                write_message_to_wire(&mut stream, HttpMessage::Response(response), RequestOptions::default());
86            }
87            Err(MessageError::NoContentLengthOrTransferEncoding(msg)) => {
88                let response = Response::length_required(Headers::empty(), BodyString(msg.as_str()));
89                write_message_to_wire(&mut stream, HttpMessage::Response(response), RequestOptions::default());
90            }
91            Ok(HttpMessage::Request(request)) => {
92                let options = RequestOptions::from(&(request.headers));
93                let mut h = handler().unwrap();
94                h.handle(request, |response| {
95                    write_message_to_wire(&mut stream, HttpMessage::Response(response), options);
96                });
97            }
98            Ok(HttpMessage::Response(response)) => {
99                write_message_to_wire(&mut stream, HttpMessage::Response(response), RequestOptions::default());
100            }
101        };
102
103        stream.flush().unwrap();
104    }
105
106    fn listen(&mut self) -> TcpListener {
107        let addr = format!("0.0.0.0:{}", self.port);
108        let listener = TcpListener::bind(addr).unwrap();
109        self.port = listener.local_addr().unwrap().port();
110        listener
111    }
112}