From b157e2c962a7ff2a6da9be69d801e9bdd308dd88 Mon Sep 17 00:00:00 2001 From: p11 Date: Fri, 21 Jul 2023 19:42:08 +0200 Subject: [PATCH] Simplified path creation, only keep files open as long as necessary --- src/main.rs | 143 +++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 73 deletions(-) diff --git a/src/main.rs b/src/main.rs index 53409b8..1c5bc56 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use std::{ fs::File, io::{prelude::*, BufReader, Error, ErrorKind, Result}, net::{TcpListener, TcpStream}, + path::Path, }; use data_stream::{ @@ -132,14 +133,12 @@ impl Context { eprintln!("- Body: {}", request.body); eprintln!(); - let Ok(current_dir) = env::current_dir() else { + let Ok(path) = env::current_dir() else { fail(stream); return; }; - let mut path = current_dir; - - let (relative_path, _) = request + let (mut relative_path, _) = request .path .split_once('?') .unwrap_or((&request.path, Default::default())); @@ -149,54 +148,47 @@ impl Context { return; } - let relative_path = if relative_path.is_empty() { - String::new() + if let Some(path) = relative_path.strip_prefix('/') { + relative_path = path; + } + + let mut pk_path = path.clone(); + let mut data_path = path.clone(); + + let (pki_path, start_level, relative_path) = if relative_path.is_empty() { + pk_path.push("index.pk"); + data_path.push("index.dat"); + + (None, 0, String::new()) } else { - let path = percent_decode_str(&relative_path[1..]).decode_utf8_lossy(); + let mut pki_path = path.clone(); + + let path = percent_decode_str(relative_path).decode_utf8_lossy(); if path.contains('_') { let path = path.replace('_', " "); let _ = write!(stream, "HTTP/1.1 308 Permanent Redirect\r\n"); let _ = write!(stream, "Location: /{path}\r\n\r\n"); return; } - path.to_string() + + pk_path.push(format!("{path}.pk")); + pki_path.push(format!("{path}.pki")); + data_path.push(format!("{path}.dat")); + + (Some(pki_path), 1, path.to_string()) }; - let (pk_file, pki_file, data_path, start_level) = if !relative_path.is_empty() { - path.push(&relative_path); - 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); + if !Path::is_file(&pk_path) { + fail(stream); + return; + } - let (Ok(pk_file), Ok(pki_file)) = (File::open(pk_path), File::open(pki_path)) else { + if let Some(pki_path) = &pki_path { + if !Path::is_file(pki_path) { fail(stream); return; - }; - - (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, data_path, 0) - }; + } + } use Entry::*; let info = match self.infos.entry(relative_path.clone().into_boxed_str()) { @@ -285,21 +277,18 @@ impl Context { let path_ref = &path; - let handle_entry = |entry: &str, output: &mut TcpStream, level: usize| { + let handle_entry = |mut entry: &str, output: &mut TcpStream, level: usize| { let level = level + 1; let mut path = path_ref.clone(); - let entry = if let Some((entry, _)) = entry.split_once(':') { - entry + if let Some((real_entry, _)) = entry.split_once(':') { + entry = real_entry + } + path.push(if relative_path.is_empty() { + format!("{entry}.pki") } else { - entry - }; - path.push(entry); - let extension = if let Some(extension) = path.extension() { - format!("{extension:?}.pki") - } else { - "pki".to_string() - }; - path.set_extension(extension); + format!("{relative_path}/{entry}.pki") + }); + let Ok(file) = File::open(path) else { return; }; @@ -316,16 +305,20 @@ impl Context { ); }; - convert_extended( - BufReader::new(pk_file) - .lines() - .map(|line| line.unwrap_or_default()), - &mut stream, - Settings::default() - .with_handler(handle_entry) - .with_start_level(start_level) - .with_use_textboxes(true), - ); + if let Ok(pk_file) = File::open(pk_path) { + convert_extended( + BufReader::new(pk_file) + .lines() + .map(|line| line.unwrap_or_default()), + &mut stream, + Settings::default() + .with_handler(handle_entry) + .with_start_level(start_level) + .with_use_textboxes(true), + ); + } else { + unreachable!(); + } let parent_path = relative_path .rsplit_once('/') @@ -335,19 +328,23 @@ impl Context { let _ = writeln!(stream, "
"); let _ = writeln!(stream, "<< Back"); - if let Some(pki_file) = pki_file { - let _ = writeln!(stream, "

Description

"); + if let Some(pki_path) = pki_path { + if let Ok(pki_file) = File::open(pki_path) { + let _ = writeln!(stream, "

Description

"); - convert_subheader( - BufReader::new(pki_file) - .lines() - .map(|line| line.unwrap_or_default()), - &mut stream, - 1, - ); + convert_subheader( + BufReader::new(pki_file) + .lines() + .map(|line| line.unwrap_or_default()), + &mut stream, + 1, + ); - let _ = writeln!(stream, "
"); - let _ = writeln!(stream, "<< Back"); + let _ = writeln!(stream, "
"); + let _ = writeln!(stream, "<< Back"); + } else { + unreachable!(); + } } let html = html! {