correctly spawn multiple tcp listeners for each address

This commit is contained in:
Jan Wolff 2020-05-26 07:36:53 +02:00
parent 2ffc8ff0cc
commit 361aa9a5d7
4 changed files with 47 additions and 24 deletions

View file

@ -6,7 +6,7 @@ gem_root = ./doc
# you can define as many of these as you like
listen = 0.0.0.0:1965
listen = [::]:1965
listen = [::1]:1965
# privilege level for the server to drop to after initializing
user = nobody

View file

@ -20,10 +20,10 @@ fn send_header(stream: &mut SslStream<TcpStream>, header: &response::Header) {
}
pub fn handle_request(config: &ServerConfig, mut stream: SslStream<TcpStream>) {
let mut buffer = [0; 1024];
let mut buffer = [0; 1025];
match stream.ssl_read(&mut buffer) {
Ok(s) => {
if s == 0 || s > 1025 {
if s == 0 || s > 1024 {
send_header(&mut stream, &response::bad_request());
return;
}

View file

@ -114,12 +114,19 @@ impl Server {
println!("serving...");
let acceptor = Server::build_acceptor(&self.config);
let mut listeners = Vec::new();
for addr in &self.config.addrs {
let listener = match TcpListener::bind(addr) {
Ok(listener) => listener,
Err(_) => {
println!("failed listening on: {}", addr);
return;
}
};
listeners.push(listener);
println!("listening on: {}", addr);
}
let listener = TcpListener::bind(&self.config.addrs[..]).unwrap();
if self.config.user.is_root() {
panic!("refusing to run as root");
}
@ -140,21 +147,42 @@ impl Server {
}
};
for stream in listener.incoming() {
println!("new connection");
match stream {
Ok(stream) => {
let acceptor = acceptor.clone();
let config = self.config.clone();
thread::spawn(move || {
let stream = acceptor.accept(stream).unwrap();
handler::handle_request(&config, stream);
println!("closing connection");
});
}
let mut threads = Vec::new();
for listener in listeners {
let config = self.config.clone();
let acceptor = acceptor.clone();
let t = thread::spawn(move || listener_loop(config, listener, acceptor));
threads.push(t);
}
for t in threads {
match t.join() {
Ok(_) => {
println!("failure! one listening thread exited");
},
Err(_) => {
println!("connection failed");
}
println!("failure! one listening thread exited");
},
};
}
}
}
fn listener_loop(config: ServerConfig, listener: TcpListener, acceptor: std::sync::Arc<SslAcceptor>) {
for stream in listener.incoming() {
println!("new connection");
match stream {
Ok(stream) => {
let acceptor = acceptor.clone();
let config = config.clone();
thread::spawn(move || {
let stream = acceptor.accept(stream).unwrap();
handler::handle_request(&config, stream);
println!("closing connection");
});
}
Err(_) => {
println!("connection failed");
}
}
}

View file

@ -4,7 +4,6 @@ use std::vec::Vec;
pub enum Status {
Success = 20,
RedirectPermanent = 31,
PermanentFailure = 50,
NotFound = 51,
ProxyRequestRefused = 53,
BadRequest = 59,
@ -36,10 +35,6 @@ pub fn redirect_permanent(meta: &str) -> Header {
Header::new(Status::RedirectPermanent, meta)
}
pub fn permanent_failure() -> Header {
Header::new(Status::PermanentFailure, "permanent failure")
}
pub fn not_found() -> Header {
Header::new(Status::NotFound, "not found")
}