melib/imap: add conf toggle flags for IMAP extensions
parent
7bbfd188ef
commit
8ec0da4fbd
|
@ -230,6 +230,11 @@ If port is 993 and use_starttls is unspecified, it becomes false by default.
|
||||||
Do not validate TLS certificates.
|
Do not validate TLS certificates.
|
||||||
.\" default value
|
.\" default value
|
||||||
.Pq Em false
|
.Pq Em false
|
||||||
|
.It Ic use_idle Ar boolean
|
||||||
|
.Pq Em optional
|
||||||
|
Use IDLE extension.
|
||||||
|
.\" default value
|
||||||
|
.Pq Em true
|
||||||
.El
|
.El
|
||||||
.Ss JMAP only
|
.Ss JMAP only
|
||||||
JMAP specific options
|
JMAP specific options
|
||||||
|
|
|
@ -335,13 +335,20 @@ impl MailBackend for ImapType {
|
||||||
let main_conn = self.connection.clone();
|
let main_conn = self.connection.clone();
|
||||||
*self.uid_store.sender.write().unwrap() = Some(sender);
|
*self.uid_store.sender.write().unwrap() = Some(sender);
|
||||||
let uid_store = self.uid_store.clone();
|
let uid_store = self.uid_store.clone();
|
||||||
|
let has_idle: bool = match self.server_conf.protocol {
|
||||||
|
ImapProtocol::IMAP {
|
||||||
|
extension_use: ImapExtensionUse { idle, .. },
|
||||||
|
} => {
|
||||||
|
idle && uid_store
|
||||||
|
.capabilities
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.any(|cap| cap.eq_ignore_ascii_case(b"IDLE"))
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
Ok(Box::pin(async move {
|
Ok(Box::pin(async move {
|
||||||
let has_idle: bool = uid_store
|
|
||||||
.capabilities
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.iter()
|
|
||||||
.any(|cap| cap.eq_ignore_ascii_case(b"IDLE"));
|
|
||||||
debug!(has_idle);
|
debug!(has_idle);
|
||||||
let kit = ImapWatchKit {
|
let kit = ImapWatchKit {
|
||||||
conn,
|
conn,
|
||||||
|
@ -1071,7 +1078,11 @@ impl ImapType {
|
||||||
use_tls,
|
use_tls,
|
||||||
use_starttls,
|
use_starttls,
|
||||||
danger_accept_invalid_certs,
|
danger_accept_invalid_certs,
|
||||||
protocol: ImapProtocol::IMAP,
|
protocol: ImapProtocol::IMAP {
|
||||||
|
extension_use: ImapExtensionUse {
|
||||||
|
idle: get_conf_val!(s["use_idle"], true)?,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
let account_hash = {
|
let account_hash = {
|
||||||
let mut hasher = DefaultHasher::new();
|
let mut hasher = DefaultHasher::new();
|
||||||
|
@ -1257,6 +1268,7 @@ impl ImapType {
|
||||||
}
|
}
|
||||||
get_conf_val!(s["danger_accept_invalid_certs"], false)?;
|
get_conf_val!(s["danger_accept_invalid_certs"], false)?;
|
||||||
get_conf_val!(s["X_header_caching"], false)?;
|
get_conf_val!(s["X_header_caching"], false)?;
|
||||||
|
get_conf_val!(s["use_idle"], true)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,25 @@ use std::time::Instant;
|
||||||
use super::protocol_parser;
|
use super::protocol_parser;
|
||||||
use super::{Capabilities, ImapServerConf, UIDStore};
|
use super::{Capabilities, ImapServerConf, UIDStore};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum ImapProtocol {
|
pub enum ImapProtocol {
|
||||||
IMAP,
|
IMAP { extension_use: ImapExtensionUse },
|
||||||
ManageSieve,
|
ManageSieve,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct ImapExtensionUse {
|
||||||
|
pub idle: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ImapExtensionUse {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
idle: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ImapStream {
|
pub struct ImapStream {
|
||||||
pub cmd_id: usize,
|
pub cmd_id: usize,
|
||||||
|
@ -116,7 +129,7 @@ impl ImapStream {
|
||||||
if server_conf.use_starttls {
|
if server_conf.use_starttls {
|
||||||
let mut buf = vec![0; 1024];
|
let mut buf = vec![0; 1024];
|
||||||
match server_conf.protocol {
|
match server_conf.protocol {
|
||||||
ImapProtocol::IMAP => socket
|
ImapProtocol::IMAP { .. } => socket
|
||||||
.write_all(format!("M{} STARTTLS\r\n", cmd_id).as_bytes())
|
.write_all(format!("M{} STARTTLS\r\n", cmd_id).as_bytes())
|
||||||
.await
|
.await
|
||||||
.chain_err_kind(crate::error::ErrorKind::Network)?,
|
.chain_err_kind(crate::error::ErrorKind::Network)?,
|
||||||
|
@ -142,7 +155,7 @@ impl ImapStream {
|
||||||
.chain_err_kind(crate::error::ErrorKind::Network)?;
|
.chain_err_kind(crate::error::ErrorKind::Network)?;
|
||||||
response.push_str(unsafe { std::str::from_utf8_unchecked(&buf[0..len]) });
|
response.push_str(unsafe { std::str::from_utf8_unchecked(&buf[0..len]) });
|
||||||
match server_conf.protocol {
|
match server_conf.protocol {
|
||||||
ImapProtocol::IMAP => {
|
ImapProtocol::IMAP { .. } => {
|
||||||
if response.starts_with("* OK ") && response.find("\r\n").is_some() {
|
if response.starts_with("* OK ") && response.find("\r\n").is_some() {
|
||||||
if let Some(pos) = response.as_bytes().find(b"\r\n") {
|
if let Some(pos) = response.as_bytes().find(b"\r\n") {
|
||||||
response.drain(0..pos + 2);
|
response.drain(0..pos + 2);
|
||||||
|
@ -338,7 +351,7 @@ impl ImapStream {
|
||||||
|
|
||||||
pub async fn read_response(&mut self, ret: &mut String) -> Result<()> {
|
pub async fn read_response(&mut self, ret: &mut String) -> Result<()> {
|
||||||
let id = match self.protocol {
|
let id = match self.protocol {
|
||||||
ImapProtocol::IMAP => format!("M{} ", self.cmd_id - 1),
|
ImapProtocol::IMAP { .. } => format!("M{} ", self.cmd_id - 1),
|
||||||
ImapProtocol::ManageSieve => String::new(),
|
ImapProtocol::ManageSieve => String::new(),
|
||||||
};
|
};
|
||||||
self.read_lines(ret, &id, true).await?;
|
self.read_lines(ret, &id, true).await?;
|
||||||
|
@ -408,7 +421,7 @@ impl ImapStream {
|
||||||
if let Err(err) = try_await(async move {
|
if let Err(err) = try_await(async move {
|
||||||
let command = command.trim();
|
let command = command.trim();
|
||||||
match self.protocol {
|
match self.protocol {
|
||||||
ImapProtocol::IMAP => {
|
ImapProtocol::IMAP { .. } => {
|
||||||
self.stream.write_all(b"M").await?;
|
self.stream.write_all(b"M").await?;
|
||||||
self.stream
|
self.stream
|
||||||
.write_all(self.cmd_id.to_string().as_bytes())
|
.write_all(self.cmd_id.to_string().as_bytes())
|
||||||
|
@ -422,7 +435,7 @@ impl ImapStream {
|
||||||
self.stream.write_all(command).await?;
|
self.stream.write_all(command).await?;
|
||||||
self.stream.write_all(b"\r\n").await?;
|
self.stream.write_all(b"\r\n").await?;
|
||||||
match self.protocol {
|
match self.protocol {
|
||||||
ImapProtocol::IMAP => {
|
ImapProtocol::IMAP { .. } => {
|
||||||
debug!("sent: M{} {}", self.cmd_id - 1, unsafe {
|
debug!("sent: M{} {}", self.cmd_id - 1, unsafe {
|
||||||
std::str::from_utf8_unchecked(command)
|
std::str::from_utf8_unchecked(command)
|
||||||
});
|
});
|
||||||
|
@ -514,7 +527,7 @@ impl ImapConnection {
|
||||||
self.stream.as_mut()?.read_response(&mut response).await?;
|
self.stream.as_mut()?.read_response(&mut response).await?;
|
||||||
|
|
||||||
match self.server_conf.protocol {
|
match self.server_conf.protocol {
|
||||||
ImapProtocol::IMAP => {
|
ImapProtocol::IMAP { .. } => {
|
||||||
let r: ImapResponse = ImapResponse::from(&response);
|
let r: ImapResponse = ImapResponse::from(&response);
|
||||||
match r {
|
match r {
|
||||||
ImapResponse::Bye(ref response_code) => {
|
ImapResponse::Bye(ref response_code) => {
|
||||||
|
|
Loading…
Reference in New Issue