Still work to do in the manual...

This commit is contained in:
Diego Nehab 2004-06-16 04:28:21 +00:00
parent 8e80e38f2c
commit 0a4c1534f3
15 changed files with 257 additions and 146 deletions

View File

@ -36,7 +36,7 @@
<h2 id=dns>DNS</h2>
<p>
Name resolution function return <em>all</em> information returned by the
Name resolution functions return <em>all</em> information obtained from the
resolver in a table of the form:
</p>
@ -59,14 +59,9 @@ socket.dns.<b>gethostname()</b>
</p>
<p class=description>
Returns the standard host name for the machine.
Returns the standard host name for the machine as a string.
</p>
<p class=return>
The function returns a string with the host name.
</p>
<!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=tohostname>

View File

@ -35,12 +35,33 @@
<p>
FTP (File Transfer Protocol) is a protocol used to transfer files
between hosts. The module <tt>ftp.lua</tt> offers simple FTP support.
Applications can easily download and upload files.
The implementation conforms to
between hosts. The <tt>ftp</tt> namespace offers thorough support
to FTP, under a simple interface. The implementation conforms to
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc0959.txt">RFC 959</a>.
</p>
<p>
High level functions are provided supporting the most common operations.
These high level functions are implemented on top of a lower level
interface. Using the low-level interface, users can easily create their
own functions to access <em>any</em> operation supported by the FTP
protocol. For that, check the implementation.
</p>
<p>
To really benefit from this module, a good understanding of
<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">
LTN012, Filters sources and sinks</a> is necessary.
</p>
<p class=description> To obtain the <tt>ftp</tt> namespace, run:
</p>
<pre class=example>
-- loads the FTP module and any libraries it requires
local ftp = require("ftp")
</pre>
<p>
URLs MUST conform to
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc1738.txt">RFC
@ -53,21 +74,7 @@ URLs MUST conform to
</blockquote>
<p>
High level functions are provided supporting the most common operations.
These high level functions are implemented on top of a lower level
interface. By using the low-level interface, users can easily create their
own functions to access <em>any</em> operation supported by the FTP
protocol. For that, check the implementation.
</p>
<p>
To use some of the functions in this module, a good understanding of
<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">
LTN012, Filters sources and sinks</a> is necessary.
</p>
<p>
The following constants can be set to control the default behaviour of
The following constants in the namespace can be set to control the default behavior of
the FTP module:
</p>
@ -78,6 +85,7 @@ the FTP module:
<li> <tt>USER</tt>: default anonymous user;
</ul>
<!-- ftp.get ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=get>
@ -116,7 +124,7 @@ optional arguments are the following:
authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>";
<li><tt>command</tt>: The FTP command used to obtain data. Defaults to
"<tt>retr</tt>", but see example below;
<li><tt>port</tt>: The port to contacct the server at. Defaults to 21;
<li><tt>port</tt>: The port to used for the control connection. Defaults to 21;
<li><tt>type</tt>: The transfer mode. Can take values "<tt>i</tt>" or
"<tt>a</tt>". Defaults to whatever is the server default;
<li><tt>step</tt>: LTN12 pump step function used to pass data from the
@ -192,9 +200,9 @@ optional arguments are the following:
<ul>
<li><tt>user</tt>, <tt>password</tt>: User name and password used for
authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>";
<li><tt>command</tt>: The FTP command used to obtain data. Defaults to
"<tt>retr</tt>", but see example below;
<li><tt>port</tt>: The port to contacct the server at. Defaults to 21;
<li><tt>command</tt>: The FTP command used to send data. Defaults to
"<tt>stor</tt>", but see example below;
<li><tt>port</tt>: The port to used for the control connection. Defaults to 21;
<li><tt>type</tt>: The transfer mode. Can take values "<tt>i</tt>" or
"<tt>a</tt>". Defaults to whatever is the server default;
<li><tt>step</tt>: LTN12 pump step function used to pass data from the
@ -213,7 +221,8 @@ local ftp = require("ftp")
-- Log as user "diego" on server "ftp.tecgraf.puc-rio.br",
-- using password "nehab", and store a file "README" with contents
-- "wrong password, of course"
f, e = ftp.put("ftp://diego:nehab@ftp.tecgraf.puc-rio.br/README", "wrong password, of course")
f, e = ftp.put("ftp://diego:nehab@ftp.tecgraf.puc-rio.br/README",
"wrong password, of course")
</pre>
<pre class=example>
@ -222,8 +231,8 @@ local ftp = require("ftp")
local ltn12 = require("ltn12")
-- Log as user "diego" on server "ftp.tecgraf.puc-rio.br",
-- using password "nehab", and append to the file "LOG", sending the
-- contents of a local file
-- using password "nehab", and append to the remote file "LOG", sending the
-- contents of the local file "LOCAL-LOG"
f, e = ftp.put{
host = "ftp.tecgraf.puc-rio.br",
user = "diego",

View File

@ -37,8 +37,9 @@
<p>
HTTP (Hyper Text Transfer Protocol) is the protocol used to exchange
information between web-browsers and servers. The <tt>http.lua</tt>
module offers support for the client side of the HTTP protocol (i.e.,
information between web-browsers and servers. The <tt>http</tt>
namespace offers full support for the client side of the HTTP
protocol (i.e.,
the facilities that would be used by a web-browser implementation). The
implementation conforms to the HTTP/1.1 standard,
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2616.txt">RFC
@ -47,11 +48,20 @@ implementation conforms to the HTTP/1.1 standard,
<p>
The module exports functions that provide HTTP functionality in different
levels of abstraction, from the simple <a
href="#get"><tt>get</tt></a> function to the generic, LTN12 based <a
href="#request"><tt>request</tt></a> function.
levels of abstraction, from the simple
<a href="#get"><tt>get</tt></a> function, through the generic
LTN12 based <a href="#request"><tt>request</tt></a> function, down to
even lower-level if you bother to look through the source code.
</p>
<p class=description> To obtain the <tt>ftp</tt> namespace, run:
</p>
<pre class=example>
-- loads the HTTP module and any libraries it requires
local http = require("http")
</pre>
<p>
URLs must conform to
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc1738.txt">RFC
@ -189,12 +199,12 @@ http.<b>request{</b><br>
</p>
<p class=description>
Performs the generic HTTP request, controled by a request table.
Performs the generic HTTP request, controlled by a request table.
</p>
<p class=parameters>
The most important parameters are the <tt>url</tt> and the <em>simple</em> LTN12 <tt>sink</tt> that will receive the downloaded content.
Any part of the <tt>url</tt> can be overriden by including
Any part of the <tt>url</tt> can be overridden by including
the appropriate field in the request table.
If authentication information is provided, the function
uses the Basic Authentication Scheme (see <a href="#authentication">note</a>)
@ -231,8 +241,8 @@ respt = {<br>
</tt></blockquote>
<p class=return>
Even when there was failure (URL not found, for example), the
function usually succeeds retrieving a message body (a web page informing the
Even when the server fails to provide the contents of the requested URL (URL not found, for example), the
it usually returns a message body (a web page informing the
URL was not found or some other useless page). To make sure the
operation was successful, check the returned status <tt>code</tt>. For
a list of the possible values and their meanings, refer to <a
@ -261,7 +271,6 @@ respt = http.request {
-- ["content-Type"] = "text/html"
-- }
</pre>
</blockquote>
<p class=note id=authentication>
Note: Some URLs are protected by their

View File

@ -37,21 +37,29 @@
<p>
LuaSocket is a <a href="http://www.lua.org">Lua</a> extension library
that is composed by two parts: a C layer that provides support for the TCP
that is composed by two parts: a C core that provides support for the TCP
and UDP transport layers, and a set of Lua modules that add support for
the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and
downloading files) protocols and other functionality commonly needed by
applications that deal with the Internet.
functionality commonly needed by applications that deal with the Internet.
</p>
<p>
Network support has been implemented so that it is both efficient and
simple to use. LuaSocket can be used by any Lua application once it has
The core support has been implemented so that it is both efficient and
simple to use. The core can be used by any Lua application once it has
been properly initialized by the interpreter running the
Lua application. The code has been tested and runs well on several Windows
and Unix platforms.
</p>
<p>
The most used modules implement the SMTP (sending e-mails), HTTP
(WWW access) and FTP (uploading and downloading files) client
protocols. These provide a very natural and generic interface to the e
functionality covered by the protocols.
In addition, you will find that the MIME (common encodings), URL (anything you
could possible want to do with one) and LTN12 (filters, sinks, sources
and pumps) modules can be very handy.
</p>
<p>
The library is available under the same
<a href="http://www.lua.org/copyright.html">
@ -112,10 +120,10 @@ option, and should be able to run the automatic test procedures.
<h2 id=thanks>Special thanks</h2>
<p>
Throughout LuaSocket's history, many people gave sugestions that helped
improve it. For that, I thank the Lua comunity.
Throughout LuaSocket's history, many people gave suggestions that helped
improve it. For that, I thank the Lua community.
Special thanks go to
David Burgess, who has pushed the library to a new level of quality and
David Burgess, who has helped push the library to a new level of quality and
from whom I have learned a lot of stuff that doesn't show up in RFCs.
Special thanks also to Carlos Cassino, who played a big part in the
extensible design seen in the C core of LuaSocket 2.0.
@ -127,28 +135,47 @@ extensible design seen in the C core of LuaSocket 2.0.
<p>
Everything is new! Many changes for 2.0 happened in the C layer, which
has been almost completely rewritten. The code has been ported to Lua 5.0
and greatly improved. There have also been some API changes
<em>Everything</em> is new! Many changes for 2.0 happened in the C layer,
which has been almost completely rewritten. The code has been ported to
Lua 5.0 and greatly improved. There have also been some API changes
that made the interface simpler and more consistent. Here are some of
the changes that made it into version 2.0:
</p>
<ul>
<li> Major C code rewrite. Code is modular and extensible. Hopefully, next
versions will include code for local domain sockets, file descriptors,
pipes (on Unix) and named pipes (on windows) as a bonus;
<li> Major C code rewrite. Code is modular and extensible. Hopefully, other
developers will be motivated to provide code for SSL, local domain
sockets, file descriptors, pipes (on Unix) and named pipes etc;
<li> Following the Lua 5.0 trend, all functions provided by the library are
in namespaces. These should be obtained with calls to the
<tt>require</tt> function. Functions such as
<li> Everything that is exported by the library is exported inside
namespaces. These should be obtained with calls to the
<tt>require</tt> function;
<li> Functions such as
send/receive/timeout/close etc do not exist anymore as stand-alone
functions. They are now only available as methods of the appropriate
objects;
<li> All functions return a non-nil value as first return value if successful.
All functions return <b><tt>nil</tt></b> followed by error message
in case of error;
in case of error. This made the library much easier to use;
<li> Greatly reduced the number of times the C select is called
during data transfers, by calling only on failure. This might
improve a lot the maximum throughput;
<li> TCP has been changed to become more uniform. It's possible to first
create a TCP object,
then connect or bind if needed, and finally use I/O functions.
<tt>socket.connect</tt> and <tt>socket.bind</tt> functions are still
provided for simplicity;
<li> This allows for setting a timeout value before connecting;
<li> And also allows binding to a local address before connecting;
<li> New <tt>socket.dns.gethostname</tt> function and <tt>shutdown</tt>
method;
<li> Better error messages and parameter checking;
@ -157,20 +184,9 @@ the changes that made it into version 2.0:
<li> UDP connected sockets can break association with peer by calling
<tt>setpeername</tt> with address '<tt>*</tt>';
<li> TCP has been changed to become more uniform. First create an object,
then connect or bind if needed, and finally use I/O functions. The
<tt>socket.connect</tt> and <tt>socket.bind</tt> functions are still
provided for simplicity, but they just call <tt>socket.tcp</tt> followed
by the <tt>connect</tt> or <tt>bind/listen</tt> methods;
<li> Sets returned by <tt>socket.select</tt> are associative;
<li> Greatly reduced the number of times select is called during data
transfers, by calling only on failure;
<li> TCP can set timeout value before connecting and also bind to local
address before connecting;
<li> <tt>socket.select</tt> returns associative sets and checks if
sockets had buffered data;
<li> Select checks if sockets have buffered data and returns immediately;
<li> <tt>socket.sleep</tt> and <tt>socket.time</tt> are now part of the
library and are supported. They used to be available only when
@ -182,7 +198,7 @@ the changes that made it into version 2.0:
high-level modules;
<li> Socket options interface has been improved. TCP objects also
support socket options and many other options were added.
support socket options and many new options were added.
</ul>
@ -191,12 +207,23 @@ Lots of changes in the Lua modules, too!
</p>
<ul>
<li> Every module loads only the modules that it needs. There is no waste
of memory. LuaSocket core takes only 20k of memory;
<li> New MIME and LTN12 modules make all other modules much more powerful;
<li> Support for multipart messages in the SMTP module;
<li> The old callback mechanism of FTP and HTTP has been replaced with LTN12 sources and sinks,
with advantage;
<li> The old callback mechanism of FTP and HTTP has been replaced with LTN12 sources and sinks, with advantage;
<li> Common implementation for low-level FTP and SMTP;
<li> FTP, HTTP, and SMTP are implemented in multiple levels in such a way
that users will have no problems extending the functionality.
that users will have no problems extending the functionality to satisfy
personal needs;
<li> SMTP knows how to perform LOGIN and PLAIN authentication.
</ul>
<!-- incompatible +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@ -208,7 +235,7 @@ that users will have no problems extending the functionality.
<li> The introduction of namespaces affects all programs that use LuaSocket,
specially code that relies on global functions. These are no longer
available. Note that even the support modules (<tt>http</tt>, <tt>smtp</tt>
etc) are independent now and should be "<tt>require</tt>ed";
etc) are independent now and should be "<tt>require</tt>"d;
<li> FTP, SMTP and HTTP are completely new; I am sure you will
agree the new stuff is better;

View File

@ -35,14 +35,22 @@
<h2>Introduction</h2>
<p>
LuaSocket is a <a href="http://www.lua.org">Lua</a> extension library
that is composed by two parts: a C core that provides support for the TCP
and UDP transport layers, and a set of Lua modules that add support for
the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and
downloading files) protocols and other functionality commonly needed by
applications that deal with the Internet. This introduction is about the C
core.
</p>
<p>
Communication in LuaSocket is performed via I/O objects. These can
represent different network domains. Currently, support is provided for TCP
and UDP, but nothing prevents other developers from implementing SSL, Local
Domain, Pipes, File Descriptors etc. I/O objects provide a standard
interface to I/O across different domains and operating systems.
LuaSocket&nbsp;2.0 has been rewritten from scratch to simplify the future
addition of new domains.
</p>
<p>
@ -52,8 +60,17 @@ Second, the simplicity and the feel of the Lua language should be
preserved. To achieve these goals, the LuaSocket API keeps the function names and semantics the C API whenever possible, but their usage in Lua has been greatly simplified.
</p>
<p>
One of the simplifications is the timeout control
One of the simplifications is the receive pattern capability.
Applications can read data from stream domains (such as TCP)
line by line, block by block, or until the connection is closed.
All I/O reads are buffered and the performance differences between
different receive patterns are negligible.
</p>
<p>
Another advantage is the flexible timeout control
mechanism. As in C, all I/O operations are blocking by default. For
example, the <a href=tcp.html#send><tt>send</tt></a>,
<a href=tcp.html#receive><tt>receive</tt></a> and
@ -69,14 +86,6 @@ call might perform several OS calls, so that the two timeout values are
<em>not</em> equivalent.
</p>
<p>
Another important difference is the receive pattern capability.
Applications can read data from stream domains (such as TCP)
line by line, block by block, or until the connection is closed.
All I/O reads are buffered and the performance differences between
different receive patterns are negligible.
</p>
<p>
Finally, the host name resolution is transparent, meaning that most
functions and methods accept both IP addresses and host names. In case a
@ -89,13 +98,8 @@ functions from the DNS module are provided to convert between host names and IP
</p>
<p>
Previous versions of LuaSocket provided global functions for operating on
I/O objects. To give the library a Lua 5.0 feel, these have been eliminated
from LuaSocket 2.0. I/O operations are only available as methods of the
corresponding I/O objects. Naturally, different I/O objects accept
different operations. The TCP and UDP objects are
introduced in the following sections, following a few words about
initialization.
Together, these changes make network programming in LuaSocket much simpler
than it is in C, as the following sections will show.
</p>
<!-- initializing +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@ -103,13 +107,14 @@ initialization.
<h3>Initializing the library</h3>
<p>
The core LuaSocket functionality is implemented in C, and usually available as
a dynamic library which the interpreter can load when required.
The core LuaSocket is almost entirely implemented in C. It is
usually available as a dynamic library which the interpreter can load
with the help of a loader module written in Lua.
Beginning with version 2.0 and following the Lua 5.0 trend, all LuaSocket
functionality is defined inside a tables (or rather a namespaces). No global
functionality is defined inside tables (or rather a namespaces). No global
variables are ever created.
Namespaces are obtained with the <tt>require</tt> Lua function, which loads
and initializes any required libraries and return the namespace.
and initializes any required library and returns the namespace.
For example, the core functionality or LuaSocket is usually available
from the "<tt>socket</tt>" namespace.
</p>
@ -130,13 +135,14 @@ words, applications communicating through TCP can send and receive data as
an error free stream of bytes. Data is split in one end and
reassembled transparently on the other end. There are no boundaries in
the data transfers. The library allows users to read data from the
sockets in several different granularity: patterns are available for
sockets in several different granularities: patterns are available for
lines, arbitrary sized blocks or "read up to connection closed", all with
good performance.
</p>
<p>
The library distinguishes three types of TCP sockets: master, client and server sockets.
The library distinguishes three types of TCP sockets: <em>master</em>,
<em>client</em> and <em>server</em> sockets.
</p>
<p>
@ -144,10 +150,11 @@ Master sockets are newly created TCP sockets returned by the function
<a href=tcp.html#tcp><tt>socket.tcp</tt></a>. A master socket is
transformed into a server socket
after it is associated with a <em>local</em> address by a call to the
<a href=tcp.html#bind><tt>bind</tt></a> method. Conversely, it
<a href=tcp.html#bind><tt>bind</tt></a> method followed by a call to the
<a href=tcp.html#listen><tt>listen</tt></a>. Conversely, a master socket
can be changed into a client socket with the method
<a href=tcp.html#connect><tt>connect</tt></a>,
that associates it with a <em>remote</em> address.
which associates it with a <em>remote</em> address.
</p>
<p>
@ -158,7 +165,7 @@ client socket object is returned representing this connection. The
other methods available for server socket objects are
<a href=tcp.html#getsockname><tt>getsockname</tt></a>,
<a href=tcp.html#setoption><tt>setoption</tt></a>,
<a href=tcp.html#settimeout><tt>settimeout</tt></a> and
<a href=tcp.html#settimeout><tt>settimeout</tt></a>, and
<a href=tcp.html#close><tt>close</tt></a>.
</p>
@ -172,7 +179,8 @@ available for client socket objects are
<a href=tcp.html#getsockname><tt>getsockname</tt></a>,
<a href=tcp.html#getpeername><tt>getpeername</tt></a>,
<a href=tcp.html#setoption><tt>setoption</tt></a>,
<a href=tcp.html#settimeout><tt>settimeout</tt></a> and
<a href=tcp.html#settimeout><tt>settimeout</tt></a>,
<a href=tcp.html#shutdown><tt>shutdown</tt></a>, and
<a href=tcp.html#close><tt>close</tt></a>.
</p>
@ -185,7 +193,7 @@ A simple echo server, using LuaSocket. The program binds to an ephemeral
port (one that is chosen by the operating system) on the local host and
awaits client connections on that port. When a connection is established,
the program reads a line from the remote end and sends it back, closing
the connection immediately after. You can test it using the telnet
the connection immediately. You can test it using the telnet
program.
</p>
@ -231,6 +239,12 @@ simplicity (no connection setup) and performance (no error checking or
error correction).
</p>
<p>
Note that although no guarantees are made, these days
networks are so good that, under normal circumstances, few errors
happen in practice.
</p>
<p>
An UDP socket object is created by the
<a href=udp.html#udp><tt>socket.udp</tt></a> function. UDP
@ -288,14 +302,13 @@ error message.
<pre class=example>
-- change here to the host an port you want to contact
host = "localhost"
port = 13
local host, port = "localhost", 13
-- load namespace
local socket = require("socket")
-- convert host name to ip address
local ip = socket.try(socket.dns.toip(host))
-- create a new UDP object
local udp = socket.udp()
local udp = socket.try(socket.udp())
-- contact daytime host
socket.try(udp:sendto("anything", ip, port))
-- retrieve the answer and print results

View File

@ -35,13 +35,21 @@
<h2 id=ltn12>LTN12</h2>
<p> The LTN12 module implements the ideas described in
<p> The <tt>ltn12</tt> namespace implements the ideas described in
<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">
LTN012, Filters sources and sinks</a>. This manual simply describe the
LTN012, Filters sources and sinks</a>. This manual simply describes the
functions. Please refer to the LTN for a deeper explanation of the
functionality provided by this module.
</p>
<p class=description> To obtain the <tt>ltn12</tt> namespace, run:
</p>
<pre class=example>
-- loads the LTN21 module
local ltn12 = require("ltn12")
</pre>
<!-- filters ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<h3 id="filter">Filters</h3>
@ -68,15 +76,15 @@ The function returns the chained filter.
</p>
<p class=note>
The nesting of filters can be arbritrary. For instance, the useless filter
The nesting of filters can be arbitrary. For instance, the useless filter
below doesn't do anything but return the data that was passed to it,
unaltered.
</p>
<pre class=example>
-- load required modules
ltn12 = require("ltn12")
mime = require("mime")
local ltn12 = require("ltn12")
local mime = require("mime")
-- create a silly identity filter
id = ltn12.filter.chain(
@ -165,12 +173,7 @@ ltn12.sink.<b>chain(</b>filter, sink<b>)</b>
</p>
<p class=description>
Creates a new sink that passes data through a <tt>filter</tt> before sending
it to a given <tt>sink</tt>.
</p>
<p class=return>
The function returns the new sink.
Creates and returns a new sink that passes data through a <tt>filter</tt> before sending it to a given <tt>sink</tt>.
</p>
<!-- error ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@ -180,7 +183,7 @@ ltn12.sink.<b>error(</b>message<b>)</b>
</p>
<p class=description>
Creates and returns a sink that aborts transmission with an error
Creates and returns a sink that aborts transmission with the error
<tt>message</tt>.
</p>
@ -202,7 +205,7 @@ Creates a sink that sends data to a file.
<p class=return>
The function returns a sink that sends all data to the given <tt>handle</tt>
and closes the file when done, or a sink that aborts the transmission with
an error <tt>message</tt>
the error <tt>message</tt>
</p>
<p class=note>
@ -258,7 +261,7 @@ efficiently concatenated into a single string.
</p>
<p class=return>
The function returns the sink and the table.
The function returns the sink and the table used to store the chunks.
</p>
<pre class=example>
@ -266,14 +269,14 @@ The function returns the sink and the table.
local http = require("http")
local ltn12 = require("ltn12")
-- the http.get function
function get(u)
-- a simplified http.get function
function http.get(u)
local t = {}
local respt = request{
url = u,
sink = ltn12.sink.table(t)
}
return table.concat(t), respt.headers, respt.code, respt.error
return table.concat(t), respt.headers, respt.code
end
</pre>
@ -334,7 +337,7 @@ ltn12.source.<b>error(</b>message<b>)</b>
</p>
<p class=description>
Creates and returns a source that aborts transmission with an error
Creates and returns a source that aborts transmission with the error
<tt>message</tt>.
</p>
@ -357,7 +360,7 @@ Creates a source that produces the contents of a file.
The function returns a source that reads chunks of data from
given <tt>handle</tt> and returns it to the user,
closing the file when done, or a source that aborts the transmission with
an error <tt>message</tt>
the error <tt>message</tt>
</p>
<p class=note>

View File

@ -36,7 +36,7 @@
<h2 id=mime>MIME</h2>
<p>
The MIME module offers filters that apply and remove common
The <tt>mime</tt> namespace offers filters that apply and remove common
content transfer encodings, such as Base64 and Quoted-Printable.
It also provides functions to break text into lines and change
the end-of-line convention.
@ -55,6 +55,15 @@ follows the ideas presented in
LTN012, Filters sources and sinks</a>.
</p>
<p class=description> To obtain the <tt>mime</tt> namespace, run:
</p>
<pre class=example>
-- loads the MIME module and everything it requires
local mime = require("mime")
</pre>
<!-- High-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<h3 id=high>High-level filters</h3>
@ -108,7 +117,7 @@ The function returns the created filter.
<p class=name id="encode">
mime.<b>encode(</b>"base64"<b>)</b><br>
mime.<b>encode(</b>"quoted-printable" [, mode])</b>
mime.<b>encode(</b>"quoted-printable" [, mode]<b>)</b>
</p>
<p class=description>
@ -278,7 +287,7 @@ that can be encoded unambiguously. <tt>B</tt> has the remaining bytes of
<tt>C..D</tt>, <em>before</em> encoding.
If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> is padded with
the encoding of the remaining bytes of <tt>C</tt>.
Throughout encoding, occurences of CRLF are replaced by the
Throughout encoding, occurrences of CRLF are replaced by the
<tt>marker</tt>, which itself defaults to CRLF.
</p>

View File

@ -152,7 +152,6 @@
<a href="socket.html#version">VERSION</a>.
</blockquote>
</blockquote>
</table>
<!-- tcp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->

View File

@ -105,6 +105,8 @@ smtp.<b>send{</b><br>
&nbsp;&nbsp;from = <i>string</i>,<br>
&nbsp;&nbsp;rcpt = <i>string</i> or <i>string-table</i>,<br>
&nbsp;&nbsp;source = <i>LTN12 source</i>,<br>
&nbsp;&nbsp;[user = <i>string</i>],<br>
&nbsp;&nbsp;[password = <i>string</i>],<br>
&nbsp;&nbsp;[server = <i>string</i>],<br>
&nbsp;&nbsp;[port = <i>string</i>]<br>
&nbsp;&nbsp;[domain = <i>string</i>],<br>
@ -127,7 +129,11 @@ address, or a string
in case there is just one recipient.
The contents of the message are given by a <em>simple</em> LTN12 <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
@ -135,7 +141,6 @@ 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>
If successful, the function returns 1. Otherwise, the function returns
@ -293,7 +298,7 @@ and an epilogue.
<p class=return>
The function returns a <em>simple</em> LTN12 source that produces the
message contents as defined by <tt>mesgt</tt>. Hopefuly, the following
message contents as defined by <tt>mesgt</tt>. Hopefully, the following
example will make things clear. When in doubt, refer to the appropriate RFC
as listed in the introduction. </p>

View File

@ -164,7 +164,7 @@ source from a stream socket object.
</p>
<p class=parameters>
<tt>Mode</tt> defines the behaviour of the source. The following
<tt>Mode</tt> defines the behavior of the source. The following
options are available:
</p>
<ul>
@ -194,15 +194,16 @@ Throws an exception in case of error.
</p>
<p class=parameters>
</b>Ret<sub>1</sub>, ret<sub>2</sub> ... ret<sub>N</sub> can be arbitrary
<tt>Ret</tt><sub>1</sub>, <tt>ret</tt><sub>2</sub> ... <tt>ret</tt><sub>N</sub> can be arbitrary
arguments, but are usually the return values of a function call that
nested with the call to <tt>try</tt>.
</p>
<p class=return>
The function returns ret<sub>1</sub>, ret<sub>2</sub> ... ret<sub>N</sub> if
ret<sub>1</sub> is not <tt><b>nil</b></tt>. Otherwise, calls <tt>error</tt>
passing ret<sub>2</sub>.
The function returns <tt>ret</tt><sub>1</sub>, <tt>ret</tt><sub>2</sub> ...
<tt>ret</tt><sub>N</sub> if
<tt>ret</tt><sub>1</sub> is not <tt><b>nil</b></tt>. Otherwise, calls <tt>error</tt>
passing <tt>ret</tt><sub>2</sub>.
</p>
<pre class=example>

View File

@ -1,3 +1,9 @@
-----------------------------------------------------------------------------
-- Little program to convert to and from Base64
-- LuaSocket sample files
-- Author: Diego Nehab
-- RCS ID: $Id$
-----------------------------------------------------------------------------
local ltn12 = require("ltn12")
local mime = require("mime")
local source = ltn12.source.file(io.stdin)

View File

@ -71,7 +71,7 @@ local function get_ERROR(dgram)
end
-----------------------------------------------------------------------------
-- High level TFTP API
-- The real work
-----------------------------------------------------------------------------
local function tget(gett)
local retries, dgram, sent, datahost, dataport, code

View File

@ -23,6 +23,7 @@ BLOCKSIZE = 2048
-----------------------------------------------------------------------------
-- returns a high level filter that cycles a low-level filter
function filter.cycle(low, ctx, extra)
assert(low)
return function(chunk)
local ret
ret, ctx = low(ctx, chunk, extra)
@ -32,6 +33,7 @@ end
-- chains two filters together
local function chain2(f1, f2)
assert(f1 and f2)
local co = coroutine.create(function(chunk)
while true do
local filtered1 = f1(chunk)
@ -95,6 +97,7 @@ end
-- turns a fancy source into a simple source
function source.simplify(src)
assert(src)
return function()
local chunk, err_or_new = src()
src = err_or_new or src
@ -118,6 +121,7 @@ end
-- creates rewindable source
function source.rewind(src)
assert(src)
local t = {}
return function(chunk)
if not chunk then
@ -132,6 +136,7 @@ end
-- chains a source with a filter
function source.chain(src, f)
assert(src and f)
local co = coroutine.create(function()
while true do
local chunk, err = src()
@ -186,6 +191,7 @@ end
-- turns a fancy sink into a simple sink
function sink.simplify(snk)
assert(snk)
return function(chunk, err)
local ret, err_or_new = snk(chunk, err)
if not ret then return nil, err_or_new end
@ -224,6 +230,7 @@ end
-- chains a sink with a filter
function sink.chain(f, snk)
assert(f and snk)
return function(chunk, err)
local filtered = f(chunk)
local done = chunk and ""
@ -248,6 +255,7 @@ end
-- pumps all data from a source to a sink, using a step function
function pump.all(src, snk, step)
assert(src and snk)
step = step or pump.step
while true do
local ret, err = step(src, snk)

View File

@ -11,6 +11,7 @@
local smtp = requirelib("smtp", "luaopen_smtp", getfenv(1))
local socket = require("socket")
local ltn12 = require("ltn12")
local mime = require("mime")
local tp = require("tp")
-----------------------------------------------------------------------------
@ -43,7 +44,7 @@ local metat = { __index = {} }
function metat.__index:greet(domain)
socket.try(self.tp:check("2.."))
socket.try(self.tp:command("EHLO", domain or DOMAIN))
return socket.try(self.tp:check("2.."))
return socket.skip(1, socket.try(self.tp:check("2..")))
end
function metat.__index:mail(from)
@ -73,6 +74,32 @@ function metat.__index:close()
return socket.try(self.tp:close())
end
function metat.__index:login(user, password)
socket.try(self.tp:command("AUTH", "LOGIN"))
socket.try(self.tp:check("3.."))
socket.try(self.tp:command(mime.b64(user)))
socket.try(self.tp:check("3.."))
socket.try(self.tp:command(mime.b64(password)))
return socket.try(self.tp:check("2.."))
end
function metat.__index:plain(user, password)
local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password)
socket.try(self.tp:command("AUTH", auth))
return socket.try(self.tp:check("2.."))
end
function metat.__index:auth(user, password, ext)
if not user or not password then return 1 end
if string.find(ext, "AUTH[^\n]+LOGIN") then
return self:login(user, password)
elseif string.find(ext, "AUTH[^\n]+PLAIN") then
return self:plain(user, password)
else
socket.try(nil, "authentication not supported")
end
end
-- send message or throw an exception
function metat.__index:send(mailt)
self:mail(mailt.from)
@ -205,10 +232,10 @@ end
---------------------------------------------------------------------------
-- High level SMTP API
-----------------------------------------------------------------------------
socket.protect = function(a) return a end
send = socket.protect(function(mailt)
local con = open(mailt.server, mailt.port)
con:greet(mailt.domain)
local ext = con:greet(mailt.domain)
con:auth(mailt.user, mailt.password, ext)
con:send(mailt)
con:quit()
return con:close()

View File

@ -8,7 +8,7 @@ local qptest = "qptest.bin"
local eqptest = "qptest.bin2"
local dqptest = "qptest.bin3"
local b64test = "luasocket.so"
local b64test = "luasocket.dylib"
local eb64test = "b64test.bin"
local db64test = "b64test.bin2"