Parses SMTP command lines (RFC 5321 §4.1).
The line is given without its CRLF. Verbs and parameter keywords are case-insensitive. Only printable ASCII is accepted. Verbs map to atoms from a fixed table; parameter keywords stay strings, upper-cased.
iex> Sovite.SMTP.Command.parse("MAIL FROM:<a@example.com> SIZE=1024")
{:ok, {:mail, "a@example.com", [{"SIZE", "1024"}]}}
iex> Sovite.SMTP.Command.parse("RCPT TO:<@relay.example:b@example.net>")
{:ok, {:rcpt, "b@example.net", []}}
iex> Sovite.SMTP.Command.parse("rcpt to:<Postmaster>")
{:ok, {:rcpt, "Postmaster", []}}Paths must be in angle brackets. Whitespace after FROM: and TO: is
tolerated, since common clients send it. Source routes are accepted and
ignored (RFC 5321 §4.1.1.3 and Appendix C). The mailbox is checked with
Sovite.Validators.split_mailbox/1.
Summary
Functions
Parses one command line. Returns the verb, if known, with errors.
Types
@type error() ::
:unrecognized
| :not_implemented
| :non_smtp
| :invalid_characters
| :syntax
| :invalid_sender
| :invalid_recipient
| :invalid_parameter
Why a line did not parse:
:unrecognized- unknown verb:not_implemented- a known SMTP verb this server does not support:non_smtp- an HTTP request line, as in cross-protocol attacks:invalid_characters- control or non-ASCII characters:syntax- wrong arguments for the verb:invalid_sender/:invalid_recipient- bad path or mailbox:invalid_parameter- malformedKEYWORD=valueparameter
@type t() :: {:ehlo, String.t()} | {:helo, String.t()} | {:lhlo, String.t()} | {:mail, String.t(), params()} | {:rcpt, String.t(), params()} | :data | :rset | :quit | {:noop, String.t()} | {:vrfy, String.t()} | {:help, String.t()} | :starttls | {:auth, mechanism :: String.t(), initial_response :: String.t() | nil}