commit 3bc09aa35a83514042ec6a349dc9618a7018b270
parent 61ad9fb75c8f123cc58e7b2a0b6ddbfa6781b56b
Author: Charlie Stanton <charlie@shtanton.com>
Date: Wed, 5 Aug 2020 16:30:42 +0100
Adds all the gopher server functionality
Diffstat:
1 file changed, 45 insertions(+), 2 deletions(-)
diff --git a/gopher-server/src/main.rs b/gopher-server/src/main.rs
@@ -1,3 +1,46 @@
-fn main() {
- println!("Hello, world!");
+use std::net::{TcpStream, TcpListener};
+use std::io::{self, Write, BufReader, BufRead};
+use std::thread;
+use std::fs::File;
+use std::path::PathBuf;
+
+fn handle_client(dir: String, mut stream: TcpStream) -> io::Result<()> {
+ let mut buf_reader = BufReader::new(stream.try_clone()?);
+ let mut line = String::new();
+ buf_reader.read_line(&mut line)?;
+ let line = line.trim();
+ let filename = if line == "" {
+ "index"
+ } else {
+ line
+ };
+ let path: PathBuf = [dir.as_str(), filename].iter().collect();
+ let mut file = File::open(path)?;
+ io::copy(&mut file, &mut stream)?;
+ Ok(())
+}
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let args: Vec<_> = std::env::args().collect();
+ if args.len() < 3 {
+ println!("Usage: server gopherdir port");
+ return Ok(());
+ }
+ let gopherdir = args[1].clone();
+
+ let listener = TcpListener::bind(format!("0.0.0.0:{}", args[2]))?;
+ for stream in listener.incoming() {
+ if let Ok(stream) = stream {
+ let gopherdir = gopherdir.clone();
+ thread::spawn(move || {
+ if let Err(err) = handle_client(gopherdir, stream) {
+ println!("Error: {}", err);
+ }
+ });
+ } else {
+ println!("Error getting tcp stream");
+ }
+ }
+
+ Ok(())
}