feat(transport): Allow sending raw emails (fixes #409)
This commit is contained in:
19
src/lib.rs
19
src/lib.rs
@@ -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
|
||||
}
|
||||
|
||||
@@ -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())?;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user