From 6dc1675ac35801321b18fcb6738e9ff1847abb98 Mon Sep 17 00:00:00 2001 From: p11 Date: Wed, 19 Jul 2023 21:40:30 +0200 Subject: [PATCH] Save site infos to their own files, never save the complete context --- src/main.rs | 86 +++++++++++++++++++---------------------------------- 1 file changed, 31 insertions(+), 55 deletions(-) diff --git a/src/main.rs b/src/main.rs index 903d4b4..250d8c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,12 +18,7 @@ mod request; use request::Request; fn main() { - let mut context = File::open("context.dat") - .map(|mut file| { - from_stream::(&mut file) - .unwrap_or_else(|_| panic!("Context file corrupted. Delete or repair it!")) - }) - .unwrap_or_default(); + let mut context = Context::default(); let mut args = env::args(); args.next(); let address = args.next().unwrap_or("127.0.0.1:8080".to_string()); @@ -118,39 +113,6 @@ struct Context { infos: HashMap, SiteInfo>, } -impl ToStream for Context { - fn to_stream(&self, stream: &mut W) -> Result<()> { - S::size_to_stream(self.infos.len(), stream)?; - for (key, info) in &self.infos { - let key_bytes = key.as_bytes(); - S::size_to_stream(key_bytes.len(), stream)?; - stream.write_all(key_bytes)?; - - to_stream::(info, stream)?; - } - - Ok(()) - } -} - -impl FromStream for Context { - fn from_stream(stream: &mut R) -> Result { - let size = S::size_from_stream(stream)?; - let infos = (0..size) - .map(|_| { - let key_bytes = as FromStream>::from_stream(stream)?; - let key = std::str::from_utf8(&key_bytes) - .map_err(|e| Error::new(ErrorKind::InvalidData, e))? - .into(); - - Ok((key, from_stream::(stream)?)) - }) - .collect::>>()?; - - Ok(Self { infos }) - } -} - impl Context { fn handle_connection(&mut self, mut stream: TcpStream) { let Some(request) = Request::from(&stream) else { @@ -200,38 +162,52 @@ impl Context { path.to_string() }; - let (pk_file, pki_file, start_level) = if !relative_path.is_empty() { + let (pk_file, pki_file, data_path, start_level) = if !relative_path.is_empty() { path.push(&relative_path); - let (pk_extension, pki_extension) = if let Some(extension) = path.extension() { - (format!("{extension:?}.pk"), format!("{extension:?}.pki")) - } else { - ("pk".to_string(), "pki".to_string()) - }; + let (pk_extension, pki_extension, data_extension) = + if let Some(extension) = path.extension() { + ( + format!("{extension:?}.pk"), + format!("{extension:?}.pki"), + format!("{extension:?}.dat"), + ) + } else { + ("pk".to_string(), "pki".to_string(), "dat".to_string()) + }; let pk_path = path.with_extension(pk_extension); let pki_path = path.with_extension(pki_extension); + let data_path = path.with_extension(data_extension); let (Ok(pk_file), Ok(pki_file)) = (File::open(pk_path), File::open(pki_path)) else { fail(stream); return; }; - (pk_file, Some(pki_file), 1) + (pk_file, Some(pki_file), data_path, 1) } else { let mut pk_path = path.clone(); pk_path.push("index.pk"); + let mut data_path = path.clone(); + data_path.push("index.dat"); let Ok(pk_file) = File::open(pk_path) else { fail(stream); return; }; - (pk_file, None, 0) + (pk_file, None, data_path, 0) }; use Entry::*; let info = match self.infos.entry(relative_path.clone().into_boxed_str()) { Occupied(o) => o.into_mut(), - Vacant(v) => v.insert(SiteInfo::default()), + Vacant(v) => v.insert( + File::open(&data_path) + .map(|mut file| { + from_stream::(&mut file).unwrap_or_default() + }) + .unwrap_or_default(), + ), }; let mut name = None; @@ -282,6 +258,13 @@ impl Context { info.visits += 1; + if let Ok(mut file) = File::create(data_path) { + if to_stream::(info, &mut file).is_err() { + eprintln!("Error saving data!"); + eprintln!(); + } + } + let _ = write!(stream, "HTTP/1.1 200 OK\r\n\r\n"); let _ = writeln!(stream, ""); @@ -389,12 +372,5 @@ impl Context { let _ = writeln!(stream, "
"); let _ = writeln!(stream, "<< Back"); - - if let Ok(mut file) = File::create("context.dat") { - if to_stream::(self, &mut file).is_err() { - eprintln!("Error saving data!"); - eprintln!(); - } - } } }