dump meta on file commit

This commit is contained in:
yggverse 2025-02-22 09:13:00 +02:00
parent 7bf68725db
commit a1ccc27cb8
2 changed files with 56 additions and 7 deletions

View file

@ -97,7 +97,7 @@ fn gemini(
match storage::Item::from_url(gemini.url.as_str(), &argument.directory) {
Ok(item) => send(
&response::success::Default {
mime: "text/gemini".to_string(),
mime: item.mime,
//data: item.file.read(vec![1000]),
}
.into_bytes(),
@ -128,8 +128,29 @@ fn titan(
stream: &mut TlsStream<TcpStream>,
) {
use titanite::*;
// require content type for application,
// even MIME value is optional by Titan specification
let mime = match titan.mime {
Some(mime) => mime,
None => {
const MESSAGE: &str = "Content type is required";
return send(
&response::failure::permanent::BadRequest {
message: Some(MESSAGE.to_string()),
}
.into_bytes(),
stream,
|result| match result {
Ok(()) => println!("[{}] [warning] [{peer}] {MESSAGE}", now()),
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
},
);
}
};
// validate total bytes
let mut total = 0;
match storage::Item::create(&argument.directory) {
// create new destination file
match storage::Item::create(&argument.directory, mime) {
Ok(mut tmp) => loop {
let mut input = vec![0; argument.chunk];
match stream.read(&mut input) {
@ -205,10 +226,13 @@ fn titan(
);
}
// just to make sure
if titan.size > total {
panic!()
}
// all data received
if titan.size >= total {
// @TODO detect/validate/cache mime based on data received
// success
if titan.size == total {
return match tmp.commit() {
Ok(pmt) => send(
&response::redirect::Permanent {

View file

@ -1,6 +1,7 @@
use anyhow::{anyhow, bail, Error, Result};
use std::{
fs::{create_dir_all, remove_file, rename, File},
io::{Read, Write},
path::{PathBuf, MAIN_SEPARATOR},
str::FromStr,
thread,
@ -8,10 +9,12 @@ use std::{
};
const TMP_SUFFIX: &str = ".tmp";
const META_SUFFIX: &str = ".meta";
pub struct Item {
pub file: File,
pub path: PathBuf,
pub mime: String,
// pub id: u64,
}
@ -42,12 +45,13 @@ impl Item {
))?;
Ok(Self {
file: File::open(&path)?,
mime: read_meta(path.to_str().unwrap())?,
path,
})
}
/// Create new `Self` with unique pathname in the root `directory`
pub fn create(directory: &str) -> Result<Self> {
pub fn create(directory: &str, mime: String) -> Result<Self> {
loop {
// generate file id from current unix time
let id = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
@ -77,6 +81,7 @@ impl Item {
return Ok(Self {
file,
path,
mime,
// id
});
}
@ -102,7 +107,10 @@ impl Item {
Ok(path) => path,
Err(e) => return Err((self, anyhow!(e))),
};
Ok(self)
match self.write_meta() {
Ok(()) => Ok(self),
Err(e) => Err((self, anyhow!(e))),
}
}
Err(e) => Err((self, anyhow!(e))),
},
@ -127,4 +135,21 @@ impl Item {
.replace(directory, "")
.replace("/", "")
}
// System
fn write_meta(&self) -> Result<()> {
Ok(File::create_new(meta_path(self.path.to_str().unwrap()))?
.write_all(self.mime.as_bytes())?)
}
}
fn meta_path(path: &str) -> String {
format!("{}{META_SUFFIX}", path)
}
fn read_meta(path: &str) -> Result<String> {
let mut buffer = String::new();
File::open(meta_path(path))?.read_to_string(&mut buffer)?;
Ok(buffer)
}