From 9fae0f2fa34cccd25d7ec18c6bff2432778bc235 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Wed, 11 Dec 2019 01:36:04 +0200 Subject: [PATCH] melib/imap: prevent minor blocking cases --- melib/src/backends/imap.rs | 22 +++++++++++----------- melib/src/backends/imap/connection.rs | 16 ++-------------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs index 84eb38fd1..7f92daa40 100644 --- a/melib/src/backends/imap.rs +++ b/melib/src/backends/imap.rs @@ -283,12 +283,6 @@ impl MailBackend for ImapType { sender: RefreshEventConsumer, work_context: WorkContext, ) -> Result { - let has_idle: bool = self - .connection - .lock() - .unwrap() - .capabilities - .contains(&b"IDLE"[0..]); let folders = self.folders.clone(); let tag_index = self.tag_index.clone(); let conn = ImapConnection::new_connection(&self.server_conf); @@ -303,6 +297,12 @@ impl MailBackend for ImapType { .set_status .send((thread.id(), "watching".to_string())) .unwrap(); + let has_idle: bool = main_conn + .lock() + .unwrap() + .capabilities + .iter() + .any(|cap| cap.eq_ignore_ascii_case(b"IDLE")); let kit = ImapWatchKit { conn, is_online, @@ -333,7 +333,7 @@ impl MailBackend for ImapType { } } let mut folders = self.folders.write()?; - *folders = ImapType::imap_folders(&self.connection); + *folders = ImapType::imap_folders(&self.connection)?; folders.retain(|_, f| (self.is_subscribed)(f.path())); let keys = folders.keys().cloned().collect::>(); let mut uid_lock = self.uid_store.uidvalidity.lock().unwrap(); @@ -565,12 +565,12 @@ impl ImapType { pub fn imap_folders( connection: &Arc>, - ) -> FnvHashMap { + ) -> Result> { let mut folders: FnvHashMap = Default::default(); let mut res = String::with_capacity(8 * 1024); let mut conn = connection.lock().unwrap(); - conn.send_command(b"LIST \"\" \"*\"").unwrap(); - conn.read_response(&mut res).unwrap(); + conn.send_command(b"LIST \"\" \"*\"")?; + conn.read_response(&mut res)?; debug!("out: {}", &res); for l in res.lines().map(|l| l.trim()) { if let Ok(mut folder) = @@ -605,7 +605,7 @@ impl ImapType { debug!("parse error for {:?}", l); } } - debug!(folders) + Ok(debug!(folders)) } pub fn capabilities(&self) -> Vec { diff --git a/melib/src/backends/imap/connection.rs b/melib/src/backends/imap/connection.rs index 5a3cfe617..65fe835a8 100644 --- a/melib/src/backends/imap/connection.rs +++ b/melib/src/backends/imap/connection.rs @@ -172,30 +172,18 @@ impl ImapStream { let mut buf = vec![0; 1024]; let mut response = String::with_capacity(1024); - let mut cap_flag = false; let mut broken = false; let now = std::time::Instant::now(); while now.elapsed().as_secs() < 3 { let len = socket.read(&mut buf)?; response.push_str(unsafe { std::str::from_utf8_unchecked(&buf[0..len]) }); - if !cap_flag { - if response.starts_with("* OK [CAPABILITY") { - cap_flag = true; - if let Some(pos) = response.as_bytes().find(b"\r\n") { - response.drain(0..pos + 2); - } - } else if response.starts_with("* OK ") && response.find("\r\n").is_some() { - if let Some(pos) = response.as_bytes().find(b"\r\n") { - response.drain(0..pos + 2); - } - } - } else if response.starts_with("* OK [CAPABILITY") { + if response.starts_with("* OK ") && response.find("\r\n").is_some() { if let Some(pos) = response.as_bytes().find(b"\r\n") { response.drain(0..pos + 2); } } - if cap_flag && response == "M0 OK Begin TLS negotiation now.\r\n" { + if response.starts_with("M0 OK") { broken = true; break; }