From f98977b2dac48fc66822402b095336e683715126 Mon Sep 17 00:00:00 2001
From: Caleb Maclennan
+IPv4 name resolution functions
+dns.toip
+and
+dns.tohostname
+return all information obtained from
+the resolver in a table of the form:
+
+Note that the alias list can be empty.
+
+The more general name resolution function
+dns.getaddrinfo, which
+supports both IPv6 and IPv4,
+returns all information obtained from
+the resolver in a table of the form:
+
+Here, family contains the string "inet" for IPv4
+addresses, and "inet6" for IPv6 addresses.
+
+socket.dns.getaddrinfo(address)
+
+Converts from host name to address.
+
+Address can be an IPv4 or IPv6 address or host name.
+
+The function returns a table with all information returned by
+the resolver. In case of error, the function returns nil
+followed by an error message.
+
+socket.dns.gethostname()
+
+Returns the standard host name for the machine as a string.
+
+socket.dns.tohostname(address)
+
+Converts from IPv4 address to host name.
+
+Address can be an IP address or host name.
+
+The function returns a string with the canonic host name of the given
+address, followed by a table with all information returned by
+the resolver. In case of error, the function returns nil
+followed by an error message.
+
+socket.dns.toip(address)
+
+Converts from host name to IPv4 address.
+
+Address can be an IP address or host name.
+
+Returns a string with the first IP address found for address,
+followed by a table with all information returned by the resolver.
+In case of error, the function returns nil followed by an error
+message.
+
+FTP (File Transfer Protocol) is a protocol used to transfer files
+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:
+
+URLs MUST conform to
+RFC 1738,
+that is, an URL is a string in the form:
+
+The following constants in the namespace can be set to control the default behavior of
+the FTP module:
+
+ftp.get(url)
+The get function has two forms. The simple form has fixed
+functionality: it downloads the contents of a URL and returns it as a
+string. The generic form allows a lot more control, as explained
+below.
+
+If the argument of the get function is a table, the function
+expects at least the fields host, sink, and one of
+argument or path (argument takes
+precedence). Host is the server to connect to. Sink is
+the simple
+LTN12
+sink that will receive the downloaded data. Argument or
+path give the target path to the resource in the server. The
+optional arguments are the following:
+
+If successful, the simple version returns the URL contents as a
+string, and the generic function returns 1. In case of error, both
+functions return nil and an error message describing the
+error.
+
+ftp.put(url, content)
+The put function has two forms. The simple form has fixed
+functionality: it uploads a string of content into a URL. The generic form
+allows a lot more control, as explained below.
+
+If the argument of the put function is a table, the function
+expects at least the fields host, source, and one of
+argument or path (argument takes
+precedence). Host is the server to connect to. Source is
+the simple
+LTN12
+source that will provide the contents to be uploaded.
+Argument or
+path give the target path to the resource in the server. The
+optional arguments are the following:
+
+Both functions return 1 if successful, or nil and an error
+message describing the reason for failure.
+
+HTTP (Hyper Text Transfer Protocol) is the protocol used to exchange
+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 2616.
+
+The module exports functions that provide HTTP functionality in different
+levels of abstraction. From the simple
+string oriented requests, through generic
+LTN12 based, down to even lower-level if you bother to look through the source code.
+
+To obtain the http namespace, run:
+
+URLs must conform to
+RFC 1738,
+that is, an URL is a string in the form:
+
+MIME headers are represented as a Lua table in the form:
+
+Field names are case insensitive (as specified by the standard) and all
+functions work with lowercase field names (but see
+socket.headers.canonic).
+Field values are left unmodified.
+
+Note: MIME headers are independent of order. Therefore, there is no problem
+in representing them in a Lua table.
+
+The following constants can be set to control the default behavior of
+the HTTP module:
+
+Note: These constants are global. Changing them will also
+change the behavior other code that might be using LuaSocket.
+
+http.request(url [, body])
+The request function has two forms. The simple form downloads
+a URL using the GET or POST method and is based
+on strings. The generic form performs any HTTP method and is
+LTN12 based.
+
+If the first argument of the request function is a string, it
+should be an url. In that case, if a body
+is provided as a string, the function will perform a POST method
+in the url. Otherwise, it performs a GET in the
+url
+
+If the first argument is instead a table, the most important fields are
+the url and the simple
+LTN12
+sink that will receive the downloaded content.
+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)
+to retrieve the document. If sink is nil, the
+function discards the downloaded data. The optional parameters are the
+following:
+
+In case of failure, the function returns nil followed by an
+error message. If successful, the simple form returns the response
+body as a string, followed by the response status code, the response
+headers and the response status line. The generic function returns the same
+information, except the first return value is just the number 1 (the body
+goes to the sink).
+
+Even when the server fails to provide the contents of the requested URL (URL not found, for example),
+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 RFC 2616.
+
+Here are a few examples with the simple interface:
+
+And here is an example using the generic interface:
+
+Note: When sending a POST request, simple interface adds a
+"Content-type: application/x-www-form-urlencoded"
+header to the request. This is the type used by
+HTML forms. If you need another type, use the generic
+interface.
+
+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 Scheme, both
+explained in detail in
+RFC 2068.
+ The Basic Authentication Scheme sends
+<user> and
+<password> unencrypted to the server and is therefore
+considered unsafe. Unfortunately, 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.
+
+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
+functionality commonly needed by applications that deal with the Internet.
+
+The core support has been implemented so that it is both efficient and
+simple to use. It is available to any Lua application once it has been
+properly initialized by the interpreter in use. The code has been tested
+and runs well on several Windows and UNIX platforms.
+Among the support modules, the most commonly used 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
+functionality defined by each protocol.
+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.
+
+The library is available under the same
+
+terms and conditions as the Lua language, the MIT license. The idea is
+that if you can use Lua in a project, you should also be able to use
+LuaSocket.
+
+Copyright © 1999-2013 Diego Nehab. All rights reserved.
+LuaSocket version 3.0-rc1 is now available for download!
+It is compatible with Lua 5.1 and 5.2, and has
+been tested on Windows XP, Linux, and Mac OS X. Chances
+are it works well on most UNIX distributions and Windows flavors.
+
+The current version of the library can be found at
+the LuaSocket
+project page on GitHub. Besides the full C and Lua source code
+for the library, the distribution contains several examples,
+this user's manual and basic test procedures.
+ Take a look at the installation section of the
+manual to find out how to properly install the library.
+
+This marks the first release of LuaSocket that
+wholeheartedly embraces the open-source development
+philosophy. After a long hiatus, Matthew Wild finally
+convinced me it was time for a release including IPv6 and
+Lua 5.2 support. It was more work than we anticipated.
+Special thanks to Sam Roberts, Florian Zeitz, and Paul
+Aurich, Liam Devine, Alexey Melnichuk, and everybody else
+that has helped bring this library back to life.
+
+Main changes for LuaSocket 3.0-rc1 are IPv6 support
+and Lua 5.2 compatibility.
+
+All previous versions of the LuaSocket library can be downloaded
+here. Although these versions are no longer supported, they are
+still available for those that have compatibility issues.
+ Here we describe the standard distribution. If the
+standard doesn't meet your needs, we refer you to the Lua
+discussion list, where any question about the package scheme
+will likely already have been answered. On Unix systems, the standard distribution uses two base
+directories, one for system dependent files, and another for system
+independent files. Let's call these directories <CDIR>
+and <LDIR>, respectively.
+For example, in my laptp, Lua 5.1 is configured to
+use '/usr/local/lib/lua/5.1' for
+<CDIR> and '/usr/local/share/lua/5.1' for
+<LDIR>. On Windows, <CDIR>
+usually points to the directory where the Lua executable is
+found, and <LDIR> points to a
+lua/ directory inside <CDIR>. (These
+settings can be overridden by environment variables
+LUA_PATH and LUA_CPATH. See the Lua
+documentation for details.) Here is the standard LuaSocket
+distribution directory structure: Naturally, on Unix systems, core.dll
+would be replaced by core.so.
+ With the above setup, and an interpreter with shared library support,
+it should be easy to use LuaSocket. Just fire the interpreter and use the
+require function to gain access to whatever module you need: Each module loads their dependencies automatically, so you only need to
+load the modules you directly depend upon:
+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.
+
+The API design had two goals in mind. First, users
+experienced with the C API to sockets should feel comfortable using LuaSocket.
+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 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
+accept methods
+of the TCP domain will block the caller application until
+the operation is completed (if ever!). However, with a call to the
+settimeout
+method, an application can specify upper limits on
+the time it can be blocked by LuaSocket (the "total" timeout), on
+the time LuaSocket can internally be blocked by any OS call (the
+"block" timeout) or a combination of the two. Each LuaSocket
+call might perform several OS calls, so that the two timeout values are
+not equivalent.
+
+Finally, the host name resolution is transparent, meaning that most
+functions and methods accept both IP addresses and host names. In case a
+host name is given, the library queries the system's resolver and
+tries the main IP address returned. Note that direct use of IP addresses
+is more efficient, of course. The
+toip
+and tohostname
+functions from the DNS module are provided to convert between host names and IP addresses.
+
+Together, these changes make network programming in LuaSocket much simpler
+than it is in C, as the following sections will show.
+
+TCP (Transfer Control Protocol) is reliable stream protocol. In other
+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 granularities: patterns are available for
+lines, arbitrary sized blocks or "read up to connection closed", all with
+good performance.
+
+The library distinguishes three types of TCP sockets: master,
+client and server sockets.
+
+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 followed by a call to the
+listen. Conversely, a master socket
+can be changed into a client socket with the method
+connect,
+which associates it with a remote address.
+
+On server sockets, applications can use the
+accept method
+to wait for a client connection. Once a connection is established, a
+client socket object is returned representing this connection. The
+other methods available for server socket objects are
+getsockname,
+setoption,
+settimeout, and
+close.
+
+Client sockets are used to exchange data between two applications over
+the Internet. Applications can call the methods
+send and
+receive
+to send and receive data. The other methods
+available for client socket objects are
+getsockname,
+getpeername,
+setoption,
+settimeout,
+shutdown, and
+close.
+
+Example:
+
+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. You can test it using the telnet
+program.
+
+UDP (User Datagram Protocol) is a non-reliable datagram protocol. In
+other words, applications communicating through UDP send and receive
+data as independent blocks, which are not guaranteed to reach the other
+end. Even when they do reach the other end, they are not guaranteed to be
+error free. Data transfers are atomic, one datagram at a time. Reading
+only part of a datagram discards the rest, so that the following read
+operation will act on the next datagram. The advantages are in
+simplicity (no connection setup) and performance (no error checking or
+error correction).
+
+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
+sockets do not need to be connected before use. The method
+sendto
+can be used immediately after creation to
+send a datagram to IP address and port. Host names are not allowed
+because performing name resolution for each packet would be forbiddingly
+slow. Methods
+receive and
+receivefrom
+can be used to retrieve datagrams, the latter returning the IP and port of
+the sender as extra return values (thus being slightly less
+efficient).
+
+When communication is performed repeatedly with a single peer, an
+application should call the
+setpeername method to specify a
+permanent partner. Methods
+sendto and
+receivefrom
+can no longer be used, but the method
+send can be used to send data
+directly to the peer, and the method
+receive
+will only return datagrams originating
+from that peer. There is about 30% performance gain due to this practice.
+
+To associate an UDP socket with a local address, an application calls the
+setsockname
+method before sending any datagrams. Otherwise, the socket is
+automatically bound to an ephemeral address before the first data
+transmission and once bound the local address cannot be changed.
+The other methods available for UDP sockets are
+getpeername,
+getsockname,
+settimeout,
+setoption and
+close.
+
+Example:
+
+A simple daytime client, using LuaSocket. The program connects to a remote
+server and tries to retrieve the daytime, printing the answer it got or an
+error message.
+ Although not covered in the introduction, LuaSocket offers
+much more than TCP and UDP functionality. As the library
+evolved, support for HTTP, FTP,
+and SMTP were built on top of these. These modules
+and many others are covered by the reference manual.
+ The ltn12 namespace implements the ideas described in
+
+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:
+
+ltn12.filter.chain(filter1, filter2
+[, ... filterN])
+
+Returns a filter that passes all data it receives through each of a
+series of given filters.
+
+Filter1 to filterN are simple
+filters.
+
+The function returns the chained 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.
+
+ltn12.filter.cycle(low [, ctx, extra])
+
+Returns a high-level filter that cycles though a low-level filter by
+passing it each chunk and updating a context between calls.
+
+Low is the low-level filter to be cycled,
+ctx is the initial context and extra is any extra
+argument the low-level filter might take.
+
+The function returns the high-level filter.
+
+ltn12.pump.all(source, sink)
+
+Pumps all data from a source to a sink.
+
+If successful, the function returns a value that evaluates to
+true. In case
+of error, the function returns a false value, followed by an error message.
+
+ltn12.pump.step(source, sink)
+
+Pumps one chunk of data from a source to a sink.
+
+If successful, the function returns a value that evaluates to
+true. In case
+of error, the function returns a false value, followed by an error message.
+
+ltn12.sink.chain(filter, sink)
+
+Creates and returns a new sink that passes data through a filter before sending it to a given sink.
+
+ltn12.sink.error(message)
+
+Creates and returns a sink that aborts transmission with the error
+message.
+
+ltn12.sink.file(handle, message)
+
+Creates a sink that sends data to a file.
+
+Handle is a file handle. If handle is nil,
+message should give the reason for failure.
+
+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
+the error message
+
+In the following example, notice how the prototype is designed to
+fit nicely with the io.open function.
+
+ltn12.sink.null()
+
+Returns a sink that ignores all data it receives.
+
+ltn12.sink.simplify(sink)
+
+Creates and returns a simple sink given a fancy sink.
+
+ltn12.sink.table([table])
+
+Creates a sink that stores all chunks in a table. The chunks can later be
+efficiently concatenated into a single string.
+
+Table is used to hold the chunks. If
+nil, the function creates its own table.
+
+The function returns the sink and the table used to store the chunks.
+
+ltn12.source.cat(source1 [, source2, ...,
+sourceN])
+
+Creates a new source that produces the concatenation of the data produced
+by a number of sources.
+
+Source1 to sourceN are the original
+sources.
+
+The function returns the new source.
+
+ltn12.source.chain(source, filter)
+
+Creates a new source that passes data through a filter
+before returning it.
+
+The function returns the new source.
+
+ltn12.source.empty()
+
+Creates and returns an empty source.
+
+ltn12.source.error(message)
+
+Creates and returns a source that aborts transmission with the error
+message.
+
+ltn12.source.file(handle, message)
+
+Creates a source that produces the contents of a file.
+
+Handle is a file handle. If handle is nil,
+message should give the reason for failure.
+
+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
+the error message
+
+In the following example, notice how the prototype is designed to
+fit nicely with the io.open function.
+
+ltn12.source.simplify(source)
+
+Creates and returns a simple source given a fancy source.
+
+ltn12.source.string(string)
+
+Creates and returns a source that produces the contents of a
+string, chunk by chunk.
+
+ltn12.source.table(table)
+
+Creates and returns a source that produces the numerically-indexed values of a table successively beginning at 1. The source returns nil (end-of-stream) whenever a nil value is produced by the current index, which proceeds forward regardless.
+
+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.
+MIME is described mainly in
+RFC 2045,
+2046,
+2047,
+2048, and
+2049.
+
+All functionality provided by the MIME module
+follows the ideas presented in
+
+LTN012, Filters sources and sinks.
+
+To obtain the mime namespace, run:
+
+mime.decode("base64")
+Returns a filter that decodes data from a given transfer content
+encoding.
+
+mime.encode("base64")
+Returns a filter that encodes data according to a given transfer content
+encoding.
+
+In the Quoted-Printable case, the user can specify whether the data is
+textual or binary, by passing the mode strings "text" or
+"binary". Mode defaults to "text".
+
+Although both transfer content encodings specify a limit for the line
+length, the encoding filters do not break text into lines (for
+added flexibility).
+Below is a filter that converts binary data to the Base64 transfer content
+encoding and breaks it into lines of the correct size.
+
+Note: Text data has to be converted to canonic form
+before being encoded.
+
+mime.normalize([marker])
+
+Converts most common end-of-line markers to a specific given marker.
+
+Marker is the new marker. It defaults to CRLF, the canonic
+end-of-line marker defined by the MIME standard.
+
+The function returns a filter that performs the conversion.
+
+Note: There is no perfect solution to this problem. Different end-of-line
+markers are an evil that will probably plague developers forever.
+This function, however, will work perfectly for text created with any of
+the most common end-of-line markers, i.e. the Mac OS (CR), the Unix (LF),
+or the DOS (CRLF) conventions. Even if the data has mixed end-of-line
+markers, the function will still work well, although it doesn't
+guarantee that the number of empty lines will be correct.
+
+mime.stuff()
+Creates and returns a filter that performs stuffing of SMTP messages.
+
+Note: The smtp.send function
+uses this filter automatically. You don't need to chain it with your
+source, or apply it to your message body.
+
+mime.wrap("text" [, length])
+Returns a filter that breaks data into lines.
+
+The "text" line-wrap filter simply breaks text into lines by
+inserting CRLF end-of-line markers at appropriate positions.
+Length defaults 76.
+The "base64" line-wrap filter works just like the default
+"text" line-wrap filter with default length.
+The function can also wrap "quoted-printable" lines, taking care
+not to break lines in the middle of an escaped character. In that case, the
+line length is fixed at 76.
+
+For example, to create an encoding filter for the Quoted-Printable transfer content encoding of text data, do the following:
+
+Note: To break into lines with a different end-of-line convention, apply
+a normalization filter after the line break filter.
+
+A, B = mime.b64(C [, D])
+
+Low-level filter to perform Base64 encoding.
+
+A is the encoded version of the largest prefix of
+C..D
+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.
+
+Note: The simplest use of this function is to encode a string into it's
+Base64 transfer content encoding. Notice the extra parenthesis around the
+call to mime.b64, to discard the second return value.
+
+A, n = mime.dot(m [, B])
+
+Low-level filter to perform SMTP stuffing and enable transmission of
+messages containing the sequence "CRLF.CRLF".
+
+A is the stuffed version of B. 'n' gives the
+number of characters from the sequence CRLF seen in the end of B.
+'m' should tell the same, but for the previous chunk.
+ Note: The message body is defined to begin with
+an implicit CRLF. Therefore, to stuff a message correctly, the
+first m should have the value 2.
+
+Note: The smtp.send function
+uses this filter automatically. You don't need to
+apply it again.
+
+A, B = mime.eol(C [, D, marker])
+
+Low-level filter to perform end-of-line marker translation.
+For each chunk, the function needs to know if the last character of the
+previous chunk could be part of an end-of-line marker or not. This is the
+context the function receives besides the chunk. An updated version of
+the context is returned after each new chunk.
+
+A is the translated version of D. C is the
+ASCII value of the last character of the previous chunk, if it was a
+candidate for line break, or 0 otherwise.
+B is the same as C, but for the current
+chunk. Marker gives the new end-of-line marker and defaults to CRLF.
+
+A, B = mime.qp(C [, D, marker])
+
+Low-level filter to perform Quoted-Printable encoding.
+
+A is the encoded version of the largest prefix of
+C..D
+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, occurrences of CRLF are replaced by the
+marker, which itself defaults to CRLF.
+
+Note: The simplest use of this function is to encode a string into it's
+Quoted-Printable transfer content encoding.
+Notice the extra parenthesis around the call to mime.qp, to discard the second return value.
+
+A, m = mime.qpwrp(n [, B, length])
+
+Low-level filter to break Quoted-Printable text into lines.
+
+A is a copy of B, broken into lines of at most
+length bytes (defaults to 76).
+'n' should tell how many bytes are left for the first
+line of B and 'm' returns the number of bytes
+left in the last line of A.
+
+Note: Besides breaking text into lines, this function makes sure the line
+breaks don't fall in the middle of an escaped character combination. Also,
+this function only breaks lines that are bigger than length bytes.
+
+A, B = mime.unb64(C [, D])
+
+Low-level filter to perform Base64 decoding.
+
+A is the decoded version of the largest prefix of
+C..D
+that can be decoded unambiguously. B has the remaining bytes of
+C..D, before decoding.
+If D is nil, A is the empty string
+and B returns whatever couldn't be decoded.
+
+Note: The simplest use of this function is to decode a string from it's
+Base64 transfer content encoding.
+Notice the extra parenthesis around the call to mime.unqp, to discard the second return value.
+
+A, B = mime.unqp(C [, D])
+
+Low-level filter to remove the Quoted-Printable transfer content encoding
+from data.
+
+A is the decoded version of the largest prefix of
+C..D
+that can be decoded unambiguously. B has the remaining bytes of
+C..D, before decoding.
+If D is nil, A is augmented with
+the encoding of the remaining bytes of C.
+
+Note: The simplest use of this function is to decode a string from it's
+Quoted-Printable transfer content encoding.
+Notice the extra parenthesis around the call to mime.unqp, to discard the second return value.
+
+A, m = mime.wrp(n [, B, length])
+
+Low-level filter to break text into lines with CRLF marker.
+Text is assumed to be in the normalize form.
+
+A is a copy of B, broken into lines of at most
+length bytes (defaults to 76).
+'n' should tell how many bytes are left for the first
+line of B and 'm' returns the number of bytes
+left in the last line of A.
+
+Note: This function only breaks lines that are bigger than
+length bytes. The resulting line length does not include the CRLF
+marker.
+ The smtp 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).
+ The implementation conforms to the Simple Mail Transfer Protocol,
+RFC 2821.
+Another RFC of interest is RFC 2822,
+which governs the Internet Message Format.
+Multipart messages (those that contain attachments) are part
+of the MIME standard, but described mainly
+in RFC 2046. In the description below, good understanding of LTN012, Filters
+sources and sinks and the MIME module is
+assumed. In fact, the SMTP module was the main reason for their
+creation.
+To obtain the smtp namespace, run:
+
+MIME headers are represented as a Lua table in the form:
+
+Field names are case insensitive (as specified by the standard) and all
+functions work with lowercase field names (but see
+socket.headers.canonic).
+Field values are left unmodified.
+
+Note: MIME headers are independent of order. Therefore, there is no problem
+in representing them in a Lua table.
+
+The following constants can be set to control the default behavior of
+the SMTP module:
+
+smtp.message(mesgt)
+
+Returns a simple
+LTN12 source that sends an SMTP message body, possibly multipart (arbitrarily deep).
+
+The only parameter of the function is a table describing the message.
+Mesgt has the following form (notice the recursive structure):
+
+For a simple message, all that is needed is a set of headers
+and the body. The message body can be given as a string
+or as a simple
+LTN12
+source. For multipart messages, the body is a table that
+recursively defines each part as an independent message, plus an optional
+preamble and epilogue.
+
+The function returns a simple
+LTN12
+source that produces the
+message contents as defined by mesgt, chunk by chunk.
+Hopefully, the following
+example will make things clear. When in doubt, refer to the appropriate RFC
+as listed in the introduction.
+smtp.send{
+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
+message source factory for
+a very powerful way to define the message contents.
+
+The sender is given by the e-mail address in the from field.
+Rcpt 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 simple
+LTN12
+source. Several arguments are optional:
+
+If successful, the function returns 1. Otherwise, the function returns
+nil followed by an error message.
+
+Note: SMTP servers can be very picky with the format of e-mail
+addresses. To be safe, use only addresses of the form
+"<fulano@example.com>" in the from and
+rcpt arguments to the send function. In headers, e-mail
+addresses can take whatever form you like.
+Big note: There is a good deal of misconception with the use of the
+destination address field headers, i.e., the 'To', 'Cc',
+and, more importantly, the 'Bcc' headers. Do not add a
+'Bcc' header to your messages because it will probably do the
+exact opposite of what you expect.
+
+Only recipients specified in the rcpt 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 part of the message and should be produced by the
+LTN12
+source function. The rcpt list is not
+part of the message and will not be sent to anyone.
+
+RFC 2822
+has two important and short 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:
+
+The LuaSocket send 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:
+
+I hope this clarifies the issue. Otherwise, please refer to
+RFC 2821
+and
+RFC 2822.
+
+The socket namespace contains the core functionality of LuaSocket.
+
+To obtain the socket namespace, run:
+
+socket.headers.canonic The socket.headers.canonic table
+is used by the HTTP and SMTP modules to translate from
+lowercase field names back into their canonic
+capitalization. When a lowercase field name exists as a key
+in this table, the associated value is substituted in
+whenever the field name is sent out.
+
+You can obtain the headers namespace if case run-time
+modifications are required by running:
+
+socket.bind(address, port [, backlog])
+
+This function is a shortcut that creates and returns a TCP server object
+bound to a local address and port, ready to
+accept client connections. Optionally,
+user can also specify the backlog argument to the
+listen method (defaults to 32).
+
+Note: The server object returned will have the option "reuseaddr"
+set to true.
+
+socket.connect[46](address, port [, locaddr] [, locport] [, family])
+
+This function is a shortcut that creates and returns a TCP client object
+connected to a remote address at a given port. Optionally,
+the user can also specify the local address and port to bind
+(locaddr and locport), or restrict the socket family
+to "inet" or "inet6".
+Without specifying family to connect, whether a tcp or tcp6
+connection is created depends on your system configuration. Two variations
+of connect are defined as simple helper functions that restrict the
+family, socket.connect4 and socket.connect6.
+
+socket._DEBUG
+
+This constant is set to true if the library was compiled
+with debug support.
+
+socket._DATAGRAMSIZE
+
+Default datagram size used by calls to
+receive and
+receivefrom.
+(Unless changed in compile time, the value is 8192.)
+
+socket.gettime()
+
+Returns the UNIX time in seconds. You should subtract the values returned by this function
+to get meaningful values.
+
+socket.newtry(finalizer)
+
+Creates and returns a clean
+try
+function that allows for cleanup before the exception
+is raised.
+
+Finalizer is a function that will be called before
+try throws the exception.
+
+The function returns your customized try function.
+
+Note: This idea saved a lot of work with the
+implementation of protocols in LuaSocket:
+
+socket.protect(func)
+
+Converts a function that throws exceptions into a safe function. This
+function only catches exceptions thrown by the try
+and newtry functions. It does not catch normal
+Lua errors.
+
+Func is a function that calls
+try (or assert, or error)
+to throw exceptions.
+
+Returns an equivalent function that instead of throwing exceptions in case of
+a failed try call, returns nil
+followed by an error message.
+
+socket.select(recvt, sendt [, timeout])
+
+Waits for a number of sockets to change status.
+
+Recvt is an array with the sockets to test for characters
+available for reading. Sockets in the sendt array are watched to
+see if it is OK to immediately write on them. Timeout is the
+maximum amount of time (in seconds) to wait for a change in status. A
+nil, negative or omitted timeout value allows the
+function to block indefinitely. Recvt and sendt can also
+be empty tables or nil. Non-socket values (or values with
+non-numeric indices) in the arrays will be silently ignored.
+ The function returns a list with the sockets ready for
+reading, a list with the sockets ready for writing and an error message.
+The error message is "timeout" if a timeout
+condition was met, "select failed" if the call
+to select failed, and
+nil otherwise. The returned tables are
+doubly keyed both by integers and also by the sockets
+themselves, to simplify the test if a specific socket has
+changed status.
+
+Note: select can monitor a limited number
+of sockets, as defined by the constant
+socket._SETSIZE. This
+number may be as high as 1024 or as low as 64 by default,
+depending on the system. It is usually possible to change this
+at compile time. Invoking select with a larger
+number of sockets will raise an error.
+
+Important note: a known bug in WinSock causes select to fail
+on non-blocking TCP sockets. The function may return a socket as
+writable even though the socket is not ready for sending.
+
+Another important note: calling select with a server socket in the receive parameter before a call to accept does not guarantee
+accept will return immediately.
+Use the settimeout
+method or accept might block forever.
+
+Yet another note: If you close a socket and pass
+it to select, it will be ignored.
+
+Using select with non-socket objects: Any object that implements getfd and dirty can be used with select, allowing objects from other libraries to be used within a socket.select driven loop.
+
+socket._SETSIZE
+
+The maximum number of sockets that the select function can handle.
+
+socket.sink(mode, socket)
+
+Creates an
+LTN12
+sink from a stream socket object.
+
+Mode defines the behavior of the sink. The following
+options are available:
+
+Socket is the stream socket object used to send the data.
+
+The function returns a sink with the appropriate behavior.
+
+socket.skip(d [, ret1, ret2 ... retN])
+
+Drops a number of arguments and returns the remaining.
+
+D is the number of arguments to drop. Ret1 to
+retN are the arguments.
+
+The function returns retd+1 to retN.
+
+Note: This function is useful to avoid creation of dummy variables:
+
+socket.sleep(time)
+
+Freezes the program execution during a given amount of time.
+
+Time is the number of seconds to sleep for. If
+time is negative, the function returns immediately.
+
+socket.source(mode, socket [, length])
+
+Creates an
+LTN12
+source from a stream socket object.
+
+Mode defines the behavior of the source. The following
+options are available:
+
+Socket is the stream socket object used to receive the data.
+
+The function returns a source with the appropriate behavior.
+
+socket._SOCKETINVALID
+
+The OS value for an invalid socket. This can be used with
+tcp:getfd and tcp:setfd methods.
+
+socket.try(ret1 [, ret2 ... retN])
+
+Throws an exception in case ret1 is falsy, using
+ret2 as the error message. The exception is supposed to be caught
+by a protected function only.
+
+Ret1 to retN can be arbitrary
+arguments, but are usually the return values of a function call
+nested with try.
+
+The function returns ret1 to retN if
+ret1 is not nil or false.
+Otherwise, it calls error passing ret2 wrapped
+in a table with metatable used by protect to
+distinguish exceptions from runtime errors.
+
+socket._VERSION
+
+This constant has a string describing the current LuaSocket version.
+
+server:accept()
+
+Waits for a remote connection on the server
+object and returns a client object representing that connection.
+
+If a connection is successfully initiated, a client object is returned.
+If a timeout condition is met, the method returns nil
+followed by the error string 'timeout'. Other errors are
+reported by nil followed by a message describing the error.
+
+Note: calling socket.select
+with a server object in
+the recvt parameter before a call to accept does
+not guarantee accept will return immediately. Use the settimeout method or accept
+might block until another client shows up.
+
+master:bind(address, port)
+
+Binds a master object to address and port on the
+local host.
+
+Address can be an IP address or a host name.
+Port must be an integer number in the range [0..64K).
+If address
+is '*', the system binds to all local interfaces
+using the INADDR_ANY constant or
+IN6ADDR_ANY_INIT, according to the family.
+If port is 0, the system automatically
+chooses an ephemeral port.
+
+In case of success, the method returns 1. In case of error, the
+method returns nil followed by an error message.
+
+Note: The function socket.bind
+is available and is a shortcut for the creation of server sockets.
+
+master:close()
+Closes a TCP object. The internal socket used by the object is closed
+and the local address to which the object was
+bound is made available to other applications. No further operations
+(except for further calls to the close method) are allowed on
+a closed socket.
+
+Note: 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 limited system resources. Garbage-collected objects are
+automatically closed before destruction, though.
+
+master:connect(address, port)
+
+Attempts to connect a master object to a remote host, transforming it into a
+client object.
+Client objects support methods
+send,
+receive,
+getsockname,
+getpeername,
+settimeout,
+and close.
+
+Address can be an IP address or a host name.
+Port must be an integer number in the range [1..64K).
+
+In case of error, the method returns nil followed by a string
+describing the error. In case of success, the method returns 1.
+
+Note: The function socket.connect
+is available and is a shortcut for the creation of client sockets.
+
+Note: Starting with LuaSocket 2.0,
+the settimeout
+method affects the behavior of connect, causing it to return
+with an error in case of a timeout. If that happens, you can still call socket.select with the socket in the
+sendt table. The socket will be writable when the connection is
+established.
+
+Note: Starting with LuaSocket 3.0, the host name resolution
+depends on whether the socket was created by
+socket.tcp,
+socket.tcp4 or
+socket.tcp6. Addresses from
+the appropriate family (or both) are tried in the order
+returned by the resolver until the
+first success or until the last failure. If the timeout was
+set to zero, only the first address is tried.
+
+master:dirty()
+Check the read buffer status.
+
+Returns true if there is any data in the read buffer, false otherwise.
+
+Note: This is an internal method, use at your own risk.
+
+master:getfd()
+Returns the underling socket descriptor or handle associated to the object.
+
+The descriptor or handle. In case the object has been closed, the return value
+will be -1. For an invalid socket it will be
+_SOCKETINVALID.
+
+Note: This is an internal method. Unlikely to be
+portable. Use at your own risk.
+
+client:getoption(option)
+Gets options for the TCP object.
+See setoption for description of the
+option names and values.
+
+Option is a string with the option name.
+The method returns the option value in case of success, or
+nil followed by an error message otherwise.
+
+client:getpeername()
+
+Returns information about the remote side of a connected client object.
+
+Returns a string with the IP address of the peer, the
+port number that peer is using for the connection,
+and a string with the family ("inet" or "inet6").
+In case of error, the method returns nil.
+
+Note: It makes no sense to call this method on server objects.
+
+master:getsockname()
+Returns the local address information associated to the object.
+
+The method returns a string with local IP address, a number with
+the local port,
+and a string with the family ("inet" or "inet6").
+In case of error, the method returns nil.
+
+master:getstats()
+Returns accounting information on the socket, useful for throttling
+of bandwidth.
+
+The method returns the number of bytes received, the number of bytes sent,
+and the age of the socket object in seconds.
+
+master:gettimeout()
+Returns the current block timeout followed by the curent
+total timeout.
+
+master:listen(backlog)
+
+Specifies the socket is willing to receive connections, transforming the
+object into a server object. Server objects support the
+accept,
+getsockname,
+setoption,
+settimeout,
+and close methods.
+
+The parameter backlog 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 method returns 1. In case of error, the
+method returns nil followed by an error message.
+
+client:receive([pattern [, prefix]])
+
+Reads data from a client object, according to the specified read
+pattern. Patterns follow the Lua file I/O format, and the difference in performance between all patterns is negligible.
+
+Pattern can be any of the following:
+
+Prefix is an optional string to be concatenated to the beginning
+of any received data before return.
+
+If successful, the method returns the received pattern. In case of error,
+the method returns nil followed by an error
+message, followed by a (possibly empty) string containing
+the partial that was received. The error message can be
+the string 'closed' in case the connection was
+closed before the transmission was completed or the string
+'timeout' in case there was a timeout during the operation.
+
+Important note: This function was changed severely. It used
+to support multiple patterns (but I have never seen this feature used) and
+now it doesn't anymore. Partial results used to be returned in the same
+way as successful results. This last feature violated the idea that all
+functions should return nil on error. Thus it was changed
+too.
+
+client:send(data [, i [, j]])
+
+Sends data through client object.
+
+Data is the string to be sent. The optional arguments
+i and j work exactly like the standard
+string.sub Lua function to allow the selection of a
+substring to be sent.
+
+If successful, the method returns the index of the last byte
+within [i, j] that has been sent. Notice that, if
+i is 1 or absent, this is effectively the total
+number of bytes sent. In case of error, the method returns
+nil, followed by an error message, followed
+by the index of the last byte within [i, j] that
+has been sent. You might want to try again from the byte
+following that. The error message can be 'closed'
+in case the connection was closed before the transmission
+was completed or the string 'timeout' in case
+there was a timeout during the operation.
+
+Note: Output is not buffered. For small strings,
+it is always better to concatenate them in Lua
+(with the '..' operator) and send the result in one call
+instead of calling the method several times.
+
+client:setoption(option [, value])
+Sets options for the TCP object. Options are only needed by low-level or
+time-critical applications. You should only modify an option if you
+are sure you need it.
+
+Option is a string with the option name, and value
+depends on the option being set:
+The method returns 1 in case of success, or nil
+followed by an error message otherwise.
+
+Note: The descriptions above come from the man pages.
+
+master:setstats(received, sent, age)
+Resets accounting information on the socket, useful for throttling
+of bandwidth.
+
+Received is a number with the new number of bytes received.
+Sent is a number with the new number of bytes sent.
+Age is the new age in seconds.
+
+The method returns 1 in case of success and nil otherwise.
+
+master:settimeout(value [, mode])
+Changes the timeout values for the object. By default,
+all I/O operations are blocking. That is, any call to the methods
+send,
+receive, and
+accept
+will block indefinitely, until the operation completes. The
+settimeout method defines a limit on the amount of time the
+I/O methods can block. When a timeout is set and the specified amount of
+time has elapsed, the affected methods give up and fail with an error code.
+
+The amount of time to wait is specified as the
+value parameter, in seconds. There are two timeout modes and
+both can be used together for fine tuning:
+
+The nil timeout value allows operations to block
+indefinitely. Negative timeout values have the same effect.
+
+Note: although timeout values have millisecond precision in LuaSocket,
+large blocks can cause I/O functions not to respect timeout values due
+to the time the library takes to transfer blocks to and from the OS
+and to and from the Lua interpreter. Also, function that accept host names
+and perform automatic name resolution might be blocked by the resolver for
+longer than the specified timeout value.
+
+Note: The old timeout method is deprecated. The name has been
+changed for sake of uniformity, since all other method names already
+contained verbs making their imperative nature obvious.
+
+client:shutdown(mode)
+Shuts down part of a full-duplex connection.
+
+Mode tells which way of the connection should be shut down and can
+take the value:
+DNS
+
+
+resolved4 = {
+
+
+ name = canonic-name,
+ alias = alias-list,
+ ip = ip-address-list
+}
+
+resolved6 = {
+
+
+ [1] = {
+ family = family-name-1,
+ addr = address-1
+ },
+ ...
+ [n] = {
+ family = family-name-n,
+ addr = address-n
+ }
+}
+ FTP
+
+
+-- loads the FTP module and any libraries it requires
+local ftp = require("socket.ftp")
+
+
+
+
+[ftp://][<user>[:<password>]@]<host>[:<port>][/<path>][type=a|i]
+
+
+
+
+
+
+
+
+
+ftp.get{
+ host = string,
+ sink = LTN12 sink,
+ argument or path = string,
+ [user = string,]
+ [password = string]
+ [command = string,]
+ [port = number,]
+ [type = string,]
+ [step = LTN12 pump step,]
+ [create = function]
+}
+
+
+
+
+-- load the ftp support
+local ftp = require("socket.ftp")
+
+-- Log as user "anonymous" on server "ftp.tecgraf.puc-rio.br",
+-- and get file "lua.tar.gz" from directory "pub/lua" as binary.
+f, e = ftp.get("ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz;type=i")
+
+
+
+-- load needed modules
+local ftp = require("socket.ftp")
+local ltn12 = require("ltn12")
+local url = require("socket.url")
+
+-- a function that returns a directory listing
+function nlst(u)
+ local t = {}
+ local p = url.parse(u)
+ p.command = "nlst"
+ p.sink = ltn12.sink.table(t)
+ local r, e = ftp.get(p)
+ return r and table.concat(t), e
+end
+
+
+
+
+
+ftp.put{
+ host = string,
+ source = LTN12 sink,
+ argument or path = string,
+ [user = string,]
+ [password = string]
+ [command = string,]
+ [port = number,]
+ [type = string,]
+ [step = LTN12 pump step,]
+ [create = function]
+}
+
+
+
+
+-- load the ftp support
+local ftp = require("socket.ftp")
+
+-- Log as user "fulano" on server "ftp.example.com",
+-- using password "silva", and store a file "README" with contents
+-- "wrong password, of course"
+f, e = ftp.put("ftp://fulano:silva@ftp.example.com/README",
+ "wrong password, of course")
+
+
+
+-- load the ftp support
+local ftp = require("socket.ftp")
+local ltn12 = require("ltn12")
+
+-- Log as user "fulano" on server "ftp.example.com",
+-- using password "silva", and append to the remote file "LOG", sending the
+-- contents of the local file "LOCAL-LOG"
+f, e = ftp.put{
+ host = "ftp.example.com",
+ user = "fulano",
+ password = "silva",
+ command = "appe",
+ argument = "LOG",
+ source = ltn12.source.file(io.open("LOCAL-LOG", "r"))
+}
+
+
+
+
+
+
+
+
+
diff --git a/docs/http.html b/docs/http.html
new file mode 100644
index 0000000..52b8a30
--- /dev/null
+++ b/docs/http.html
@@ -0,0 +1,339 @@
+
+
+
+
+
+
+HTTP
+
+
+-- loads the HTTP module and any libraries it requires
+local http = require("socket.http")
+
+
+
+
+
+
+[http://][<user>[:<password>]@]<host>[:<port>][/<path>]
+
+
+
+
+
+
+
+
+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
+}
+
+
+
+
+http.request{
+ url = string,
+ [sink = LTN12 sink,]
+ [method = string,]
+ [headers = header-table,]
+ [source = LTN12 source],
+ [step = LTN12 pump step,]
+ [proxy = string,]
+ [redirect = boolean,]
+ [create = function,]
+ [maxredirects = number]
+}
+
+
+
+
+-- load the http module
+local io = require("io")
+local http = require("socket.http")
+local ltn12 = require("ltn12")
+
+-- connect to server "www.cs.princeton.edu" and retrieves this manual
+-- file from "~diego/professional/luasocket/http.html" and print it to stdout
+http.request{
+ url = "http://www.cs.princeton.edu/~diego/professional/luasocket/http.html",
+ sink = ltn12.sink.file(io.stdout)
+}
+
+-- connect to server "www.example.com" and tries to retrieve
+-- "/private/index.html". Fails because authentication is needed.
+b, c, h = http.request("http://www.example.com/private/index.html")
+-- b returns some useless page telling about the denied access,
+-- h returns authentication information
+-- and c returns with value 401 (Authentication Required)
+
+-- tries to connect to server "wrong.host" to retrieve "/"
+-- and fails because the host does not exist.
+r, e = http.request("http://wrong.host/")
+-- r is nil, and e returns with value "host not found"
+
+
+
+-- load the http module
+http = require("socket.http")
+
+-- Requests information about a document, without downloading it.
+-- Useful, for example, if you want to display a download gauge and need
+-- to know the size of the document in advance
+r, c, h = http.request {
+ method = "HEAD",
+ url = "http://www.tecgraf.puc-rio.br/~diego"
+}
+-- r is 1, c is 200, and h would return the following headers:
+-- h = {
+-- date = "Tue, 18 Sep 2001 20:42:21 GMT",
+-- server = "Apache/1.3.12 (Unix) (Red Hat/Linux)",
+-- ["last-modified"] = "Wed, 05 Sep 2001 06:11:20 GMT",
+-- ["content-length"] = 15652,
+-- ["connection"] = "close",
+-- ["content-Type"] = "text/html"
+-- }
+
+
+
+-- load required modules
+http = require("socket.http")
+mime = require("mime")
+
+-- Connect to server "www.example.com" and tries to retrieve
+-- "/private/index.html", using the provided name and password to
+-- authenticate the request
+b, c, h = http.request("http://fulano:silva@www.example.com/private/index.html")
+
+-- Alternatively, one could fill the appropriate header and authenticate
+-- the request directly.
+r, c = http.request {
+ url = "http://www.example.com/private/index.html",
+ headers = { authorization = "Basic " .. (mime.b64("fulano:silva")) }
+}
+
+
+
+
+
+
+
+
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..e92b4d4
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,215 @@
+
+
+
+
+
+
+What is LuaSocket?
+
+
+Author: Diego Nehab
+Download
+
+Special thanks
+
+What's New
+
+
+
+
+
+
+
+
+
+
+Old Versions
+
+Installation
+
+Directory structure
+
+
+<LDIR>/ltn12.lua
+<LDIR>/socket.lua
+<CDIR>/socket/core.dll
+<LDIR>/socket/http.lua
+<LDIR>/socket/tp.lua
+<LDIR>/socket/ftp.lua
+<LDIR>/socket/smtp.lua
+<LDIR>/socket/url.lua
+<LDIR>/mime.lua
+<CDIR>/mime/core.dll
+
+
+Using LuaSocket
+
+
+Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
+> socket = require("socket")
+> print(socket._VERSION)
+--> LuaSocket 3.0-rc1
+
+
+
+Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
+> http = require("socket.http")
+> print(http.request("http://www.impa.br/~diego/software/luasocket"))
+--> homepage gets dumped to terminal
+
+
+
+
+
+
+
+
diff --git a/docs/introduction.html b/docs/introduction.html
new file mode 100644
index 0000000..fd22f48
--- /dev/null
+++ b/docs/introduction.html
@@ -0,0 +1,333 @@
+
+
+
+
+
+
+Introduction
+
+TCP
+
+
+
+
+
+
+
+-- load namespace
+local socket = require("socket")
+-- create a TCP socket and bind it to the local host, at any port
+local server = assert(socket.bind("*", 0))
+-- find out which port the OS chose for us
+local ip, port = server:getsockname()
+-- print a message informing what's up
+print("Please telnet to localhost on port " .. port)
+print("After connecting, you have 10s to enter a line to be echoed")
+-- loop forever waiting for clients
+while 1 do
+ -- wait for a connection from any client
+ local client = server:accept()
+ -- make sure we don't block waiting for this client's line
+ client:settimeout(10)
+ -- receive the line
+ local line, err = client:receive()
+ -- if there was no error, send it back to the client
+ if not err then client:send(line .. "\n") end
+ -- done with client, close the object
+ client:close()
+end
+
+UDP
+
+
+
+
+
+
+
+-- change here to the host an port you want to contact
+local host, port = "localhost", 13
+-- load namespace
+local socket = require("socket")
+-- convert host name to ip address
+local ip = assert(socket.dns.toip(host))
+-- create a new UDP object
+local udp = assert(socket.udp())
+-- contact daytime host
+assert(udp:sendto("anything", ip, port))
+-- retrieve the answer and print results
+io.write(assert(udp:receive()))
+
+Support modules
+
+LTN12
+
+
+-- loads the LTN21 module
+local ltn12 = require("ltn12")
+
+
+
+
+Filters
+
+
+
+
+-- load required modules
+local ltn12 = require("ltn12")
+local mime = require("mime")
+
+-- create a silly identity filter
+id = ltn12.filter.chain(
+ mime.encode("quoted-printable"),
+ mime.encode("base64"),
+ mime.decode("base64"),
+ mime.decode("quoted-printable")
+)
+
+
+
+
+
+-- load the ltn12 module
+local ltn12 = require("ltn12")
+
+-- the base64 mime filter factory
+encodet['base64'] = function()
+ return ltn12.filter.cycle(b64, "")
+end
+
+
+
+
+Pumps
+
+
+
+Sinks
+
+
+
+
+-- load the ltn12 module
+local ltn12 = require("ltn12")
+
+-- copy a file
+ltn12.pump.all(
+ ltn12.source.file(io.open("original.png", "rb")),
+ ltn12.sink.file(io.open("copy.png", "wb"))
+)
+
+
+
+
+
+-- load needed modules
+local http = require("socket.http")
+local ltn12 = require("ltn12")
+
+-- 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
+end
+
+
+
+
+Sources
+
+
+
+
+-- load the ltn12 module
+local ltn12 = require("ltn12")
+
+-- copy a file
+ltn12.pump.all(
+ ltn12.source.file(io.open("original.png", "rb")),
+ ltn12.sink.file(io.open("copy.png", "wb"))
+)
+
+
+
+
+MIME
+
+
+-- loads the MIME module and everything it requires
+local mime = require("mime")
+
+
+
+
+
+High-level filters
+
+
+
+
+
+mime.decode("quoted-printable")
+
+mime.encode("quoted-printable" [, mode])
+
+base64 = ltn12.filter.chain(
+ mime.encode("base64"),
+ mime.wrap("base64")
+)
+
+
+
+base64 = ltn12.filter.chain(
+ mime.normalize(),
+ mime.encode("base64"),
+ mime.wrap("base64")
+)
+
+
+
+
+
+
+mime.wrap("base64")
+mime.wrap("quoted-printable")
+
+qp = ltn12.filter.chain(
+ mime.normalize(),
+ mime.encode("quoted-printable"),
+ mime.wrap("quoted-printable")
+)
+
+
+Low-level filters
+
+
+
+
+print((mime.b64("diego:password")))
+--> ZGllZ286cGFzc3dvcmQ=
+
+
+
+
+print((string.gsub(mime.dot(2, ".\r\nStuffing the message.\r\n.\r\n."), "\r\n", "\\n")))
+--> ..\nStuffing the message.\n..\n..
+
+
+
+-- translates the end-of-line marker to UNIX
+unix = mime.eol(0, dos, "\n")
+
+
+
+
+
+print((mime.qp("ma��")))
+--> ma=E7=E3=
+
+
+
+
+
+print((mime.unb64("ZGllZ286cGFzc3dvcmQ=")))
+--> diego:password
+
+
+
+
+
+print((mime.qp("ma=E7=E3=")))
+--> ma��
+
+
+
+
+Reference
+
+
+DNS (in socket)
+
+
+
+
+
+getaddrinfo,
+gethostname,
+tohostname,
+toip.
+
+
+FTP
+
+
+
+
+
+get,
+put.
+
+
+HTTP
+
+
+
+
+
+request.
+
+
+LTN12
+
+
+
+
+
+filter:
+chain,
+cycle.
+
+
+pump:
+all,
+step.
+
+
+sink:
+chain,
+error,
+file,
+null,
+simplify,
+table.
+
+
+source:
+cat,
+chain,
+empty,
+error,
+file,
+simplify,
+string,
+table.
+
+
+MIME
+
+
+
+
+
+high-level:
+decode,
+encode,
+normalize,
+stuff,
+wrap.
+
+
+low-level:
+b64,
+dot,
+eol,
+qp,
+qpwrp,
+unb64,
+unqp,
+wrp.
+
+
+SMTP
+
+
+
+
+
+message,
+send.
+
+
+Socket
+
+
+
+
+
+bind,
+connect,
+connect4,
+connect6,
+_DATAGRAMSIZE,
+_DEBUG,
+dns,
+gettime,
+headers.canonic,
+newtry,
+protect,
+select,
+sink,
+skip,
+sleep,
+_SETSIZE,
+_SOCKETINVALID,
+source,
+tcp,
+tcp4,
+tcp6,
+try,
+udp,
+udp4,
+udp6,
+_VERSION.
+
+
+TCP (in socket)
+
+
+
+
+
+accept,
+bind,
+close,
+connect,
+dirty,
+getfd,
+getoption,
+getpeername,
+getsockname,
+getstats,
+gettimeout,
+listen,
+receive,
+send,
+setfd,
+setoption,
+setstats,
+settimeout,
+shutdown.
+
+
+UDP (in socket)
+
+
+
+
+
+close,
+getoption,
+getpeername,
+getsockname,
+gettimeout,
+receive,
+receivefrom,
+send,
+sendto,
+setpeername,
+setsockname,
+setoption,
+settimeout.
+
+
+URL
+
+
+
+
+
+
+
+
diff --git a/docs/smtp.html b/docs/smtp.html
new file mode 100644
index 0000000..787d0b1
--- /dev/null
+++ b/docs/smtp.html
@@ -0,0 +1,419 @@
+
+
+
+
+
+
+
+absolute,
+build,
+build_path,
+escape,
+parse,
+parse_path,
+unescape.
+
+SMTP
+
+
+-- loads the SMTP module and everything it requires
+local smtp = require("socket.smtp")
+
+
+
+
+
+
+
+
+
+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
+}
+
+
+
+
+
+
+
+
+
+
+
+
+mesgt = {
+ headers = header-table,
+ body = LTN12 source or string or
+multipart-mesgt
+}
+
+multipart-mesgt = {
+ [preamble = string,]
+ [1] = mesgt,
+ [2] = mesgt,
+ ...
+ [n] = mesgt,
+ [epilogue = string,]
+}
+
+-- 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,
+}
+
+
+
+
+
+
+ from = string,
+ rcpt = string or string-table,
+ source = LTN12 source,
+ [user = string,]
+ [password = string,]
+ [server = string,]
+ [port = number,]
+ [domain = string,]
+ [step = LTN12 pump step,]
+ [create = function]
+}
+
+
+
+
+
+
+
+
+
+
+-- 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)
+}
+
+
+
+
+
+
+
+
diff --git a/docs/socket.html b/docs/socket.html
new file mode 100644
index 0000000..c148114
--- /dev/null
+++ b/docs/socket.html
@@ -0,0 +1,481 @@
+
+
+
+
+
+
+The socket namespace
+
+
+-- loads the socket module
+local socket = require("socket")
+
+
+
+
+
+-- loads the headers module
+local headers = require("headers")
+
+
+
+
+
+
+t = socket.gettime()
+-- do stuff
+print(socket.gettime() - t .. " seconds elapsed")
+
+
+
+
+
+foo = socket.protect(function()
+ -- connect somewhere
+ local c = socket.try(socket.connect("somewhere", 42))
+ -- create a try function that closes 'c' on error
+ local try = socket.newtry(function() c:close() end)
+ -- do everything reassured c will be closed
+ try(c:send("hello there?\r\n"))
+ local answer = try(c:receive())
+ ...
+ try(c:send("good bye\r\n"))
+ c:close()
+end)
+
+
+
+
+
+
+
+
+-- get the status code and separator from SMTP server reply
+local code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
+
+
+
+
+
+
+
+-- connects or throws an exception with the appropriate error message
+c = socket.try(socket.connect("localhost", 80))
+
+
+
+
+TCP
+
+
+
+
+client:close()
+server:close()
+
+client:dirty()
+server:dirty()
+
+client:getfd()
+server:getfd()
+
+server:getoption(option)
+
+
+
+
+client:getsockname()
+server:getsockname()
+
+client:getstats()
+server:getstats()
+
+client:gettimeout()
+server:gettimeout()
+
+
+
+
+server:setoption(option [, value])
+
+
+
+
+
+client:setstats(received, sent, age)
+server:setstats(received, sent, age)
+
+client:settimeout(value [, mode])
+server:settimeout(value [, mode])
+
+
+
+
+
+
+
+This function returns 1. +
+ + + +
+master:setfd(fd)
+client:setfd(fd)
+server:setfd(fd)
+
+Sets the underling socket descriptor or handle associated to the object. The current one +is simply replaced, not closed, and no other change to the object state is made. +To set it as invalid use _SOCKETINVALID. +
+ ++No return value. +
+ ++Note: This is an internal method. Unlikely to be +portable. Use at your own risk. +
+ + + ++socket.tcp() +
+ ++Creates and returns an TCP master object. A master object can +be transformed into a server object with the method +listen (after a call to bind) or into a client object with +the method connect. The only other +method supported by a master object is the +close method.
+ ++In case of success, a new master object is returned. In case of error, +nil is returned, followed by an error message. +
+ ++Note: The choice between IPv4 and IPv6 happens during a call to +bind or connect, depending on the address +family obtained from the resolver. +
+ ++Note: Before the choice between IPv4 and IPv6 happens, +the internal socket object is invalid and therefore setoption will fail. +
+ + + ++socket.tcp4() +
+ ++Creates and returns an IPv4 TCP master object. A master object can +be transformed into a server object with the method +listen (after a call to bind) or into a client object with +the method connect. The only other +method supported by a master object is the +close method.
+ ++In case of success, a new master object is returned. In case of error, +nil is returned, followed by an error message. +
+ + + ++socket.tcp6() +
+ ++Creates and returns an IPv6 TCP master object. A master object can +be transformed into a server object with the method +listen (after a call to bind) or into a client object with +the method connect. The only other +method supported by a master object is the +close method.
+ ++In case of success, a new master object is returned. In case of error, +nil is returned, followed by an error message. +
+ ++Note: The TCP object returned will have the option +"ipv6-v6only" set to true. +
+ + + + + + + + + diff --git a/docs/udp.html b/docs/udp.html new file mode 100644 index 0000000..db711cb --- /dev/null +++ b/docs/udp.html @@ -0,0 +1,596 @@ + + + + + + +
+connected:close()
+unconnected:close()
+
+Closes a UDP object. The internal socket +used by the object is closed and the local address to which the +object was bound is made available to other applications. No +further operations (except for further calls to the close +method) are allowed on a closed socket. +
+ ++Note: 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 limited system resources. +Garbage-collected objects are automatically closed before +destruction, though. +
+ + + +
+connected:getoption()
+unconnected:getoption()
+
+Gets an option value from the UDP object. +See setoption for +description of the option names and values. +
+ +Option is a string with the option name. +
+The method returns the option value in case of +success, or +nil followed by an error message otherwise. +
+ + + ++connected:getpeername() +
+ ++Retrieves information about the peer +associated with a connected UDP object. +
+ + ++Returns a string with the IP address of the peer, the +port number that peer is using for the connection, +and a string with the family ("inet" or "inet6"). +In case of error, the method returns nil. +
+ ++Note: It makes no sense to call this method on unconnected objects. +
+ + + +
+connected:getsockname()
+unconnected:getsockname()
+
+Returns the local address information associated to the object. +
+ + ++The method returns a string with local IP address, a number with +the local port, +and a string with the family ("inet" or "inet6"). +In case of error, the method returns nil. +
+ ++Note: UDP sockets are not bound to any address +until the setsockname or the +sendto method is called for the +first time (in which case it is bound to an ephemeral port and the +wild-card address). +
+ + + +
+connected:settimeout(value)
+unconnected:settimeout(value)
+
+Returns the current timeout value. +
+ + + + +
+connected:receive([size])
+unconnected:receive([size])
+
+Receives a datagram from the UDP object. If +the UDP object is connected, only datagrams coming from the peer +are accepted. Otherwise, the returned datagram can come from any +host. +
+ ++The optional size parameter +specifies the maximum size of the datagram to be retrieved. If +there are more than size bytes available in the datagram, +the excess bytes are discarded. If there are less then +size bytes available in the current datagram, the +available bytes are returned. +If size is omitted, the +compile-time constant +socket._DATAGRAMSIZE is used +(it defaults to 8192 bytes). Larger sizes will cause a +temporary buffer to be allocated for the operation. +
+ ++In case of success, the method returns the +received datagram. In case of timeout, the method returns +nil followed by the string 'timeout'. +
+ + + ++unconnected:receivefrom([size]) +
+ ++Works exactly as the receive +method, except it returns the IP +address and port as extra return values (and is therefore slightly less +efficient). +
+ + + ++connected:send(datagram) +
+ ++Sends a datagram to the UDP peer of a connected object. +
+ ++Datagram is a string with the datagram contents. +The maximum datagram size for UDP is 64K minus IP layer overhead. +However datagrams larger than the link layer packet size will be +fragmented, which may deteriorate performance and/or reliability. +
+ ++If successful, the method returns 1. In case of +error, the method returns nil followed by an error message. +
+ ++Note: In UDP, the send method never blocks +and the only way it can fail is if the underlying transport layer +refuses to send a message to the specified address (i.e. no +interface accepts the address). +
+ + + ++unconnected:sendto(datagram, ip, port) +
+ ++Sends a datagram to the specified IP address and port number. +
+ ++Datagram is a string with the +datagram contents. +The maximum datagram size for UDP is 64K minus IP layer overhead. +However datagrams larger than the link layer packet size will be +fragmented, which may deteriorate performance and/or reliability. +Ip is the IP address of the recipient. +Host names are not allowed for performance reasons. + +Port is the port number at the recipient. +
+ ++If successful, the method returns 1. In case of +error, the method returns nil followed by an error message. +
+ ++Note: In UDP, the send method never blocks +and the only way it can fail is if the underlying transport layer +refuses to send a message to the specified address (i.e. no +interface accepts the address). +
+ + + +
+connected:setoption(option [, value])
+unconnected:setoption(option [, value])
+
+Sets options for the UDP object. Options are +only needed by low-level or time-critical applications. You should +only modify an option if you are sure you need it.
+Option is a string with the option +name, and value depends on the option being set: +
+ ++The method returns 1 in case of success, or +nil followed by an error message otherwise. +
+ ++Note: The descriptions above come from the man pages. +
+ + + + +
+connected:setpeername('*')
+unconnected:setpeername(address, port)
+
+Changes the peer of a UDP object. This +method turns an unconnected UDP object into a connected UDP +object or vice versa. +
+ ++For connected objects, outgoing datagrams +will be sent to the specified peer, and datagrams received from +other peers will be discarded by the OS. Connected UDP objects must +use the send and +receive methods instead of +sendto and +receivefrom. +
+ ++Address can be an IP address or a +host name. Port is the port number. If address is +'*' and the object is connected, the peer association is +removed and the object becomes an unconnected object again. In that +case, the port argument is ignored. +
+ ++In case of error the method returns +nil followed by an error message. In case of success, the +method returns 1. +
+ ++Note: Since the address of the peer does not have +to be passed to and from the OS, the use of connected UDP objects +is recommended when the same peer is used for several transmissions +and can result in up to 30% performance gains. +
+ ++Note: Starting with LuaSocket 3.0, the host name resolution +depends on whether the socket was created by socket.udp or socket.udp6. Addresses from +the appropriate family are tried in succession until the +first success or until the last failure. +
+ + + ++unconnected:setsockname(address, port) +
+ ++Binds the UDP object to a local address. +
+ ++Address can be an IP address or a +host name. If address is '*' the system binds to +all local interfaces using the constant INADDR_ANY. If +port is 0, the system chooses an ephemeral port. +
+ ++If successful, the method returns 1. In case of +error, the method returns nil followed by an error +message. +
+ ++Note: This method can only be called before any +datagram is sent through the UDP object, and only once. Otherwise, +the system automatically binds the object to all local interfaces +and chooses an ephemeral port as soon as the first datagram is +sent. After the local address is set, either automatically by the +system or explicitly by setsockname, it cannot be +changed. +
+ + + +
+connected:settimeout(value)
+unconnected:settimeout(value)
+
+Changes the timeout values for the object. By default, the +receive and +receivefrom +operations are blocking. That is, any call to the methods will block +indefinitely, until data arrives. The settimeout function defines +a limit on the amount of time the functions can block. When a timeout is +set and the specified amount of time has elapsed, the affected methods +give up and fail with an error code. +
+ ++The amount of time to wait is specified as +the value parameter, in seconds. The nil timeout +value allows operations to block indefinitely. Negative +timeout values have the same effect. +
+ ++Note: In UDP, the send +and sendto methods never block (the +datagram is just passed to the OS and the call returns +immediately). Therefore, the settimeout method has no +effect on them. +
+ ++Note: The old timeout method is +deprecated. The name has been changed for sake of uniformity, since +all other method names already contained verbs making their +imperative nature obvious. +
+ + + ++socket.udp() +
+ ++Creates and returns an unconnected UDP object. +Unconnected objects support the +sendto, +receive, +receivefrom, +getoption, +getsockname, +setoption, +settimeout, +setpeername, +setsockname, and +close. +The setpeername +is used to connect the object. +
+ ++In case of success, a new unconnected UDP object +returned. In case of error, nil is returned, followed by +an error message. +
+ ++Note: The choice between IPv4 and IPv6 happens during a call to +sendto, setpeername, or sockname, depending on the address +family obtained from the resolver. +
+ ++Note: Before the choice between IPv4 and IPv6 happens, +the internal socket object is invalid and therefore setoption will fail. +
+ + + ++socket.udp4() +
+ ++Creates and returns an unconnected IPv4 UDP object. +Unconnected objects support the +sendto, +receive, +receivefrom, +getoption, +getsockname, +setoption, +settimeout, +setpeername, +setsockname, and +close. +The setpeername +is used to connect the object. +
+ ++In case of success, a new unconnected UDP object +returned. In case of error, nil is returned, followed by +an error message. +
+ + + ++socket.udp6() +
+ ++Creates and returns an unconnected IPv6 UDP object. +Unconnected objects support the +sendto, +receive, +receivefrom, +getoption, +getsockname, +setoption, +settimeout, +setpeername, +setsockname, and +close. +The setpeername +is used to connect the object. +
+ ++In case of success, a new unconnected UDP object +returned. In case of error, nil is returned, followed by +an error message. +
+ ++Note: The TCP object returned will have the option +"ipv6-v6only" set to true. +
+ + + + + + + + + diff --git a/docs/url.html b/docs/url.html new file mode 100644 index 0000000..6ff673d --- /dev/null +++ b/docs/url.html @@ -0,0 +1,328 @@ + + + + + + ++The url namespace provides functions to parse, protect, +and build URLs, as well as functions to compose absolute URLs +from base and relative URLs, according to +RFC 2396. +
+ ++To obtain the url namespace, run: +
+ ++-- loads the URL module +local url = require("socket.url") ++ +
+An URL is defined by the following grammar: +
+ ++ +<url> ::= [<scheme>:][//<authority>][/<path>][;<params>][?<query>][#<fragment>]+ + + +
+<authority> ::= [<userinfo>@]<host>[:<port>]
+<userinfo> ::= <user>[:<password>]
+<path> ::= {<segment>/}<segment>
+ +
+url.absolute(base, relative) +
+ ++Builds an absolute URL from a base URL and a relative URL. +
+ ++Base is a string with the base URL or +a parsed URL table. Relative is a +string with the relative URL. +
+ ++The function returns a string with the absolute URL. +
+ ++Note: The rules that +govern the composition are fairly complex, and are described in detail in +RFC 2396. +The example bellow should give an idea of what the rules are. +
+ ++http://a/b/c/d;p?q + ++ + +g:h = g:h +g = http://a/b/c/g +./g = http://a/b/c/g +g/ = http://a/b/c/g/ +/g = http://a/g +//g = http://g +?y = http://a/b/c/?y +g?y = http://a/b/c/g?y +#s = http://a/b/c/d;p?q#s +g#s = http://a/b/c/g#s +g?y#s = http://a/b/c/g?y#s +;x = http://a/b/c/;x +g;x = http://a/b/c/g;x +g;x?y#s = http://a/b/c/g;x?y#s +. = http://a/b/c/ +./ = http://a/b/c/ +.. = http://a/b/ +../ = http://a/b/ +../g = http://a/b/g +../.. = http://a/ +../../ = http://a/ +../../g = http://a/g ++ + + +
+url.build(parsed_url) +
+ ++Rebuilds an URL from its parts. +
+ ++Parsed_url is a table with same components returned by +parse. +Lower level components, if specified, +take precedence over high level components of the URL grammar. +
+ ++The function returns a string with the built URL. +
+ + + ++url.build_path(segments, unsafe) +
+ ++Builds a <path> component from a list of +<segment> parts. +Before composition, any reserved characters found in a segment are escaped into +their protected form, so that the resulting path is a valid URL path +component. +
+ ++Segments is a list of strings with the <segment> +parts. If unsafe is anything but nil, reserved +characters are left untouched. +
+ ++The function returns a string with the +built <path> component. +
+ + + ++url.escape(content) +
+ ++Applies the URL escaping content coding to a string +Each byte is encoded as a percent character followed +by the two byte hexadecimal representation of its integer +value. +
+ ++Content is the string to be encoded. +
+ ++The function returns the encoded string. +
+ ++-- load url module +url = require("socket.url") + +code = url.escape("/#?;") +-- code = "%2f%23%3f%3b" ++ + + +
+url.parse(url, default) +
+ ++Parses an URL given as a string into a Lua table with its components. +
+ ++Url is the URL to be parsed. If the default table is +present, it is used to store the parsed fields. Only fields present in the +URL are overwritten. Therefore, this table can be used to pass default +values for each field. +
+ ++The function returns a table with all the URL components: +
+ ++parsed_url = {+ +
+ url = string,
+ scheme = string,
+ authority = string,
+ path = string,
+ params = string,
+ query = string,
+ fragment = string,
+ userinfo = string,
+ host = string,
+ port = string,
+ user = string,
+ password = string
+} +
+-- load url module +url = require("socket.url") + +parsed_url = url.parse("http://www.example.com/cgilua/index.lua?a=2#there") +-- parsed_url = { +-- scheme = "http", +-- authority = "www.example.com", +-- path = "/cgilua/index.lua" +-- query = "a=2", +-- fragment = "there", +-- host = "www.puc-rio.br", +-- } + +parsed_url = url.parse("ftp://root:passwd@unsafe.org/pub/virus.exe;type=i") +-- parsed_url = { +-- scheme = "ftp", +-- authority = "root:passwd@unsafe.org", +-- path = "/pub/virus.exe", +-- params = "type=i", +-- userinfo = "root:passwd", +-- host = "unsafe.org", +-- user = "root", +-- password = "passwd", +-- } ++ + + +
+url.parse_path(path) +
+ ++Breaks a <path> URL component into all its +<segment> parts. +
+ ++Path is a string with the path to be parsed. +
+ ++Since some characters are reserved in URLs, they must be escaped +whenever present in a <path> component. Therefore, before +returning a list with all the parsed segments, the function removes +escaping from all of them. +
+ + + ++url.unescape(content) +
+ ++Removes the URL escaping content coding from a string. +
+ ++Content is the string to be decoded. +
+ ++The function returns the decoded string. +
+ + + + + + + -- cgit v1.2.3-55-g6feb From 2eac8950396247b412c4089c23a46015c8cc12bb Mon Sep 17 00:00:00 2001 From: Caleb Maclennan
The current version of the library can be found at
-the LuaSocket
+the LuaSocket
project page on GitHub. Besides the full C and Lua source code
for the library, the distribution contains several examples,
this user's manual and basic test procedures.
--
cgit v1.2.3-55-g6feb
From f7f0a77a3dbcd066c2f228ada63ee78546a01f78 Mon Sep 17 00:00:00 2001
From: Caleb Maclennan
-Main changes for LuaSocket 3.0-rc1 are IPv6 support -and Lua 5.2 compatibility. -
- --All previous versions of the LuaSocket library can be downloaded -here. Although these versions are no longer supported, they are -still available for those that have compatibility issues. -
- -- cgit v1.2.3-55-g6feb From 88c8a85cb6528232288ec590910b7a966aace52b Mon Sep 17 00:00:00 2001 From: Caleb Maclennan-LuaSocket version 3.0-rc1 is now available for download! -It is compatible with Lua 5.1 and 5.2, and has -been tested on Windows XP, Linux, and Mac OS X. Chances -are it works well on most UNIX distributions and Windows flavors. +LuaSocket version 3.0.0 is now available for download! +It is compatible with Lua 5.1 through 5.4. +Chances are it works well on most UNIX distributions and Windows flavors.
diff --git a/rockspecs/luasocket-3.0.0-1.rockspec b/rockspecs/luasocket-3.0.0-1.rockspec
new file mode 100644
index 0000000..4cf4acf
--- /dev/null
+++ b/rockspecs/luasocket-3.0.0-1.rockspec
@@ -0,0 +1,134 @@
+package = "LuaSocket"
+version = "3.0.0-1"
+source = {
+ url = "git+https://github.com/lunarmodules/luasocket.git",
+ tag = "v3.0.0"
+}
+description = {
+ summary = "Network support for the Lua language",
+ detailed = [[
+ LuaSocket is a Lua extension library composed of two parts: a set of C
+ modules that provide support for the TCP and UDP transport layers, and a
+ set of Lua modules that provide functions commonly needed by applications
+ that deal with the Internet.
+ ]],
+ homepage = "https://github.com/lunarmodules/luasocket",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+
+local function make_plat(plat)
+ local defines = {
+ unix = {
+ "LUASOCKET_DEBUG"
+ },
+ macosx = {
+ "LUASOCKET_DEBUG",
+ "UNIX_HAS_SUN_LEN"
+ },
+ win32 = {
+ "LUASOCKET_DEBUG",
+ "NDEBUG"
+ },
+ mingw32 = {
+ "LUASOCKET_DEBUG",
+ "LUASOCKET_INET_PTON",
+ "WINVER=0x0501"
+ }
+ }
+ local modules = {
+ ["socket.core"] = {
+ sources = {
+ "src/luasocket.c"
+ , "src/timeout.c"
+ , "src/buffer.c"
+ , "src/io.c"
+ , "src/auxiliar.c"
+ , "src/options.c"
+ , "src/inet.c"
+ , "src/except.c"
+ , "src/select.c"
+ , "src/tcp.c"
+ , "src/udp.c"
+ , "src/compat.c" },
+ defines = defines[plat],
+ incdir = "/src"
+ },
+ ["mime.core"] = {
+ sources = { "src/mime.c", "src/compat.c" },
+ defines = defines[plat],
+ incdir = "/src"
+ },
+ ["socket.http"] = "src/http.lua",
+ ["socket.url"] = "src/url.lua",
+ ["socket.tp"] = "src/tp.lua",
+ ["socket.ftp"] = "src/ftp.lua",
+ ["socket.headers"] = "src/headers.lua",
+ ["socket.smtp"] = "src/smtp.lua",
+ ltn12 = "src/ltn12.lua",
+ socket = "src/socket.lua",
+ mime = "src/mime.lua"
+ }
+ if plat == "unix"
+ or plat == "macosx"
+ or plat == "haiku"
+ then
+ modules["socket.core"].sources[#modules["socket.core"].sources+1] = "src/usocket.c"
+ if plat == "haiku" then
+ modules["socket.core"].libraries = {"network"}
+ end
+ modules["socket.unix"] = {
+ sources = {
+ "src/buffer.c"
+ , "src/compat.c"
+ , "src/auxiliar.c"
+ , "src/options.c"
+ , "src/timeout.c"
+ , "src/io.c"
+ , "src/usocket.c"
+ , "src/unix.c"
+ , "src/unixdgram.c"
+ , "src/unixstream.c" },
+ defines = defines[plat],
+ incdir = "/src"
+ }
+ modules["socket.serial"] = {
+ sources = {
+ "src/buffer.c"
+ , "src/compat.c"
+ , "src/auxiliar.c"
+ , "src/options.c"
+ , "src/timeout.c"
+ , "src/io.c"
+ , "src/usocket.c"
+ , "src/serial.c" },
+ defines = defines[plat],
+ incdir = "/src"
+ }
+ end
+ if plat == "win32"
+ or plat == "mingw32"
+ then
+ modules["socket.core"].sources[#modules["socket.core"].sources+1] = "src/wsocket.c"
+ modules["socket.core"].libraries = { "ws2_32" }
+ end
+ return { modules = modules }
+end
+
+build = {
+ type = "builtin",
+ platforms = {
+ unix = make_plat("unix"),
+ macosx = make_plat("macosx"),
+ haiku = make_plat("haiku"),
+ win32 = make_plat("win32"),
+ mingw32 = make_plat("mingw32")
+ },
+ copy_directories = {
+ "docs"
+ , "samples"
+ , "etc"
+ , "test" }
+}
--
cgit v1.2.3-55-g6feb
From 1d61853ab84f0724502205f45849c2347d6a49ac Mon Sep 17 00:00:00 2001
From: Robert Scheck Each module loads their dependencies automatically, so you only need to
diff --git a/makefile.dist b/makefile.dist
index 3a2e100..a27ba57 100644
--- a/makefile.dist
+++ b/makefile.dist
@@ -1,7 +1,7 @@
#--------------------------------------------------------------------------
# Distribution makefile
#--------------------------------------------------------------------------
-DIST = luasocket-3.0-rc1
+DIST = luasocket-3.0.0
TEST = \
test/README \
diff --git a/src/luasocket.h b/src/luasocket.h
index d22b1be..1017fba 100644
--- a/src/luasocket.h
+++ b/src/luasocket.h
@@ -10,7 +10,7 @@
/*-------------------------------------------------------------------------* \
* Current socket library version
\*-------------------------------------------------------------------------*/
-#define LUASOCKET_VERSION "LuaSocket 3.0-rc1"
+#define LUASOCKET_VERSION "LuaSocket 3.0.0"
#define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2013 Diego Nehab"
/*-------------------------------------------------------------------------*\
diff --git a/src/makefile b/src/makefile
index f95498a..06f4d19 100755
--- a/src/makefile
+++ b/src/makefile
@@ -272,7 +272,7 @@ SOCKET_win64=wsocket.obj
#
SO=$(SO_$(PLAT))
O=$(O_$(PLAT))
-SOCKET_V=3.0-rc1
+SOCKET_V=3.0.0
MIME_V=1.0.3
SOCKET_SO=socket-$(SOCKET_V).$(SO)
MIME_SO=mime-$(MIME_V).$(SO)
--
cgit v1.2.3-55-g6feb
From ec7d7a2b8feead992f0f9197ae299fe410ec16a0 Mon Sep 17 00:00:00 2001
From: Thijs Schreijer
-LuaSocket version 3.0.0 is now available for download!
+LuaSocket version 3.1.0 is now available for download!
It is compatible with Lua 5.1 through 5.4.
Chances are it works well on most UNIX distributions and Windows flavors.
Download