correctly spawn multiple tcp listeners for each address
This commit is contained in:
parent
2ffc8ff0cc
commit
361aa9a5d7
4 changed files with 47 additions and 24 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue