mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 01:16:31 +03:00
feat: Drop support for replacing partial download stubs
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user