Skip to content
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ba573bb
fix python lint errors
Simon-Laux Oct 31, 2025
b69082d
fix lint of python test
Simon-Laux Nov 6, 2025
17df902
restore test `test_webxdc_update_for_not_downloaded_instance` and rename
Simon-Laux Nov 14, 2025
6f9823f
remove `test_webxdc_update_for_not_yet_received_instance`
Simon-Laux Nov 14, 2025
6042fd0
feat: send pre-message on messages with large attachments
Simon-Laux Nov 2, 2025
1954506
allow unused for `MAX_FETCH_MSG_SIZE`
Simon-Laux Nov 6, 2025
f49ecfa
remove todo comment
Simon-Laux Nov 6, 2025
bf5d081
add tests for sending pre-messages
Simon-Laux Nov 8, 2025
709a965
delimit `Chat-Full-Message-ID` with `<>` like other message ids.
Simon-Laux Nov 8, 2025
9ffe300
fix test
Simon-Laux Nov 8, 2025
a3846ee
test that Autocrypt-gossip and selfavatar should never go into
Simon-Laux Nov 8, 2025
74a1fc9
fix bug that broke
Simon-Laux Nov 8, 2025
2d32a58
cargo fmt after rebase
Simon-Laux Nov 14, 2025
305498d
fix typo
Simon-Laux Nov 14, 2025
07c2d8e
Apply suggestions from code review
Simon-Laux Nov 20, 2025
7668b7f
remove mention of hashes from doc comment
Simon-Laux Nov 20, 2025
23dd202
rename`PRE_MESSAGE_SIZE_WARNING_THRESHOLD` to
Simon-Laux Nov 20, 2025
d37c565
explain current `PRE_MSG_ATTACHMENT_SIZE_THRESHOLD` value
Simon-Laux Nov 20, 2025
273f497
rename `PRE_MESSAGE_SIZE_WARNING_THRESHOLD` to
Simon-Laux Nov 20, 2025
ef873d0
use `TestContextManager`
Simon-Laux Nov 20, 2025
c2fc525
convert some comments in assert errors
Simon-Laux Nov 20, 2025
49fc3b8
rm raw string literal in `get_smtp_rows_for_msg`
Simon-Laux Nov 20, 2025
67baf10
move logic "!is_full_msg" check to `should_do_gossip`
Simon-Laux Nov 20, 2025
8e1468a
test that case insensitive header parsing works for
Simon-Laux Nov 20, 2025
1626fd4
don't use HeaderDef for sending pre message headers in mimefactory
Simon-Laux Nov 21, 2025
cdf839a
encrypt "Chat-Full-Message-ID" header
Simon-Laux Nov 21, 2025
1c9df9d
remove accidental semicolon
Simon-Laux Nov 21, 2025
d9cf44e
format sql statement
Simon-Laux Nov 21, 2025
dcfab1b
async closure to extra method for readability
Simon-Laux Nov 21, 2025
6a34464
add Tests that pre message has autocrypt gossip headers and self avatar
Simon-Laux Nov 21, 2025
9f42ade
don't send pre message for unencrypted messages and add test for it
Simon-Laux Nov 21, 2025
f45faae
fix encryption check
Simon-Laux Nov 21, 2025
0a5c1e2
apply suggestions from code review:
Simon-Laux Nov 23, 2025
027f3d9
reference to test contexts
Simon-Laux Nov 24, 2025
3a36854
`assert!(!` to `assert_eq!(,false` for "easier" code reading
Simon-Laux Nov 24, 2025
5ec079c
test: simplify chat creation by using `.create_chat_with_contact`
Simon-Laux Nov 24, 2025
d5f8819
Apply suggestions from code review
Simon-Laux Nov 24, 2025
3cc7a56
remove now unessesary test
Simon-Laux Nov 24, 2025
2ef8b6f
sql style
Simon-Laux Nov 24, 2025
413a6ca
rm unused imports
Simon-Laux Nov 24, 2025
9d3a506
tests: `.headers` instead of `.get_headers()`
Simon-Laux Nov 24, 2025
1dcd328
get_smtp_rows_for_msg now returns SentMessage instead of tuple
Simon-Laux Nov 26, 2025
8737c29
use `bob.parse_msg(msg)` instead of using mimeparser directly
Simon-Laux Nov 26, 2025
381b709
Update src/mimefactory.rs
Simon-Laux Nov 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 73 additions & 10 deletions src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ use crate::constants::{
use crate::contact::{self, Contact, ContactId, Origin};
use crate::context::Context;
use crate::debug_logging::maybe_set_logging_xdc;
use crate::download::DownloadState;
use crate::download::{
DownloadState, PRE_MSG_ATTACHMENT_SIZE_THRESHOLD, PRE_MSG_SIZE_WARNING_THRESHOLD,
};
use crate::ephemeral::{Timer as EphemeralTimer, start_chat_ephemeral_timers};
use crate::events::EventType;
use crate::key::self_fingerprint;
use crate::location;
use crate::log::{LogExt, error, info, warn};
use crate::logged_debug_assert;
use crate::message::{self, Message, MessageState, MsgId, Viewtype};
use crate::mimefactory::MimeFactory;
use crate::mimefactory::{MimeFactory, RenderedEmail};
use crate::mimeparser::SystemMessage;
use crate::param::{Param, Params};
use crate::receive_imf::ReceivedMsg;
Expand Down Expand Up @@ -2733,6 +2735,52 @@ async fn prepare_send_msg(
Ok(row_ids)
}

/// Renders the message or Full-Message and Pre-Message.
///
/// Pre-Message is a small message with metadata which announces a larger Full-Message.
/// Full messages are not downloaded in the background.
///
/// If pre-message is not nessesary this returns a normal message instead.
async fn render_mime_message_and_pre_message(
context: &Context,
msg: &mut Message,
mimefactory: MimeFactory,
) -> Result<(RenderedEmail, Option<RenderedEmail>)> {
let needs_pre_message = msg.viewtype.has_file()
&& mimefactory.will_be_encrypted() // unencrypted is likely email, we don't want to spam by sending multiple messages
&& msg
.get_filebytes(context)
.await?
.context("filebytes not available, even though message has attachment")?
> PRE_MSG_ATTACHMENT_SIZE_THRESHOLD;

if needs_pre_message {
let mut mimefactory_full_msg = mimefactory.clone();
mimefactory_full_msg.set_as_full_message();
let rendered_msg = mimefactory_full_msg.render(context).await?;

let mut mimefactory_pre_msg = mimefactory;
mimefactory_pre_msg.set_as_pre_message_for(&rendered_msg);
let rendered_pre_msg = mimefactory_pre_msg
.render(context)
.await
.context("pre-message failed to render")?;

if rendered_pre_msg.message.len() > PRE_MSG_SIZE_WARNING_THRESHOLD {
warn!(
context,
"Pre-message for message (MsgId={}) is larger than expected: {}.",
msg.id,
rendered_pre_msg.message.len()
);
}

Ok((rendered_msg, Some(rendered_pre_msg)))
} else {
Ok((mimefactory.render(context).await?, None))
}
}

/// Constructs jobs for sending a message and inserts them into the appropriate table.
///
/// Updates the message `GuaranteeE2ee` parameter and persists it
Expand Down Expand Up @@ -2804,13 +2852,14 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -
return Ok(Vec::new());
}

