123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
- <html>
- <head>
- <meta name="description" content="LuaSocket: SMTP support">
- <meta name="keywords" content="Lua, LuaSocket, SMTP, E-Mail, MIME, Multipart,
- Library, Support">
- <title>LuaSocket: SMTP support</title>
- <link rel="stylesheet" href="reference.css" type="text/css">
- </head>
- <body>
- <!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
- <div class=header>
- <hr>
- <center>
- <table summary="LuaSocket logo">
- <tr><td align=center><a href="http://www.lua.org">
- <img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png">
- </a></td></tr>
- <tr><td align=center valign=top>Network support for the Lua language
- </td></tr>
- </table>
- <p class=bar>
- <a href="index.html">home</a> ·
- <a href="index.html#download">download</a> ·
- <a href="installation.html">installation</a> ·
- <a href="introduction.html">introduction</a> ·
- <a href="reference.html">reference</a>
- </p>
- </center>
- <hr>
- </div>
- <!-- smtp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
- <h2 id=smtp>SMTP</h2>
- <p> The <tt>smtp</tt> namespace provides functionality to send e-mail
- messages. The high-level API consists of two functions: one to
- define an e-mail message, and another to actually send the message.
- Although almost all users will find that these functions provide more than
- enough functionality, the underlying implementation allows for even more
- control (if you bother to read the code).
- </p>
- <p>The implementation conforms to the Simple Mail Transfer Protocol,
- <a href="http://www.ietf.org/rfc/rfc2821.txt">RFC 2821</a>.
- Another RFC of interest is <a
- href="http://www.ietf.org/rfc/rfc2822.txt">RFC 2822</a>,
- which governs the Internet Message Format.
- Multipart messages (those that contain attachments) are part
- of the MIME standard, but described mainly
- in <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a>
- <p> In the description below, good understanding of <a
- href="http://lua-users.org/wiki/FiltersSourcesAndSinks"> LTN012, Filters
- sources and sinks</a> and the <a href=mime.html>MIME</a> module is
- assumed. In fact, the SMTP module was the main reason for their
- creation. </p>
- <p>
- To obtain the <tt>smtp</tt> namespace, run:
- </p>
- <pre class=example>
- -- loads the SMTP module and everything it requires
- local smtp = require("socket.smtp")
- </pre>
- <p>
- MIME headers are represented as a Lua table in the form:
- </p>
- <blockquote>
- <table summary="MIME headers in Lua table">
- <tr><td><tt>
- headers = {<br>
- field-1-name = <i>field-1-value</i>,<br>
- field-2-name = <i>field-2-value</i>,<br>
- field-3-name = <i>field-3-value</i>,<br>
- ...<br>
- field-n-name = <i>field-n-value</i><br>
- }
- </tt></td></tr>
- </table>
- </blockquote>
- <p>
- Field names are case insensitive (as specified by the standard) and all
- functions work with lowercase field names (but see
- <a href=socket.html#headers.canonic><tt>socket.headers.canonic</tt></a>).
- Field values are left unmodified.
- </p>
- <p class=note>
- Note: MIME headers are independent of order. Therefore, there is no problem
- in representing them in a Lua table.
- </p>
- <p>
- The following constants can be set to control the default behavior of
- the SMTP module:
- </p>
- <ul>
- <li> <tt>DOMAIN</tt>: domain used to greet the server;
- <li> <tt>PORT</tt>: default port used for the connection;
- <li> <tt>SERVER</tt>: default server used for the connection;
- <li> <tt>TIMEOUT</tt>: default timeout for all I/O operations;
- <li> <tt>ZONE</tt>: default time zone.
- </ul>
- <!-- message ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
- <p class=name id=message>
- smtp.<b>message(</b>mesgt<b>)</b>
- </p>
- <p class=description>
- Returns a <em>simple</em>
- <a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> source that sends an SMTP message body, possibly multipart (arbitrarily deep).
- </p>
- <p class=parameters>
- The only parameter of the function is a table describing the message.
- <tt>Mesgt</tt> has the following form (notice the recursive structure):
- </p>
- <blockquote>
- <table summary="Mesgt table structure">
- <tr><td><tt>
- mesgt = {<br>
- headers = <i>header-table</i>,<br>
- body = <i>LTN12 source</i> or <i>string</i> or
- <i>multipart-mesgt</i><br>
- }<br>
- <br>
- multipart-mesgt = {<br>
- [preamble = <i>string</i>,]<br>
- [1] = <i>mesgt</i>,<br>
- [2] = <i>mesgt</i>,<br>
- ...<br>
- [<i>n</i>] = <i>mesgt</i>,<br>
- [epilogue = <i>string</i>,]<br>
- }<br>
- </tt></td></tr>
- </table>
- </blockquote>
- <p class=parameters>
- For a simple message, all that is needed is a set of <tt>headers</tt>
- and the <tt>body</tt>. The message <tt>body</tt> can be given as a string
- or as a <em>simple</em>
- <a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
- source. For multipart messages, the body is a table that
- recursively defines each part as an independent message, plus an optional
- <tt>preamble</tt> and <tt>epilogue</tt>.
- </p>
- <p class=return>
- The function returns a <em>simple</em>
- <a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
- source that produces the
- message contents as defined by <tt>mesgt</tt>, chunk by chunk.
- Hopefully, the following
- example will make things clear. When in doubt, refer to the appropriate RFC
- as listed in the introduction. </p>
- <pre class=example>
- -- load the smtp support and its friends
- local smtp = require("socket.smtp")
- local mime = require("mime")
- local ltn12 = require("ltn12")
- -- creates a source to send a message with two parts. The first part is
- -- plain text, the second part is a PNG image, encoded as base64.
- source = smtp.message{
- headers = {
- -- Remember that headers are *ignored* by smtp.send.
- from = "Sicrano de Oliveira <[email protected]>",
- to = "Fulano da Silva <[email protected]>",
- subject = "Here is a message with attachments"
- },
- body = {
- preamble = "If your client doesn't understand attachments, \r\n" ..
- "it will still display the preamble and the epilogue.\r\n" ..
- "Preamble will probably appear even in a MIME enabled client.",
- -- first part: no headers means plain text, us-ascii.
- -- The mime.eol low-level filter normalizes end-of-line markers.
- [1] = {
- body = mime.eol(0, [[
- Lines in a message body should always end with CRLF.
- The smtp module will *NOT* perform translation. However, the
- send function *DOES* perform SMTP stuffing, whereas the message
- function does *NOT*.
- ]])
- },
- -- second part: headers describe content to be a png image,
- -- sent under the base64 transfer content encoding.
- -- notice that nothing happens until the message is actually sent.
- -- small chunks are loaded into memory right before transmission and
- -- translation happens on the fly.
- [2] = {
- headers = {
- ["content-type"] = 'image/png; name="image.png"',
- ["content-disposition"] = 'attachment; filename="image.png"',
- ["content-description"] = 'a beautiful image',
- ["content-transfer-encoding"] = "BASE64"
- },
- body = ltn12.source.chain(
- ltn12.source.file(io.open("image.png", "rb")),
- ltn12.filter.chain(
- mime.encode("base64"),
- mime.wrap()
- )
- )
- },
- epilogue = "This might also show up, but after the attachments"
- }
- }
- -- finally send it
- r, e = smtp.send{
- from = "<[email protected]>",
- rcpt = "<[email protected]>",
- source = source,
- }
- </pre>
- <!-- send +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
- <p class=name id=send>
- smtp.<b>send{</b><br>
- from = <i>string</i>,<br>
- rcpt = <i>string</i> or <i>string-table</i>,<br>
- source = <i>LTN12 source</i>,<br>
- [user = <i>string</i>,]<br>
- [password = <i>string</i>,]<br>
- [server = <i>string</i>,]<br>
- [port = <i>number</i>,]<br>
- [domain = <i>string</i>,]<br>
- [step = <i>LTN12 pump step</i>,]<br>
- [create = <i>function</i>]<br>
- <b>}</b>
- </p>
- <p class=description>
- Sends a message to a recipient list. Since sending messages is not as
- simple as downloading an URL from a FTP or HTTP server, this function
- doesn't have a simple interface. However, see the
- <a href=#message><tt>message</tt></a> source factory for
- a very powerful way to define the message contents.
- </p>
- <p class=parameters>
- The sender is given by the e-mail address in the <tt>from</tt> field.
- <tt>Rcpt</tt> is a Lua table with one entry for each recipient e-mail
- address, or a string
- in case there is just one recipient.
- The contents of the message are given by a <em>simple</em>
- <a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
- <tt>source</tt>. Several arguments are optional:
- </p>
- <ul>
- <li> <tt>user</tt>, <tt>password</tt>: User and password for
- authentication. The function will attempt LOGIN and PLAIN authentication
- methods if supported by the server (both are unsafe);
- <li> <tt>server</tt>: Server to connect to. Defaults to "localhost";
- <li> <tt>port</tt>: Port to connect to. Defaults to 25;
- <li> <tt>domain</tt>: Domain name used to greet the server; Defaults to the
- local machine host name;
- <li> <tt>step</tt>:
- <a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
- pump step function used to pass data from the
- source to the server. Defaults to the LTN12 <tt>pump.step</tt> function;
- <li><tt>create</tt>: An optional function to be used instead of
- <a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created.
- </ul>
- <p class=return>
- If successful, the function returns 1. Otherwise, the function returns
- <b><tt>nil</tt></b> followed by an error message.
- </p>
- <p class=note>
- Note: SMTP servers can be very picky with the format of e-mail
- addresses. To be safe, use only addresses of the form
- "<tt><[email protected]></tt>" in the <tt>from</tt> and
- <tt>rcpt</tt> arguments to the <tt>send</tt> function. In headers, e-mail
- addresses can take whatever form you like. </p>
- <p class=note>
- Big note: There is a good deal of misconception with the use of the
- destination address field headers, i.e., the '<tt>To</tt>', '<tt>Cc</tt>',
- and, more importantly, the '<tt>Bcc</tt>' headers. Do <em>not</em> add a
- '<tt>Bcc</tt>' header to your messages because it will probably do the
- exact opposite of what you expect.
- </p>
- <p class=note>
- Only recipients specified in the <tt>rcpt</tt> list will receive a copy of the
- message. Each recipient of an SMTP mail message receives a copy of the
- message body along with the headers, and nothing more. The headers
- <em>are</em> part of the message and should be produced by the
- <a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
- <tt>source</tt> function. The <tt>rcpt</tt> list is <em>not</em>
- part of the message and will not be sent to anyone.
- </p>
- <p class=note>
- <a href="http://www.ietf.org/rfc/rfc2822.txt">RFC 2822</a>
- has two <em>important and short</em> sections, "3.6.3. Destination address
- fields" and "5. Security considerations", explaining the proper
- use of these headers. Here is a summary of what it says:
- </p>
- <ul>
- <li> <tt>To</tt>: contains the address(es) of the primary recipient(s)
- of the message;
- <li> <tt>Cc</tt>: (where the "Cc" means "Carbon Copy" in the sense of
- making a copy on a typewriter using carbon paper) contains the
- addresses of others who are to receive the message, though the
- content of the message may not be directed at them;
- <li> <tt>Bcc</tt>: (where the "Bcc" means "Blind Carbon
- Copy") contains addresses of recipients of the message whose addresses are not to be revealed to other recipients of the message.
- </ul>
- <p class=note>
- The LuaSocket <tt>send</tt> function does not care or interpret the
- headers you send, but it gives you full control over what is sent and
- to whom it is sent:
- </p>
- <ul>
- <li> If someone is to receive the message, the e-mail address <em>has</em>
- to be in the recipient list. This is the only parameter that controls who
- gets a copy of the message;
- <li> If there are multiple recipients, none of them will automatically
- know that someone else got that message. That is, the default behavior is
- similar to the <tt>Bcc</tt> field of popular e-mail clients;
- <li> It is up to you to add the <tt>To</tt> header with the list of primary
- recipients so that other recipients can see it;
- <li> It is also up to you to add the <tt>Cc</tt> header with the
- list of additional recipients so that everyone else sees it;
- <li> Adding a header <tt>Bcc</tt> is nonsense, unless it is
- empty. Otherwise, everyone receiving the message will see it and that is
- exactly what you <em>don't</em> want to happen!
- </ul>
- <p class=note>
- I hope this clarifies the issue. Otherwise, please refer to
- <a href="http://www.ietf.org/rfc/rfc2821.txt">RFC 2821</a>
- and
- <a href="http://www.ietf.org/rfc/rfc2822.txt">RFC 2822</a>.
- </p>
- <pre class=example>
- -- load the smtp support
- local smtp = require("socket.smtp")
- -- Connects to server "localhost" and sends a message to users
- -- "[email protected]", "[email protected]",
- -- and "[email protected]".
- -- Note that "fulano" is the primary recipient, "beltrano" receives a
- -- carbon copy and neither of them knows that "sicrano" received a blind
- -- carbon copy of the message.
- from = "<[email protected]>"
- rcpt = {
- "<[email protected]>",
- "<[email protected]>",
- "<[email protected]>"
- }
- mesgt = {
- headers = {
- to = "Fulano da Silva <[email protected]>",
- cc = '"Beltrano F. Nunes" <[email protected]>',
- subject = "My first message"
- },
- body = "I hope this works. If it does, I can send you another 1000 copies."
- }
- r, e = smtp.send{
- from = from,
- rcpt = rcpt,
- source = smtp.message(mesgt)
- }
- </pre>
- <!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
- <div class=footer>
- <hr>
- <center>
- <p class=bar>
- <a href="index.html">home</a> ·
- <a href="index.html#down">download</a> ·
- <a href="installation.html">installation</a> ·
- <a href="introduction.html">introduction</a> ·
- <a href="reference.html">reference</a>
- </p>
- <p>
- <small>
- Last modified by Diego Nehab on <br>
- Thu Apr 20 00:25:51 EDT 2006
- </small>
- </p>
- </center>
- </div>
- </body>
- </html>
|