Skip to content

Commit 0d46626

Browse files
committed
remove: partial downloads
1 parent 6fe6723 commit 0d46626

File tree

5 files changed

+67
-237
lines changed

5 files changed

+67
-237
lines changed

src/config.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,6 @@ pub enum Config {
437437
/// to avoid encrypting it differently and
438438
/// storing the same token multiple times on the server.
439439
EncryptedDeviceToken,
440-
441-
/// Return an error from `receive_imf_inner()` for a fully downloaded message. For tests.
442-
FailOnReceivingFullMsg,
443440
}
444441

445442
impl Config {

src/download.rs

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ use crate::config::Config;
1111
use crate::context::Context;
1212
use crate::imap::session::Session;
1313
use crate::log::info;
14-
use crate::message::{Message, MsgId, Viewtype};
15-
use crate::mimeparser::{MimeMessage, Part};
16-
use crate::{EventType, chatlist_events, stock_str};
14+
use crate::message::{Message, MsgId};
15+
use crate::{EventType, chatlist_events};
1716

1817
/// Download limits should not be used below `MIN_DOWNLOAD_LIMIT`.
1918
///
@@ -205,7 +204,7 @@ impl Session {
205204
let mut uid_message_ids: BTreeMap<u32, String> = BTreeMap::new();
206205
uid_message_ids.insert(uid, rfc724_mid);
207206
let (sender, receiver) = async_channel::unbounded();
208-
self.fetch_many_msgs(context, folder, vec![uid], &uid_message_ids, false, sender)
207+
self.fetch_many_msgs(context, folder, vec![uid], &uid_message_ids, sender)
209208
.await?;
210209
if receiver.recv().await.is_err() {
211210
bail!("Failed to fetch UID {uid}");
@@ -214,43 +213,6 @@ impl Session {
214213
}
215214
}
216215

217-
impl MimeMessage {
218-
/// Creates a placeholder part and add that to `parts`.
219-
///
220-
/// To create the placeholder, only the outermost header can be used,
221-
/// the mime-structure itself is not available.
222-
///
223-
/// The placeholder part currently contains a text with size and availability of the message;
224-
/// `error` is set as the part error;
225-
/// in the future, we may do more advanced things as previews here.
226-
pub(crate) async fn create_stub_from_partial_download(
227-
&mut self,
228-
context: &Context,
229-
org_bytes: u32,
230-
error: Option<String>,
231-
) -> Result<()> {
232-
let prefix = match error {
233-
None => "",
234-
Some(_) => "[❗] ",
235-
};
236-
let text = format!(
237-
"{prefix}[{}]",
238-
stock_str::partial_download_msg_body(context, org_bytes).await
239-
);
240-
241-
info!(context, "Partial download: {}", text);
242-
243-
self.do_add_single_part(Part {
244-
typ: Viewtype::Text,
245-
msg: text,
246-
error,
247-
..Default::default()
248-
});
249-
250-
Ok(())
251-
}
252-
}
253-
254216
#[cfg(test)]
255217
mod tests {
256218
use num_traits::FromPrimitive;

src/imap.rs

Lines changed: 22 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ const RFC724MID_UID: &str = "(UID BODY.PEEK[HEADER.FIELDS (\
6767
X-MICROSOFT-ORIGINAL-MESSAGE-ID\
6868
)])";
6969
const BODY_FULL: &str = "(FLAGS BODY.PEEK[])";
70-
const BODY_PARTIAL: &str = "(FLAGS RFC822.SIZE BODY.PEEK[HEADER])";
7170

