Blame doc/smtp.html

Packit b53373
Packit b53373
    "http://www.w3.org/TR/html4/strict.dtd">
Packit b53373
<html>
Packit b53373
Packit b53373
<head>
Packit b53373
<meta name="description" content="LuaSocket: SMTP support">
Packit b53373
Packit b53373
Library, Support"> 
Packit b53373
<title>LuaSocket: SMTP support</title>
Packit b53373
<link rel="stylesheet" href="reference.css" type="text/css">
Packit b53373
</head>
Packit b53373
Packit b53373
<body>
Packit b53373
Packit b53373
Packit b53373
Packit b53373
Packit b53373

Packit b53373
<center>
Packit b53373
Packit b53373
Packit b53373
LuaSocket
Packit b53373
Packit b53373
Network support for the Lua language
Packit b53373
Packit b53373
Packit b53373

Packit b53373
home ·
Packit b53373
download ·
Packit b53373
installation ·
Packit b53373
introduction ·
Packit b53373
reference 
Packit b53373

Packit b53373
</center>
Packit b53373

Packit b53373
Packit b53373
Packit b53373
Packit b53373
Packit b53373

SMTP

Packit b53373
Packit b53373

The <tt>smtp</tt> namespace provides functionality to send e-mail

Packit b53373
messages. The high-level API consists of two functions: one to 
Packit b53373
define an e-mail message, and another to actually send the message.
Packit b53373
Although almost all users will find that these functions provide more than
Packit b53373
enough functionality, the underlying implementation allows for even more
Packit b53373
control (if you bother to read the code).  
Packit b53373

Packit b53373
Packit b53373

The implementation conforms to the Simple Mail Transfer Protocol,

Packit b53373
RFC 2821.
Packit b53373
Another RFC of interest is 
Packit b53373
href="http://www.ietf.org/rfc/rfc2822.txt">RFC 2822,
Packit b53373
which governs the Internet Message Format.
Packit b53373
Multipart messages (those that contain attachments) are part
Packit b53373
of the MIME standard, but described mainly
Packit b53373
in RFC 2046
Packit b53373
Packit b53373

In the description below, good understanding of

Packit b53373
href="http://lua-users.org/wiki/FiltersSourcesAndSinks"> LTN012, Filters
Packit b53373
sources and sinks and the  MIME module is
Packit b53373
assumed.  In fact, the SMTP module was the main reason for their 
Packit b53373
creation. 

Packit b53373
Packit b53373

Packit b53373
To obtain the <tt>smtp</tt> namespace, run:
Packit b53373

Packit b53373
Packit b53373
Packit b53373
-- loads the SMTP module and everything it requires
Packit b53373
local smtp = require("socket.smtp")
Packit b53373
Packit b53373
Packit b53373

Packit b53373
MIME headers are represented as a Lua table in the form:
Packit b53373

Packit b53373
Packit b53373
Packit b53373
Packit b53373
<tt>
Packit b53373
headers = {
Packit b53373
  field-1-name = field-1-value,
Packit b53373
  field-2-name = field-2-value,
Packit b53373
  field-3-name = field-3-value,
Packit b53373
  ...
Packit b53373
  field-n-name = field-n-value
Packit b53373
}
Packit b53373
</tt>
Packit b53373
Packit b53373
Packit b53373
Packit b53373

Packit b53373
Field names are case insensitive (as specified by the standard) and all
Packit b53373
functions work with lowercase field names (but see
Packit b53373
<tt>socket.headers.canonic</tt>).
Packit b53373
Field values are left unmodified.
Packit b53373

Packit b53373
Packit b53373

Packit b53373
Note: MIME headers are independent of order. Therefore, there is no problem
Packit b53373
in representing them in a Lua table. 
Packit b53373

Packit b53373
Packit b53373

Packit b53373
The following constants can be set to control the default behavior of
Packit b53373
the SMTP module: 
Packit b53373

