mirror of
https://github.com/mikedilger/chorus.git
synced 2026-05-03 06:51:42 +00:00
Blossom: Determine mime type and supply extension in Blob Descriptor URL
This commit is contained in:
parent
a4544702b5
commit
3cacc4e963
36
Cargo.lock
generated
36
Cargo.lock
generated
@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
@ -278,6 +278,8 @@ dependencies = [
|
|||||||
"hyper-util",
|
"hyper-util",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
|
"mime-sniffer",
|
||||||
|
"new_mime_guess",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"pocket-db",
|
"pocket-db",
|
||||||
"pocket-types",
|
"pocket-types",
|
||||||
@ -1094,6 +1096,22 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime-sniffer"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b8b2a64cd735f1d5f17ff6701ced3cc3c54851f9448caf454cd9c923d812408"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -1137,6 +1155,16 @@ dependencies = [
|
|||||||
"memmap2",
|
"memmap2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "new_mime_guess"
|
||||||
|
version = "4.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02a2dfb3559d53e90b709376af1c379462f7fb3085a0177deb73e6ea0d99eff4"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "7.1.3"
|
version = "7.1.3"
|
||||||
@ -1931,6 +1959,12 @@ version = "1.17.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.13"
|
version = "1.0.13"
|
||||||
|
|||||||
@ -21,6 +21,8 @@ hyper-tungstenite = "0.15"
|
|||||||
hyper-util = "0.1"
|
hyper-util = "0.1"
|
||||||
lazy_static = "1.5"
|
lazy_static = "1.5"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
mime-sniffer = "0.1"
|
||||||
|
new_mime_guess = "4.0"
|
||||||
pocket-types = { git = "https://github.com/mikedilger/pocket", branch = "master" }
|
pocket-types = { git = "https://github.com/mikedilger/pocket", branch = "master" }
|
||||||
pocket-db = { git = "https://github.com/mikedilger/pocket", branch = "master" }
|
pocket-db = { git = "https://github.com/mikedilger/pocket", branch = "master" }
|
||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
|
|||||||
@ -48,7 +48,7 @@ impl FileStore {
|
|||||||
&self,
|
&self,
|
||||||
data: BoxBody<Bytes, Error>,
|
data: BoxBody<Bytes, Error>,
|
||||||
expected_hash: Option<HashOutput>,
|
expected_hash: Option<HashOutput>,
|
||||||
) -> Result<(u64, HashOutput), Error> {
|
) -> Result<(u64, HashOutput, Option<String>), Error> {
|
||||||
use bitcoin_hashes::sha256;
|
use bitcoin_hashes::sha256;
|
||||||
use std::io::Write; // for hash_engine.write_all()
|
use std::io::Write; // for hash_engine.write_all()
|
||||||
|
|
||||||
@ -78,6 +78,7 @@ impl FileStore {
|
|||||||
|
|
||||||
// Copy the data into the tempfile (hashing and counting as we go)
|
// Copy the data into the tempfile (hashing and counting as we go)
|
||||||
let count = tokio::io::copy(&mut inspect_reader, &mut tempfile).await?;
|
let count = tokio::io::copy(&mut inspect_reader, &mut tempfile).await?;
|
||||||
|
drop(tempfile);
|
||||||
|
|
||||||
// Verify our code was correct
|
// Verify our code was correct
|
||||||
if count != size {
|
if count != size {
|
||||||
@ -101,6 +102,16 @@ impl FileStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sniff the mime-type
|
||||||
|
let maybe_mime_string = {
|
||||||
|
use mime_sniffer::MimeTypeSniffer;
|
||||||
|
use tokio::io::AsyncReadExt;
|
||||||
|
let mut readtempfile = File::open(&temppathbuf).await?;
|
||||||
|
let mut buffer: Vec<u8> = vec![0; 128];
|
||||||
|
let _ = readtempfile.read(&mut buffer).await?;
|
||||||
|
buffer.sniff_mime_type().map(|s| s.to_string())
|
||||||
|
};
|
||||||
|
|
||||||
// Compute the proper path
|
// Compute the proper path
|
||||||
let pathbuf = hash.to_pathbuf(&self.base);
|
let pathbuf = hash.to_pathbuf(&self.base);
|
||||||
|
|
||||||
@ -109,7 +120,7 @@ impl FileStore {
|
|||||||
// Just clean up
|
// Just clean up
|
||||||
fs::remove_file(&temppathbuf).await?;
|
fs::remove_file(&temppathbuf).await?;
|
||||||
|
|
||||||
return Ok((size, hash));
|
return Ok((size, hash, maybe_mime_string));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the parent directory
|
// Make the parent directory
|
||||||
@ -118,7 +129,7 @@ impl FileStore {
|
|||||||
// Move the file
|
// Move the file
|
||||||
fs::rename(&temppathbuf, &pathbuf).await?;
|
fs::rename(&temppathbuf, &pathbuf).await?;
|
||||||
|
|
||||||
Ok((size, hash))
|
Ok((size, hash, maybe_mime_string))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a file from storage by its HashOutput, streamed to a hyper BoxBoxy
|
/// Retrieve a file from storage by its HashOutput, streamed to a hyper BoxBoxy
|
||||||
|
|||||||
@ -229,7 +229,15 @@ pub async fn handle_upload(
|
|||||||
|
|
||||||
let uri = request.uri().to_owned();
|
let uri = request.uri().to_owned();
|
||||||
|
|
||||||
let (size, hash) = GLOBALS
|
let maybe_content_type = match request.headers().get(http::header::CONTENT_TYPE) {
|
||||||
|
Some(s) => match s.to_str() {
|
||||||
|
Ok(s) => Some(s.to_owned()),
|
||||||
|
Err(_) => None,
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (size, hash, maybe_sniffed_mime_string) = GLOBALS
|
||||||
.filestore
|
.filestore
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -239,11 +247,26 @@ pub async fn handle_upload(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let extension = {
|
||||||
|
let mut mime_string: String = "".to_owned();
|
||||||
|
if let Some(ms) = maybe_content_type {
|
||||||
|
mime_string = ms.to_owned();
|
||||||
|
} else if let Some(ms) = maybe_sniffed_mime_string {
|
||||||
|
mime_string = ms.to_owned();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(exts) = new_mime_guess::get_mime_extensions_str(&mime_string) {
|
||||||
|
exts[0]
|
||||||
|
} else {
|
||||||
|
"blob"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let uri = {
|
let uri = {
|
||||||
let mut parts = GLOBALS.config.read().uri_parts(uri, true)?;
|
let mut parts = GLOBALS.config.read().uri_parts(uri, true)?;
|
||||||
parts.path_and_query = Some(http::uri::PathAndQuery::from_maybe_shared(format!(
|
parts.path_and_query = Some(http::uri::PathAndQuery::from_maybe_shared(format!(
|
||||||
"/{}",
|
"/{}.{}",
|
||||||
hash
|
hash, extension
|
||||||
))?);
|
))?);
|
||||||
http::Uri::from_parts(parts)?
|
http::Uri::from_parts(parts)?
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user