Pass mimetype to frontend

This commit is contained in:
Edward Shen 2022-01-11 22:19:15 -08:00
parent f1c40d64c7
commit 247a5ad6f6
Signed by: edward
GPG key ID: 19182661E818369F
3 changed files with 34 additions and 22 deletions

View file

@ -49,11 +49,13 @@ fn now() -> f64 {
.now() .now()
} }
pub struct MimeType(pub String);
pub fn decrypt( pub fn decrypt(
mut container: Vec<u8>, mut container: Vec<u8>,
key: &Secret<Key>, key: &Secret<Key>,
maybe_password: Option<SecretVec<u8>>, maybe_password: Option<SecretVec<u8>>,
) -> Result<DecryptedData, Error> { ) -> Result<(DecryptedData, MimeType), Error> {
open_in_place(&mut container, key, maybe_password)?; open_in_place(&mut container, key, maybe_password)?;
let mime_type = tree_magic_mini::from_u8(&container); let mime_type = tree_magic_mini::from_u8(&container);
@ -76,14 +78,14 @@ pub fn decrypt(
log!(format!("Blob conversion completed in {}ms", now() - start)); log!(format!("Blob conversion completed in {}ms", now() - start));
match container.content_type() { let data = match container.content_type() {
ContentType::Text => Ok(DecryptedData::String(Arc::new( ContentType::Text => DecryptedData::String(Arc::new(
// SAFETY: ContentType::Text is guaranteed to be valid UTF-8. // SAFETY: ContentType::Text is guaranteed to be valid UTF-8.
unsafe { String::from_utf8_unchecked(container) }, unsafe { String::from_utf8_unchecked(container) },
))), )),
ContentType::Image => Ok(DecryptedData::Image(blob, container.len())), ContentType::Image => DecryptedData::Image(blob, container.len()),
ContentType::Audio => Ok(DecryptedData::Audio(blob)), ContentType::Audio => DecryptedData::Audio(blob),
ContentType::Video => Ok(DecryptedData::Video(blob)), ContentType::Video => DecryptedData::Video(blob),
ContentType::ZipArchive => { ContentType::ZipArchive => {
let mut entries = vec![]; let mut entries = vec![];
let cursor = Cursor::new(container); let cursor = Cursor::new(container);
@ -107,11 +109,13 @@ pub fn decrypt(
} }
entries.sort_by(|a, b| a.name.cmp(&b.name)); entries.sort_by(|a, b| a.name.cmp(&b.name));
Ok(DecryptedData::Archive(blob, entries)) DecryptedData::Archive(blob, entries)
}
ContentType::GzipArchive => Ok(DecryptedData::Archive(blob, vec![])),
ContentType::Unknown => Ok(DecryptedData::Blob(blob)),
} }
ContentType::GzipArchive => DecryptedData::Archive(blob, vec![]),
ContentType::Unknown => DecryptedData::Blob(blob),
};
Ok((data, MimeType(mime_type.to_owned())))
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]

View file

@ -20,7 +20,7 @@ use std::str::FromStr;
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use byte_unit::{n_mib_bytes, Byte}; use byte_unit::{n_mib_bytes, Byte};
use decrypt::DecryptedData; use decrypt::{DecryptedData, MimeType};
use gloo_console::{error, log}; use gloo_console::{error, log};
use http::uri::PathAndQuery; use http::uri::PathAndQuery;
use http::{StatusCode, Uri}; use http::{StatusCode, Uri};
@ -47,7 +47,7 @@ const DOWNLOAD_SIZE_LIMIT: u128 = n_mib_bytes!(500);
#[wasm_bindgen] #[wasm_bindgen]
extern "C" { extern "C" {
#[wasm_bindgen(js_name = loadFromDb)] #[wasm_bindgen(js_name = loadFromDb)]
pub fn load_from_db(); pub fn load_from_db(mimetype: JsString);
#[wasm_bindgen(js_name = renderMessage)] #[wasm_bindgen(js_name = renderMessage)]
pub fn render_message(message: JsString); pub fn render_message(message: JsString);
} }
@ -175,7 +175,7 @@ async fn fetch_resources(
return Ok(()); return Ok(());
} }
let decrypted = match decrypt(data, &key, password) { let (decrypted, mimetype) = match decrypt(data, &key, password) {
Ok(data) => data, Ok(data) => data,
Err(e) => { Err(e) => {
let msg = match e { let msg = match e {
@ -194,7 +194,7 @@ async fn fetch_resources(
let db_open_req = open_idb()?; let db_open_req = open_idb()?;
let on_success = Closure::once(Box::new(move |event| { let on_success = Closure::once(Box::new(move |event| {
on_success(&event, &decrypted, &expires); on_success(&event, &decrypted, mimetype, &expires);
})); }));
db_open_req.set_onsuccess(Some(on_success.into_js_value().unchecked_ref())); db_open_req.set_onsuccess(Some(on_success.into_js_value().unchecked_ref()));
@ -226,7 +226,7 @@ async fn fetch_resources(
Ok(()) Ok(())
} }
fn on_success(event: &Event, decrypted: &DecryptedData, expires: &str) { fn on_success(event: &Event, decrypted: &DecryptedData, mimetype: MimeType, expires: &str) {
let transaction: IdbObjectStore = as_idb_db(event) let transaction: IdbObjectStore = as_idb_db(event)
.transaction_with_str_and_mode("decrypted data", IdbTransactionMode::Readwrite) .transaction_with_str_and_mode("decrypted data", IdbTransactionMode::Readwrite)
.unwrap() .unwrap()
@ -275,7 +275,7 @@ fn on_success(event: &Event, decrypted: &DecryptedData, expires: &str) {
put_action.set_onsuccess(Some( put_action.set_onsuccess(Some(
Closure::once(Box::new(|| { Closure::once(Box::new(|| {
log!("success"); log!("success");
load_from_db(); load_from_db(JsString::from(mimetype.0));
})) }))
.into_js_value() .into_js_value()
.unchecked_ref(), .unchecked_ref(),

View file

@ -15,7 +15,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// Exported to main.rs // Exported to main.rs
function loadFromDb() { function loadFromDb(mimetype: string) {
console.log("Got mime type:", mimetype);
const dbReq = window.indexedDB.open("omegaupload", 1); const dbReq = window.indexedDB.open("omegaupload", 1);
dbReq.onsuccess = (evt) => { dbReq.onsuccess = (evt) => {
const db = (evt.target as IDBRequest).result; const db = (evt.target as IDBRequest).result;
@ -27,7 +28,7 @@ function loadFromDb() {
const data = (evt.target as IDBRequest).result; const data = (evt.target as IDBRequest).result;
switch (data.type) { switch (data.type) {
case "string": case "string":
createStringPasteUi(data); createStringPasteUi(data, mimetype);
break; break;
case "blob": case "blob":
createBlobPasteUi(data); createBlobPasteUi(data);
@ -70,7 +71,7 @@ function loadFromDb() {
}; };
} }
function createStringPasteUi(data) { function createStringPasteUi(data, type: string) {
let bodyEle = document.getElementsByTagName("body")[0]; let bodyEle = document.getElementsByTagName("body")[0];
bodyEle.textContent = ''; bodyEle.textContent = '';
@ -84,6 +85,14 @@ function createStringPasteUi(data) {
headerEle.textContent = data.expiration; headerEle.textContent = data.expiration;
preEle.appendChild(headerEle); preEle.appendChild(headerEle);
let downloadEle = document.createElement("a");
downloadEle.href = URL.createObjectURL(new Blob([data.data], { type }));
downloadEle.download = window.location.pathname;
downloadEle.classList.add("hljs-meta");
downloadEle.classList.add("centered");
downloadEle.textContent = "Download file.";
preEle.appendChild(downloadEle);
preEle.appendChild(document.createElement("hr")); preEle.appendChild(document.createElement("hr"));
let codeEle = document.createElement("code"); let codeEle = document.createElement("code");
@ -120,7 +129,6 @@ function createBlobPasteUi(data) {
downloadEle.textContent = "Download binary file."; downloadEle.textContent = "Download binary file.";
divEle.appendChild(downloadEle); divEle.appendChild(downloadEle);
mainEle.appendChild(divEle); mainEle.appendChild(divEle);
let displayAnywayEle = document.createElement("p"); let displayAnywayEle = document.createElement("p");
@ -130,7 +138,7 @@ function createBlobPasteUi(data) {
displayAnywayEle.onclick = () => { displayAnywayEle.onclick = () => {
data.data.text().then(text => { data.data.text().then(text => {
data.data = text; data.data = text;
createStringPasteUi(data); createStringPasteUi(data, "application/octet-stream");
}) })
}; };
mainEle.appendChild(displayAnywayEle); mainEle.appendChild(displayAnywayEle);