Packit b53373
Packit b53373
    Packit b53373
  • <tt>DOMAIN</tt>: domain used to greet the server;
  • Packit b53373
  • <tt>PORT</tt>: default port used for the connection;
  • Packit b53373
  • <tt>SERVER</tt>: default server used for the connection;
  • Packit b53373
  • <tt>TIMEOUT</tt>: default timeout for all I/O operations;
  • Packit b53373
  • <tt>ZONE</tt>: default time zone.
  • Packit b53373
    Packit b53373
    Packit b53373
    Packit b53373
    Packit b53373

    Packit b53373
    smtp.send{
    Packit b53373
      from = string,
    Packit b53373
      rcpt = string or string-table,
    Packit b53373
      source = LTN12 source,
    Packit b53373
      [user = string,]
    Packit b53373
      [password = string,]
    Packit b53373
      [server = string,]
    Packit b53373
      [port = number,]
    Packit b53373
      [domain = string,]
    Packit b53373
      [step = LTN12 pump step,]
    Packit b53373
      [create = function]
    Packit b53373
    }
    Packit b53373

    Packit b53373
    Packit b53373

    Packit b53373
    Sends a message to a recipient list. Since sending messages is not as
    Packit b53373
    simple as downloading an URL from a FTP or HTTP server, this function 
    Packit b53373
    doesn't have a simple interface. However, see the 
    Packit b53373
    <tt>message</tt> source factory for 
    Packit b53373
    a very powerful way to define the message contents.
    Packit b53373

    Packit b53373
    Packit b53373
    Packit b53373

    Packit b53373
    The sender is given by the e-mail address in the <tt>from</tt> field. 
    Packit b53373
    <tt>Rcpt</tt> is a Lua table with one entry for each recipient e-mail
    Packit b53373
    address, or a string
    Packit b53373
    in case there is just one recipient. 
    Packit b53373
    The contents of the message are given by a simple 
    Packit b53373
    LTN12 
    Packit b53373
    <tt>source</tt>. Several arguments are optional:
    Packit b53373

    Packit b53373
      Packit b53373
    • <tt>user</tt>, <tt>password</tt>: User and password for
    • Packit b53373
      authentication. The function will attempt LOGIN and PLAIN authentication
      Packit b53373
      methods if supported by the server (both are unsafe);
      Packit b53373
    • <tt>server</tt>: Server to connect to. Defaults to "localhost";
    • Packit b53373
    • <tt>port</tt>: Port to connect to. Defaults to 25;
    • Packit b53373
    • <tt>domain</tt>: Domain name used to greet the server; Defaults to the
    • Packit b53373
      local machine host name; 
      Packit b53373
    • <tt>step</tt>:
    • Packit b53373
      LTN12 
      Packit b53373
      pump step function used to pass data from the
      Packit b53373
      source to the server. Defaults to the LTN12 <tt>pump.step</tt> function;
      Packit b53373
    • <tt>create</tt>: An optional function to be used instead of
    • Packit b53373
      <tt>socket.tcp</tt> when the communications socket is created. 
      Packit b53373
      Packit b53373
      Packit b53373

      Packit b53373
      If  successful, the function returns 1. Otherwise, the function returns
      Packit b53373
      <tt>nil</tt> followed by an error message.
      Packit b53373

      Packit b53373
      Packit b53373

      Packit b53373
      Note: SMTP servers can be very picky with the format of e-mail
      Packit b53373
      addresses. To be safe, use only addresses of the form
      Packit b53373
      "<tt><fulano@example.com></tt>" in the <tt>from</tt> and
      Packit b53373
      <tt>rcpt</tt> arguments to the <tt>send</tt> function. In headers, e-mail
      Packit b53373
      addresses can take whatever form you like.  

      Packit b53373
      Packit b53373

      Packit b53373
      Big note: There is a good deal of misconception with the use of the
      Packit b53373
      destination address field headers, i.e., the '<tt>To</tt>', '<tt>Cc</tt>',
      Packit b53373
      and, more importantly, the '<tt>Bcc</tt>' headers. Do not add a
      Packit b53373
      '<tt>Bcc</tt>' header to your messages because it will probably do the
      Packit b53373
      exact opposite of what you expect.
      Packit b53373

      Packit b53373
      Packit b53373

      Packit b53373
      Only recipients specified in the <tt>rcpt</tt> list will receive a copy of the
      Packit b53373
      message.  Each recipient of an SMTP mail message receives a copy of the
      Packit b53373
      message body along with the headers, and nothing more.  The headers
      Packit b53373
      are part of the message and should be produced by the 
      Packit b53373
      LTN12 
      Packit b53373
      <tt>source</tt> function. The <tt>rcpt</tt> list is not
      Packit b53373
      part of the message and will not be sent to anyone.
      Packit b53373

      Packit b53373
      Packit b53373

      Packit b53373
      RFC 2822
      Packit b53373
      has two important and short sections, "3.6.3. Destination address
      Packit b53373
      fields" and "5. Security considerations",  explaining the proper
      Packit b53373
      use of these headers. Here is a summary of what it says: 
      Packit b53373

      Packit b53373
      Packit b53373
        Packit b53373
      • <tt>To</tt>: contains the address(es) of the primary recipient(s)
      • Packit b53373
        of the message;
        Packit b53373
      • <tt>Cc</tt>: (where the "Cc" means "Carbon Copy" in the sense of
      • Packit b53373
        making a copy on a typewriter using carbon paper) contains the
        Packit b53373
        addresses of others who are to receive the message, though the
        Packit b53373
        content of the message may not be directed at them;
        Packit b53373
      • <tt>Bcc</tt>: (where the "Bcc" means "Blind Carbon
      • Packit b53373
        Copy") contains addresses of recipients of the message whose addresses are not to be revealed to other recipients of the message.
        Packit b53373
         
        Packit b53373
        Packit b53373

        Packit b53373
        The LuaSocket <tt>send</tt> function does not care or interpret the 
        Packit b53373
        headers you send, but it gives you full control over what is sent and 
        Packit b53373
        to whom it is sent:
        Packit b53373

        Packit b53373
          Packit b53373
        • If someone is to receive the message, the e-mail address has
        • Packit b53373
          to be in the recipient list. This is the only parameter that controls who
          Packit b53373
          gets a copy of the message;
          Packit b53373
        • If there are multiple recipients, none of them will automatically
        • Packit b53373
          know that someone else got that message. That is, the default behavior is
          Packit b53373
          similar to the <tt>Bcc</tt> field of popular e-mail clients; 
          Packit b53373
        • It is up to you to add the <tt>To</tt> header with the list of primary
        • Packit b53373
          recipients so that other recipients can see it;
          Packit b53373
        • It is also up to you to add the <tt>Cc</tt> header with the
        • Packit b53373
          list of additional recipients so that everyone else sees it;
          Packit b53373
        • Adding a header <tt>Bcc</tt> is nonsense, unless it is
        • Packit b53373
          empty. Otherwise, everyone receiving the message will see it and that is
          Packit b53373
          exactly what you don't want to happen!
          Packit b53373
          Packit b53373
          Packit b53373

          Packit b53373
          I hope this clarifies the issue. Otherwise, please refer to 
          Packit b53373
          RFC 2821
          Packit b53373
          and
          Packit b53373
          RFC 2822.
          Packit b53373

          Packit b53373
          Packit b53373
          Packit b53373
          -- load the smtp support
          Packit b53373
          local smtp = require("socket.smtp")
          Packit b53373
          Packit b53373
          -- Connects to server "localhost" and sends a message to users
          Packit b53373
          -- "fulano@example.com",  "beltrano@example.com", 
          Packit b53373
          -- and "sicrano@example.com".
          Packit b53373
          -- Note that "fulano" is the primary recipient, "beltrano" receives a
          Packit b53373
          -- carbon copy and neither of them knows that "sicrano" received a blind
          Packit b53373
          -- carbon copy of the message.
          Packit b53373
          from = "<luasocket@example.com>"
          Packit b53373
          Packit b53373
          rcpt = {
          Packit b53373
            "<fulano@example.com>",
          Packit b53373
            "<beltrano@example.com>",
          Packit b53373
            "<sicrano@example.com>"
          Packit b53373
          }
          Packit b53373
          Packit b53373
          mesgt = {
          Packit b53373
            headers = {
          Packit b53373
              to = "Fulano da Silva <fulano@example.com>",
          Packit b53373
              cc = '"Beltrano F. Nunes" <beltrano@example.com>',
          Packit b53373
              subject = "My first message"
          Packit b53373
            },
          Packit b53373
            body = "I hope this works. If it does, I can send you another 1000 copies."
          Packit b53373
          }
          Packit b53373
          Packit b53373
          r, e = smtp.send{
          Packit b53373
            from = from,
          Packit b53373
            rcpt = rcpt, 
          Packit b53373
            source = smtp.message(mesgt)
          Packit b53373
          }
          Packit b53373
          Packit b53373
          Packit b53373
          Packit b53373
          Packit b53373

          Packit b53373
          smtp.message(mesgt)
          Packit b53373

          Packit b53373
          Packit b53373

          Packit b53373
          Returns a simple
          Packit b53373
          LTN12 source that sends an SMTP message body, possibly multipart (arbitrarily deep). 
          Packit b53373

          Packit b53373
          Packit b53373

          Packit b53373
          The only parameter of the function is a table describing the message.
          Packit b53373
          <tt>Mesgt</tt> has the following form (notice the recursive structure):
          Packit b53373

          Packit b53373
          Packit b53373
          Packit b53373
          Packit b53373
          <tt>
          Packit b53373
          mesgt = {
          Packit b53373
            headers = header-table,
          Packit b53373
            body = LTN12 source or string or 
          Packit b53373
          multipart-mesgt
          Packit b53373
          }
          Packit b53373
           
          Packit b53373
          multipart-mesgt = {
          Packit b53373
            [preamble = string,]
          Packit b53373
            [1] = mesgt,
          Packit b53373
            [2] = mesgt,
          Packit b53373
            ...
          Packit b53373
            [n] = mesgt,
          Packit b53373
            [epilogue = string,]
          Packit b53373
          }
          Packit b53373
          </tt>
          Packit b53373
          Packit b53373
          Packit b53373
          Packit b53373

          Packit b53373
          For a simple message, all that is needed is a set of <tt>headers</tt>
          Packit b53373
          and the <tt>body</tt>. The message <tt>body</tt> can be given as a string
          Packit b53373
          or as a simple 
          Packit b53373
          LTN12 
          Packit b53373
          source. For multipart messages, the body is a table that
          Packit b53373
          recursively defines each part as an independent message, plus an optional
          Packit b53373
          <tt>preamble</tt> and <tt>epilogue</tt>.
          Packit b53373

          Packit b53373
          Packit b53373

          Packit b53373
          The function returns a simple 
          Packit b53373
          LTN12 
          Packit b53373
          source that produces the
          Packit b53373
          message contents as defined by <tt>mesgt</tt>, chunk by chunk. 
          Packit b53373
          Hopefully, the following
          Packit b53373
          example will make things clear. When in doubt, refer to the appropriate RFC
          Packit b53373
          as listed in the introduction.  

          Packit b53373
          Packit b53373
          Packit b53373
          -- load the smtp support and its friends
          Packit b53373
          local smtp = require("socket.smtp")
          Packit b53373
          local mime = require("mime")
          Packit b53373
          local ltn12 = require("ltn12")
          Packit b53373
          Packit b53373
          -- creates a source to send a message with two parts. The first part is 
          Packit b53373
          -- plain text, the second part is a PNG image, encoded as base64.
          Packit b53373
          source = smtp.message{
          Packit b53373
            headers = {
          Packit b53373
               -- Remember that headers are *ignored* by smtp.send. 
          Packit b53373
               from = "Sicrano de Oliveira <sicrano@example.com>",
          Packit b53373
               to = "Fulano da Silva <fulano@example.com>",
          Packit b53373
               subject = "Here is a message with attachments"
          Packit b53373
            },
          Packit b53373
            body = {
          Packit b53373
              preamble = "If your client doesn't understand attachments, \r\n" ..
          Packit b53373
                         "it will still display the preamble and the epilogue.\r\n" ..
          Packit b53373
                         "Preamble will probably appear even in a MIME enabled client.",
          Packit b53373
              -- first part: no headers means plain text, us-ascii.
          Packit b53373
              -- The mime.eol low-level filter normalizes end-of-line markers.
          Packit b53373
              [1] = { 
          Packit b53373
                body = mime.eol(0, [[
          Packit b53373
                  Lines in a message body should always end with CRLF. 
          Packit b53373
                  The smtp module will *NOT* perform translation. However, the 
          Packit b53373
                  send function *DOES* perform SMTP stuffing, whereas the message
          Packit b53373
                  function does *NOT*.
          Packit b53373
                ]])
          Packit b53373
              },
          Packit b53373
              -- second part: headers describe content to be a png image, 
          Packit b53373
              -- sent under the base64 transfer content encoding.
          Packit b53373
              -- notice that nothing happens until the message is actually sent. 
          Packit b53373
              -- small chunks are loaded into memory right before transmission and 
          Packit b53373
              -- translation happens on the fly.
          Packit b53373
              [2] = { 
          Packit b53373
                headers = {
          Packit b53373
                  ["content-type"] = 'image/png; name="image.png"',
          Packit b53373
                  ["content-disposition"] = 'attachment; filename="image.png"',
          Packit b53373
                  ["content-description"] = 'a beautiful image',
          Packit b53373
                  ["content-transfer-encoding"] = "BASE64"
          Packit b53373
                },
          Packit b53373
                body = ltn12.source.chain(
          Packit b53373
                  ltn12.source.file(io.open("image.png", "rb")),
          Packit b53373
                  ltn12.filter.chain(
          Packit b53373
                    mime.encode("base64"),
          Packit b53373
                    mime.wrap()
          Packit b53373
                  )
          Packit b53373
                )
          Packit b53373
              },
          Packit b53373
              epilogue = "This might also show up, but after the attachments"
          Packit b53373
            }
          Packit b53373
          }
          Packit b53373
          Packit b53373
          -- finally send it
          Packit b53373
          r, e = smtp.send{
          Packit b53373
              from = "<sicrano@example.com>",
          Packit b53373
              rcpt = "<fulano@example.com>",
          Packit b53373
              source = source,
          Packit b53373
          }
          Packit b53373
          Packit b53373
          Packit b53373
          Packit b53373
          Packit b53373
          Packit b53373

          Packit b53373
          <center>
          Packit b53373

          Packit b53373
          home ·
          Packit b53373
          download ·
          Packit b53373
          installation ·
          Packit b53373
          introduction ·
          Packit b53373
          reference
          Packit b53373

          Packit b53373

          Packit b53373
          <small>
          Packit b53373
          Last modified by Diego Nehab on 
          Packit b53373
          Thu Apr 20 00:25:51 EDT 2006
          Packit b53373
          </small>
          Packit b53373

          Packit b53373
          </center>
          Packit b53373
          Packit b53373
          Packit b53373
          </body>
          Packit b53373
          </html>