module

Alumna::SMTP::Message

Writes one Mail as an RFC 5322 / MIME message for the SMTP DATA phase. The message streams to the IO. There is no String for the full message.

Text only (html nil or empty): one text/plain part. Text + html: multipart/alternative, text first, html last (RFC 2046). Bodies are UTF-8 quoted-printable. Every line ends in CRLF.

No line starts with ".": headers start with a name, folded lines with a space, boundaries with "--", and QuotedPrintable writes a first "." as =2E. The session writes "." CRLF after this output and needs no dot-stuffing.

The output is ASCII, except a bare address with non-ASCII bytes. The session must refuse that address (no SMTPUTF8 support).

Constants

FALLBACK_DOMAIN = "localhost"

Used when the from-address has no "@" domain.

HTML_HEADERS = "Content-Type: text/html; charset=UTF-8\r\nContent-Transfer-Encoding: quoted-printable\r\n"
TEXT_HEADERS = "Content-Type: text/plain; charset=UTF-8\r\nContent-Transfer-Encoding: quoted-printable\r\n"

Class methods

write(io : IO, mail : Mail, *, time : Time = Time.utc, token : String = Random::Secure.hex(16)) : Nil

time goes into Date. token is random hex for Message-ID and the boundary. Specs pass both, so the bytes are the same on each run.

The boundary starts with "=_". Quoted-printable always writes "=" as "=3D" (a soft break is "=" + CRLF), so a body line cannot contain the boundary.

Source