Merge pull request #107 from amousset/stream-timeout
feat(transport-smtp): Add timeout suppor to SMTP transport
This commit is contained in:
@@ -7,9 +7,10 @@ use std::io;
|
|||||||
use std::io::{BufRead, Read, Write};
|
use std::io::{BufRead, Read, Write};
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
use std::time::Duration;
|
||||||
use transport::smtp::{CRLF, MESSAGE_ENDING};
|
use transport::smtp::{CRLF, MESSAGE_ENDING};
|
||||||
use transport::smtp::authentication::Mechanism;
|
use transport::smtp::authentication::Mechanism;
|
||||||
use transport::smtp::client::net::{Connector, NetworkStream};
|
use transport::smtp::client::net::{Connector, NetworkStream, Timeout};
|
||||||
use transport::smtp::error::{Error, SmtpResult};
|
use transport::smtp::error::{Error, SmtpResult};
|
||||||
use transport::smtp::response::ResponseParser;
|
use transport::smtp::response::ResponseParser;
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ impl<S: Write + Read> Client<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Connector + Write + Read + Debug> Client<S> {
|
impl<S: Connector + Timeout + Write + Read + Debug> Client<S> {
|
||||||
/// Closes the SMTP transaction if possible
|
/// Closes the SMTP transaction if possible
|
||||||
pub fn close(&mut self) {
|
pub fn close(&mut self) {
|
||||||
let _ = self.quit();
|
let _ = self.quit();
|
||||||
@@ -92,6 +93,18 @@ impl<S: Connector + Write + Read + Debug> Client<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set timeout
|
||||||
|
pub fn set_timeout(&mut self, duration: Option<Duration>) -> io::Result<()> {
|
||||||
|
match self.stream {
|
||||||
|
Some(ref mut stream) => {
|
||||||
|
try!(stream.get_mut().set_read_timeout(duration));
|
||||||
|
try!(stream.get_mut().set_read_timeout(duration));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Connects to the configured server
|
/// Connects to the configured server
|
||||||
pub fn connect<A: ToSocketAddrs>(&mut self,
|
pub fn connect<A: ToSocketAddrs>(&mut self,
|
||||||
addr: &A,
|
addr: &A,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use std::fmt::{Debug, Formatter};
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{ErrorKind, Read, Write};
|
use std::io::{ErrorKind, Read, Write};
|
||||||
use std::net::{SocketAddr, TcpStream};
|
use std::net::{SocketAddr, TcpStream};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
/// A trait for the concept of opening a stream
|
/// A trait for the concept of opening a stream
|
||||||
pub trait Connector: Sized {
|
pub trait Connector: Sized {
|
||||||
@@ -97,3 +98,28 @@ impl Write for NetworkStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A trait for read and write timeout support
|
||||||
|
pub trait Timeout: Sized {
|
||||||
|
/// Set read timeout for IO calls
|
||||||
|
fn set_read_timeout(&mut self, duration: Option<Duration>) -> io::Result<()>;
|
||||||
|
/// Set write timeout for IO calls
|
||||||
|
fn set_write_timeout(&mut self, duration: Option<Duration>) -> io::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Timeout for NetworkStream {
|
||||||
|
fn set_read_timeout(&mut self, duration: Option<Duration>) -> io::Result<()> {
|
||||||
|
match *self {
|
||||||
|
NetworkStream::Plain(ref mut stream) => stream.set_read_timeout(duration),
|
||||||
|
NetworkStream::Ssl(ref mut stream) => stream.get_mut().set_read_timeout(duration),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set write tiemout for IO calls
|
||||||
|
fn set_write_timeout(&mut self, duration: Option<Duration>) -> io::Result<()> {
|
||||||
|
match *self {
|
||||||
|
NetworkStream::Plain(ref mut stream) => stream.set_write_timeout(duration),
|
||||||
|
NetworkStream::Ssl(ref mut stream) => stream.get_mut().set_write_timeout(duration),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ use email::SendableEmail;
|
|||||||
use openssl::ssl::{SslContext, SslMethod};
|
use openssl::ssl::{SslContext, SslMethod};
|
||||||
use std::net::{SocketAddr, ToSocketAddrs};
|
use std::net::{SocketAddr, ToSocketAddrs};
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
use std::time::Duration;
|
||||||
use transport::EmailTransport;
|
use transport::EmailTransport;
|
||||||
use transport::smtp::authentication::Mechanism;
|
use transport::smtp::authentication::Mechanism;
|
||||||
use transport::smtp::client::Client;
|
use transport::smtp::client::Client;
|
||||||
@@ -85,6 +86,9 @@ pub struct SmtpTransportBuilder {
|
|||||||
smtp_utf8: bool,
|
smtp_utf8: bool,
|
||||||
/// Optional enforced authentication mechanism
|
/// Optional enforced authentication mechanism
|
||||||
authentication_mechanism: Option<Mechanism>,
|
authentication_mechanism: Option<Mechanism>,
|
||||||
|
/// Define network timeout
|
||||||
|
/// It can be changed later for specific needs (like a different timeout for each SMTP command)
|
||||||
|
timeout: Option<Duration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builder for the SMTP `SmtpTransport`
|
/// Builder for the SMTP `SmtpTransport`
|
||||||
@@ -105,6 +109,7 @@ impl SmtpTransportBuilder {
|
|||||||
connection_reuse: false,
|
connection_reuse: false,
|
||||||
hello_name: "localhost".to_string(),
|
hello_name: "localhost".to_string(),
|
||||||
authentication_mechanism: None,
|
authentication_mechanism: None,
|
||||||
|
timeout: Some(Duration::new(60, 0)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
None => Err(From::from("Could nor resolve hostname")),
|
None => Err(From::from("Could nor resolve hostname")),
|
||||||
@@ -183,6 +188,12 @@ impl SmtpTransportBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the timeout duration
|
||||||
|
pub fn timeout(mut self, timeout: Option<Duration>) -> SmtpTransportBuilder {
|
||||||
|
self.timeout = timeout;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Build the SMTP client
|
/// Build the SMTP client
|
||||||
///
|
///
|
||||||
/// It does not connect to the server, but only creates the `SmtpTransport`
|
/// It does not connect to the server, but only creates the `SmtpTransport`
|
||||||
@@ -297,6 +308,8 @@ impl EmailTransport<SmtpResult> for SmtpTransport {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
try!(self.client.set_timeout(self.client_info.timeout));
|
||||||
|
|
||||||
// Log the connection
|
// Log the connection
|
||||||
info!("connection established to {}", self.client_info.server_addr);
|
info!("connection established to {}", self.client_info.server_addr);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user