feat: Drop support for replacing partial download stubs

This commit is contained in:
iequidoo
2026-04-26 11:05:15 -03:00
committed by iequidoo
parent aa1f129a48
commit 82bb77b056
2 changed files with 19 additions and 116 deletions

View File

@@ -524,53 +524,15 @@ pub(crate) async fn receive_imf_inner(
"Receiving message {rfc724_mid_orig:?}, seen={seen}...", "Receiving message {rfc724_mid_orig:?}, seen={seen}...",
); );
// check, if the mail is already in our database. // These checks must be done before processing of SecureJoin and other special messages.
// make sure, this check is done eg. before securejoin-processing.
let (replace_msg_id, replace_chat_id);
if mime_parser.pre_message == mimeparser::PreMessageMode::Post { if mime_parser.pre_message == mimeparser::PreMessageMode::Post {
// Post-Message just replaces the attachment and modifies Params, not the whole message. // Post-Message just replaces the attachment and modifies Params, not the whole message.
// This is done in the `handle_post_message` method. // This is done in the `handle_post_message` method.
replace_msg_id = None; } else if let Some(msg_id) = message::rfc724_mid_exists(context, rfc724_mid_orig).await? {
replace_chat_id = None; info!(
} else if let Some(old_msg_id) = message::rfc724_mid_exists(context, rfc724_mid).await? { context,
replace_msg_id = Some(old_msg_id); "Message {rfc724_mid} is already in some chat or deleted."
replace_chat_id = if let Some(msg) = Message::load_from_db_optional(context, old_msg_id) );
.await?
.filter(|msg| msg.download_state() != DownloadState::Done)
{
// This code handles the download of old partial download stub messages
// It will be removed after a transitioning period,
// after we have released a few versions with pre-messages
match mime_parser.pre_message {
PreMessageMode::Post | PreMessageMode::None => {
info!(context, "Message already partly in DB, replacing.");
Some(msg.chat_id)
}
PreMessageMode::Pre { .. } => {
info!(context, "Cannot replace pre-message with a pre-message");
None
}
}
} else {
info!(
context,
"Message {rfc724_mid} is fully downloaded or deleted."
);
None
};
} else {
replace_msg_id = if rfc724_mid_orig == rfc724_mid {
None
} else {
message::rfc724_mid_exists(context, rfc724_mid_orig).await?
};
replace_chat_id = None;
}
if replace_chat_id.is_some() {
// Need to update chat id in the db.
} else if let Some(msg_id) = replace_msg_id {
info!(context, "Message is already downloaded.");
if mime_parser.incoming { if mime_parser.incoming {
return Ok(None); return Ok(None);
} }
@@ -589,7 +551,7 @@ pub(crate) async fn receive_imf_inner(
msg_id.set_delivered(context).await?; msg_id.set_delivered(context).await?;
} }
return Ok(None); return Ok(None);
}; }
let prevent_rename = should_prevent_rename(&mime_parser); let prevent_rename = should_prevent_rename(&mime_parser);
@@ -639,8 +601,7 @@ pub(crate) async fn receive_imf_inner(
mime_parser.get_header(HeaderDef::References), mime_parser.get_header(HeaderDef::References),
mime_parser.get_header(HeaderDef::InReplyTo), mime_parser.get_header(HeaderDef::InReplyTo),
) )
.await? .await?;
.filter(|p| Some(p.id) != replace_msg_id);
let mut chat_assignment = let mut chat_assignment =
decide_chat_assignment(context, &mime_parser, &parent_message, rfc724_mid, from_id).await?; decide_chat_assignment(context, &mime_parser, &parent_message, rfc724_mid, from_id).await?;
@@ -756,7 +717,6 @@ pub(crate) async fn receive_imf_inner(
rfc724_mid_orig, rfc724_mid_orig,
from_id, from_id,
seen, seen,
replace_msg_id,
prevent_rename, prevent_rename,
chat_id, chat_id,
chat_id_blocked, chat_id_blocked,
@@ -1051,11 +1011,6 @@ UPDATE msgs SET state=? WHERE
.await?; .await?;
} else if received_msg.hidden { } else if received_msg.hidden {
// No need to emit an event about the changed message // No need to emit an event about the changed message
} else if let Some(replace_chat_id) = replace_chat_id {
match replace_chat_id == chat_id {
false => context.emit_msgs_changed_without_msg_id(replace_chat_id),
true => context.emit_msgs_changed(chat_id, replace_msg_id.unwrap_or_default()),
}
} else if !chat_id.is_trash() { } else if !chat_id.is_trash() {
let fresh = received_msg.state == MessageState::InFresh let fresh = received_msg.state == MessageState::InFresh
&& mime_parser.is_system_message != SystemMessage::CallAccepted && mime_parser.is_system_message != SystemMessage::CallAccepted
@@ -1782,7 +1737,6 @@ async fn add_parts(
rfc724_mid: &str, rfc724_mid: &str,
from_id: ContactId, from_id: ContactId,
seen: bool, seen: bool,
mut replace_msg_id: Option<MsgId>,
prevent_rename: bool, prevent_rename: bool,
mut chat_id: ChatId, mut chat_id: ChatId,
mut chat_id_blocked: Blocked, mut chat_id_blocked: Blocked,
@@ -2163,22 +2117,6 @@ async fn add_parts(
param.set_int(Param::Cmd, is_system_message as i32); param.set_int(Param::Cmd, is_system_message as i32);
} }
if let Some(replace_msg_id) = replace_msg_id {
let placeholder = Message::load_from_db(context, replace_msg_id)
.await
.context("Failed to load placeholder message")?;
for key in [
Param::WebxdcSummary,
Param::WebxdcSummaryTimestamp,
Param::WebxdcDocument,
Param::WebxdcDocumentTimestamp,
] {
if let Some(value) = placeholder.param.get(key) {
param.set(key, value);
}
}
}
let (msg, typ): (&str, Viewtype) = if let Some(better_msg) = &better_msg { let (msg, typ): (&str, Viewtype) = if let Some(better_msg) = &better_msg {
(better_msg, Viewtype::Text) (better_msg, Viewtype::Text)
} else { } else {
@@ -2221,10 +2159,9 @@ async fn add_parts(
.sql .sql
.call_write(|conn| { .call_write(|conn| {
let mut stmt = conn.prepare_cached( let mut stmt = conn.prepare_cached(
r#" "
INSERT INTO msgs INSERT INTO msgs
( (
id,
rfc724_mid, pre_rfc724_mid, chat_id, rfc724_mid, pre_rfc724_mid, chat_id,
from_id, to_id, timestamp, timestamp_sent, from_id, to_id, timestamp, timestamp_sent,
timestamp_rcvd, type, state, msgrmsg, timestamp_rcvd, type, state, msgrmsg,
@@ -2234,28 +2171,15 @@ INSERT INTO msgs
ephemeral_timestamp, download_state, hop_info ephemeral_timestamp, download_state, hop_info
) )
VALUES ( VALUES (
?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, 1,
?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ? ?, ?, ?, ?
) )",
ON CONFLICT (id) DO UPDATE )?;
SET rfc724_mid=excluded.rfc724_mid, chat_id=excluded.chat_id, let params = params![
from_id=excluded.from_id, to_id=excluded.to_id, timestamp_sent=excluded.timestamp_sent,
type=excluded.type, state=max(state,excluded.state), msgrmsg=excluded.msgrmsg,
txt=excluded.txt, txt_normalized=excluded.txt_normalized, subject=excluded.subject,
param=excluded.param,
hidden=excluded.hidden,bytes=excluded.bytes, mime_headers=excluded.mime_headers,
mime_compressed=excluded.mime_compressed, mime_in_reply_to=excluded.mime_in_reply_to,
mime_references=excluded.mime_references, mime_modified=excluded.mime_modified, error=excluded.error, ephemeral_timer=excluded.ephemeral_timer,
ephemeral_timestamp=excluded.ephemeral_timestamp, download_state=excluded.download_state, hop_info=excluded.hop_info
RETURNING id
"#)?;
let row_id: MsgId = stmt.query_row(params![
replace_msg_id,
if let PreMessageMode::Pre {post_msg_rfc724_mid, ..} = &mime_parser.pre_message { if let PreMessageMode::Pre {post_msg_rfc724_mid, ..} = &mime_parser.pre_message {
post_msg_rfc724_mid post_msg_rfc724_mid
} else { rfc724_mid_orig }, } else { rfc724_mid_orig },
@@ -2306,20 +2230,11 @@ RETURNING id
DownloadState::Done DownloadState::Done
}, },
if trash { "" } else { &mime_parser.hop_info }, if trash { "" } else { &mime_parser.hop_info },
], ];
|row| { let row_id = MsgId::new(stmt.insert(params)?.try_into()?);
let msg_id: MsgId = row.get(0)?;
Ok(msg_id)
}
)?;
Ok(row_id) Ok(row_id)
}) })
.await?; .await?;
// We only replace placeholder with a first part,
// afterwards insert additional parts.
replace_msg_id = None;
ensure_and_debug_assert!(!row_id.is_special(), "Rowid {row_id} is special"); ensure_and_debug_assert!(!row_id.is_special(), "Rowid {row_id} is special");
created_db_entries.push(row_id); created_db_entries.push(row_id);
} }
@@ -2344,14 +2259,6 @@ RETURNING id
.await?; .await?;
} }
if let Some(replace_msg_id) = replace_msg_id {
// Trash the "replace" placeholder with a message that has no parts. If it has the original
// "Message-ID", mark the placeholder for server-side deletion so as if the user deletes the
// fully downloaded message later, the server-side deletion is issued.
let on_server = rfc724_mid == rfc724_mid_orig;
replace_msg_id.trash(context, on_server).await?;
}
let unarchive = match mime_parser.get_header(HeaderDef::ChatGroupMemberRemoved) { let unarchive = match mime_parser.get_header(HeaderDef::ChatGroupMemberRemoved) {
Some(addr) => context.is_self_addr(addr).await?, Some(addr) => context.is_self_addr(addr).await?,
None => true, None => true,

View File

@@ -5,13 +5,9 @@ use crate::download::DownloadState;
use crate::receive_imf::receive_imf_from_inbox; use crate::receive_imf::receive_imf_from_inbox;
use crate::test_utils::TestContext; use crate::test_utils::TestContext;
// The code for downloading stub messages stays // The code for replacing partial download stubs is already removed, so check that nothing happens
// during the transition perios to pre-messages // if after that a full message is passed to receive_imf. Users should ask the sender to send the
// so people can still download their files shortly after they updated. // message again.
// After there are a few release with pre-message rolled out,
// we will remove the ability to download stub messages and replace the following test
// so it checks that it doesn't crash or that the messages are replaced by sth.
// like "download failed/expired, please ask sender to send it again"
#[tokio::test(flavor = "multi_thread", worker_threads = 2)] #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_download_stub_message() -> Result<()> { async fn test_download_stub_message() -> Result<()> {
let t = TestContext::new_alice().await; let t = TestContext::new_alice().await;
@@ -53,9 +49,9 @@ async fn test_download_stub_message() -> Result<()> {
) )
.await?; .await?;
let msg = t.get_last_msg().await; let msg = t.get_last_msg().await;
assert_eq!(msg.download_state(), DownloadState::Done); assert_eq!(msg.download_state(), DownloadState::Available);
assert_eq!(msg.get_subject(), "foo"); assert_eq!(msg.get_subject(), "foo");
assert_eq!(msg.get_text(), "100k text..."); assert!(msg.get_text().contains("[97.66 KiB message]"));
Ok(()) Ok(())
} }