Better error handling (where it's needed)

This commit is contained in:
Mark 2021-03-16 22:10:47 +02:00
parent ecb32b205c
commit 570b0617ef
2 changed files with 22 additions and 20 deletions

View File

@ -42,7 +42,6 @@ impl ThreadPool {
}
pub fn execute<F: FnOnce() + Send + 'static>(&self, f: F) {
// TODO error handling
self.sender.send(Box::new(f)).unwrap();
}
}

View File

@ -4,9 +4,9 @@ use std::io::{self, Read, Write};
use std::net::{SocketAddr, TcpListener};
use url::Url;
use log::{warn, info, error};
use crate::proto::{self, ErrorCode, ResponseBody};
use crate::pool::ThreadPool;
use crate::proto::{self, ErrorCode, ResponseBody};
use log::{error, info, warn};
pub struct ServerConfig {
pub thread_count: usize,
@ -35,7 +35,7 @@ fn read_request(stream: &mut impl Read) -> Result<Url, proto::Error> {
if read_line(&mut line, stream).is_err() {
return Err(proto::Error::new(
ErrorCode::BadRequest,
Some("Bad Request")
Some("Bad Request"),
));
}
match Url::parse(&line) {
@ -51,12 +51,12 @@ fn send_response_body(stream: &mut impl Write, response: ResponseBody) -> Result
match response {
ResponseBody::GeminiText(data) => {
write!(stream, "20 text/gemini; charset=utf8\r\n{}", data)
},
ResponseBody::File(_, _) => todo!()
}
ResponseBody::File(_, _) => todo!(),
}
}
fn handle_request(_peer: SocketAddr, url: Url) -> Result<ResponseBody, proto::Error> {
fn handle_request(_peer: Option<SocketAddr>, url: Url) -> Result<ResponseBody, proto::Error> {
// TODO url logic
if url.path() == "/ping" {
return Ok(ResponseBody::GeminiText("pong".to_string()));
@ -64,44 +64,45 @@ fn handle_request(_peer: SocketAddr, url: Url) -> Result<ResponseBody, proto::Er
Err(proto::Error::new(ErrorCode::NotFound, Some(url.path())))
}
fn handle_stream<S: Read + Write>(peer: SocketAddr, stream: &mut S) {
fn handle_stream<S: Read + Write>(peer: Option<SocketAddr>, stream: &mut S) {
let url = match read_request(stream) {
// TODO fix duplicate code here?
Ok(url) => url,
Err(err) => {
let _ = writeln!(stream, "{}\r\n", err);
error!("{} {}", peer, err);
error!("{:?} {}", peer, err);
return;
}
};
match handle_request(peer, url.clone()) {
Ok(response) => {
let _ = send_response_body(stream, response);
info!("{} {} 20", peer, url);
},
info!("{:?} {} 20", peer, url);
}
Err(err) => {
let _ = writeln!(stream, "{}\r\n", err);
error!("{} {} {}", peer, url, err);
error!("{:?} {} {}", peer, url, err);
}
};
}
// TODO Result
pub fn run(config: &ServerConfig) {
pub fn run(config: &ServerConfig) -> Result<(), io::Error> {
info!("Listening to gemini requests on {}", &config.bind_address);
let mut der = vec![];
let mut file = File::open(&config.identity_file).unwrap();
file.read_to_end(&mut der).unwrap();
let identity = Identity::from_pkcs12(&der, "").unwrap();
let mut file = File::open(&config.identity_file)?;
file.read_to_end(&mut der)?;
let identity =
Identity::from_pkcs12(&der, "").map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let listener = TcpListener::bind(&config.bind_address).unwrap();
let acceptor = TlsAcceptor::new(identity).unwrap();
let listener = TcpListener::bind(&config.bind_address)?;
let acceptor = TlsAcceptor::new(identity).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let pool = ThreadPool::new(config.thread_count);
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let peer = stream.peer_addr().unwrap();
let peer = stream.peer_addr();
let mut stream = match acceptor.accept(stream) {
Ok(r) => r,
Err(e) => {
@ -111,7 +112,7 @@ pub fn run(config: &ServerConfig) {
};
pool.execute(move || {
handle_stream(peer, &mut stream);
handle_stream(peer.ok(), &mut stream);
});
}
Err(e) => {
@ -120,4 +121,6 @@ pub fn run(config: &ServerConfig) {
}
}
}
Ok(())
}