From a5cffc35a215cc50b3afe1ef7b66f3a4180b3eac Mon Sep 17 00:00:00 2001 From: alemidev Date: Fri, 18 Mar 2022 02:21:08 +0100 Subject: [PATCH] added super basic file server, very wip --- server/Cargo.toml | 9 +++++ server/src/main.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 server/Cargo.toml create mode 100644 server/src/main.rs diff --git a/server/Cargo.toml b/server/Cargo.toml new file mode 100644 index 0000000..0a12d56 --- /dev/null +++ b/server/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "memo-server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +toml = "0.5.8" diff --git a/server/src/main.rs b/server/src/main.rs new file mode 100644 index 0000000..de54b16 --- /dev/null +++ b/server/src/main.rs @@ -0,0 +1,99 @@ +use std::collections::LinkedList; +use std::fs; +use std::io::{BufRead, BufReader, BufWriter, Write, Read}; +use std::net::{SocketAddr, TcpListener, TcpStream}; +use std::thread; + +fn main() { + // TODO load address and port from config toml + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + // TODO make a thread pool + let mut threads: LinkedList> = LinkedList::new(); + + for stream in listener.incoming() { + match stream { + Ok(stream) => threads.push_back(thread::spawn(|| handle_connection(stream))), + Err(e) => println!("[!] ERROR establishing a connection : {}", e.to_string()), + } + } +} + +fn handle_connection(stream: TcpStream) { + let mut addr = "?.?.?.?".to_string(); + if stream.peer_addr().is_ok() { + let peer: SocketAddr = stream.peer_addr().unwrap(); + addr = format!("{}:{}", peer.ip(), peer.port()); + } + + println!("[+] new connection from {}", addr); + + let mut reader = BufReader::new(&stream); + let mut writer = BufWriter::new(&stream); + let mut buffer = String::new(); + + match reader.read_line(&mut buffer) { + Ok(_count) => { + let mut s = buffer.as_str().splitn(2, " "); + let cmd = s.next().unwrap_or("").to_lowercase(); + let arg = s.next().unwrap_or("").replace("\n", ""); + match cmd.as_str() { + "get" => { + let paths = fs::read_dir("./").unwrap(); + + for path in paths { + match path { + Ok(p) => { + if p.path().ends_with(arg.as_str()) { + match fs::read_to_string(p.path()) { + Ok(contents) => { + println!("[<] serving file : {}", arg); + match writer.write(contents.as_bytes()) { + Ok(_) => writer.flush().unwrap(), + Err(e) => println!("[!] Error sending contents : {}", e.to_string()), + } + } + Err(e) => println!("[!] Error reading file {} : {}", arg, e.to_string()), + } + } + }, + Err(e) => println!("[!] could not list dirs : {}", e.to_string()), + } + } + }, + "put" => { + let mut fname : String = arg.chars().filter(|c| c.is_alphanumeric()).collect::(); + fname.push_str(".txt"); + if fs::metadata(&fname).is_err() { + let mut file = fs::File::create(&fname).unwrap(); + let mut buf = [0;4096]; + loop { + match reader.read(&mut buf) { + Ok(count) => { + if count <= 0 { break } + match file.write(&buf[..count]) { + Ok(_c) => { /* TODO check that we write as many as read */ }, + Err(_e) => { + // TODO log + break + } + } + }, + Err(_e) => { + // TODO log if bad + break; + } + } + } + } + }, + _ => println!("[!] Command misunderstood : '{}' '{}' [{}]", cmd, arg, buffer), + } + buffer.clear(); + }, + Err(e) => { + println!("[!] Error reading from socket : {}", e.to_string()); + } + } + + println!("[-] closed connection from : {}", addr); +}