capture and print errors

pull/1/head
dvkt 4 years ago
parent 6311b90807
commit 09d691c568

@ -1,17 +1,17 @@
use async_std::{ use async_std::{
fs, fs,
io::BufReader, io::BufReader,
net::{TcpListener, TcpStream}, net::{TcpListener, TcpStream, ToSocketAddrs},
path::PathBuf,
prelude::*, prelude::*,
task, task,
}; };
use std::path::PathBuf;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
const MAX_PEEK_SIZE: usize = 1024; const MAX_PEEK_SIZE: usize = 1024;
pub fn start(addr: &str, root: &str) -> Result<()> { pub fn start(addr: impl ToSocketAddrs, root: &str) -> Result<()> {
task::block_on(async { task::block_on(async {
let listener = TcpListener::bind(addr).await?; let listener = TcpListener::bind(addr).await?;
let mut incoming = listener.incoming(); let mut incoming = listener.incoming();
@ -19,7 +19,11 @@ pub fn start(addr: &str, root: &str) -> Result<()> {
let stream = stream?; let stream = stream?;
println!("-> Connection from: {}", stream.peer_addr()?); println!("-> Connection from: {}", stream.peer_addr()?);
let root = root.to_string(); let root = root.to_string();
task::spawn(client_loop(stream, root)); task::spawn(async {
if let Err(e) = client_loop(stream, root).await {
eprintln!("-> {}", e);
}
});
} }
Ok(()) Ok(())
}) })
@ -30,15 +34,16 @@ async fn client_loop(mut stream: TcpStream, root: String) -> Result<()> {
let mut lines = reader.lines(); let mut lines = reader.lines();
if let Some(Ok(line)) = lines.next().await { if let Some(Ok(line)) = lines.next().await {
println!("-> client sent: {:?}", line); println!("-> {} sent: {:?}", stream.peer_addr()?, line);
respond(&mut stream, &line, &root).await?; respond(&mut stream, &line, &root).await?;
} }
Ok(()) Ok(())
} }
async fn respond(stream: &mut TcpStream, selector: &str, root: &str) -> Result<()> { async fn respond(stream: &mut TcpStream, selector: &str, root: &str) -> Result<()> {
let mut path = PathBuf::from(root); let mut path = fs::canonicalize(root).await?;
path.push(selector.replace("..", ".")); path.push(selector.replace("..", ".").trim_start_matches('/'));
println!("path {:?}", path);
let md = fs::metadata(path.clone()).await?; let md = fs::metadata(path.clone()).await?;
if md.is_file() { if md.is_file() {
@ -53,17 +58,17 @@ async fn respond(stream: &mut TcpStream, selector: &str, root: &str) -> Result<(
async fn send_dir(stream: &mut TcpStream, path: PathBuf) -> Result<()> { async fn send_dir(stream: &mut TcpStream, path: PathBuf) -> Result<()> {
let mut response = String::new(); let mut response = String::new();
let mut dir = fs::read_dir(path.clone()).await?; let mut dir = fs::read_dir(path.clone()).await?;
while let Some(Ok(entry)) = dir.next().await { while let Some(Ok(entry)) = dir.next().await {
let file_type = file_type(&entry).await; let file_type = file_type(&entry).await;
let f = entry.file_name();
let file_name = f.to_string_lossy();
response.push_str(&format!( response.push_str(&format!(
"{}{}\t{}\tlocalhost\t7070\r\n", "{}{}\t{}\tlocalhost\t7070\r\n",
file_type, file_type, file_name, file_name,
entry.file_name().into_string().unwrap(),
entry.path().to_string_lossy(),
)); ));
} }
stream.write_all(response.as_bytes()).await?; stream.write_all(response.as_bytes()).await?;
stream.write_all(b".\r\n").await?; // end gopher response
Ok(()) Ok(())
} }
@ -77,6 +82,7 @@ async fn send_text(stream: &mut TcpStream, path: PathBuf) -> Result<()> {
bytes -= n as u64; bytes -= n as u64;
stream.write_all(&buf).await?; stream.write_all(&buf).await?;
} }
stream.write_all(b".\r\n").await?; // end gopher response
Ok(()) Ok(())
} }

Loading…
Cancel
Save