diff options
Diffstat (limited to 'src/imap/mod.rs')
-rw-r--r-- | src/imap/mod.rs | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/src/imap/mod.rs b/src/imap/mod.rs index b08a4ff..6f143d7 100644 --- a/src/imap/mod.rs +++ b/src/imap/mod.rs @@ -26,8 +26,8 @@ use imap_codec::imap_types::response::{Code, CommandContinuationRequest, Respons use imap_codec::imap_types::{core::Text, response::Greeting}; use imap_flow::server::{ServerFlow, ServerFlowEvent, ServerFlowOptions}; use imap_flow::stream::AnyStream; -use tokio_rustls::TlsAcceptor; use rustls_pemfile::{certs, private_key}; +use tokio_rustls::TlsAcceptor; use crate::config::{ImapConfig, ImapUnsecureConfig}; use crate::imap::capability::ServerCapability; @@ -53,8 +53,14 @@ struct ClientContext { } pub fn new(config: ImapConfig, login: ArcLoginProvider) -> Result<Server> { - let loaded_certs = certs(&mut std::io::BufReader::new(std::fs::File::open(config.certs)?)).collect::<Result<Vec<_>, _>>()?; - let loaded_key = private_key(&mut std::io::BufReader::new(std::fs::File::open(config.key)?))?.unwrap(); + let loaded_certs = certs(&mut std::io::BufReader::new(std::fs::File::open( + config.certs, + )?)) + .collect::<Result<Vec<_>, _>>()?; + let loaded_key = private_key(&mut std::io::BufReader::new(std::fs::File::open( + config.key, + )?))? + .unwrap(); let tls_config = rustls::ServerConfig::builder() .with_no_client_auth() @@ -109,7 +115,7 @@ impl Server { } }; AnyStream::new(stream) - }, + } None => AnyStream::new(socket), }; @@ -135,6 +141,8 @@ use std::sync::Arc; use tokio::sync::mpsc::*; use tokio::sync::Notify; use tokio_util::bytes::BytesMut; + +#[derive(Debug)] enum LoopMode { Quit, Interactive, @@ -232,8 +240,10 @@ impl NetLoop { } async fn core(mut self) -> Result<()> { + tracing::trace!("Starting the core loop"); let mut mode = LoopMode::Interactive; loop { + tracing::trace!(mode=?mode, "Core loop iter"); mode = match mode { LoopMode::Interactive => self.interactive_mode().await?, LoopMode::Idle(buff, stop) => self.idle_mode(buff, stop).await?, @@ -275,6 +285,7 @@ impl NetLoop { // Managing response generated by Aerogramme maybe_msg = self.resp_rx.recv() => match maybe_msg { Some(ResponseOrIdle::Response(response)) => { + tracing::trace!("Interactive, server has a response for the client"); for body_elem in response.body.into_iter() { let _handle = match body_elem { Body::Data(d) => self.server.enqueue_data(d), @@ -284,6 +295,7 @@ impl NetLoop { self.server.enqueue_status(response.completion); }, Some(ResponseOrIdle::StartIdle(stop)) => { + tracing::trace!("Interactive, server agreed to switch in idle mode"); let cr = CommandContinuationRequest::basic(None, "Idling")?; self.server.enqueue_continuation(cr); self.cmd_tx.try_send(Request::Idle)?; @@ -299,6 +311,7 @@ impl NetLoop { // When receiving a CTRL+C _ = self.ctx.must_exit.changed() => { + tracing::trace!("Interactive, CTRL+C, exiting"); self.server.enqueue_status(Status::bye(None, "Server is being shutdown").unwrap()); }, }; @@ -308,6 +321,7 @@ impl NetLoop { async fn idle_mode(&mut self, mut buff: BytesMut, stop: Arc<Notify>) -> Result<LoopMode> { // Flush send loop { + tracing::trace!("flush server send"); match self.server.progress_send().await? { Some(..) => continue, None => break, @@ -319,6 +333,7 @@ impl NetLoop { maybe_msg = self.resp_rx.recv() => match maybe_msg { // Session decided idle is terminated Some(ResponseOrIdle::Response(response)) => { + tracing::trace!("server imap session said idle is done, sending response done, switching to interactive"); for body_elem in response.body.into_iter() { let _handle = match body_elem { Body::Data(d) => self.server.enqueue_data(d), @@ -330,6 +345,7 @@ impl NetLoop { }, // Session has some information for user Some(ResponseOrIdle::IdleEvent(elems)) => { + tracing::trace!("server imap session has some change to communicate to the client"); for body_elem in elems.into_iter() { let _handle = match body_elem { Body::Data(d) => self.server.enqueue_data(d), @@ -352,16 +368,21 @@ impl NetLoop { }, // User is trying to interact with us - _read_client_bytes = self.server.stream.read(&mut buff) => { + read_client_result = self.server.stream.read(&mut buff) => { + let _bytes_read = read_client_result?; use imap_codec::decode::Decoder; let codec = imap_codec::IdleDoneCodec::new(); + tracing::trace!("client sent some data for the server IMAP session"); match codec.decode(&buff) { Ok(([], imap_codec::imap_types::extensions::idle::IdleDone)) => { // Session will be informed that it must stop idle // It will generate the "done" message and change the loop mode + tracing::trace!("client sent DONE and want to stop IDLE"); stop.notify_one() }, - Err(_) => (), + Err(_) => { + tracing::trace!("Unable to decode DONE, maybe not enough data were sent?"); + }, _ => bail!("Client sent data after terminating the continuation without waiting for the server. This is an unsupported behavior and bug in Aerogramme, quitting."), }; @@ -370,6 +391,7 @@ impl NetLoop { // When receiving a CTRL+C _ = self.ctx.must_exit.changed() => { + tracing::trace!("CTRL+C sent, aborting IDLE for this session"); self.server.enqueue_status(Status::bye(None, "Server is being shutdown").unwrap()); return Ok(LoopMode::Interactive) }, |