View Source smtp_server_example (gen_smtp v1.2.0)
gen_smtp_server_session
that also serves as documentation for the required callback API.
Link to this section Summary
Functions
Handle the DATA verb from the client, which corresponds to the body of the message. After receiving the body, a SMTP server can put the email in a queue for later delivering while a LMTP server can handle the delivery directly (LMTP servers are supposed to be simpler and handle emails to local users directly without the need for a queue). Relaying the email to another server is also an option.
Handle the EHLO verb from the client. As with EHLO the hostname is provided as an argument, but in addition to that the list of ESMTP Extensions enabled in the session is passed. This list of extensions can be modified by the callback module to add/remove extensions.
Handle the HELO verb from the client. Arguments are the Hostname sent by the client as part of the HELO and the callback State.
Handle the MAIL FROM verb. The From argument is the email address specified by the MAIL FROM command. Extensions to the MAIL verb are handled by the handle_MAIL_extension
function.
{ok, State}
or error
to reject the option.Initialize the callback module's state for a new session. The arguments to the function are the SMTP server's hostname (for use in the SMTP banner), The number of current sessions (eg. so you can do session limiting), the IP address of the connecting client, and a freeform list of options for the module. The Options are extracted from the callbackoptions
parameter passed into the gen_smtp_server_session
when it was started.
Link to this section Types
Specs
error_message() :: {error, string(), #state{}}.
Link to this section Functions
Specs
code_change(OldVsn :: any(), State :: #state{}, Extra :: any()) -> {ok, #state{}}.
Specs
handle_AUTH(Type :: login | plain | 'cram-md5', Username :: binary(), Password :: binary() | {binary(), binary()}, #state{}) -> {ok, #state{}} | error.
Specs
handle_DATA(From :: binary(), To :: [binary(), ...], Data :: binary(), State :: #state{}) -> {ok | error, string(), #state{}} | {multiple, [{ok | error, string()}], #state{}}.
Handle the DATA verb from the client, which corresponds to the body of the message. After receiving the body, a SMTP server can put the email in a queue for later delivering while a LMTP server can handle the delivery directly (LMTP servers are supposed to be simpler and handle emails to local users directly without the need for a queue). Relaying the email to another server is also an option.
When using the SMTP protocol, handle_DATA
should return a single "aggregate" delivery status in the form of a {ok, SuccessMsg, State}
tuple or {error, ErrorMsg, State}
. At this point, if ok
is returned, we have accepted the full responsibility of delivering the email.
When using the LMTP protocol, handle_DATA
should return a status for each accepted address in handle_RCPT
in the form of a {multiple, StatusList, State}
tuple where StatusList
is a list of {ok, SuccessMsg}
or {error, ErrorMsg}
tuples (the statuses should be presented in the same order as the recipient addresses were accepted). For each ok
in the StatusList
, we have accepted full responsibility for delivering the email to that specific recipient. When a single recipient is specified the returned value can also follow the SMTP format.
ErrorMsg
should always start with the SMTP error code, while SuccessMsg
should not (the 250
code is automatically prepended).
Specs
handle_EHLO(Hostname :: binary(), Extensions :: list(), State :: #state{}) -> {ok, list(), #state{}} | error_message().
Handle the EHLO verb from the client. As with EHLO the hostname is provided as an argument, but in addition to that the list of ESMTP Extensions enabled in the session is passed. This list of extensions can be modified by the callback module to add/remove extensions.
The return values are{ok, Extensions, State}
where Extensions is the new list of extensions to use for this session or {error, Message, State}
where Message is the reject message as with handle_HELO.
Specs
handle_HELO(Hostname :: binary(), State :: #state{}) -> {ok, pos_integer(), #state{}} | {ok, #state{}} | error_message().
Handle the HELO verb from the client. Arguments are the Hostname sent by the client as part of the HELO and the callback State.
Return values are{ok, State}
to simply continue with a new state, {ok, MessageSize, State}
to continue with the SMTP session but to impose a maximum message size (which you can determine , for example, by looking at the IP address passed in to the init function) and the new callback state. You can reject the HELO by returning {error, Message, State}
and the Message will be sent back to the client. The reject message MUST contain the SMTP status code, eg. 554.
Specs
handle_MAIL(From :: binary(), State :: #state{}) -> {ok, #state{}} | error_message().
Handle the MAIL FROM verb. The From argument is the email address specified by the MAIL FROM command. Extensions to the MAIL verb are handled by the handle_MAIL_extension
function.
{ok, State}
or {error, Message, State}
as before.
Specs
handle_MAIL_extension(Extension :: binary(), State :: #state{}) -> {ok, #state{}} | error.
{ok, State}
or error
to reject the option.
Specs
handle_RCPT(To :: binary(), State :: #state{}) -> {ok, #state{}} | {error, string(), #state{}}.
Specs
handle_RCPT_extension(Extension :: binary(), State :: #state{}) -> {ok, #state{}} | error.
Specs
handle_RSET(State :: #state{}) -> #state{}.
Specs
handle_STARTTLS(#state{}) -> #state{}.
Specs
handle_VRFY(Address :: binary(), State :: #state{}) -> {ok, string(), #state{}} | {error, string(), #state{}}.
Specs
handle_error(gen_smtp_server_session:error_class(), any(), #state{}) -> {ok, State} | {stop, any(), State}.
Specs
handle_info(Info :: term(), State :: term()) -> {noreply, NewState :: term()} | {noreply, NewState :: term(), timeout() | hibernate} | {stop, Reason :: term(), NewState :: term()}.
Specs
handle_other(Verb :: binary(), Args :: binary(), #state{}) -> {string(), #state{}}.
Specs
init(Hostname :: inet:hostname(), SessionCount :: non_neg_integer(), Address :: inet:ip_address(), Options :: list()) -> {ok, iodata(), #state{}} | {stop, any(), iodata()}.
Initialize the callback module's state for a new session. The arguments to the function are the SMTP server's hostname (for use in the SMTP banner), The number of current sessions (eg. so you can do session limiting), the IP address of the connecting client, and a freeform list of options for the module. The Options are extracted from the callbackoptions
parameter passed into the gen_smtp_server_session
when it was started.
{ok, Banner, State}
where Banner is the SMTP banner to send to the client and State is the callback module's state. The State will be passed to ALL subsequent calls to the callback module, so it can be used to keep track of the SMTP session. You can also return {stop, Reason, Message}
where the session will exit with Reason and send Message to the client.
Specs
terminate(Reason :: any(), State :: #state{}) -> {ok, any(), #state{}}.