LuaSocket: TCP/IP support for the Lua language


Contents


What is LuaSocket?

LuaSocket is a Lua extension library that provides support for TCP/IP socket layer within the Lua language. The library also provides support for SMTP (sending e-mails), HTTP (www) and FTP (uploading and downloading files).

It can be used by any Lua application desiring access to TCP/IP communication, once it has been properly linked with and initialized by the interpreter running the application. The code has been tested and runs well both on Windows and on Unix Platforms.

The library is available under the same terms as the Lua language, that is, it can be used at no cost for both academic and commercial purposes.

Copyright (C) 2000 TeCGraf, PUC-Rio. All rights reserved.
Author: Diego Nehab

Introduction

To have the TCP/IP functions made available to a Lua script, the interpreter running the script must be linked to the luasocket library. The functions are registered in the Lua scope when the interpreter calls the C function lua_socketlibopen, the only C function exported by the library. The scripts can then use all registered functions.

To connect to a server, a client application creates a client socket object with a call to the function connect. Once this object is created, the client application can use the functions send and receive to exchange information with the server. After all data exchange is done, the client application can close the connection by calling the close function on the client socket.

On the server side, a server application binds to an address with a call to the bind function, which returns a server socket object. The server application can then accept remote connections on the server socket, with calls to the accept function. This function returns a client socket, through which the server application can communicate with the client application that attempted connection. Both server and client sockets can be closed with the close function.

All functions are available both as stand-alone functions and as methods of the socket objects. For example, the function call send(socket,"test") is equivalent to the function call socket:send("test"), where socket is a client socket.

Download

LuaSocket version 1.1 is now available for download! It is compatible with Lua 4.0 and has been tested on Windows 98, Windows 2000, Linux, AIX, SunOS and Solaris.

luasocket-1.1.tar.gz
luasocket-1.1.zip

What's New

Incompatibilities with Previous Versions

The only incompatibility with previous version is the return value of the bind function. It used to return only the server socket and and error message.

Function Reference

All the functions of the API are described below. Several examples are given in the distribution, including the automated tests and the full implementation of the protocols FTP, SMTP and HTTP.

accept(socket)

Returns a client socket object, representing a client attempting connection on the server socket socket. The function blocks until a connection attempt is detected.

bind(address, port [, backlog])

Binds to the address address and port port on the local host. Address can be an IP address or a host name. If address is '*', the system decides the address to bind to. If the chosen port is 0, the system decides what port to bind to. The optional parameter backlog (default value 1) specifies the number of client connections that can be queued waiting for service. If the queue is full and another client attempts connection, the connection is refused. In case of success, the function returns a server socket, on which the operations accept, close and listen are permitted. As two extra values, the function returns a string with the IP address bound to and a number with the port bound to. In case of error, the function returns nil followed by a string describing the error.

close(socket)

Closes the socket socket. No further operations are allowed on a closed socket. In case socket is a server socket, the address to which it is bound is made available to other applications. It is important to close all used sockets once they are not needed, since, in many systems, each socket uses a file descriptor, which are a limited system resource.

connect(address, port)

Attempts connection to address address and port port. Address can be an IP address or a host name. In case of success, the function returns a client socket on which the operations send, receive and close are permitted. In case of error, the function returns nil followed by a string describing the error.

listen(socket, backlog)

Changes the backlog parameter of the server socket socket.

send(socket, string1 [, string2, ... stringN])

Sends the strings string1, string2, ... stringN through the client socket socket. The function returns an error code, which is nil in case of success, the string 'closed' in case the connection was closed before the transmission was complete or the string 'timeout' in case there was a timeout during the operation. After the error code, the function returns the number of bytes accepted by the transport layer.

receive(socket [, pattern1, pattern2, ... patternN])

Receives pattern1, pattern2, ... patternN from the client socket socket. A pattern can be one of the following:

