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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::net::{TcpListener, TcpStream};
use std::thread;
use std::io::{Write};
use std::sync::{Arc};
use crate::handler::Handler;
use crate::headers::Headers;
use crate::http_message::{HttpMessage, read_message_from_wire, MessageError, RequestOptions, Response, write_message_to_wire};
use crate::http_message::Body::{BodyString};
pub struct Server {
pub port: u16,
}
pub struct ServerOptions {
pub threadpool_size: usize,
pub headers_size: usize,
pub trailers_size: usize,
}
impl Server where {
pub fn new(port: u16) -> Server {
Server {
port,
}
}
pub fn start<F, H>(&mut self, fun: F, close_on_finish: bool)
where F: Fn() -> Result<H, String> + Send + Sync + 'static, H: Handler {
let listener = self.listen();
let handler = Arc::new(fun);
if close_on_finish {
thread::spawn(|| {
Self::handle_tcp_stream(listener, handler)
});
} else {
Self::handle_tcp_stream(listener, handler);
};
}
fn handle_tcp_stream<F, H>(listener: TcpListener, handler: Arc<F>)
where F: Fn() -> Result<H, String> + Send + Sync + 'static,
H: Handler {
for stream in listener.incoming() {
let h = handler.clone();
thread::spawn(move || {
Self::handle_request(h.clone(), stream.unwrap());
});
}
}
fn handle_request<F, H>(handler: Arc<F>, mut stream: TcpStream)
where F: Fn() -> Result<H, String> + Send + Sync + 'static, H: Handler {
let mut reader: &mut [u8] = &mut [0; 4096];
let mut chunks_writer = Vec::with_capacity(1048576);
let mut compress_writer = Vec::with_capacity(1048576);
let mut start_line_writer = Vec::with_capacity(16384);
let mut headers_writer = Vec::with_capacity(16384);
let mut trailers_writer = Vec::with_capacity(16384);
let result = read_message_from_wire(
stream.try_clone().unwrap(),
&mut reader,
&mut start_line_writer,
&mut headers_writer,
&mut chunks_writer,
&mut compress_writer,
&mut trailers_writer,
);
match result {
Err(MessageError::HeadersTooBig(msg))
| Err(MessageError::TrailersTooBig(msg))
| Err(MessageError::InvalidContentLength(msg))
| Err(MessageError::StartLineTooBig(msg))
| Err(MessageError::InvalidBoundaryDigit(msg))
=> {
let response = Response::bad_request(Headers::empty(), BodyString(msg.as_str()));
write_message_to_wire(&mut stream, HttpMessage::Response(response), RequestOptions::default());
}
Err(MessageError::NoContentLengthOrTransferEncoding(msg)) => {
let response = Response::length_required(Headers::empty(), BodyString(msg.as_str()));
write_message_to_wire(&mut stream, HttpMessage::Response(response), RequestOptions::default());
}
Ok(HttpMessage::Request(request)) => {
let options = RequestOptions::from(&(request.headers));
let mut h = handler().unwrap();
h.handle(request, |response| {
write_message_to_wire(&mut stream, HttpMessage::Response(response), options);
});
}
Ok(HttpMessage::Response(response)) => {
write_message_to_wire(&mut stream, HttpMessage::Response(response), RequestOptions::default());
}
};
stream.flush().unwrap();
}
fn listen(&mut self) -> TcpListener {
let addr = format!("0.0.0.0:{}", self.port);
let listener = TcpListener::bind(addr).unwrap();
self.port = listener.local_addr().unwrap().port();
listener
}
}