Manual is almost done. HTTP is missing.
Implemented new distribution scheme. Select is now purely C. HTTP reimplemented seems faster dunno why. LTN12 functions that coroutines fail gracefully.
This commit is contained in:
parent
9ed7f955e5
commit
58096449c6
40 changed files with 2035 additions and 815 deletions
235
doc/smtp.html
235
doc/smtp.html
|
@ -35,15 +35,22 @@
|
|||
|
||||
<h2 id=smtp>SMTP</h2>
|
||||
|
||||
<p>
|
||||
The <tt>smtp.lua</tt> module provides functionality to send e-mail
|
||||
<p> The <tt>smtp.lua</tt> module provides functionality to send e-mail
|
||||
messages. The implementation conforms to the Simple Mail Transfer Protocol,
|
||||
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2821.txt">RFC 2821</a>.
|
||||
The other RFC of interest in this implementation is
|
||||
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2822.txt">RFC 2822</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 attatchments) 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>
|
||||
<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>
|
||||
MIME headers are represented as a Lua table in the form:
|
||||
|
@ -78,29 +85,56 @@ Note: MIME headers are independent of order. Therefore, there is no problem
|
|||
in representing them in a Lua table.
|
||||
</p>
|
||||
|
||||
<!-- mail +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||
<p>
|
||||
The following constants can be set to control the default behaviour of
|
||||
the SMTP module:
|
||||
</p>
|
||||
|
||||
<p class=name id=mail>
|
||||
socket.smtp.<b>mail{</b><br>
|
||||
<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>
|
||||
body = <i>string</i>,<br>
|
||||
headers = <i>headers-table</i>,<br>
|
||||
server = <i>string</i><br>
|
||||
source = <i>LTN12 source</i>,<br>
|
||||
[server = <i>string</i>],<br>
|
||||
[port = <i>string</i>]<br>
|
||||
[domain = <i>string</i>],<br>
|
||||
[step = <i>LTN12 pump step</i>],<br>
|
||||
<b>}</b>
|
||||
</p>
|
||||
|
||||
<p class=description>
|
||||
Sends a message to a recipient list.
|
||||
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>
|
||||
<tt>Rcpt</tt> is a Lua table with one entry for each recipient, or a string
|
||||
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 sender is given by the e-mail address <tt>from</tt>.
|
||||
The message is composed by the optional MIME Headers <tt>headers</tt>
|
||||
and text <tt>body</tt>. The message is sent using the server
|
||||
<tt>server</tt>.
|
||||
The contents of the message are given by a LTN12 <tt>source</tt>. Several
|
||||
arguments are optional:
|
||||
<ul>
|
||||
<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>: LTN12 pump step function used to pass data from the
|
||||
source to the server. Defaults to the LTN12 <tt>pump.step</tt> function.
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p class=return>
|
||||
|
@ -108,6 +142,13 @@ 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 are can be very picky with the format of e-mail
|
||||
addresses. To be safe, use only addresses of the form
|
||||
"<tt><fulano@tecgraf.puc-rio.br></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>',
|
||||
|
@ -117,11 +158,12 @@ exact opposite of what you expect.
|
|||
</p>
|
||||
|
||||
<p class=note>
|
||||
Only recipients specified in the recipient list will receive a copy of the
|
||||
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 are
|
||||
considered as part of the message. The list of recipients is <em>not</em>
|
||||
part of the message.
|
||||
message body along with the headers, and nothing more. The headers
|
||||
<em>are</em> part of the message and should be produced by the LTN12
|
||||
<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>
|
||||
|
@ -143,9 +185,9 @@ Copy") contains addresses of recipients of the message whose addresses are not t
|
|||
</ul>
|
||||
|
||||
<p class=note>
|
||||
The LuaSocket <tt>mail</tt> function does not interpret the headers you
|
||||
pass to, but it gives you full control over what is sent and to whom
|
||||
it is sent:
|
||||
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>
|
||||
|
@ -171,36 +213,147 @@ and
|
|||
</p>
|
||||
|
||||
<pre class=example>
|
||||
-- load the smtp support
|
||||
local smtp = require("smtp")
|
||||
|
||||
-- Connects to server "localhost" and sends a message to users
|
||||
-- "fulano@tecgraf.puc-rio.br", "beltrano@tecgraf.puc-rio.br",
|
||||
-- and "sicrano@tecgraf.puc-rio.br".
|
||||
-- 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.
|
||||
headers = {
|
||||
to = "fulano@tecgraf.puc-rio.br",
|
||||
cc = "beltrano@tecgraf.puc-rio.br",
|
||||
subject = "LuaSocket test message"
|
||||
}
|
||||
|
||||
from = "luasocket@tecgraf.puc-rio.br"
|
||||
from = "<luasocket@tecgraf.puc-rio.br>"
|
||||
|
||||
rcpt = {
|
||||
"fulano@tecgraf.puc-rio.br",
|
||||
"beltrano@tecgraf.puc-rio.br",
|
||||
"sicrano@tecgraf.puc-rio.br"
|
||||
"<fulano@tecgraf.puc-rio.br>",
|
||||
"<beltrano@tecgraf.puc-rio.br>",
|
||||
"<sicrano@tecgraf.puc-rio.br>"
|
||||
}
|
||||
|
||||
body = "This is a test message. Please ignore."
|
||||
mesgt = {
|
||||
headers = {
|
||||
to = "Fulano da Silva <fulano@tecgraf.puc-rio.br>",
|
||||
cc = '"Beltrano F. Nunes" <beltrano@tecgraf.puc-rio.br>',
|
||||
subject = "My first message"
|
||||
}
|
||||
body = "I hope this works. If it does, I can send you another 1000 copies."
|
||||
}
|
||||
|
||||
server = "localhost"
|
||||
|
||||
r, e = socket.smtp.mail{
|
||||
r, e = smtp.send{
|
||||
from = from,
|
||||
rcpt = rcpt,
|
||||
headers = headers,
|
||||
body = body,
|
||||
server = server
|
||||
source = smtp.message(mesgt)
|
||||
}
|
||||
</pre>
|
||||
|
||||
<!-- message ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||
|
||||
<p class=name id=message>
|
||||
smtp.<b>message(</b>mesgt<b>)</b>
|
||||
</p>
|
||||
|
||||
<p class=description>
|
||||
Returns a LTN12 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 LTN12 source. For multipart messages, the body is a table that
|
||||
recursively defines each part as an independent message, plus a preamble
|
||||
and an epilogue.
|
||||
</p>
|
||||
|
||||
<p class=return>
|
||||
The function returns an LTN12 source that produces the message contents as
|
||||
defined by <tt>mesgt</tt>. Hopefuly, 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("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@tecgraf.puc-rio.br>",
|
||||
to = "Fulano da Silva <fulano@tecgraf.puc-rio.br>",
|
||||
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 might show up 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. It will
|
||||
perform necessary stuffing or '.' characters, though.
|
||||
]])
|
||||
},
|
||||
-- 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@tecgraf.puc-rio.br>",
|
||||
rcpt = "<fulano@tecgraf.puc-rio.br>",
|
||||
source = source,
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue