aboutsummaryrefslogtreecommitdiff
path: root/src/imap/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/imap/mod.rs')
-rw-r--r--src/imap/mod.rs34
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)
},