View Source smtp_server_example (gen_smtp v1.2.0)

A simple example callback module for 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.

Handle an extension to the MAIL verb. Return either {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

Link to this function

code_change(OldVsn, State, Extra)

View Source

Specs

code_change(OldVsn :: any(), State :: #state{}, Extra :: any()) -> {ok, #state{}}.
Link to this function

handle_AUTH(Type, Username, Password, State)

View Source

Specs

handle_AUTH(Type :: login | plain | 'cram-md5',
            Username :: binary(),
            Password :: binary() | {binary(), binary()},
            #state{}) ->
               {ok, #state{}} | error.
Link to this function

handle_DATA(From, To, Data, State)

View Source

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).

According to the SMTP specification the, responsibility of delivering an email must be taken seriously and the servers MUST NOT loose the message.
Link to this function

handle_EHLO(Hostname, Extensions, State)

View Source

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.
Link to this function

handle_HELO(Hostname, State)

View Source

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.
Link to this function

handle_MAIL(From, State)

View Source

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.

Return values are either {ok, State} or {error, Message, State} as before.
Link to this function

handle_MAIL_extension(Extension, State)

View Source

Specs

handle_MAIL_extension(Extension :: binary(), State :: #state{}) -> {ok, #state{}} | error.
Handle an extension to the MAIL verb. Return either {ok, State} or error to reject the option.

Specs

handle_RCPT(To :: binary(), State :: #state{}) -> {ok, #state{}} | {error, string(), #state{}}.
Link to this function

handle_RCPT_extension(Extension, State)

View Source

Specs

handle_RCPT_extension(Extension :: binary(), State :: #state{}) -> {ok, #state{}} | error.

Specs

handle_RSET(State :: #state{}) -> #state{}.

Specs

handle_STARTTLS(#state{}) -> #state{}.
Link to this function

handle_VRFY(Address, State)

View Source

Specs

handle_VRFY(Address :: binary(), State :: #state{}) ->
               {ok, string(), #state{}} | {error, string(), #state{}}.
Link to this function

handle_error(Class, Details, State)

View Source

Specs

handle_error(gen_smtp_server_session:error_class(), any(), #state{}) ->
                {ok, State} | {stop, any(), State}.
Link to this function

handle_info(Info, State)

View Source

Specs

handle_info(Info :: term(), State :: term()) ->
               {noreply, NewState :: term()} |
               {noreply, NewState :: term(), timeout() | hibernate} |
               {stop, Reason :: term(), NewState :: term()}.
Link to this function

handle_other(Verb, Args, State)

View Source

Specs

handle_other(Verb :: binary(), Args :: binary(), #state{}) -> {string(), #state{}}.
Link to this function

init(Hostname, SessionCount, Address, Options)

View Source

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.

If you want to continue the session, return {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.
Link to this function

terminate(Reason, State)

View Source

Specs

terminate(Reason :: any(), State :: #state{}) -> {ok, any(), #state{}}.