mirror of
https://github.com/chatmail/core.git
synced 2026-04-20 23:16:30 +03:00
fix: Don't update timestamp, timestamp_rcvd, state when replacing partially downloaded message (#4700)
Also add a test on downloading a message later. Although it doesn't reproduce #4700 for some reason, it fails w/o the fix because before a message state was changing to `InSeen` after a full download which doesn't look correct. The result of a full message download should be such as if it was fully downloaded initially.
This commit is contained in:
@@ -23,7 +23,7 @@ use crate::{job_try, stock_str, EventType};
|
||||
/// eg. to assign them to the correct chat.
|
||||
/// As these messages are typically small,
|
||||
/// they're caught by `MIN_DOWNLOAD_LIMIT`.
|
||||
const MIN_DOWNLOAD_LIMIT: u32 = 32768;
|
||||
pub(crate) const MIN_DOWNLOAD_LIMIT: u32 = 32768;
|
||||
|
||||
/// If a message is downloaded only partially
|
||||
/// and `delete_server_after` is set to small timeouts (eg. "at once"),
|
||||
|
||||
@@ -77,6 +77,24 @@ pub async fn receive_imf(
|
||||
let mail = parse_mail(imf_raw).context("can't parse mail")?;
|
||||
let rfc724_mid =
|
||||
imap::prefetch_get_message_id(&mail.headers).unwrap_or_else(imap::create_message_id);
|
||||
if let Some(download_limit) = context.download_limit().await? {
|
||||
let download_limit: usize = download_limit.try_into()?;
|
||||
if imf_raw.len() > download_limit {
|
||||
let head = std::str::from_utf8(imf_raw)?
|
||||
.split("\r\n\r\n")
|
||||
.next()
|
||||
.context("No empty line in the message")?;
|
||||
return receive_imf_inner(
|
||||
context,
|
||||
&rfc724_mid,
|
||||
head.as_bytes(),
|
||||
seen,
|
||||
Some(imf_raw.len().try_into()?),
|
||||
false,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
receive_imf_inner(context, &rfc724_mid, imf_raw, seen, None, false).await
|
||||
}
|
||||
|
||||
@@ -1186,8 +1204,8 @@ INSERT INTO msgs
|
||||
)
|
||||
ON CONFLICT (id) DO UPDATE
|
||||
SET rfc724_mid=excluded.rfc724_mid, chat_id=excluded.chat_id,
|
||||
from_id=excluded.from_id, to_id=excluded.to_id, timestamp=excluded.timestamp, timestamp_sent=excluded.timestamp_sent,
|
||||
timestamp_rcvd=excluded.timestamp_rcvd, type=excluded.type, state=excluded.state, msgrmsg=excluded.msgrmsg,
|
||||
from_id=excluded.from_id, to_id=excluded.to_id, timestamp_sent=excluded.timestamp_sent,
|
||||
type=excluded.type, msgrmsg=excluded.msgrmsg,
|
||||
txt=excluded.txt, subject=excluded.subject, txt_raw=excluded.txt_raw, param=excluded.param,
|
||||
bytes=excluded.bytes, mime_headers=excluded.mime_headers,
|
||||
mime_compressed=excluded.mime_compressed, mime_in_reply_to=excluded.mime_in_reply_to,
|
||||
|
||||
@@ -10,8 +10,9 @@ use crate::chat::{get_chat_msgs, ChatItem, ChatVisibility};
|
||||
use crate::chatlist::Chatlist;
|
||||
use crate::config::Config;
|
||||
use crate::constants::{DC_GCL_FOR_FORWARDING, DC_GCL_NO_SPECIALS};
|
||||
use crate::download::{DownloadState, MIN_DOWNLOAD_LIMIT};
|
||||
use crate::imap::prefetch_should_download;
|
||||
use crate::message::Message;
|
||||
use crate::message::{self, Message};
|
||||
use crate::test_utils::{get_chat_msg, TestContext, TestContextManager};
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
@@ -3697,3 +3698,30 @@ async fn test_keep_member_list_if_possibly_nomember() -> Result<()> {
|
||||
assert!(is_contact_in_chat(&bob, bob_chat_id, bob_alice_contact).await?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_download_later() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = tcm.alice().await;
|
||||
alice.set_config(Config::DownloadLimit, Some("1")).await?;
|
||||
assert_eq!(alice.download_limit().await?, Some(MIN_DOWNLOAD_LIMIT));
|
||||
|
||||
let bob = tcm.bob().await;
|
||||
let bob_chat = bob.create_chat(&alice).await;
|
||||
let text = String::from_utf8(vec![b'a'; MIN_DOWNLOAD_LIMIT as usize])?;
|
||||
let sent_msg = bob.send_text(bob_chat.id, &text).await;
|
||||
let msg = alice.recv_msg(&sent_msg).await;
|
||||
assert_eq!(msg.download_state, DownloadState::Available);
|
||||
assert_eq!(msg.state, MessageState::InFresh);
|
||||
|
||||
let hi_msg = tcm.send_recv(&bob, &alice, "hi").await;
|
||||
|
||||
alice.set_config(Config::DownloadLimit, None).await?;
|
||||
let msg = alice.recv_msg(&sent_msg).await;
|
||||
assert_eq!(msg.download_state, DownloadState::Done);
|
||||
assert_eq!(msg.state, MessageState::InFresh);
|
||||
assert_eq!(alice.get_last_msg_in(msg.chat_id).await.id, hi_msg.id);
|
||||
assert!(msg.timestamp_sort <= hi_msg.timestamp_sort);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user