| <!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="home.html">home</a> · |
| <a href="home.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.cs.princeton.edu/~diego/rfc/rfc2821.txt">RFC 2821</a>. |
| Another RFC of interest is <a |
| href="http://www.cs.princeton.edu/~diego/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.cs.princeton.edu/~diego/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. |
| 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> |
| |
| <!-- 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><fulano@example.com></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.cs.princeton.edu/~diego/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.cs.princeton.edu/~diego/rfc/rfc2821.txt">RFC 2821</a> |
| and |
| <a href="http://www.cs.princeton.edu/~diego/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 |
| -- "fulano@example.com", "beltrano@example.com", |
| -- and "sicrano@example.com". |
| -- 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 = "<luasocket@example.com>" |
| |
| rcpt = { |
| "<fulano@example.com>", |
| "<beltrano@example.com>", |
| "<sicrano@example.com>" |
| } |
| |
| mesgt = { |
| headers = { |
| to = "Fulano da Silva <fulano@example.com>", |
| cc = '"Beltrano F. Nunes" <beltrano@example.com>', |
| 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> |
| |
| <!-- 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 <sicrano@example.com>", |
| to = "Fulano da Silva <fulano@example.com>", |
| 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 = "<sicrano@example.com>", |
| rcpt = "<fulano@example.com>", |
| source = source, |
| } |
| </pre> |
| |
| <!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
| |
| <div class=footer> |
| <hr> |
| <center> |
| <p class=bar> |
| <a href="home.html">home</a> · |
| <a href="home.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> |