diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2022-09-10 19:32:51 +0300 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2022-09-10 21:39:56 +0300 |
commit | 36883692782ed2355a0ec12ccf9f82aa2edcc8c1 (patch) | |
tree | e95a0f33518130e8ea5da9f5d4adc1308767fa26 /melib | |
parent | 3c0f5d8274d8039b1a2c928f99194835bca7b83a (diff) | |
download | meli-36883692782ed2355a0ec12ccf9f82aa2edcc8c1.zip |
melib/smtp: add smtp test
Diffstat (limited to 'melib')
-rw-r--r-- | melib/Cargo.toml | 4 | ||||
-rw-r--r-- | melib/src/smtp.rs | 220 | ||||
-rw-r--r-- | melib/test_sample_longmessage.eml | 65 |
3 files changed, 287 insertions, 2 deletions
diff --git a/melib/Cargo.toml b/melib/Cargo.toml index 1d383d38..1399b2bf 100644 --- a/melib/Cargo.toml +++ b/melib/Cargo.toml @@ -49,6 +49,10 @@ uuid = { version = "^1", features = ["serde", "v4", "v5"] } xdg = "2.1.0" xdg-utils = "^0.4.0" +[dev-dependencies] +mailin-embedded = { version = "0.7", features = ["rtls"] } +stderrlog = "^0.5" + [features] default = ["unicode_algorithms", "imap_backend", "maildir_backend", "mbox_backend", "vcard", "sqlite3", "smtp", "deflate_compression"] diff --git a/melib/src/smtp.rs b/melib/src/smtp.rs index 6a57a494..75fc3629 100644 --- a/melib/src/smtp.rs +++ b/melib/src/smtp.rs @@ -155,11 +155,11 @@ pub struct SmtpAuthType { login: bool, } -fn true_val() -> bool { +const fn true_val() -> bool { true } -fn false_val() -> bool { +const fn false_val() -> bool { false } @@ -1048,3 +1048,219 @@ async fn read_lines<'r>( } Ok(reply) } + +#[cfg(test)] +mod test { + use super::*; + + use mailin_embedded::{Handler, Response, Server, SslConfig}; + use std::net::IpAddr; //, Ipv4Addr, Ipv6Addr}; + use std::sync::{Arc, Mutex}; + use std::thread; + + const ADDRESS: &str = "127.0.0.1:8825"; + #[derive(Debug, Clone)] + enum Message { + Helo, + Mail { + from: String, + }, + Rcpt { + from: String, + to: Vec<String>, + }, + DataStart { + from: String, + to: Vec<String>, + }, + Data { + #[allow(dead_code)] + from: String, + to: Vec<String>, + buf: Vec<u8>, + }, + } + + #[derive(Debug, Clone)] + struct MyHandler { + mails: Arc<Mutex<Vec<((IpAddr, String), Message)>>>, + stored: Arc<Mutex<Vec<(String, crate::Envelope)>>>, + } + use mailin_embedded::response::{INTERNAL_ERROR, OK}; + + impl Handler for MyHandler { + fn helo(&mut self, ip: IpAddr, domain: &str) -> Response { + eprintln!("helo ip {:?} domain {:?}", ip, domain); + self.mails + .lock() + .unwrap() + .push(((ip, domain.to_string()), Message::Helo)); + OK + } + + fn mail(&mut self, ip: IpAddr, domain: &str, from: &str) -> Response { + eprintln!("mail() ip {:?} domain {:?} from {:?}", ip, domain, from); + if let Some((_, message)) = self + .mails + .lock() + .unwrap() + .iter_mut() + .find(|((i, d), _)| (i, d.as_str()) == (&ip, domain)) + { + std::dbg!(&message); + if let Message::Helo = message { + *message = Message::Mail { + from: from.to_string(), + }; + return OK; + } + } + INTERNAL_ERROR + } + + fn rcpt(&mut self, _to: &str) -> Response { + eprintln!("rcpt() to {:?}", _to); + if let Some((_, message)) = self.mails.lock().unwrap().last_mut() { + std::dbg!(&message); + if let Message::Mail { from } = message { + *message = Message::Rcpt { + from: from.clone(), + to: vec![_to.to_string()], + }; + return OK; + } else if let Message::Rcpt { to, .. } = message { + to.push(_to.to_string()); + return OK; + } + } + INTERNAL_ERROR + } + + fn data_start( + &mut self, + _domain: &str, + _from: &str, + _is8bit: bool, + _to: &[String], + ) -> Response { + eprintln!( + "data_start() domain {:?} from {:?} is8bit {:?} to {:?}", + _domain, _from, _is8bit, _to + ); + if let Some(((_, d), ref mut message)) = self.mails.lock().unwrap().last_mut() { + if d != _domain { + return INTERNAL_ERROR; + } + std::dbg!(&message); + if let Message::Rcpt { from, to } = message { + *message = Message::DataStart { + from: from.to_string(), + to: to.to_vec(), + }; + return OK; + } + } + INTERNAL_ERROR + } + + fn data(&mut self, _buf: &[u8]) -> std::result::Result<(), std::io::Error> { + if let Some(((_, _), ref mut message)) = self.mails.lock().unwrap().last_mut() { + if let Message::DataStart { from, to } = message { + *message = Message::Data { + from: from.to_string(), + to: to.clone(), + buf: _buf.to_vec(), + }; + return Ok(()); + } else if let Message::Data { buf, .. } = message { + buf.extend(_buf.into_iter().copied()); + return Ok(()); + } + } + Ok(()) + } + + fn data_end(&mut self) -> Response { + eprintln!("datae_nd() "); + if let Some(((_, _), message)) = self.mails.lock().unwrap().pop() { + if let Message::Data { from: _, to, buf } = message { + for to in to { + match crate::Envelope::from_bytes(&buf, None) { + Ok(env) => { + std::dbg!(&env); + std::dbg!(env.other_headers()); + self.stored.lock().unwrap().push((to.clone(), env)); + } + Err(err) => { + eprintln!("envelope parse error {}", err); + } + } + } + return OK; + } + } + INTERNAL_ERROR + } + } + + fn get_smtp_conf() -> SmtpServerConf { + SmtpServerConf { + hostname: "127.0.0.1".into(), + port: 8825, + envelope_from: "foo-chat@example.com".into(), + auth: SmtpAuth::None, + security: SmtpSecurity::None, + extensions: Default::default(), + } + } + + #[test] + fn test_smtp() { + stderrlog::new() + .quiet(false) + .verbosity(0) + .show_module_names(true) + .timestamp(stderrlog::Timestamp::Millisecond) + .init() + .unwrap(); + + let handler = MyHandler { + mails: Arc::new(Mutex::new(vec![])), + stored: Arc::new(Mutex::new(vec![])), + }; + let handler2 = handler.clone(); + let _smtp_handle = thread::spawn(move || { + let mut server = Server::new(handler2); + + server + .with_name("example.com") + .with_ssl(SslConfig::None) + .unwrap() + .with_addr(ADDRESS) + .unwrap(); + eprintln!("Running smtp server at {}", ADDRESS); + server.serve().expect("Could not run server"); + }); + + let smtp_server_conf = get_smtp_conf(); + let input_str = include_str!("../test_sample_longmessage.eml"); + match crate::Envelope::from_bytes(input_str.as_bytes(), None) { + Ok(_envelope) => {} + Err(err) => { + panic!("Could not parse message: {}", err); + } + } + let mut connection = + futures::executor::block_on(SmtpConnection::new_connection(smtp_server_conf)).unwrap(); + futures::executor::block_on(connection.mail_transaction( + input_str, + /*tos*/ + Some(&[ + Address::try_from("foo-chat@example.com").unwrap(), + Address::try_from("webmaster@example.com").unwrap(), + ]), + )) + .unwrap(); + assert_eq!(handler.stored.lock().unwrap().len(), 2); + } +} diff --git a/melib/test_sample_longmessage.eml b/melib/test_sample_longmessage.eml new file mode 100644 index 00000000..67fe3a26 --- /dev/null +++ b/melib/test_sample_longmessage.eml @@ -0,0 +1,65 @@ +Return-Path: <japoeunp@hotmail.com>
+Delivered-To: jonnny@miami-dice.co.uk
+Received: from violet.xenserver.co.uk
+ by violet.xenserver.co.uk with LMTP
+ id qBHcI7LKml9FxzIAYrQLqw
+ (envelope-from <japoeunp@hotmail.com>)
+ for <jonnny@miami-dice.co.uk>; Thu, 29 Oct 2020 13:59:14 +0000
+Return-path: <japoeunp@hotmail.com>
+Envelope-to: jonnny@miami-dice.co.uk
+Delivery-date: Thu, 29 Oct 2020 13:59:14 +0000
+Received: from mail-oln040092254105.outbound.protection.outlook.com ([40.92.254.105]:29481 helo=APC01-PU1-obe.outbound.protection.outlook.com)
+ by violet.xenserver.co.uk with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ (Exim 4.93)
+ (envelope-from <japoeunp@hotmail.com>)
+ id 1kY8SJ-00DxYw-WD
+ for jonnny@miami-dice.co.uk; Thu, 29 Oct 2020 13:59:14 +0000
+ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
+ b=KKU/kthPXLl8CnAmBXXsD1QQWr4evL4ymaLwgHgRi5eSnOe2d2sQxrhcZ1VvLSvW2DQEQoNAm6NUtTC5uRUnBDS0n+g1E5/t1z8oFbzdioCIT6rL77ta3MVcaQ/o+gRa6dIwiNfu8z5GxAujOOu57gCfnCw3/gLeOHH01KtP4ezEB/DvAU9bC8eyso1T7nv+HT0riTjZOywGwDHnVb1aIPPIUiOQrrEi+cfLQRiCer01d94U8Wp+FUECrVYbr4uZGl8mbTwU4oZL1rJ25ubYG54e1ktaPJRa2YEitgJEF5sS8Z503c3RjzzBvvHkc/Kl6ypXcovP9xxeoSrS7YIPKA==
+ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;
+ s=arcselector9901;
+ h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
+ bh=NUSuxgSF4fNUuTts93/OAIsK9q9w8XhbybHWH/oRmXo=;
+ b=VU2clBW8reAfnfCef0DeEDlBzcCU2u288YCjTvB0ekvBkJGSdI657WyS8KR7JSy0KcPWRfGbN9GJaETaasoa7bLdfuB6K9foup+vSqlA1witS5JQXQM/vJCKx67DbT8/8emLrKi7yDD2qjtRsb6HfvbwAGGvmPyUeyfTvRv6js+4YUbe5eN6CCdJEploBXDrWjFXHpSCwVCL1oF6rgrJf0+Td+ufX0QEHbOz2uJWj4yz0A8hK2yV+2JDVW7GiBwZMrO4yLNXYck/0HQRyYFe8I86xUBJWp/0IITCTe96x5L/H3lqmGkh4uRt8IsXT/2jBEm5CmXLxJZAMR8RONG9BQ==
+ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
+ dkim=none; arc=none
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hotmail.com;
+ s=selector1;
+ h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
+ bh=NUSuxgSF4fNUuTts93/OAIsK9q9w8XhbybHWH/oRmXo=;
+ b=JRkih9HxwazdzH6MSzSetJMcRwvDr+e97VnoDCQYJf9qQqgtQvzMZR0Z+d2Gu74Ip3ebcvx5oYlOpV15yVZAqUmUeirpF2rdkmMWQiaDQMq9SLiF09eMDkDfEdGLD4V+C36QIISRamgyagIsC72/UB6OyxpXoAjP0SFxbyItvWVgB9EVVsSJLOKXWgRWiYSZxMLye3OQUqdWoiQ9Tw/o8uywLTvcojOizZaS2SrYWajYScBmMiCh58dUarKzrfXmR/WisfBepCf1ia7BKttjalhuJBcMyKfM923X5IbZ+Yw+gVpLtzwGUyPt2cobOAxKna11whmpWdtoBeXRR/hKOg==
+Received: from PU1APC01FT013.eop-APC01.prod.protection.outlook.com
+ (2a01:111:e400:7ebe::45) by
+ PU1APC01HT068.eop-APC01.prod.protection.outlook.com (2a01:111:e400:7ebe::323)
+ with Microsoft SMTP Server (version=TLS1_2,
+ cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3520.15; Thu, 29 Oct
+ 2020 13:58:16 +0000
+Received: from PS1PR0601MB3675.apcprd06.prod.outlook.com
+ (2a01:111:e400:7ebe::44) by PU1APC01FT013.mail.protection.outlook.com
+ (2a01:111:e400:7ebe::78) with Microsoft SMTP Server (version=TLS1_2,
+ cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3520.15 via Frontend
+ Transport; Thu, 29 Oct 2020 13:58:16 +0000
+Received: from PS1PR0601MB3675.apcprd06.prod.outlook.com
+ ([fe80::65ed:e320:1c31:1695]) by PS1PR0601MB3675.apcprd06.prod.outlook.com
+ ([fe80::65ed:e320:1c31:1695%7]) with mapi id 15.20.3499.027; Thu, 29 Oct 2020
+ 13:58:16 +0000
+From: Jamaica Poe <japoeunp@hotmail.com>
+To: <foo-chat@example.com>
+Subject: thankful that I had the chance to written report, that I could learn
+ and let alone the chance $4454.32
+Thread-Topic: thankful that I had the chance to written report, that I could
+ learn and let alone the chance $4454.32
+Thread-Index: AQHWrfuHFQ6EC5DxDEG0hktDfP8BQg==
+Date: Thu, 29 Oct 2020 13:58:16 +0000
+Message-ID:
+ <PS1PR0601MB36750BD00EA89E1482FA98A2D5140@PS1PR0601MB3675.apcprd06.prod.outlook.com>
+Accept-Language: en-US
+Content-Language: en-US
+Content-Type: text/html
+Content-Transfer-Encoding: base64
+MIME-Version: 1.0
+
+PCFET0NUWVBFPjxodG1sPjxoZWFkPjx0aXRsZT5mb288L3RpdGxlPjwvaGVhZD48Ym9k
+eT48dGFibGUgY2xhc3M9ImZvbyI+PHRoZWFkPjx0cj48dGQ+Zm9vPC90ZD48L3RoZWFk
+Pjx0Ym9keT48dHI+PHRkPmZvbzE8L3RkPjwvdHI+PC90Ym9keT48L3RhYmxlPjwvYm9k
+eT48L2h0bWw+
|