From 3403368e71ec846091e55f713af5ba49481d92a3 Mon Sep 17 00:00:00 2001 From: Mauro D Date: Sat, 24 Dec 2022 16:57:50 +0000 Subject: [PATCH] LineReceiver implementation. --- src/lib.rs | 1 + src/request/receiver.rs | 32 +++++++++++++++++++++++++++++++- src/response/generate.rs | 1 + src/response/mod.rs | 2 ++ src/response/parser.rs | 3 +++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index a55eb58..62b8e05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -192,6 +192,7 @@ pub const EXT_SMTP_UTF8: u32 = 1 << 23; pub const EXT_START_TLS: u32 = 1 << 24; pub const EXT_VERB: u32 = 1 << 25; pub const EXT_EXPN: u32 = 1 << 26; +pub const EXT_VRFY: u32 = 1 << 27; #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] pub enum MtPriority { diff --git a/src/request/receiver.rs b/src/request/receiver.rs index 1722f0d..7d0234d 100644 --- a/src/request/receiver.rs +++ b/src/request/receiver.rs @@ -2,7 +2,7 @@ use std::slice::Iter; use crate::{Error, Request}; -const MAX_LINE_LENGTH: usize = 2048; +pub const MAX_LINE_LENGTH: usize = 2048; #[derive(Default)] pub struct RequestReceiver { @@ -31,6 +31,12 @@ pub struct DummyDataReceiver { #[derive(Default)] pub struct DummyLineReceiver {} +#[derive(Default)] +pub struct LineReceiver { + pub buf: Vec, + pub state: T, +} + impl RequestReceiver { pub fn ingest( &mut self, @@ -180,6 +186,30 @@ impl DummyDataReceiver { } } +impl LineReceiver { + pub fn new(state: T) -> Self { + Self { + buf: Vec::with_capacity(32), + state, + } + } + + pub fn ingest(&mut self, bytes: &mut Iter<'_, u8>) -> bool { + for &ch in bytes { + match ch { + b'\n' => return true, + b'\r' => (), + _ => { + if self.buf.len() < MAX_LINE_LENGTH { + self.buf.push(ch); + } + } + } + } + false + } +} + impl DummyLineReceiver { pub fn ingest(&mut self, bytes: &mut Iter<'_, u8>) -> bool { for &ch in bytes { diff --git a/src/response/generate.rs b/src/response/generate.rs index 48de3de..97daa0d 100644 --- a/src/response/generate.rs +++ b/src/response/generate.rs @@ -60,6 +60,7 @@ impl EhloResponse { EXT_ENHANCED_STATUS_CODES => write!(writer, "ENHANCEDSTATUSCODES\r\n"), EXT_ETRN => write!(writer, "ETRN\r\n"), EXT_EXPN => write!(writer, "EXPN\r\n"), + EXT_VRFY => write!(writer, "VRFY\r\n"), EXT_FUTURE_RELEASE => write!( writer, "FUTURERELEASE {} {}\r\n", diff --git a/src/response/mod.rs b/src/response/mod.rs index 4fdb351..b07ad15 100644 --- a/src/response/mod.rs +++ b/src/response/mod.rs @@ -90,6 +90,8 @@ pub(crate) const ETRN: u128 = (b'E' as u128) | (b'T' as u128) << 8 | (b'R' as u128) << 16 | (b'N' as u128) << 24; pub(crate) const EXPN: u128 = (b'E' as u128) | (b'X' as u128) << 8 | (b'P' as u128) << 16 | (b'N' as u128) << 24; +pub(crate) const VRFY: u128 = + (b'V' as u128) | (b'R' as u128) << 8 | (b'F' as u128) << 16 | (b'Y' as u128) << 24; pub(crate) const FUTURERELEASE: u128 = (b'F' as u128) | (b'U' as u128) << 8 | (b'T' as u128) << 16 diff --git a/src/response/parser.rs b/src/response/parser.rs index d04a4b6..4168747 100644 --- a/src/response/parser.rs +++ b/src/response/parser.rs @@ -201,6 +201,7 @@ impl EhloResponse { } ETRN => EXT_ETRN, EXPN => EXT_EXPN, + VRFY => EXT_VRFY, FUTURERELEASE => { let max_interval = if parser.stop_char != LF { parser.size()? @@ -327,6 +328,7 @@ mod tests { "250-ENHANCEDSTATUSCODES\n", "250-ETRN\n", "250-EXPN\n", + "250-VRFY\n", "250-FUTURERELEASE 1234 5678\n", "250-HELP\n", "250-MT-PRIORITY\n", @@ -355,6 +357,7 @@ mod tests { | EXT_ENHANCED_STATUS_CODES | EXT_ETRN | EXT_EXPN + | EXT_VRFY | EXT_FUTURE_RELEASE | EXT_HELP | EXT_MT_PRIORITY