phlog

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
Mgopher-server/src/main.rs | 47+++++++++++++++++++++++++++++++++++++++++++++--
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(()) }