aboutsummaryrefslogtreecommitdiff
path: root/src/smtp_server.rs
diff options
context:
space:
mode:
authorMroik <mroik@delayed.space>2026-04-10 00:21:25 +0200
committerMroik <mroik@delayed.space>2026-04-13 06:56:11 +0200
commitb336fd39444e8089d35a7a2bd4c0c3e8228c6c36 (patch)
tree945f577f4c8b1d8c9e58b10d39e38832ec77391c /src/smtp_server.rs
parent0ff548961a68213487faa85b7b01cf717bb27268 (diff)
Add mail processing scaffolding
After receiving the email we don't want to process it in the same thread as soon as we can, instead we queue it to a MailProcessor. This allows us to be more flexible with the pipeline and reduce the amount of concurrency for the database connection. This also helps with writing possible fences around resource consumption. Signed-off-by: Mroik <mroik@delayed.space>
Diffstat (limited to 'src/smtp_server.rs')
-rw-r--r--src/smtp_server.rs19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/smtp_server.rs b/src/smtp_server.rs
index 2795ecf..bacf8eb 100644
--- a/src/smtp_server.rs
+++ b/src/smtp_server.rs
@@ -4,7 +4,9 @@ use std::{
};
use anyhow::Result;
-use tokio::spawn;
+use tokio::{spawn, sync::mpsc::Sender};
+
+use crate::model::Mail;
const SERVER_NAME: &str = "";
@@ -22,12 +24,13 @@ impl SmtpServer {
}
// TODO: trap SIGINT to stop server?
- pub async fn run(&mut self) -> Result<()> {
+ pub async fn run(&mut self, tx_processor: Sender<Mail>) -> Result<()> {
self.running = true;
while self.running {
let (stream, addr) = self.listener.accept()?;
let session = SessionHandler {
addr,
+ tx_processor: tx_processor.clone(),
state: SessionState::default(),
client_host: String::new(),
from: None,
@@ -42,6 +45,7 @@ impl SmtpServer {
struct SessionHandler {
addr: SocketAddr,
+ tx_processor: Sender<Mail>,
state: SessionState,
client_host: String,
from: Option<String>,
@@ -158,18 +162,25 @@ impl SessionHandler {
Ok(Reply::StartMailInput)
}
- // TODO: Forward and store email
async fn process_mail(&mut self) -> Result<Reply> {
if self.from.is_none() || self.to.is_empty() || self.data.trim().is_empty() {
return Ok(Reply::InvalidCommand);
}
+ let mail = Mail {
+ from: self.from.as_ref().unwrap().clone(),
+ recipient: self.to.clone(),
+ data: self.data.clone(),
+ };
+
+ self.tx_processor.send(mail).await?;
+
self.state = SessionState::Normal;
self.from = None;
self.to.clear();
self.data.clear();
- todo!()
+ Ok(Reply::Completed(String::from("Ok")))
}
}
XMR address: 854DmXNrxULU3ZFJVs4Wc8PFhbq29RhqHhY8W6cdWrtFN3qmooKyyeYPcDzZTNRxphhJ5UzASQfAdEMwSteVqymk28aLhqj