7271
#[derive(Debug)]
7372
pub(crate) struct Imap {
@@ -597,8 +596,7 @@ impl Imap {
597596
.context("prefetch")?;
598597
let read_cnt = msgs.len();
599598

600-
let download_limit = context.download_limit().await?;
601-
let mut uids_fetch = Vec::<(u32, bool /* partially? */)>::with_capacity(msgs.len() + 1);
599+
let mut uids_fetch = Vec::<u32>::with_capacity(msgs.len() + 1);
602600
let mut uid_message_ids = BTreeMap::new();
603601
let mut largest_uid_skipped = None;
604602
let delete_target = context.get_delete_msgs_target().await?;
@@ -681,13 +679,7 @@ impl Imap {
681679
)
682680
.await.context("prefetch_should_download")?
683681
{
684-
match download_limit {
685-
Some(download_limit) => uids_fetch.push((
686-
uid,
687-
fetch_response.size.unwrap_or_default() > download_limit,
688-
)),
689-
None => uids_fetch.push((uid, false)),
690-
}
682+
uids_fetch.push(uid);
691683
uid_message_ids.insert(uid, message_id);
692684
} else {
693685
largest_uid_skipped = Some(uid);
@@ -722,29 +714,16 @@ impl Imap {
722714
};
723715

724716
let actually_download_messages_future = async {
725-
let sender = sender;
726-
let mut uids_fetch_in_batch = Vec::with_capacity(max(uids_fetch.len(), 1));
727-
let mut fetch_partially = false;
728-
uids_fetch.push((0, !uids_fetch.last().unwrap_or(&(0, false)).1));
729-
for (uid, fp) in uids_fetch {
730-
if fp != fetch_partially {
731-
session
732-
.fetch_many_msgs(
733-
context,
734-
folder,
735-
uids_fetch_in_batch.split_off(0),
736-
&uid_message_ids,
737-
fetch_partially,
738-
sender.clone(),
739-
)
740-
.await
741-
.context("fetch_many_msgs")?;
742-
fetch_partially = fp;
743-
}
744-
uids_fetch_in_batch.push(uid);
745-
}
746-
747-
anyhow::Ok(())
717+
session
718+
.fetch_many_msgs(
719+
context,
720+
folder,
721+
uids_fetch,
722+
&uid_message_ids,
723+
sender.clone(),
724+
)
725+
.await
726+
.context("fetch_many_msgs")
748727
};
749728

750729
let (largest_uid_fetched, fetch_res) =
@@ -1347,33 +1326,17 @@ impl Session {
13471326
folder: &str,
13481327
request_uids: Vec<u32>,
13491328
uid_message_ids: &BTreeMap<u32, String>,
1350-
fetch_partially: bool,
13511329
received_msgs_channel: Sender<(u32, Option<ReceivedMsg>)>,
13521330
) -> Result<()> {
13531331
if request_uids.is_empty() {
13541332
return Ok(());
13551333
}
13561334

13571335
for (request_uids, set) in build_sequence_sets(&request_uids)? {
1358-
info!(
1359-
context,
1360-
"Starting a {} FETCH of message set \"{}\".",
1361-
if fetch_partially { "partial" } else { "full" },
1362-
set
1363-
);
1364-
let mut fetch_responses = self
1365-
.uid_fetch(
1366-
&set,
1367-
if fetch_partially {
1368-
BODY_PARTIAL
1369-
} else {
1370-
BODY_FULL
1371-
},
1372-
)
1373-
.await
1374-
.with_context(|| {
1375-
format!("fetching messages {} from folder \"{}\"", &set, folder)
1376-
})?;
1336+
info!(context, "Starting a full FETCH of message set \"{}\".", set);
1337+
let mut fetch_responses = self.uid_fetch(&set, BODY_FULL).await.with_context(|| {
1338+
format!("fetching messages {} from folder \"{}\"", &set, folder)
1339+
})?;
13771340

13781341
// Map from UIDs to unprocessed FETCH results. We put unprocessed FETCH results here
13791342
// when we want to process other messages first.
@@ -1430,11 +1393,7 @@ impl Session {
14301393
count += 1;
14311394

14321395
let is_deleted = fetch_response.flags().any(|flag| flag == Flag::Deleted);
1433-
let (body, partial) = if fetch_partially {
1434-
(fetch_response.header(), fetch_response.size) // `BODY.PEEK[HEADER]` goes to header() ...
1435-
} else {
1436-
(fetch_response.body(), None) // ... while `BODY.PEEK[]` goes to body() - and includes header()
1437-
};
1396+
let body = fetch_response.body();
14381397

14391398
if is_deleted {
14401399
info!(context, "Not processing deleted msg {}.", request_uid);
@@ -1468,33 +1427,13 @@ impl Session {
14681427
context,
14691428
"Passing message UID {} to receive_imf().", request_uid
14701429
);
1471-
let res = receive_imf_inner(
1472-
context,
1473-
rfc724_mid,
1474-
body,
1475-
is_seen,
1476-
partial.map(|msg_size| (msg_size, None)),
1477-
)
1478-
.await;
1479-
let received_msg = if let Err(err) = res {
1480-
warn!(context, "receive_imf error: {:#}.", err);
1481-
if partial.is_some() {
1482-
return Err(err);
1483-
}
1484-
receive_imf_inner(
1485-
context,
1486-
rfc724_mid,
1487-
body,
1488-
is_seen,
1489-
Some((body.len().try_into()?, Some(format!("{err:#}")))),
1490-
)
1491-
.await?
1430+
let res = receive_imf_inner(context, rfc724_mid, body, is_seen).await;
1431+
if let Err(err) = res {
1432+
error!(context, "receive_imf error: {:#}.", err);
1433+
received_msgs_channel.send((request_uid, None)).await?;
14921434
} else {
1493-
res?
1435+
received_msgs_channel.send((request_uid, res?)).await?;
14941436
};
1495-
received_msgs_channel
1496-
.send((request_uid, received_msg))
1497-
.await?;
14981437
}
14991438

15001439
// If we don't process the whole response, IMAP client is left in a broken state where

src/mimeparser.rs

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,7 @@ const MIME_AC_SETUP_FILE: &str = "application/autocrypt-setup";
239239

240240
impl MimeMessage {
241241
/// Parse a mime message.
242-
///
243-
/// If `partial` is set, it contains the full message size in bytes and an optional error text
244-
/// for the partially downloaded message, and `body` contains the HEADER only.
245-
pub(crate) async fn from_bytes(
246-
context: &Context,
247-
body: &[u8],
248-
partial: Option<(u32, Option<String>)>,
249-
) -> Result<Self> {
242+
pub(crate) async fn from_bytes(context: &Context, body: &[u8]) -> Result<Self> {
250243
let mail = mailparse::parse_mail(body)?;
251244

252245
let timestamp_rcvd = smeared_time(context);
@@ -305,6 +298,7 @@ impl MimeMessage {
305298
(part, part.ctype.mimetype.parse::<Mime>()?)
306299
} else {
307300
// If it's a partially fetched message, there are no subparts.
301+
// TODO: partial messages don't exist anymore -> so check if this here needs change
308302
(&mail, mimetype)
309303
}
310304
} else {
@@ -611,31 +605,24 @@ impl MimeMessage {
611605
timestamp_sent,
612606
};
613607

614-
match partial {
615-
Some((org_bytes, err)) => {
616-
parser
617-
.create_stub_from_partial_download(context, org_bytes, err)
618-
.await?;
608+
match mail {
609+
Ok(mail) => {
610+
parser.parse_mime_recursive(context, mail, false).await?;
611+
}
612+
Err(err) => {
613+
let txt = "[This message cannot be decrypted.\n\n• It might already help to simply reply to this message and ask the sender to send the message again.\n\n• If you just re-installed Delta Chat then it is best if you re-setup Delta Chat now and choose \"Add as second device\" or import a backup.]";
614+
615+
let part = Part {
616+
typ: Viewtype::Text,
617+
msg_raw: Some(txt.to_string()),
618+
msg: txt.to_string(),
619+
// Don't change the error prefix for now,
620+
// receive_imf.rs:lookup_chat_by_reply() checks it.
621+
error: Some(format!("Decrypting failed: {err:#}")),
622+
..Default::default()
623+
};
624+
parser.do_add_single_part(part);
619625
}
620-
None => match mail {
621-
Ok(mail) => {
622-
parser.parse_mime_recursive(context, mail, false).await?;
623-
}
624-
Err(err) => {
625-
let txt = "[This message cannot be decrypted.\n\n• It might already help to simply reply to this message and ask the sender to send the message again.\n\n• If you just re-installed Delta Chat then it is best if you re-setup Delta Chat now and choose \"Add as second device\" or import a backup.]";
626-
627-
let part = Part {
628-
typ: Viewtype::Text,
629-
msg_raw: Some(txt.to_string()),
630-
msg: txt.to_string(),
631-
// Don't change the error prefix for now,
632-
// receive_imf.rs:lookup_chat_by_reply() checks it.
633-
error: Some(format!("Decrypting failed: {err:#}")),
634-
..Default::default()
635-
};
636-
parser.do_add_single_part(part);
637-
}
638-
},
639626
};
640627

641628
let is_location_only = parser.location_kml.is_some() && parser.parts.is_empty();

0 commit comments

Comments
 (0)