The function returns one string for each pattern, followed by a single error code that can be nil in case of success, the string 'closed' in case the connection was closed before the transmission was complete or the string 'timeout' in case there was a timeout during the operation. The patterns number and '*a' are the most efficient and should be used whenever possible.

timeout(socket, value [, mode])

Changes the timeout values for the socket socket. By default, all I/O operations are blocking. That is, any call to the functions send and receive will block indefinetely, until the operation completes. The timeout function defines a limit on the ammount of time the functions can block, specified as the value parameter, in seconds. There are two timeout modes and both can be used together for fine tuning:

Supported Protocols Reference

Besides raw TCP/IP transport layer capabilities, the LuaSocket toolkit offers straightforward support for the HTTP, SMTP and FTP protocols. The support is implemented in the Lua language and is distributed as three separate modules.

SMTP

The module smtp.lua provides functionality to send e-mail messages to a SMTP mail server. The implementation conforms to RFC 821.

MIME Headers are represented as a table in the form:

headers = {
  ["field-1-name"] = "field-1-value",
  ["field-2-name"] = "field-2-value",
  ["field-3-name"] = "field-3-value",
         ...               ...
  ["field-n-name"] = "field-n-value"
}
The module exports two functions:

smtp_mail(from, rcpt, headers, body, server)

Sends a message to recipient list rcpt, a lua table. The sender is given by the e-mail address from. The message is composed by the optional MIME Headers headers and text body. The message is sent using the server server. If successfull, the function returns nil, otherwise an error message is returned.

Examples:

headers = {
  to = "fulano@tecgraf.puc-rio.br, beltrano@tecgraf.puc-rio.br",
  subject = "LuaSocket test message"
}
from = "luasocket@tecgraf.puc-rio.br"
rcpt = {
  "fulano@tecgraf.puc-rio.br",
  "beltrano@tecgraf.puc-rio.br",
  "sicrano@tecgraf.puc-rio.br"
}
body = "This is a test message. Please ignore."
server = "localhost"
-- connects to server "localhost" and sends a message to users 
-- "fulano@tecgraf.puc-rio.br" and "beltrano@tecgraf.puc-rio.br"
-- "sicrano@tecgraf.puc-rio.br" receives a 'blind carbon copy' of the message.
e = smtp_mail(from, rcpt, headers, body, server)

mail{to=tolist, from=frm, subject=sbj, message=msg, cc=cclist, bcc=bcclist, mailserver=server}

The mail function, for compatibility, implements the same interface as that of CGILua 3.2, except the mailserver parameter is mandatory.

to:A comma-separated list of the emails of the recipients of the message.
from:The email of the sender.
subject:(Optional). The subject of the message.
message: (Optional). The body of the message.
cc: (Optional). A comma-separated list of the emails of the recipients "carbon-copy" of the message.
bcc: (Optional). A comma-separated list of the emails of the recipients "blind carbon-copy" of the message.
mailserver: address of SMTP server to be used.

The function returns nil if the message was sent successfully. In case of error, an error message is returned.

HTTP

The module http.lua provides functionality to download an URL from an HTTP server. The implementation conforms to the HTTP/1.1 standard, RFC 2068.

URLs must conform to RFC 1738, that is, an URL is a string in the form:

