Sovite.SMTP.Command (sovite v0.2.0)

Copy Markdown View Source

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

Types

Why a line did not parse

t()

Functions

Parses one command line. Returns the verb, if known, with errors.

Types

error()

@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 - malformed KEYWORD=value parameter

params()

@type params() :: [{String.t(), String.t() | nil}]

t()

@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}

Functions

parse(line)

@spec parse(binary()) :: {:ok, t()} | {:error, atom() | nil, error()}

Parses one command line. Returns the verb, if known, with errors.