Sovite.SMTP.Reply (sovite v0.2.0)

Copy Markdown View Source

An SMTP reply: a code, an optional enhanced status code (RFC 3463), and one or more text lines.

iex> Sovite.SMTP.Reply.new(250, "2.1.0", "Ok") |> Sovite.SMTP.Reply.encode() |> IO.iodata_to_binary()
"250 2.1.0 Ok\r\n"

Summary

Types

Why decode/2 rejected a reply.

t()

Functions

Decodes one reply from the start of buffer, as received from a server.

Encodes a reply for the wire. The enhanced code, when present, starts every line (RFC 2034 §4).

Returns true for 4xx and 5xx replies.

Builds a reply. text is a string or a list of lines. CR and LF in the text are replaced with spaces, so text can never end a reply early.

Returns true for 2xx and 3xx replies.

Returns the enhanced status code, or a generic one for the reply class ("2.0.0", "4.0.0", "5.0.0") when the reply has none.

Returns the reply as a single line of text, for logs.

Types

decode_error()

@type decode_error() :: :line_too_long | :too_many_lines | :malformed

Why decode/2 rejected a reply.

t()

@type t() :: %Sovite.SMTP.Reply{
  code: 200..599,
  enhanced: String.t() | nil,
  lines: [String.t(), ...]
}

Functions

decode(buffer, opts \\ [])

@spec decode(binary(), keyword()) ::
  {:ok, t(), binary()} | :more | {:error, decode_error()}

Decodes one reply from the start of buffer, as received from a server.

  • {:ok, reply, rest} - a complete reply and the bytes after it.
  • :more - the reply is not complete yet.
  • {:error, reason} - not a valid reply, or over a limit.

Lines end in CRLF; a bare LF is tolerated. Every line must have the same code. When the first line starts with an enhanced status code of the same class (RFC 2034), it is moved to enhanced and stripped from every line that carries it.

Options

  • :max_line_length - bytes per line, including the line ending. Defaults to 2048 (RFC 5321 §4.5.3.1.5 allows 512).

  • :max_lines - lines per reply. Defaults to 100.

    iex> Sovite.SMTP.Reply.decode("250-mx.example\r\n250 SIZE 100\r\nrest") {:ok, %Sovite.SMTP.Reply{code: 250, enhanced: nil, lines: ["mx.example", "SIZE 100"]}, "rest"} iex> Sovite.SMTP.Reply.decode("550 5.1.1 Unknown user\r\n") {:ok, %Sovite.SMTP.Reply{code: 550, enhanced: "5.1.1", lines: ["Unknown user"]}, ""}

encode(reply)

@spec encode(t()) :: iodata()

Encodes a reply for the wire. The enhanced code, when present, starts every line (RFC 2034 §4).

negative?(reply)

@spec negative?(t()) :: boolean()

Returns true for 4xx and 5xx replies.

new(code, enhanced \\ nil, text)

@spec new(200..599, String.t() | nil, String.t() | [String.t()]) :: t()

Builds a reply. text is a string or a list of lines. CR and LF in the text are replaced with spaces, so text can never end a reply early.

positive?(reply)

@spec positive?(t()) :: boolean()

Returns true for 2xx and 3xx replies.

status(reply)

@spec status(t()) :: String.t()

Returns the enhanced status code, or a generic one for the reply class ("2.0.0", "4.0.0", "5.0.0") when the reply has none.

to_string(reply)

@spec to_string(t()) :: String.t()

Returns the reply as a single line of text, for logs.