arg parsing, server

pull/1/head
dvkt 4 years ago
parent c3d6e57de9
commit 20e73ffdf1

@ -1,53 +1 @@
use async_std::{
fs,
io::BufReader,
net::{TcpListener, TcpStream, ToSocketAddrs},
prelude::*,
task,
};
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
pub fn start_server(addr: impl ToSocketAddrs) -> Result<()> {
let fut = listen(addr);
task::block_on(fut)
}
async fn listen(addr: impl ToSocketAddrs) -> Result<()> {
let listener = TcpListener::bind(addr).await?;
let mut incoming = listener.incoming();
while let Some(stream) = incoming.next().await {
let stream = stream?;
println!("-> Connection from: {}", stream.peer_addr()?);
task::spawn(client_loop(stream));
}
Ok(())
}
async fn client_loop(mut stream: TcpStream) -> Result<()> {
let reader = BufReader::new(&stream);
let mut lines = reader.lines();
if let Some(Ok(line)) = lines.next().await {
println!("-> client sent: {:?}", line);
respond(&mut stream, &line).await?;
}
Ok(())
}
async fn respond(stream: &mut TcpStream, selector: &str) -> Result<()> {
let mut response = format!("iYou sent: {}\r\n", selector);
let mut dir = fs::read_dir(".").await?;
while let Some(Ok(entry)) = dir.next().await {
response.push_str(&format!(
"1{}\t/{}\tlocalhost\t7070\r\n",
entry.file_name().into_string().unwrap(),
entry.file_name().into_string().unwrap(),
));
}
stream.write_all(response.as_bytes()).await?;
Ok(())
}
pub mod server;

@ -4,33 +4,47 @@ use std::process;
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() < 2 {
print_usage();
print_help();
return;
}
let dir = args.get(1).unwrap();
if dir == "--version" || dir == "-v" || dir == "-version" {
print_version();
return;
}
if dir == "--help" || dir == "-h" || dir == "-help" {
print_usage();
return;
}
if !dir.is_empty() && dir.starts_with('-') {
eprintln!("unknown flag: {}", dir);
process::exit(1);
let mut root = ".".to_string();
let mut iter = args.iter();
let mut host = "localhost".to_string();
let mut port = "70".to_string();
while let Some(arg) = iter.next() {
match arg.as_ref() {
"--version" | "-v" | "-version" => return print_version(),
"--help" | "-h" | "-help" => return print_help(),
"--port" | "-p" | "-port" => {
if let Some(p) = iter.next() {
port = p.into();
}
}
"--host" | "-H" | "-host" => {
if let Some(h) = iter.next() {
host = h.into();
}
}
_ => {
if let Some('-') = arg.chars().nth(0) {
eprintln!("unknown flag: {}", arg);
process::exit(1);
} else {
root = arg.clone();
}
}
}
}
println!("-> Listening on localhost:7070");
if let Err(e) = phd::start_server("localhost:7070") {
let addr = format!("{}:{}", host, port);
println!("-> Serving {} on {}", root, addr);
if let Err(e) = phd::server::start(addr, &root) {
eprintln!("{}", e);
}
}
fn print_usage() {
fn print_help() {
println!(
"Usage:

@ -0,0 +1,53 @@
use async_std::{
fs,
io::BufReader,
net::{TcpListener, TcpStream, ToSocketAddrs},
prelude::*,
task,
};
use std::path;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
pub fn start(addr: &str, root: &str) -> Result<()> {
let fut = listen(addr, root);
task::block_on(fut)
}
async fn listen(addr: &str, root: &str) -> Result<()> {
let listener = TcpListener::bind(addr).await?;
let mut incoming = listener.incoming();
while let Some(stream) = incoming.next().await {
let stream = stream?;
println!("-> Connection from: {}", stream.peer_addr()?);
task::spawn(client_loop(stream, &root.to_string()));
}
Ok(())
}
async fn client_loop(mut stream: TcpStream, root: &str) -> Result<()> {
let reader = BufReader::new(&stream);
let mut lines = reader.lines();
if let Some(Ok(line)) = lines.next().await {
println!("-> client sent: {:?}", line);
respond(&mut stream, &line, root).await?;
}
Ok(())
}
async fn respond(stream: &mut TcpStream, selector: &str, root: &str) -> Result<()> {
let mut response = format!("iYou sent: {}\r\n", selector);
let mut dir = fs::read_dir(root).await?;
while let Some(Ok(entry)) = dir.next().await {
response.push_str(&format!(
"1{}\t/{}\tlocalhost\t7070\r\n",
entry.file_name().into_string().unwrap(),
entry.file_name().into_string().unwrap(),
));
}
stream.write_all(response.as_bytes()).await?;
Ok(())
}
Loading…
Cancel
Save