crow/src/routes/upload.rs
2022-07-01 19:27:28 -03:00

69 lines
1.6 KiB
Rust

use crate::*;
use blake2::{Blake2s256, Digest};
use lmdb::LmdbResultExt;
use lmdb_zero as lmdb;
use multipart::server::Multipart;
use std::io::Read;
use tiny_http::{Request, Response};
fn upload<'u>(
mut request: Request,
db_context: &DatabaseContext,
_: matchit::Params<'u, 'u>,
) -> CrowResult<()> {
let mut entry = some_or_response!(
single_multipart!(&mut request), or respond to request with Response::empty(400)
);
let mut data: Vec<u8> = Vec::with_capacity(20000);
entry.data.read_to_end(&mut data)?;
let data_hash = Blake2s256::digest(&data);
let txn = db_context.write_txn()?;
let mut accessor = txn.access();
if accessor
.get::<[u8], [u8]>(&db_context.binary_store, data_hash.as_slice())
.to_opt()?
.is_some()
{
request.respond(Response::from_string(base64_url::encode(&data_hash)))?;
return Ok(());
}
accessor.put(
&db_context.binary_store,
data_hash.as_slice(),
&data,
lmdb::put::Flags::empty(),
)?;
let header = FileHeader {
file_name: entry.headers.filename,
content_type: entry
.headers
.content_type
.map(|v| v.essence_str().to_owned()),
};
accessor.put(
&db_context.metadata_store,
data_hash.as_slice(),
rkyv::to_bytes::<_, 256>(&header).unwrap().as_slice(),
lmdb::put::Flags::empty(),
)?;
request.respond(Response::from_string(base64_url::encode(&data_hash)))?;
drop(accessor);
txn.commit()?;
Ok(())
}
fn_to_handler!(upload: UploadHandler);