let rendered_msg = match mimefactory.render(context).await {
Ok(res) => Ok(res),
Err(err) => {
message::set_msg_failed(context, msg, &err.to_string()).await?;
Err(err)
}
}?;
let (rendered_msg, rendered_pre_msg) =
match render_mime_message_and_pre_message(context, msg, mimefactory).await {
Ok(res) => Ok(res),
Err(err) => {
message::set_msg_failed(context, msg, &err.to_string()).await?;
Err(err)
}
}?;

if needs_encryption && !rendered_msg.is_encrypted {
/* unrecoverable */
Expand Down Expand Up @@ -2870,12 +2919,26 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -
} else {
for recipients_chunk in recipients.chunks(chunk_size) {
let recipients_chunk = recipients_chunk.join(" ");
// send pre-message before actual message
if let Some(pre_msg) = &rendered_pre_msg {
let row_id = t.execute(
"INSERT INTO smtp (rfc724_mid, recipients, mime, msg_id) \
VALUES (?1, ?2, ?3, ?4)",
(
&pre_msg.rfc724_mid,
&recipients_chunk,
&pre_msg.message,
msg.id,
),
)?;
row_ids.push(row_id.try_into()?);
}
let row_id = t.execute(
"INSERT INTO smtp (rfc724_mid, recipients, mime, msg_id) \
VALUES (?1, ?2, ?3, ?4)",
(
&rendered_msg.rfc724_mid,
recipients_chunk,
&recipients_chunk,
&rendered_msg.message,
msg.id,
),
Expand Down
Loading
Loading