Skip to main content

AsyncSmtpTransport

Struct AsyncSmtpTransport 

Source
pub struct AsyncSmtpTransport<E: Executor> { /* private fields */ }
Available on crate feature smtp-transport only.
Expand description

Asynchronously sends emails using the SMTP protocol

AsyncSmtpTransport is the primary way for communicating with SMTP relay servers to send email messages. It holds the client connect configuration and creates new connections as necessary.

§Connection pool

When the pool feature is enabled (default), AsyncSmtpTransport maintains a connection pool to manage SMTP connections. The pool:

  • Establishes a new connection when sending a message.
  • Recycles connections internally after a message is sent.
  • Reuses connections for subsequent messages, reducing connection setup overhead.

The connection pool can grow to hold multiple SMTP connections if multiple emails are sent concurrently, as SMTP does not support multiplexing within a single connection.

However, connection reuse is not possible if the SyncSmtpTransport instance is dropped after every email send operation. You must reuse the instance of this struct for the connection pool to be of any use.

To customize connection pool settings, use AsyncSmtpTransportBuilder::pool_config.

Implementations§

Source§

impl<E> AsyncSmtpTransport<E>
where E: Executor,

Source

pub fn relay(relay: &str) -> Result<AsyncSmtpTransportBuilder, Error>

Available on crate features async-std1-rustls or tokio1-native-tls or tokio1-rustls only.

Simple and secure transport, using TLS connections to communicate with the SMTP server

The right option for most SMTP servers.

Creates an encrypted transport over submissions port, using the provided domain to validate TLS certificates.

Source

pub fn starttls_relay(relay: &str) -> Result<AsyncSmtpTransportBuilder, Error>

Available on crate features async-std1-rustls or tokio1-native-tls or tokio1-rustls only.

Simple and secure transport, using STARTTLS to obtain encrypted connections

Alternative to AsyncSmtpTransport::relay, for SMTP servers that don’t take SMTPS connections.

Creates an encrypted transport over submissions port, by first connecting using an unencrypted connection and then upgrading it with STARTTLS. The provided domain is used to validate TLS certificates.

An error is returned if the connection can’t be upgraded. No credentials or emails will be sent to the server, protecting from downgrade attacks.

Source

pub fn unencrypted_localhost() -> AsyncSmtpTransport<E>

Creates a new local SMTP client to port 25

Shortcut for local unencrypted relay (typical local email daemon that will handle relaying)

Source

pub fn builder_dangerous<T: Into<String>>( server: T, ) -> AsyncSmtpTransportBuilder

Creates a new SMTP client

Defaults are:

  • No authentication
  • No TLS
  • A 60-seconds timeout for smtp commands
  • Port 25

Consider using AsyncSmtpTransport::relay or AsyncSmtpTransport::starttls_relay instead, if possible.

Source

pub fn from_url( connection_url: &str, ) -> Result<AsyncSmtpTransportBuilder, Error>

Available on crate features boring-tls or native-tls or rustls only.

Creates a AsyncSmtpTransportBuilder from a connection URL

The protocol, credentials, host, port and EHLO name can be provided in a single URL. This may be simpler than having to configure SMTP through multiple configuration parameters and then having to pass those options to lettre.

The URL is created in the following way: scheme://user:pass@hostname:port/ehlo-name?tls=TLS.

user (Username) and pass (Password) are optional in case the SMTP relay doesn’t require authentication. When port is not configured it is automatically determined based on the scheme. ehlo-name optionally overwrites the hostname sent for the EHLO command. TLS controls whether STARTTLS is simply enabled (opportunistic - not enough to prevent man-in-the-middle attacks) or required (require the server to upgrade the connection to STARTTLS, otherwise fail on suspicion of main-in-the-middle attempt).

Use the following table to construct your SMTP url:

schemetls query parameterexampledefault portremarks
smtpsunsetsmtps://user:pass@hostname:port465SMTP over TLS, recommended method
smtprequiredsmtp://user:pass@hostname:port?tls=required587SMTP with STARTTLS required, when SMTP over TLS is not available
smtpopportunisticsmtp://user:pass@hostname:port?tls=opportunistic587SMTP with optionally STARTTLS when supported by the server. Not suitable for production use: vulnerable to a man-in-the-middle attack
smtpunsetsmtp://user:pass@hostname:port587Always unencrypted SMTP. Not suitable for production use: sends all data unencrypted

IMPORTANT: some parameters like user and pass cannot simply be concatenated to construct the final URL because special characters contained within the parameter may confuse the URL decoder. Manually URL encode the parameters before concatenating them or use a proper URL encoder, like the following cargo script:

#!/usr/bin/env cargo

//! ```cargo
//! [dependencies]
//! url = "2"
//! ```

use url::Url;

fn main() {
    // don't touch this line
    let mut url = Url::parse("foo://bar").unwrap();

    // configure the scheme (`smtp` or `smtps`) here.
    url.set_scheme("smtps").unwrap();
    // configure the username and password.
    // remove the following two lines if unauthenticated.
    url.set_username("username").unwrap();
    url.set_password(Some("password")).unwrap();
    // configure the hostname
    url.set_host(Some("smtp.example.com")).unwrap();
    // configure the port - only necessary if using a non-default port
    url.set_port(Some(465)).unwrap();
    // configure the EHLO name
    url.set_path("ehlo-name");

    println!("{url}");
}

The connection URL can then be used in the following way:

use lettre::{
    AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor, message::header::ContentType,
    transport::smtp::authentication::Credentials,
};

let email = Message::builder()
    .from("NoBody <nobody@domain.tld>".parse().unwrap())
    .reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
    .to("Hei <hei@domain.tld>".parse().unwrap())
    .subject("Happy new year")
    .header(ContentType::TEXT_PLAIN)
    .body(String::from("Be happy!"))
    .unwrap();

// Open a remote connection to gmail
let mailer: AsyncSmtpTransport<Tokio1Executor> =
    AsyncSmtpTransport::<Tokio1Executor>::from_url(
        "smtps://username:password@smtp.example.com:465",
    )?
    .build();

// Send the email
mailer.send(email).await?;
Source

pub async fn test_connection(&self) -> Result<bool, Error>

Tests the SMTP connection

test_connection() tests the connection by using the SMTP NOOP command. The connection is closed afterward if a connection pool is not used.

Trait Implementations§

Source§

impl AsyncTransport for AsyncSmtpTransport<Tokio1Executor>

Source§

fn send_raw<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, envelope: &'life1 Envelope, email: &'life2 [u8], ) -> Pin<Box<dyn Future<Output = Result<Self::Ok, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Available on crate features async-std1 or tokio1 only.

Sends an email

Source§

type Ok = Response

Available on crate features async-std1 or tokio1 only.
Response produced by the Transport
Source§

type Error = Error

Available on crate features async-std1 or tokio1 only.
Error produced by the Transport
Source§

fn shutdown<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Available on crate features async-std1 or tokio1 only.
Shuts down the transport. Future calls to Self::send and Self::send_raw might fail.
Source§

fn send<'life0, 'async_trait>( &'life0 self, message: Message, ) -> Pin<Box<dyn Future<Output = Result<Self::Ok, Self::Error>> + Send + 'async_trait>>
where Self: Sync + 'async_trait, 'life0: 'async_trait,

Available on crate feature builder and (crate features async-std1 or tokio1) only.
Sends the email
Source§

impl AsyncTransport for AsyncSmtpTransport<AsyncStd1Executor>

Source§

fn send_raw<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, envelope: &'life1 Envelope, email: &'life2 [u8], ) -> Pin<Box<dyn Future<Output = Result<Self::Ok, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Available on crate features async-std1 or tokio1 only.

Sends an email

Source§

type Ok = Response

Available on crate features async-std1 or tokio1 only.
Response produced by the Transport
Source§

type Error = Error

Available on crate features async-std1 or tokio1 only.
Error produced by the Transport
Source§

fn shutdown<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Available on crate features async-std1 or tokio1 only.
Shuts down the transport. Future calls to Self::send and Self::send_raw might fail.
Source§

fn send<'life0, 'async_trait>( &'life0 self, message: Message, ) -> Pin<Box<dyn Future<Output = Result<Self::Ok, Self::Error>> + Send + 'async_trait>>
where Self: Sync + 'async_trait, 'life0: 'async_trait,

Available on crate feature builder and (crate features async-std1 or tokio1) only.
Sends the email
Source§

impl<E> Clone for AsyncSmtpTransport<E>
where E: Executor,

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<E: Executor> Debug for AsyncSmtpTransport<E>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more