[http://][<user>[:<password>]@]<host>[:<port>][/<path>] 
MIME Headers are represented as a table in the form:

headers = {
  ["field-1-name"] = "field-1-value",
  ["field-2-name"] = "field-2-value",
  ["field-3-name"] = "field-3-value",
         ...               ...
  ["field-n-name"] = "field-n-value"
}
Field names are case insensitive (as specified by the standard) and all API functions work with lowercase field names. Field values are left unmodified.

The module exports one function:

http_get(url [, headers])

Retrieves the URL url sending the MIME Headers headers along with the request.

If successfull, the function returns the body of the document pointed to by url, the mime headers returned by the server, and the server HTTP status reply. In case of error, the function returns whatever it managed to retrieve (nil values representing failure) and and an error message describing the error. If <user> and <password> are provided in the URL, the function uses the Basic Authentication Scheme (see note) to retrieve the document.

Examples:

-- connect to server "www.tecgraf.puc-rio.br" and retrieves this manual
-- file from "~diego/luasocket/manual.html"
f, m, s, e = http_get("http://www.tecgraf.puc-rio.br/~diego/luasocket/manual.html")

-- connect to server "www.tecgraf.puc-rio.br" and tries to retrieve
-- "~diego/auth/index.html". Fails because authentication is needed.
f, m, s, e = http_get("http://www.tecgraf.puc-rio.br/~diego/auth/index.html")
-- s returns with value "401 Authentication Required"

Note: Some URLs are protected by their servers from anonymous download. For those URLs, the server must receive some sort of authentication along with the request or it will deny download and return status "401 Authentication Required".

The HTTP/1.1 standard defines two authentication methods: the Basic Authentication Scheme and the Digest Authentication Sheme, both explained in detail in RFC 2068.

The Basic Authentication Scheme sends <user> and <password> unencrypted to the server and is therefore considered unsafe. Unfortunatelly, by the time of this implementation, the wide majority of servers and browsers support the Basic Scheme only. Therefore, this is the method used by the toolkit whenever authentication is required.

Example:

-- connect to server "www.tecgraf.puc-rio.br" and tries to retrieve
-- "~diego/auth/index.html", using the provided name and password to
-- authenticate the request
f, m, s, e = http_get("http://diego:nehab@www.tecgraf.puc-rio.br/~diego/auth/index.html")

-- alternatively, one could fill the appropriate header and authenticate
-- the request directly. both calls are equivalent
h = {authentication = "Basic " .. base64("diego:nehab")}
f, m, s, e = http_get("http://www.tecgraf.puc-rio.br/~diego/auth/index.html", h)

FTP

The module ftp.lua provides functions to download and upload files from and to FTP servers. The implementation conforms to RFC 959.

URLs must conform to RFC 1738, that is, an URL is a string in the form:

[ftp://][<user>[:<password>]@]<host>[:<port>][/<path>] 
The module exports two functions:

ftp_get(url [, type])

Downloads the URL url using transfer type type and returns it as a string.

The parameter type can receive values 'a' (ascii, the default) or 'b' (binary) and determines the transfer type. If <path> ends with a '/', a directory listing of <path> is returned. If successfull, the function returns the file contents as a string. In case of error, the function returns nil and an error message describing the error.

If no <user> is provided, the function tries to log in as 'anonymous'.

Examples:

-- log as user "anonymous" on server "ftp.tecgraf.puc-rio.br"
-- go to directory "pub/lua" and get file "lua.tar.gz" as binary.
f, e = ftp_get("ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz", "b")

-- log as user "anonymous" on server "ftp.tecgraf.puc-rio.br"
-- go to director "pub" and retrive directory listing of directory "lua"
f, e = ftp_get("ftp://ftp.tecgraf.puc-rio.br/pub/lua/")

-- log as user "diego", password "nehab", on server "derain.tecgraf.puc-rio.br"
-- go to directory "tec/luasocket/html" and retrieve file "manual.html"
-- (actually, fails because of wrong password :-)
f, e = ftp_get("ftp://diego:nehab@derain.tecgraf.puc-rio.br/tec/luasocket/html/manual.html")

ftp_put(url, data [, type])

Stores a file at url with contents given by the string data and using transfer type type.

The parameter type can receive values 'a' (ascii, the default) or 'b' (binary) and determines the transfer type. If successfull, the function returns nil. In case of error, the function returns a string describing the error.

If no <user> is provided, the function tries to log in as anonymous.

Examples:

-- log as user "anonymous" on server "ftp.free.org" and store file
-- "hello" with contents "hello world!" on current directory
e = ftp_put("ftp://ftp.free.org/hello", "hello world!")


Last modified by Diego Nehab
Wed Dec 27 19:18:50 EDT 2000