Save site infos to their own files, never save the complete context
This commit is contained in:
parent
8a1f94bb66
commit
6dc1675ac3
82
src/main.rs
82
src/main.rs
@ -18,12 +18,7 @@ mod request;
|
|||||||
use request::Request;
|
use request::Request;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut context = File::open("context.dat")
|
let mut context = Context::default();
|
||||||
.map(|mut file| {
|
|
||||||
from_stream::<PortableSettings, Context, _>(&mut file)
|
|
||||||
.unwrap_or_else(|_| panic!("Context file corrupted. Delete or repair it!"))
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
|
||||||
let mut args = env::args();
|
let mut args = env::args();
|
||||||
args.next();
|
args.next();
|
||||||
let address = args.next().unwrap_or("127.0.0.1:8080".to_string());
|
let address = args.next().unwrap_or("127.0.0.1:8080".to_string());
|
||||||
@ -118,39 +113,6 @@ struct Context {
|
|||||||
infos: HashMap<Box<str>, SiteInfo>,
|
infos: HashMap<Box<str>, SiteInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: SizeSettings> ToStream<S> for Context {
|
|
||||||
fn to_stream<W: Write>(&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::<S, _, _>(info, stream)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: SizeSettings> FromStream<S> for Context {
|
|
||||||
fn from_stream<R: Read>(stream: &mut R) -> Result<Self> {
|
|
||||||
let size = S::size_from_stream(stream)?;
|
|
||||||
let infos = (0..size)
|
|
||||||
.map(|_| {
|
|
||||||
let key_bytes = <Vec<_> as FromStream<S>>::from_stream(stream)?;
|
|
||||||
let key = std::str::from_utf8(&key_bytes)
|
|
||||||
.map_err(|e| Error::new(ErrorKind::InvalidData, e))?
|
|
||||||
.into();
|
|
||||||
|
|
||||||
Ok((key, from_stream::<S, SiteInfo, _>(stream)?))
|
|
||||||
})
|
|
||||||
.collect::<Result<HashMap<_, _>>>()?;
|
|
||||||
|
|
||||||
Ok(Self { infos })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
fn handle_connection(&mut self, mut stream: TcpStream) {
|
fn handle_connection(&mut self, mut stream: TcpStream) {
|
||||||
let Some(request) = Request::from(&stream) else {
|
let Some(request) = Request::from(&stream) else {
|
||||||
@ -200,38 +162,52 @@ impl Context {
|
|||||||
path.to_string()
|
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);
|
path.push(&relative_path);
|
||||||
let (pk_extension, pki_extension) = if let Some(extension) = path.extension() {
|
let (pk_extension, pki_extension, data_extension) =
|
||||||
(format!("{extension:?}.pk"), format!("{extension:?}.pki"))
|
if let Some(extension) = path.extension() {
|
||||||
|
(
|
||||||
|
format!("{extension:?}.pk"),
|
||||||
|
format!("{extension:?}.pki"),
|
||||||
|
format!("{extension:?}.dat"),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
("pk".to_string(), "pki".to_string())
|
("pk".to_string(), "pki".to_string(), "dat".to_string())
|
||||||
};
|
};
|
||||||
let pk_path = path.with_extension(pk_extension);
|
let pk_path = path.with_extension(pk_extension);
|
||||||
let pki_path = path.with_extension(pki_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 {
|
let (Ok(pk_file), Ok(pki_file)) = (File::open(pk_path), File::open(pki_path)) else {
|
||||||
fail(stream);
|
fail(stream);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
(pk_file, Some(pki_file), 1)
|
(pk_file, Some(pki_file), data_path, 1)
|
||||||
} else {
|
} else {
|
||||||
let mut pk_path = path.clone();
|
let mut pk_path = path.clone();
|
||||||
pk_path.push("index.pk");
|
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 {
|
let Ok(pk_file) = File::open(pk_path) else {
|
||||||
fail(stream);
|
fail(stream);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
(pk_file, None, 0)
|
(pk_file, None, data_path, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
use Entry::*;
|
use Entry::*;
|
||||||
let info = match self.infos.entry(relative_path.clone().into_boxed_str()) {
|
let info = match self.infos.entry(relative_path.clone().into_boxed_str()) {
|
||||||
Occupied(o) => o.into_mut(),
|
Occupied(o) => o.into_mut(),
|
||||||
Vacant(v) => v.insert(SiteInfo::default()),
|
Vacant(v) => v.insert(
|
||||||
|
File::open(&data_path)
|
||||||
|
.map(|mut file| {
|
||||||
|
from_stream::<PortableSettings, _, _>(&mut file).unwrap_or_default()
|
||||||
|
})
|
||||||
|
.unwrap_or_default(),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut name = None;
|
let mut name = None;
|
||||||
@ -282,6 +258,13 @@ impl Context {
|
|||||||
|
|
||||||
info.visits += 1;
|
info.visits += 1;
|
||||||
|
|
||||||
|
if let Ok(mut file) = File::create(data_path) {
|
||||||
|
if to_stream::<PortableSettings, _, _>(info, &mut file).is_err() {
|
||||||
|
eprintln!("Error saving data!");
|
||||||
|
eprintln!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let _ = write!(stream, "HTTP/1.1 200 OK\r\n\r\n");
|
let _ = write!(stream, "HTTP/1.1 200 OK\r\n\r\n");
|
||||||
|
|
||||||
let _ = writeln!(stream, "<meta charset=\"utf-8\">");
|
let _ = writeln!(stream, "<meta charset=\"utf-8\">");
|
||||||
@ -389,12 +372,5 @@ impl Context {
|
|||||||
|
|
||||||
let _ = writeln!(stream, "<hr>");
|
let _ = writeln!(stream, "<hr>");
|
||||||
let _ = writeln!(stream, "<a href=\"/{parent_path}\"><< Back</a>");
|
let _ = writeln!(stream, "<a href=\"/{parent_path}\"><< Back</a>");
|
||||||
|
|
||||||
if let Ok(mut file) = File::create("context.dat") {
|
|
||||||
if to_stream::<PortableSettings, _, _>(self, &mut file).is_err() {
|
|
||||||
eprintln!("Error saving data!");
|
|
||||||
eprintln!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user