57 lines
1.5 KiB
Rust
57 lines
1.5 KiB
Rust
use crate::*;
|
|
use lmdb::LmdbResultExt;
|
|
use lmdb_zero as lmdb;
|
|
|
|
use rkyv::option::ArchivedOption;
|
|
|
|
use tiny_http::{Header, Request, Response};
|
|
|
|
fn get<'u>(
|
|
request: Request,
|
|
db_context: &DatabaseContext,
|
|
params: matchit::Params<'u, 'u>,
|
|
) -> CrowResult<()> {
|
|
let get_id = some_or_response!(
|
|
parse_base64_hash!(params.get("id")), or respond to request with Response::empty(400)
|
|
);
|
|
|
|
let read = db_context.read_txn()?;
|
|
let access = read.access();
|
|
|
|
let data = some_or_response!(
|
|
access
|
|
.get::<[u8], [u8]>(&db_context.binary_store, &get_id)
|
|
.to_opt()?,
|
|
or respond to request with
|
|
Response::empty(404)
|
|
);
|
|
|
|
let header = access
|
|
.get::<[u8], ArchivedFileHeader>(&db_context.metadata_store, &get_id)
|
|
.to_opt()?
|
|
.ok_or(anyhow::anyhow!("header missing for file"))?;
|
|
|
|
let mut response = Response::new(200.into(), vec![], data, Some(data.len()), None);
|
|
|
|
if let ArchivedOption::Some(ref file_name) = header.file_name {
|
|
response = response.with_header(
|
|
Header::from_bytes(
|
|
&b"Content-Disposition"[..],
|
|
format!("inline; filename=\"{file_name}\"").into_bytes(),
|
|
)
|
|
.unwrap(),
|
|
);
|
|
}
|
|
|
|
if let ArchivedOption::Some(ref mime_type) = header.content_type {
|
|
response = response
|
|
.with_header(Header::from_bytes(&b"Content-Type"[..], mime_type.as_bytes()).unwrap());
|
|
}
|
|
|
|
request.respond(response)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn_to_handler!(get: GetHandler);
|