From 39d0ecdeaf078dce5cdb59cba95ab9e02bce11ee Mon Sep 17 00:00:00 2001 From: Kai Ren Date: Thu, 7 Jan 2021 15:30:50 +0200 Subject: [PATCH] fix: Check deliverability using successful response code instead of message parsing (#822) * Check deliverability using successful response code instead of message parsing * Mention no 3xx response codes in comment --- core/src/smtp/mod.rs | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/core/src/smtp/mod.rs b/core/src/smtp/mod.rs index 9a358448b..de01dccba 100644 --- a/core/src/smtp/mod.rs +++ b/core/src/smtp/mod.rs @@ -198,26 +198,24 @@ async fn email_deliverable( .command(RcptCommand::new(to_email.clone(), vec![])) .await { - Ok(response) => match response.first_line() { - Some(message) => { - let message = message.to_lowercase(); - let is_deliverable = message.contains("2.1.5") || - // 250 Recipient address accepted - // 250 Accepted - message.contains("accepted")|| - // 250 OK - // 250 Recipient OK - message.contains("ok"); - Ok(Deliverability { - has_full_inbox: false, - is_deliverable, - is_disabled: false, - }) - } - None => Err(SmtpError::SmtpError(AsyncSmtpError::Client( - "No response on RCPT command", - ))), - }, + Ok(_) => { + // According to RFC 5321, `RCPT TO` command succeeds with 250 and + // 251 codes only (no 3xx codes at all): + // https://tools.ietf.org/html/rfc5321#page-56 + // + // Where the 251 code is used for forwarding, which is not our case, + // because we always deliver to the SMTP server hosting the address + // itself. + // + // So, if `response.is_positive()` (which is a condition for + // returning `Ok` from the `command()` method above), then delivery + // succeeds, accordingly to RFC 5321. + Ok(Deliverability { + has_full_inbox: false, + is_deliverable: true, // response.is_positive() + is_disabled: false, + }) + } Err(err) => { // We cast to lowercase, because our matched strings below are all // lowercase.