add metadata
This commit is contained in:
parent
e4e4a3dc7f
commit
462134b36d
143
Cargo.lock
generated
143
Cargo.lock
generated
|
@ -2,6 +2,17 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.58"
|
version = "1.0.58"
|
||||||
|
@ -69,6 +80,27 @@ dependencies = [
|
||||||
"safemem",
|
"safemem",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytecheck"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a31f923c2db9513e4298b72df143e6e655a759b3d6a0966df18f81223fff54f"
|
||||||
|
dependencies = [
|
||||||
|
"bytecheck_derive",
|
||||||
|
"ptr_meta",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytecheck_derive"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "edb17c862a905d912174daa27ae002326fff56dc8b8ada50a0a5f0976cb174f0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -90,6 +122,7 @@ dependencies = [
|
||||||
"blake2",
|
"blake2",
|
||||||
"lmdb-zero",
|
"lmdb-zero",
|
||||||
"multipart",
|
"multipart",
|
||||||
|
"rkyv",
|
||||||
"tiny_http",
|
"tiny_http",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
@ -161,6 +194,15 @@ dependencies = [
|
||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "httparse"
|
||||||
version = "1.7.1"
|
version = "1.7.1"
|
||||||
|
@ -285,6 +327,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
@ -297,12 +345,50 @@ version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ptr_meta"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1"
|
||||||
|
dependencies = [
|
||||||
|
"ptr_meta_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ptr_meta_derive"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-error"
|
name = "quick-error"
|
||||||
version = "1.2.3"
|
version = "1.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
|
@ -351,12 +437,52 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rend"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95"
|
||||||
|
dependencies = [
|
||||||
|
"bytecheck",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rkyv"
|
||||||
|
version = "0.7.39"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15"
|
||||||
|
dependencies = [
|
||||||
|
"bytecheck",
|
||||||
|
"hashbrown",
|
||||||
|
"ptr_meta",
|
||||||
|
"rend",
|
||||||
|
"rkyv_derive",
|
||||||
|
"seahash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rkyv_derive"
|
||||||
|
version = "0.7.39"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "safemem"
|
name = "safemem"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "seahash"
|
||||||
|
version = "4.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.4.1"
|
version = "2.4.1"
|
||||||
|
@ -369,6 +495,17 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "171758edb47aa306a78dfa4ab9aeb5167405bd4e3dc2b64e88f6a84bbe98bd63"
|
checksum = "171758edb47aa306a78dfa4ab9aeb5167405bd4e3dc2b64e88f6a84bbe98bd63"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.98"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.3.0"
|
version = "3.3.0"
|
||||||
|
@ -459,6 +596,12 @@ version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
version = "0.1.20"
|
version = "0.1.20"
|
||||||
|
|
|
@ -11,5 +11,6 @@ base64-url = "1.4.13"
|
||||||
blake2 = "0.10.4"
|
blake2 = "0.10.4"
|
||||||
lmdb-zero = "0.4.4"
|
lmdb-zero = "0.4.4"
|
||||||
multipart = { git = "https://github.com/emily-signet/multipart", default-features = false, features = ["server", "tiny_http"] }
|
multipart = { git = "https://github.com/emily-signet/multipart", default-features = false, features = ["server", "tiny_http"] }
|
||||||
|
rkyv = { version = "0.7.39", features = ["strict", "archive_le"] }
|
||||||
tiny_http = "0.11.0"
|
tiny_http = "0.11.0"
|
||||||
url = "2.2.2"
|
url = "2.2.2"
|
||||||
|
|
71
src/main.rs
71
src/main.rs
|
@ -5,16 +5,20 @@ use blake2::{Blake2s256, Digest};
|
||||||
use lmdb::{Database, Environment, LmdbResultExt};
|
use lmdb::{Database, Environment, LmdbResultExt};
|
||||||
use lmdb_zero as lmdb;
|
use lmdb_zero as lmdb;
|
||||||
use multipart::server::Multipart;
|
use multipart::server::Multipart;
|
||||||
use std::{
|
use rkyv::option::ArchivedOption;
|
||||||
io::{self, Read},
|
use std::{io::Read, sync::Arc, thread};
|
||||||
sync::Arc,
|
use tiny_http::{Header, Request, Response};
|
||||||
thread,
|
|
||||||
};
|
#[derive(rkyv::Archive, rkyv::Serialize)]
|
||||||
use tiny_http::{Request, Response};
|
pub struct FileHeader {
|
||||||
|
file_name: Option<String>,
|
||||||
|
content_type: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DatabaseContext {
|
pub struct DatabaseContext {
|
||||||
env: Arc<Environment>,
|
env: Arc<Environment>,
|
||||||
|
metadata_store: Arc<Database<'static>>,
|
||||||
binary_store: Arc<Database<'static>>,
|
binary_store: Arc<Database<'static>>,
|
||||||
image_store: Arc<Database<'static>>,
|
image_store: Arc<Database<'static>>,
|
||||||
}
|
}
|
||||||
|
@ -23,7 +27,7 @@ impl DatabaseContext {
|
||||||
pub fn create(path: &str) -> anyhow::Result<DatabaseContext> {
|
pub fn create(path: &str) -> anyhow::Result<DatabaseContext> {
|
||||||
let env = Arc::new(unsafe {
|
let env = Arc::new(unsafe {
|
||||||
let mut builder = lmdb::EnvBuilder::new()?;
|
let mut builder = lmdb::EnvBuilder::new()?;
|
||||||
builder.set_maxdbs(2)?;
|
builder.set_maxdbs(3)?;
|
||||||
builder.open(path, lmdb::open::NOTLS, 0o600)?
|
builder.open(path, lmdb::open::NOTLS, 0o600)?
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,10 +41,16 @@ impl DatabaseContext {
|
||||||
Some("image"),
|
Some("image"),
|
||||||
&lmdb::DatabaseOptions::new(lmdb::db::CREATE),
|
&lmdb::DatabaseOptions::new(lmdb::db::CREATE),
|
||||||
)?);
|
)?);
|
||||||
|
let metadata_store = Arc::new(lmdb::Database::open(
|
||||||
|
env.clone(),
|
||||||
|
Some("metadata"),
|
||||||
|
&lmdb::DatabaseOptions::new(lmdb::db::CREATE),
|
||||||
|
)?);
|
||||||
|
|
||||||
Ok(DatabaseContext {
|
Ok(DatabaseContext {
|
||||||
env,
|
env,
|
||||||
binary_store,
|
binary_store,
|
||||||
|
metadata_store,
|
||||||
image_store,
|
image_store,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -123,6 +133,21 @@ fn process_upload(mut request: Request, db_context: &DatabaseContext) -> anyhow:
|
||||||
lmdb::put::Flags::empty(),
|
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)?.as_slice(),
|
||||||
|
lmdb::put::Flags::empty(),
|
||||||
|
)?;
|
||||||
|
|
||||||
request.respond(Response::from_string(base64_url::encode(&data_hash)))?;
|
request.respond(Response::from_string(base64_url::encode(&data_hash)))?;
|
||||||
|
|
||||||
drop(accessor);
|
drop(accessor);
|
||||||
|
@ -147,13 +172,31 @@ fn process_get(request: Request, db_context: &DatabaseContext) -> anyhow::Result
|
||||||
.to_opt()
|
.to_opt()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
request.respond(Response::new(
|
let header_bytes = access
|
||||||
200.into(),
|
.get::<[u8], [u8]>(&db_context.metadata_store, &get_id)
|
||||||
vec![],
|
.to_opt()?
|
||||||
data,
|
.ok_or(anyhow::anyhow!("header missing for file"))?;
|
||||||
Some(data.len()),
|
let header = unsafe { rkyv::archived_root::<FileHeader>(header_bytes) };
|
||||||
None,
|
|
||||||
))?;
|
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)?;
|
||||||
} else {
|
} else {
|
||||||
request.respond(Response::empty(404))?;
|
request.respond(Response::empty(404))?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue