Handle Dovecot's periodic IDLE notification messages ("OK Still here").

These messages show up at an interval controlled by Dovecot's
imap_idle_notify_interval setting, which defaults to 2 minutes.
These messages were causing the IDLE loop to exit prematurely
because it looks like a notification response from the server.
This commit is contained in:
Todd Mortimer 2020-04-18 19:48:25 -04:00
parent 1b7ba0b0b1
commit 746bdfe6b9

View file

@ -93,16 +93,26 @@ impl<'a, T: Read + Write + 'a> Handle<'a, T> {
/// This is necessary so that we can keep using the inner `Session` in `wait_keepalive`. /// This is necessary so that we can keep using the inner `Session` in `wait_keepalive`.
fn wait_inner(&mut self) -> Result<()> { fn wait_inner(&mut self) -> Result<()> {
let mut v = Vec::new(); let mut v = Vec::new();
match self.session.readline(&mut v).map(|_| ()) { loop {
Err(Error::Io(ref e)) match self.session.readline(&mut v).map(|_| ()) {
if e.kind() == io::ErrorKind::TimedOut || e.kind() == io::ErrorKind::WouldBlock => Err(Error::Io(ref e))
{ if e.kind() == io::ErrorKind::TimedOut
// we need to refresh the IDLE connection || e.kind() == io::ErrorKind::WouldBlock =>
self.terminate()?; {
self.init()?; // we need to refresh the IDLE connection
self.wait_inner() self.terminate()?;
self.init()?;
return self.wait_inner();
}
r => r,
}?;
// Handle Dovecot's imap_idle_notify_interval message
if v.eq_ignore_ascii_case(b"* OK Still here\r\n") {
v.clear();
} else {
break Ok(());
} }
r => r,
} }
} }