From 0a4c1534f39511894728da193ab8225ad6022de9 Mon Sep 17 00:00:00 2001
From: Diego Nehab
-Name resolution function return all information returned by the
+Name resolution functions return all information obtained from the
resolver in a table of the form:
DNS
-Returns the standard host name for the machine. +Returns the standard host name for the machine as a string.
--The function returns a string with the host name. -
- -diff --git a/doc/ftp.html b/doc/ftp.html index e834f07..9fda02b 100644 --- a/doc/ftp.html +++ b/doc/ftp.html @@ -35,12 +35,33 @@
FTP (File Transfer Protocol) is a protocol used to transfer files -between hosts. The module ftp.lua offers simple FTP support. -Applications can easily download and upload files. -The implementation conforms to +between hosts. The ftp namespace offers thorough support +to FTP, under a simple interface. The implementation conforms to RFC 959.
++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 any operation supported by the FTP +protocol. For that, check the implementation. +
+ ++To really benefit from this module, a good understanding of + +LTN012, Filters sources and sinks is necessary. +
+ +To obtain the ftp namespace, run: +
+ ++-- loads the FTP module and any libraries it requires +local ftp = require("ftp") ++
URLs MUST conform to
RFC
@@ -53,21 +74,7 @@ URLs MUST conform to
-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 any operation supported by the FTP
-protocol. For that, check the implementation.
-
-To use some of the functions in this module, a good understanding of
-
-LTN012, Filters sources and sinks is necessary.
-
-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:
@@ -116,7 +124,7 @@ optional arguments are the following:
authentication. Defaults to "ftp:anonymous@anonymous.org";
HTTP (Hyper Text Transfer Protocol) is the protocol used to exchange
-information between web-browsers and servers. The http.lua
-module offers support for the client side of the HTTP protocol (i.e.,
+information between web-browsers and servers. The http
+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,
RFC
@@ -47,11 +48,20 @@ implementation conforms to the HTTP/1.1 standard,
The module exports functions that provide HTTP functionality in different
-levels of abstraction, from the simple get function to the generic, LTN12 based request function.
+levels of abstraction, from the simple
+get function, through the generic
+LTN12 based request function, down to
+even lower-level if you bother to look through the source code.
To obtain the ftp namespace, run:
+
URLs must conform to
RFC
@@ -189,12 +199,12 @@ http.request{
-Performs the generic HTTP request, controled by a request table.
+Performs the generic HTTP request, controlled by a request table.
The most important parameters are the url and the simple LTN12 sink that will receive the downloaded content.
-Any part of the url can be overriden by including
+Any part of the url 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 note)
@@ -231,8 +241,8 @@ respt = {
-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 code. For
a list of the possible values and their meanings, refer to
-
Note: Some URLs are protected by their
diff --git a/doc/index.html b/doc/index.html
index 7a3afa8..888bc92 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -37,21 +37,29 @@
LuaSocket is a Lua 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.
-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.
+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.
+
+LuaSocket is a Lua 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.
+
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 2.0 has been rewritten from scratch to simplify the future
-addition of new domains.
@@ -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.
-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.
+
+Another advantage is the flexible timeout control
mechanism. As in C, all I/O operations are blocking by default. For
example, the send,
receive and
@@ -69,14 +86,6 @@ call might perform several OS calls, so that the two timeout values are
not equivalent.
-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.
-
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
-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.
-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 require 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 "socket" namespace.
-The library distinguishes three types of TCP sockets: master, client and server sockets.
+The library distinguishes three types of TCP sockets: master,
+client and server sockets.
@@ -144,10 +150,11 @@ Master sockets are newly created TCP sockets returned by the function
socket.tcp. A master socket is
transformed into a server socket
after it is associated with a local address by a call to the
-bind method. Conversely, it
+bind method followed by a call to the
+listen. Conversely, a master socket
can be changed into a client socket with the method
connect,
-that associates it with a remote address.
+which associates it with a remote address.
@@ -158,7 +165,7 @@ client socket object is returned representing this connection. The
other methods available for server socket objects are
getsockname,
setoption,
-settimeout and
+settimeout, and
close.
@@ -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",
diff --git a/doc/http.html b/doc/http.html
index bda3088..0fc04cd 100644
--- a/doc/http.html
+++ b/doc/http.html
@@ -37,8 +37,9 @@
+-- loads the HTTP module and any libraries it requires
+local http = require("http")
+
+
+
@@ -208,7 +235,7 @@ that users will have no problems extending the functionality.
Introduction
+Initializing the library
+Note that although no guarantees are made, these days +networks are so good that, under normal circumstances, few errors +happen in practice. +
+An UDP socket object is created by the socket.udp function. UDP @@ -288,14 +302,13 @@ error message.
-- 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 diff --git a/doc/ltn12.html b/doc/ltn12.html index 363ce43..7b379c2 100644 --- a/doc/ltn12.html +++ b/doc/ltn12.html @@ -35,13 +35,21 @@LTN12
-The LTN12 module implements the ideas described in +
The ltn12 namespace implements the ideas described in -LTN012, Filters sources and sinks. This manual simply describe the +LTN012, Filters sources and sinks. This manual simply describes the functions. Please refer to the LTN for a deeper explanation of the functionality provided by this module.
+To obtain the ltn12 namespace, run: +
+ ++-- loads the LTN21 module +local ltn12 = require("ltn12") ++Filters
@@ -68,15 +76,15 @@ The function returns the chained filter.-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.
-- 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.chain(filter, sink)-Creates a new sink that passes data through a filter before sending -it to a given sink. -
- --The function returns the new sink. +Creates and returns a new sink that passes data through a filter before sending it to a given sink.
@@ -180,7 +183,7 @@ ltn12.sink.error(message)-Creates and returns a sink that aborts transmission with an error +Creates and returns a sink that aborts transmission with the error message.
@@ -202,7 +205,7 @@ Creates a sink that sends data to a file.The function returns a sink that sends all data to the given handle and closes the file when done, or a sink that aborts the transmission with -an error message +the error message
@@ -258,7 +261,7 @@ efficiently concatenated into a single string.
-The function returns the sink and the table. +The function returns the sink and the table used to store the chunks.
@@ -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@@ -334,7 +337,7 @@ ltn12.source.error(message)-Creates and returns a source that aborts transmission with an error +Creates and returns a source that aborts transmission with the error message.
@@ -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 handle and returns it to the user, closing the file when done, or a source that aborts the transmission with -an error message +the error messagediff --git a/doc/mime.html b/doc/mime.html index 286e41c..791861e 100644 --- a/doc/mime.html +++ b/doc/mime.html @@ -36,7 +36,7 @@
MIME
-The MIME module offers filters that apply and remove common +The mime 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.
+To obtain the mime namespace, run: +
+ ++-- loads the MIME module and everything it requires +local mime = require("mime") ++ +High-level filters
@@ -108,7 +117,7 @@ The function returns the created filter.mime.encode("base64")
-mime.encode("quoted-printable" [, mode]) +mime.encode("quoted-printable" [, mode])@@ -278,7 +287,7 @@ that can be encoded unambiguously. B has the remaining bytes of C..D, before encoding. If D is nil, A is padded with the encoding of the remaining bytes of C. -Throughout encoding, occurences of CRLF are replaced by the +Throughout encoding, occurrences of CRLF are replaced by the marker, which itself defaults to CRLF.
diff --git a/doc/reference.html b/doc/reference.html index ebcfb5b..43aeea5 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -152,7 +152,6 @@ VERSION. - diff --git a/doc/smtp.html b/doc/smtp.html index 03698bf..0fdc4a4 100644 --- a/doc/smtp.html +++ b/doc/smtp.html @@ -105,6 +105,8 @@ smtp.send{
from = string,
rcpt = string or string-table,
source = LTN12 source,
+ [user = string],
+ [password = string],
[server = string],
[port = string]
[domain = string],
@@ -127,7 +129,11 @@ address, or a string in case there is just one recipient. The contents of the message are given by a simple LTN12 source. Several arguments are optional: +
If successful, the function returns 1. Otherwise, the function returns @@ -293,7 +298,7 @@ and an epilogue.
The function returns a simple LTN12 source that produces the -message contents as defined by mesgt. Hopefuly, the following +message contents as defined by mesgt. Hopefully, the following example will make things clear. When in doubt, refer to the appropriate RFC as listed in the introduction.
diff --git a/doc/socket.html b/doc/socket.html index dbfdaed..b3fbb6e 100644 --- a/doc/socket.html +++ b/doc/socket.html @@ -164,7 +164,7 @@ source from a stream socket object.-Mode defines the behaviour of the source. The following +Mode defines the behavior of the source. The following options are available:
-Ret1, ret2 ... retN can be arbitrary +Ret1, ret2 ... retN can be arbitrary arguments, but are usually the return values of a function call that nested with the call to try.
-The function returns ret1, ret2 ... retN if -ret1 is not nil. Otherwise, calls error -passing ret2. +The function returns ret1, ret2 ... +retN if +ret1 is not nil. Otherwise, calls error +passing ret2.
diff --git a/etc/b64.lua b/etc/b64.lua index 4d5f83e..d74c949 100644 --- a/etc/b64.lua +++ b/etc/b64.lua @@ -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) diff --git a/etc/tftp.lua b/etc/tftp.lua index 5238de0..6a1a093 100644 --- a/etc/tftp.lua +++ b/etc/tftp.lua @@ -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 diff --git a/src/ltn12.lua b/src/ltn12.lua index bb527bd..09771d4 100644 --- a/src/ltn12.lua +++ b/src/ltn12.lua @@ -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) diff --git a/src/smtp.lua b/src/smtp.lua index fb76ea4..2ea6097 100644 --- a/src/smtp.lua +++ b/src/smtp.lua @@ -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() diff --git a/test/mimetest.lua b/test/mimetest.lua index 808c402..2d5bce6 100644 --- a/test/mimetest.lua +++ b/test/mimetest.lua @@ -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"