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
|
# you can define as many of these as you like
|
||||||
listen = 0.0.0.0:1965
|
listen = 0.0.0.0:1965
|
||||||
listen = [::]:1965
|
listen = [::1]:1965
|
||||||
|
|
||||||
# privilege level for the server to drop to after initializing
|
# privilege level for the server to drop to after initializing
|
||||||
user = nobody
|
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>) {
|
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) {
|
match stream.ssl_read(&mut buffer) {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
if s == 0 || s > 1025 {
|
if s == 0 || s > 1024 {
|
||||||
send_header(&mut stream, &response::bad_request());
|
send_header(&mut stream, &response::bad_request());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,12 +114,19 @@ impl Server {
|
||||||
println!("serving...");
|
println!("serving...");
|
||||||
let acceptor = Server::build_acceptor(&self.config);
|
let acceptor = Server::build_acceptor(&self.config);
|
||||||
|
|
||||||
|
let mut listeners = Vec::new();
|
||||||
for addr in &self.config.addrs {
|
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);
|
println!("listening on: {}", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let listener = TcpListener::bind(&self.config.addrs[..]).unwrap();
|
|
||||||
|
|
||||||
if self.config.user.is_root() {
|
if self.config.user.is_root() {
|
||||||
panic!("refusing to run as root");
|
panic!("refusing to run as root");
|
||||||
}
|
}
|
||||||
|
@ -140,21 +147,42 @@ impl Server {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
let mut threads = Vec::new();
|
||||||
println!("new connection");
|
for listener in listeners {
|
||||||
match stream {
|
let config = self.config.clone();
|
||||||
Ok(stream) => {
|
let acceptor = acceptor.clone();
|
||||||
let acceptor = acceptor.clone();
|
let t = thread::spawn(move || listener_loop(config, listener, acceptor));
|
||||||
let config = self.config.clone();
|
threads.push(t);
|
||||||
thread::spawn(move || {
|
}
|
||||||
let stream = acceptor.accept(stream).unwrap();
|
|
||||||
handler::handle_request(&config, stream);
|
for t in threads {
|
||||||
println!("closing connection");
|
match t.join() {
|
||||||
});
|
Ok(_) => {
|
||||||
}
|
println!("failure! one listening thread exited");
|
||||||
|
},
|
||||||
Err(_) => {
|
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 {
|
pub enum Status {
|
||||||
Success = 20,
|
Success = 20,
|
||||||
RedirectPermanent = 31,
|
RedirectPermanent = 31,
|
||||||
PermanentFailure = 50,
|
|
||||||
NotFound = 51,
|
NotFound = 51,
|
||||||
ProxyRequestRefused = 53,
|
ProxyRequestRefused = 53,
|
||||||
BadRequest = 59,
|
BadRequest = 59,
|
||||||
|
@ -36,10 +35,6 @@ pub fn redirect_permanent(meta: &str) -> Header {
|
||||||
Header::new(Status::RedirectPermanent, meta)
|
Header::new(Status::RedirectPermanent, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn permanent_failure() -> Header {
|
|
||||||
Header::new(Status::PermanentFailure, "permanent failure")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn not_found() -> Header {
|
pub fn not_found() -> Header {
|
||||||
Header::new(Status::NotFound, "not found")
|
Header::new(Status::NotFound, "not found")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue