Trait smtp_server::Config
source · [−]pub trait Config: Send + Sync {
type Protocol: for<'resp> Protocol<'resp>;
type ConnectionUserMeta: Send;
type MailUserMeta: Send;
Show 32 methods
fn hostname(
&self,
conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
) -> &str;
fn tls_accept<'life0, 'life1, 'async_trait, IO>(
&'life0 self,
io: IO,
conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Result<Duplex<Pin<Box<dyn Send + AsyncRead>>, Pin<Box<dyn Send + AsyncWrite>>>>> + Send + 'async_trait>>
where
IO: 'static + Unpin + Send + AsyncRead + AsyncWrite,
IO: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn new_mail<'life0, 'life1, 'async_trait>(
&'life0 self,
conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Self::MailUserMeta> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn filter_from<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
from: Option<Email>,
meta: &'life1 mut MailMetadata<Self::MailUserMeta>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<Option<Email>>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
fn filter_to<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
to: Email,
meta: &'life1 mut MailMetadata<Self::MailUserMeta>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<Email>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
fn handle_mail<'resp, 'life0, 'life1, 'async_trait, R>(
&'resp self,
stream: &'life0 mut EscapedDataReader<'life1, R>,
meta: MailMetadata<Self::MailUserMeta>,
conn_meta: &'resp mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = <Self::Protocol as Protocol<'resp>>::HandleMailReturnType> + Send + 'async_trait>>
where
R: Send + Unpin + AsyncRead,
Self: 'resp,
'resp: 'async_trait,
R: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn welcome_banner(
&self,
conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
) -> &str { ... }
fn welcome_banner_reply(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn hello_banner(
&self,
conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
) -> &str { ... }
fn filter_hello<'life0, 'life1, 'async_trait>(
&'life0 self,
is_extended: bool,
hostname: Hostname,
conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<HelloInfo>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
{ ... }
fn can_do_tls(
&self,
conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
) -> bool { ... }
fn filter_data<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
meta: &'life1 mut MailMetadata<Self::MailUserMeta>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
{ ... }
fn handle_rset<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
meta: &'life1 mut Option<MailMetadata<Self::MailUserMeta>>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
{ ... }
fn handle_starttls<'life0, 'life1, 'async_trait>(
&'life0 self,
conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
{ ... }
fn handle_expn<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
name: MaybeUtf8<&'life1 str>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
{ ... }
fn handle_vrfy<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
name: MaybeUtf8<&'life1 str>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
{ ... }
fn handle_help<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
subject: MaybeUtf8<&'life1 str>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
{ ... }
fn handle_noop<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
string: MaybeUtf8<&'life1 str>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
{ ... }
fn handle_quit<'life0, 'life1, 'async_trait>(
&'life0 self,
conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
{ ... }
fn already_did_hello(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn mail_before_hello(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn already_in_mail(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn rcpt_before_mail(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn data_before_rcpt(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn data_before_mail(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn starttls_unsupported(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn command_unrecognized(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn pipeline_forbidden_after_starttls(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn line_too_long(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn handle_mail_did_not_call_complete(
&self,
conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Reply { ... }
fn reply_write_timeout(&self) -> Duration { ... }
fn command_read_timeout(&self) -> Duration { ... }
}
Associated Types
type ConnectionUserMeta: Send
type MailUserMeta: Send
Required methods
fn hostname(
&self,
conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
) -> &str
fn hostname(
&self,
conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
) -> &str
Note: this function is only ever used for the default implementations of
other functions in this trait. As such, it is OK to leave it
unimplemented!()
if other functions are implemented.
fn tls_accept<'life0, 'life1, 'async_trait, IO>(
&'life0 self,
io: IO,
conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Result<Duplex<Pin<Box<dyn Send + AsyncRead>>, Pin<Box<dyn Send + AsyncWrite>>>>> + Send + 'async_trait>> where
IO: 'static + Unpin + Send + AsyncRead + AsyncWrite,
IO: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn tls_accept<'life0, 'life1, 'async_trait, IO>(
&'life0 self,
io: IO,
conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Result<Duplex<Pin<Box<dyn Send + AsyncRead>>, Pin<Box<dyn Send + AsyncWrite>>>>> + Send + 'async_trait>> where
IO: 'static + Unpin + Send + AsyncRead + AsyncWrite,
IO: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Note: if you don’t want to implement TLS, you should override
can_do_tls
to return false
so that STARTTLS is not advertized. This
being said, returning an error here should have the same result in
practice, except clients will try STARTTLS and fail
fn new_mail<'life0, 'life1, 'async_trait>(
&'life0 self,
conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Self::MailUserMeta> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn filter_from<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
from: Option<Email>,
meta: &'life1 mut MailMetadata<Self::MailUserMeta>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<Option<Email>>> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn filter_to<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
to: Email,
meta: &'life1 mut MailMetadata<Self::MailUserMeta>,
conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = Decision<Email>> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn handle_mail<'resp, 'life0, 'life1, 'async_trait, R>(
&'resp self,
stream: &'life0 mut EscapedDataReader<'life1, R>,
meta: MailMetadata<Self::MailUserMeta>,
conn_meta: &'resp mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = <Self::Protocol as Protocol<'resp>>::HandleMailReturnType> + Send + 'async_trait>> where
R: Send + Unpin + AsyncRead,
Self: 'resp,
'resp: 'async_trait,
R: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn handle_mail<'resp, 'life0, 'life1, 'async_trait, R>(
&'resp self,
stream: &'life0 mut EscapedDataReader<'life1, R>,
meta: MailMetadata<Self::MailUserMeta>,
conn_meta: &'resp mut ConnectionMetadata<Self::ConnectionUserMeta>
) -> Pin<Box<dyn Future<Output = <Self::Protocol as Protocol<'resp>>::HandleMailReturnType> + Send + 'async_trait>> where
R: Send + Unpin + AsyncRead,
Self: 'resp,
'resp: 'async_trait,
R: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
handle_mail
is an async function that returns either a single decision
in the case of the SMTP protocol, or an async stream of decisions in the
case of the LMTP protocol.
For LMTP: there must be one such decision for each RCPT TO command that succeeded (i.e. for each accepted recipient), which allows to indicate that the message could be stored in the mailbox of some users, but not in that of other users. This can happen for instance if their mail quota is used up. The lifetimes of the borrow on the mail’s data stream is limited to the duration of the async call; this reference may not be retained by the returned stream. The async function must consume the entire data stream before returning its stream of responses. The recommended implementation of this function would start by reading the message’s content to a temporary file, and then produce a stream that writes the message to all of the mailboxes one after the other.
Note: the EscapedDataReader has an inner buffer size of
RDBUF_SIZE
, which means that reads should not happen
with more than this buffer size.
Also, note that there is no timeout applied here, so the implementation of this function is responsible for making sure that the client does not just stop sending anything to DOS the system.
Provided methods
Note: this function is only ever used for the default implementations of
other functions in this trait. As such, it is OK to leave it
unimplemented!()
if other functions are implemented.
Note: this function is only ever used for the default implementations of
other functions in this trait. As such, it is OK to leave it
unimplemented!()
if other functions are implemented.