Simplified path creation, only keep files open as long as necessary

This commit is contained in:
p11 2023-07-21 19:42:08 +02:00
parent a2104976ef
commit b157e2c962

View File

@ -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);
let (Ok(pk_file), Ok(pki_file)) = (File::open(pk_path), File::open(pki_path)) else {
if !Path::is_file(&pk_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 {
if let Some(pki_path) = &pki_path {
if !Path::is_file(pki_path) {
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,6 +305,7 @@ impl Context {
);
};
if let Ok(pk_file) = File::open(pk_path) {
convert_extended(
BufReader::new(pk_file)
.lines()
@ -326,6 +316,9 @@ impl Context {
.with_start_level(start_level)
.with_use_textboxes(true),
);
} else {
unreachable!();
}
let parent_path = relative_path
.rsplit_once('/')
@ -335,7 +328,8 @@ impl Context {
let _ = writeln!(stream, "<hr>");
let _ = writeln!(stream, "<a href=\"/{parent_path}\">&lt;&lt; Back</a>");
if let Some(pki_file) = pki_file {
if let Some(pki_path) = pki_path {
if let Ok(pki_file) = File::open(pki_path) {
let _ = writeln!(stream, "<h1>Description</h1>");
convert_subheader(
@ -348,6 +342,9 @@ impl Context {
let _ = writeln!(stream, "<hr>");
let _ = writeln!(stream, "<a href=\"/{parent_path}\">&lt;&lt; Back</a>");
} else {
unreachable!();
}
}
let html = html! {