feat(transport): Allow sending raw emails (fixes #409)

This commit is contained in:
Alexis Mousset
2020-04-25 11:16:56 +02:00
parent 8f31fb9804
commit 8b1399261f
5 changed files with 29 additions and 52 deletions

View File

@@ -118,17 +118,16 @@ pub trait Transport<'a, B> {
/// Sends the email
/// FIXME not mut
fn send(&mut self, email: Message<B>) -> Self::Result
where
B: Display;
/*
{
&mut self,
Box::new(Cursor::new(email.to_string().as_bytes())),
email.envelope(),
Uuid::new_v4().to_string(),
}*/
// email = message (bytes) + envelope
fn send(&mut self, message: Message<B>) -> Self::Result
where
B: Display,
{
self.send_raw(message.envelope(), message.to_string().as_bytes())
}
fn send_raw(&mut self, envelope: &Envelope, email: &[u8]) -> Self::Result;
// TODO allow sending generic data
}

View File

@@ -3,9 +3,8 @@
//! It can be useful for testing purposes, or if you want to keep track of sent messages.
//!
use crate::{transport::file::error::FileResult, Envelope, Message, Transport};
use crate::{transport::file::error::FileResult, Envelope, Transport};
use std::{
fmt::Display,
fs::File,
io::prelude::*,
path::{Path, PathBuf},
@@ -40,18 +39,15 @@ struct SerializableEmail {
impl<'a, B> Transport<'a, B> for FileTransport {
type Result = FileResult;
fn send(&mut self, email: Message<B>) -> Self::Result
where
B: Display,
{
fn send_raw(&mut self, envelope: &Envelope, email: &[u8]) -> Self::Result {
let email_id = Uuid::new_v4();
let mut file = self.path.clone();
file.push(format!("{}.json", email_id));
let serialized = serde_json::to_string(&SerializableEmail {
envelope: email.envelope().clone(),
message: email.to_string().into_bytes(),
envelope: envelope.clone(),
message: email.to_vec(),
})?;
File::create(file.as_path())?.write_all(serialized.as_bytes())?;

View File

@@ -1,11 +1,11 @@
//! The sendmail transport sends the email using the local sendmail command.
//!
use crate::{transport::sendmail::error::SendmailResult, Message, Transport};
use crate::Envelope;
use crate::{transport::sendmail::error::SendmailResult, Transport};
use log::info;
use std::{
convert::AsRef,
fmt::Display,
io::prelude::*,
process::{Command, Stdio},
};
@@ -39,33 +39,20 @@ impl SendmailTransport {
impl<'a, B> Transport<'a, B> for SendmailTransport {
type Result = SendmailResult;
fn send(&mut self, email: Message<B>) -> Self::Result
where
B: Display,
{
fn send_raw(&mut self, envelope: &Envelope, email: &[u8]) -> Self::Result {
let email_id = Uuid::new_v4();
// Spawn the sendmail command
let mut process = Command::new(&self.command)
.arg("-i")
.arg("-f")
.arg(
email
.envelope()
.from()
.map(|f| f.as_ref())
.unwrap_or("\"\""),
)
.args(email.envelope().to())
.arg(envelope.from().map(|f| f.as_ref()).unwrap_or("\"\""))
.args(envelope.to())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
process
.stdin
.as_mut()
.unwrap()
.write_all(email.to_string().as_bytes())?;
process.stdin.as_mut().unwrap().write_all(email)?;
info!("Wrote {} message to stdin", email_id);

View File

@@ -13,6 +13,7 @@
//! * SMTPUTF8 ([RFC 6531](http://tools.ietf.org/html/rfc6531))
//!
use crate::Envelope;
use crate::{
transport::smtp::{
authentication::{
@@ -23,7 +24,7 @@ use crate::{
error::{Error, SmtpResult},
extension::{ClientId, Extension, MailBodyParameter, MailParameter, ServerInfo},
},
Message, Transport,
Transport,
};
use log::{debug, info};
#[cfg(feature = "native-tls")]
@@ -31,7 +32,6 @@ use native_tls::{Protocol, TlsConnector};
#[cfg(feature = "rustls")]
use rustls::ClientConfig;
use std::{
fmt::Display,
net::{SocketAddr, ToSocketAddrs},
time::Duration,
};
@@ -445,12 +445,9 @@ impl<'a, B> Transport<'a, B> for SmtpTransport {
feature = "cargo-clippy",
allow(clippy::match_same_arms, clippy::cyclomatic_complexity)
)]
fn send(&mut self, email: Message<B>) -> Self::Result
where
B: Display,
{
fn send_raw(&mut self, envelope: &Envelope, email: &[u8]) -> Self::Result {
let email_id = Uuid::new_v4();
let envelope = email.envelope();
let envelope = envelope;
if !self.client.is_connected() {
self.connect()?;
@@ -509,7 +506,7 @@ impl<'a, B> Transport<'a, B> for SmtpTransport {
try_smtp!(self.client.command(DataCommand), self);
// Message content
let result = self.client.message(email.to_string().as_bytes());
let result = self.client.message(email);
if let Ok(ref result) = result {
// Increment the connection reuse counter

View File

@@ -2,7 +2,8 @@
//! testing purposes.
//!
use crate::{Message, Transport};
use crate::Envelope;
use crate::Transport;
use log::info;
use std::fmt::Display;
@@ -33,17 +34,14 @@ where
{
type Result = StubResult;
fn send(&mut self, email: Message<B>) -> Self::Result
where
B: Display,
{
fn send_raw(&mut self, envelope: &Envelope, _email: &[u8]) -> Self::Result {
info!(
"from=<{}> to=<{:?}>",
match email.envelope().from() {
match envelope.from() {
Some(address) => address.to_string(),
None => "".to_string(),
},
email.envelope().to()
envelope.to()
);
self.response
}