diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs index 8b83978e..05bd98c4 100644 --- a/melib/src/backends/imap.rs +++ b/melib/src/backends/imap.rs @@ -147,7 +147,7 @@ impl MailBackend for ImapType { if Instant::now().duration_since(self.online.lock().unwrap().0) >= std::time::Duration::new(2, 0) { - let _ = self.folders(); + let _ = self.connection.lock().unwrap().connect(); } } } @@ -505,13 +505,6 @@ impl MailBackend for ImapType { let mut response = String::with_capacity(8 * 1024); { let mut conn_lck = self.connection.lock()?; - if folders[&folder_hash].is_subscribed() { - conn_lck.send_command( - format!("UNSUBSCRIBE \"{}\"", folders[&folder_hash].imap_path()).as_bytes(), - )?; - conn_lck.read_response(&mut response)?; - } - if !folders[&folder_hash].no_select { /* make sure mailbox is not selected before it gets deleted, otherwise * connection gets dropped by server */ @@ -535,6 +528,13 @@ impl MailBackend for ImapType { conn_lck.read_response(&mut response)?; } } + if folders[&folder_hash].is_subscribed() { + conn_lck.send_command( + format!("UNSUBSCRIBE \"{}\"", folders[&folder_hash].imap_path()).as_bytes(), + )?; + conn_lck.read_response(&mut response)?; + } + conn_lck.send_command( debug!(format!("DELETE \"{}\"", folders[&folder_hash].imap_path())).as_bytes(), )?; @@ -675,6 +675,7 @@ impl ImapType { pub fn shell(&mut self) { let mut conn = ImapConnection::new_connection(&self.server_conf, self.online.clone()); + conn.connect().unwrap(); let mut res = String::with_capacity(8 * 1024); conn.send_command(b"NOOP").unwrap(); conn.read_response(&mut res).unwrap(); diff --git a/melib/src/backends/imap/connection.rs b/melib/src/backends/imap/connection.rs index e6a6e602..d6cc7f02 100644 --- a/melib/src/backends/imap/connection.rs +++ b/melib/src/backends/imap/connection.rs @@ -338,6 +338,31 @@ impl ImapConnection { } } + pub fn connect(&mut self) -> Result<()> { + if let (instant, ref mut status @ Ok(())) = *self.online.lock().unwrap() { + if Instant::now().duration_since(instant) >= std::time::Duration::new(60 * 30, 0) { + *status = Err(MeliError::new("Connection timed out")); + self.stream = Err(MeliError::new("Connection timed out")); + } + } + if self.stream.is_ok() { + return Ok(()); + } + let new_stream = ImapStream::new_connection(&self.server_conf); + if new_stream.is_err() { + *self.online.lock().unwrap() = ( + Instant::now(), + Err(new_stream.as_ref().unwrap_err().clone()), + ); + } else { + *self.online.lock().unwrap() = (Instant::now(), Ok(())); + } + let (capabilities, stream) = new_stream?; + self.stream = Ok(stream); + self.capabilities = capabilities; + Ok(()) + } + pub fn read_response(&mut self, ret: &mut String) -> Result<()> { self.try_send(|s| s.read_response(ret))?; let r: ImapResponse = ImapResponse::from(&ret); diff --git a/melib/src/backends/imap/watch.rs b/melib/src/backends/imap/watch.rs index b8a31864..223d2fd6 100644 --- a/melib/src/backends/imap/watch.rs +++ b/melib/src/backends/imap/watch.rs @@ -67,6 +67,7 @@ pub fn poll_with_examine(kit: ImapWatchKit) -> Result<()> { } std::thread::sleep(std::time::Duration::from_millis(100)); } + conn.connect()?; let mut response = String::with_capacity(8 * 1024); let thread_id: std::thread::ThreadId = std::thread::current().id(); loop { @@ -119,6 +120,7 @@ pub fn idle(kit: ImapWatchKit) -> Result<()> { } std::thread::sleep(std::time::Duration::from_millis(100)); } + conn.connect()?; let thread_id: std::thread::ThreadId = std::thread::current().id(); let folder: ImapFolder = match folders .read()