Sovite.Core.Transport (sovite v0.2.0)

Copy Markdown View Source

Transport specifications: transport:nexthop.

  • smtp - SMTP to the recipient domain's MX hosts, or the relay host.
  • smtp:example.com / smtp:example.com:587 - SMTP to the MX hosts of example.com.
  • smtp:[mail.example.com] / smtp:[192.0.2.1]:587 - SMTP to that host, without an MX lookup.
  • lmtp:unix:/run/dovecot/lmtp / lmtp:inet:mail.example.com:24 / lmtp:[mail.example.com]:24 - LMTP. Port 24 by default.
  • local / mailbox - Maildir delivery for local and hosted domains, to the folders maildir.local and maildir.mailbox name.
  • pipe:name - run the command of the [pipe.name] config section.
  • error:5.1.1 text - bounce with that status and text. The status is optional (5.0.0).
  • retry:4.3.0 text - keep the mail and try again later.
  • discard:text - drop the mail, as if delivered.

In the transports table, an empty transport (:[relay.example.com]) keeps the transport and only changes the next hop; an empty next hop (smtp:) keeps the default next hop.

Summary

Types

An SMTP or LMTP host: mx: true looks up the MX hosts of host.

t()

Functions

Merges a transports table entry into a default: an empty transport or next hop keeps the default's.

Parses a specification.

Parses a host: host and host:port look up MX records, [host] and [host]:port do not. An IP address must be in brackets and becomes an address literal ("[192.0.2.1]").

Whether name can name a pipe: letters, digits, _, and -.

Types

host()

@type host() :: %{host: String.t(), port: :inet.port_number(), mx: boolean()}

An SMTP or LMTP host: mx: true looks up the MX hosts of host.

t()

@type t() :: %{
  transport:
    :smtp | :lmtp | :local | :mailbox | :pipe | :error | :retry | :discard | nil,
  nexthop:
    host()
    | {:unix, Path.t()}
    | {status :: String.t(), text :: String.t()}
    | String.t()
    | nil
}

Functions

merge(default, override)

@spec merge(t(), t()) :: t()

Merges a transports table entry into a default: an empty transport or next hop keeps the default's.

parse(spec)

@spec parse(String.t()) :: {:ok, t()} | :error

Parses a specification.

iex> Sovite.Core.Transport.parse("smtp:[mail.example.com]:587")
{:ok, %{transport: :smtp, nexthop: %{host: "mail.example.com", port: 587, mx: false}}}
iex> Sovite.Core.Transport.parse("lmtp:unix:/run/dovecot/lmtp")
{:ok, %{transport: :lmtp, nexthop: {:unix, "/run/dovecot/lmtp"}}}
iex> Sovite.Core.Transport.parse("error:5.1.1 no such user")
{:ok, %{transport: :error, nexthop: {"5.1.1", "no such user"}}}

parse_host(value, default_port)

@spec parse_host(String.t(), :inet.port_number()) :: {:ok, host()} | :error

Parses a host: host and host:port look up MX records, [host] and [host]:port do not. An IP address must be in brackets and becomes an address literal ("[192.0.2.1]").

iex> Sovite.Core.Transport.parse_host("example.com", 25)
{:ok, %{host: "example.com", port: 25, mx: true}}
iex> Sovite.Core.Transport.parse_host("[IPv6:2001:db8::1]:2525", 25)
{:ok, %{host: "[IPv6:2001:db8::1]", port: 2525, mx: false}}

pipe_name?(name)

@spec pipe_name?(term()) :: boolean()

Whether name can name a pipe: letters, digits, _, and -.

iex> Sovite.Core.Transport.pipe_name?("procmail")
true
iex> Sovite.Core.Transport.pipe_name?("../x")
false