melib/jmap: fastmail downloadUrl bug fix WIP

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
jmap-headers
Manos Pitsidianakis 3 months ago
parent b330f232de
commit 8005cdaf8c
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

@ -826,7 +826,7 @@ pub fn download_request_format(
download_url: &RequestUrlTemplate,
account_id: &Id<Account>,
blob_id: &Id<BlobObject>,
name: Option<String>,
name: Option<&str>,
) -> Result<Url> {
let mut ret = String::with_capacity(
download_url.text.len()
@ -846,11 +846,18 @@ pub fn download_request_format(
ret.push_str(blob_id.as_str());
prev_pos += "{blobId}".len();
} else if download_url.text[prev_pos..].starts_with("{name}") {
ret.push_str(name.as_deref().unwrap_or(""));
if let Some(name) = name.as_deref() {
ret.push_str(name);
//} else if ret.ends_with('/') {
// ret.pop();
//}
} else {
ret.push_str("{name}");
}
prev_pos += "{name}".len();
} else if download_url.text[prev_pos..].starts_with("{type}") {
ret.push_str("application/octet-stream");
prev_pos += "{name}".len();
prev_pos += "{type}".len();
} else {
log::error!(
"BUG: unknown parameter in download_url: {}",

@ -279,6 +279,7 @@ pub struct Store {
pub id_store: Arc<FutureMutex<HashMap<EnvelopeHash, Id<email::EmailObject>>>>,
pub reverse_id_store: Arc<FutureMutex<HashMap<Id<email::EmailObject>, EnvelopeHash>>>,
pub blob_id_store: Arc<FutureMutex<HashMap<EnvelopeHash, Id<BlobObject>>>>,
pub name_store: Arc<FutureMutex<HashMap<EnvelopeHash, Box<str>>>>,
pub collection: Collection,
pub mailboxes: Arc<RwLock<HashMap<MailboxHash, JmapMailbox>>>,
pub mailboxes_index: Arc<RwLock<HashMap<MailboxHash, HashSet<EnvelopeHash>>>>,
@ -293,9 +294,38 @@ impl Store {
pub async fn add_envelope(&self, obj: email::EmailObject) -> Envelope {
let mut flags = Flag::default();
let mut labels: IndexSet<TagHash> = IndexSet::new();
let id;
let mailbox_ids;
let blob_id;
let id = obj.id.clone();
let mailbox_ids = obj.mailbox_ids.clone();
let blob_id = obj.blob_id.clone();
// Source: https://datatracker.ietf.org/doc/html/rfc8621#section-4.1.4
// name: "String|null"
// This is the decoded "filename" parameter of the Content-
// Disposition header field per [RFC2231], or (for compatibility with
// existing systems) if not present, then it's the decoded "name"
// parameter of the Content-Type header field per [RFC2047].
let name_fallback = |obj: &email::EmailObject| -> Box<str> {
if let Some(val) = obj.headers.get(HeaderName::CONTENT_TYPE) {
val.to_string().into()
} else {
"text/plain".to_string().into()
}
};
let name = if let Some(val) = obj.headers.get(HeaderName::CONTENT_DISPOSITION) {
use crate::email::attachment_types::ContentDisposition;
let mut cp = ContentDisposition::from(val);
if cp.kind.is_attachment() {
if let Some(fname) = cp.filename.take() {
fname.into()
} else {
name_fallback(&obj)
}
} else {
name_fallback(&obj)
}
} else {
name_fallback(&obj)
};
{
let mut tag_lck = self.collection.tag_index.write().unwrap();
for t in obj.keywords().keys() {
@ -320,11 +350,8 @@ impl Store {
}
}
}
id = obj.id.clone();
mailbox_ids = obj.mailbox_ids.clone();
blob_id = obj.blob_id.clone();
}
let mut ret: Envelope = obj.into();
ret.set_flags(flags);
ret.tags_mut().extend(labels);
@ -332,6 +359,7 @@ impl Store {
let mut id_store_lck = self.id_store.lock().await;
let mut reverse_id_store_lck = self.reverse_id_store.lock().await;
let mut blob_id_store_lck = self.blob_id_store.lock().await;
let mut name_store_lck = self.name_store.lock().await;
let mailboxes_lck = self.mailboxes.read().unwrap();
let mut mailboxes_index_lck = self.mailboxes_index.write().unwrap();
for (mailbox_id, _) in mailbox_ids {
@ -346,6 +374,7 @@ impl Store {
reverse_id_store_lck.insert(id.clone(), ret.hash());
id_store_lck.insert(ret.hash(), id);
blob_id_store_lck.insert(ret.hash(), blob_id);
name_store_lck.insert(ret.hash(), name);
ret
}
@ -1217,6 +1246,7 @@ impl JmapType {
id_store: Default::default(),
reverse_id_store: Default::default(),
blob_id_store: Default::default(),
name_store: Default::default(),
mailboxes: Default::default(),
mailboxes_index: Default::default(),
mailbox_state: Default::default(),

@ -64,6 +64,7 @@ impl BackendOp for JmapOp {
}
}
let blob_id = store.blob_id_store.lock().await[&hash].clone();
let name = store.name_store.lock().await[&hash].clone();
let mut conn = connection.lock().await;
conn.connect().await?;
let (download_url, mail_account_id) = {

Loading…
Cancel
Save