aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-06-15 06:24:00 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-06-15 06:24:00 +0000
commit58096449c6044b7aade5cd41cfd71c6bec1d273d (patch)
tree1814ffebe89c4c2556d84f97f66db37a7e8b4554 /doc
parent9ed7f955e5fc69af9bf1794fa2c8cd227981ba24 (diff)
downloadluasocket-58096449c6044b7aade5cd41cfd71c6bec1d273d.tar.gz
luasocket-58096449c6044b7aade5cd41cfd71c6bec1d273d.tar.bz2
luasocket-58096449c6044b7aade5cd41cfd71c6bec1d273d.zip
Manual is almost done. HTTP is missing.
Implemented new distribution scheme. Select is now purely C. HTTP reimplemented seems faster dunno why. LTN12 functions that coroutines fail gracefully.
Diffstat (limited to 'doc')
-rw-r--r--doc/ftp.html272
-rw-r--r--doc/ltn12.html421
-rw-r--r--doc/mime.html428
-rw-r--r--doc/reference.css3
-rw-r--r--doc/reference.html89
-rw-r--r--doc/smtp.html235
-rw-r--r--doc/socket.html25
-rw-r--r--doc/tcp.html29
-rw-r--r--doc/udp.html5
-rw-r--r--doc/url.html76
10 files changed, 1296 insertions, 287 deletions
diff --git a/doc/ftp.html b/doc/ftp.html
index 6776a17..a0c9268 100644
--- a/doc/ftp.html
+++ b/doc/ftp.html
@@ -35,9 +35,9 @@
35 35
36<p> 36<p>
37FTP (File Transfer Protocol) is a protocol used to transfer files 37FTP (File Transfer Protocol) is a protocol used to transfer files
38between hosts. The module <tt>ftp.lua</tt> offers simple FTP support, 38between hosts. The module <tt>ftp.lua</tt> offers simple FTP support.
39allowing applications to download and upload files, and list directory 39Applications can easily download and upload files.
40contents. The implementation conforms to 40The implementation conforms to
41<a href="http://www.cs.princeton.edu/~diego/rfc/rfc0959.txt">RFC 959</a>. 41<a href="http://www.cs.princeton.edu/~diego/rfc/rfc0959.txt">RFC 959</a>.
42</p> 42</p>
43 43
@@ -49,175 +49,191 @@ URLs MUST conform to
49 49
50<blockquote> 50<blockquote>
51<tt> 51<tt>
52[ftp://][&lt;user&gt;[:&lt;password&gt;]@]&lt;host&gt;[:&lt;port&gt;][/&lt;path&gt;][<i>type</i>=a|i|d]</tt> 52[ftp://][&lt;user&gt;[:&lt;password&gt;]@]&lt;host&gt;[:&lt;port&gt;][/&lt;path&gt;][<i>type</i>=a|i]</tt>
53</blockquote> 53</blockquote>
54 54
55<p>
56High level functions are provided supporting the most common operations.
57These high level functions are implemented on top of a lower level
58interface. By using the low-level interface, users can easily create their
59own functions to access <em>any</em> operation supported by the FTP
60protocol. For that, check the implementation.
61</p>
62
63<p>
64To use some of the functions in this module, a good understanding of
65<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">
66LTN012, Filters sources and sinks</a> is necessary.
67</p>
68
69<p>
70The following constants can be set to control the default behaviour of
71the FTP module:
72</p>
73
74<ul>
75<li> <tt>PASSWORD</tt>: default anonymous password.
76<li> <tt>PORT</tt>: default port used for the control connection;
77<li> <tt>TIMEOUT</tt>: sets the timeout for all I/O operations;
78<li> <tt>USER</tt>: default anonymous user;
79</ul>
80
55<!-- ftp.get ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 81<!-- ftp.get ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
56 82
57<p class=name id=get> 83<p class=name id=get>
58socket.ftp.<b>get(</b>url<b>)</b><br> 84ftp.<b>get(</b>url<b>)</b><br>
59socket.ftp.<b>get{</b><br> 85ftp.<b>get{</b><br>
60&nbsp;&nbsp;url = <i>string</i>,<br> 86&nbsp;&nbsp;host = <i>string</i>,<br>
61&nbsp;&nbsp;type = <i>string</i>,<br> 87&nbsp;&nbsp;sink = <i>LTN12 sink</i>,<br>
62&nbsp;&nbsp;user = <i>string</i>,<br> 88&nbsp;&nbsp;argument <i>or</i> path = <i>string</i>,<br>
63&nbsp;&nbsp;password = <i>string</i><br> 89&nbsp;&nbsp;[user = <i>string</i>,]<br>
90&nbsp;&nbsp;[password = <i>string</i>]<br>
91&nbsp;&nbsp;[command = <i>string</i>,]<br>
92&nbsp;&nbsp;[port = <i>number</i>,]<br>
93&nbsp;&nbsp;[type = <i>string</i>,]<br>
94&nbsp;&nbsp;[step = <i>LTN12 pump step</i>],<br>
64<b>}</b> 95<b>}</b>
65</p> 96</p>
66 97
67<p class=description> 98<p class=description>
68Downloads an URL from a FTP server. 99The <tt>get</tt> function has two forms. The simple form has fixed
100functionality: it downloads the contents of a URL and returns it as a
101string. The generic form allows a <em>lot</em> more control, as explained
102below.
69</p> 103</p>
70 104
71<p class=parameters> 105<p class=parameters>
72The function can be called either directly with a <tt>url</tt> 106If the argument of the <tt>get</tt> function is a table, the function
73or with a <em>request table</em>. 107expects at least the fields <tt>host</tt>, <tt>sink</tt>, and one of
74Fields passed explicitly in the request table override those 108<tt>argument</tt> or <tt>path</tt> (<tt>argument</tt> takes
75present in the <tt>url</tt>. 109precedence). <tt>Host</tt> is the server to connect to. <tt>Sink</tt> is
76</p> 110the LTN12 sink that will receive the downloaded data. <tt>Argument</tt> or
77 111<tt>path</tt> give the target path to the resource in the server. The
78<p class=parameters> 112optional arguments are the following:
79The parameter <tt>type</tt> accepts values '<tt>a</tt>' (ASCII, the
80default), '<tt>i</tt>' (binary) or '<tt>d</tt>' (directory listing) and
81determines the transfer type. If <tt>&lt;path&gt;</tt> ends with a
82'<tt>/</tt>' or <tt>type</tt> is '<tt>d</tt>', a directory listing of
83<tt>&lt;path&gt;</tt> is returned. If no <tt>user</tt> is provided in the
84<tt>url</tt> or explicitly, the function tries to log in as user
85'<tt>anonymous</tt>'.
86</p> 113</p>
114<ul>
115<li><tt>user</tt>, <tt>password</tt>: User name and password used for
116authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>";
117<li><tt>command</tt>: The FTP command used to obtain data. Defaults to
118"<tt>retr</tt>", but see example below;
119<li><tt>port</tt>: The port to contacct the server at. Defaults to 21;
120<li><tt>type</tt>: The transfer mode. Can take values "<tt>i</tt>" or
121"<tt>a</tt>". Defaults to whatever is the server default;
122<li><tt>step</tt>: LTN12 pump step function used to pass data from the
123server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function.
124</ul>
87 125
88<p class=return> 126<p class=return>
89If successful, the function returns 127If successful, the simple version returns the URL contents as a
90the file content as a string. In case of error, the function returns 128string, and the generic function returns 1. In case of error, both
91<b><tt>nil</tt></b> and an error message describing the error. 129functions return <b><tt>nil</tt></b> and an error message describing the
130error.
92</p> 131</p>
93 132
94<pre class=example> 133<pre class=example>
95-- Log as user "anonymous" on server "ftp.tecgraf.puc-rio.br", 134-- load the ftp support
96-- go to directory "pub/lua" and get file "lua.tar.gz" as binary. 135local ftp = require("ftp")
97f, e = socket.ftp.get("ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz;type=i")
98 136
99-- Log as user "anonymous" on server "ftp.tecgraf.puc-rio.br", 137-- Log as user "anonymous" on server "ftp.tecgraf.puc-rio.br",
100-- go to director "pub" and retrieve directory listing of directory "lua" 138-- and get file "lua.tar.gz" from directory "pub/lua" as binary.
101f, e = socket.ftp.get("ftp://ftp.tecgraf.puc-rio.br/pub/lua;type=d") 139f, e = ftp.get("ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz;type=i")
102
103-- Log as user "diego", password "nehab", on server "ftp.tecgraf.puc-rio.br",
104-- go to directory "tec/luasocket/bin" and retrieve file "luasocket.exe"
105-- (actually, fails because of wrong password, of course)
106f, e = socket.ftp.get{
107 url = "ftp://ftp.tecgraf.puc-rio.br/tec/luasocket/bin/luasocket.exe",
108 user = "diego",
109 password = "nehab",
110 type = "i"
111}
112-- f returns nil, and e returns an appropriate error message
113</pre> 140</pre>
114 141
115<!-- get_cb +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 142<pre class=example>
116 143-- load needed modules
117<p class=name id=get_cb> 144local ftp = require("ftp")
118socket.ftp.<b>get_cb{</b><br> 145local ltn12 = require("ltn12")
119&nbsp;&nbsp;url = <i>string</i>,<br> 146local url = require("url")
120&nbsp;&nbsp;type = <i>string</i>,<br> 147
121&nbsp;&nbsp;content_cb = <i>receive-callback</i>,<br> 148-- a function that returns a directory listing
122&nbsp;&nbsp;user = <i>string</i>,<br> 149function ls(u)
123&nbsp;&nbsp;password = <i>string</i><br> 150 local t = {}
124<b>}</b> 151 local p = url.parse(u)
125</p> 152 p.command = "nlst"
126 153 p.sink = ltn12.sink.table(t)
127<p class=description> 154 local r, e = ftp.get(p)
128Same as <a href="#get"><tt>get</tt></a>, but the library returns 155 return r and table.concat(t), e
129the content of the downloaded file to the receive callback 156end
130<tt>content_cb</tt>. 157</pre>
131</p>
132
133<p class=note>
134Note: for more information on callbacks, refer to
135<a href="stream.html#stream">Streaming with callbacks</a>.
136</p>
137 158
138<!-- put ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 159<!-- put ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
139 160
140<p class=name id=put> 161<p class=name id=put>
141socket.ftp.<b>put(</b>url, content<b>)</b><br> 162ftp.<b>put(</b>url, content<b>)</b><br>
142socket.ftp.<b>put{</b><br> 163ftp.<b>put{</b><br>
143&nbsp;&nbsp;url = <i>string</i>,<br> 164&nbsp;&nbsp;host = <i>string</i>,<br>
144&nbsp;&nbsp;content = <i>string</i>,<br> 165&nbsp;&nbsp;source = <i>LTN12 sink</i>,<br>
145&nbsp;&nbsp;type = <i>string</i>,<br> 166&nbsp;&nbsp;argument <i>or</i> path = <i>string</i>,<br>
146&nbsp;&nbsp;user = <i>string</i>,<br> 167&nbsp;&nbsp;[user = <i>string</i>,]<br>
147&nbsp;&nbsp;password = <i>string</i><br> 168&nbsp;&nbsp;[password = <i>string</i>]<br>
169&nbsp;&nbsp;[command = <i>string</i>,]<br>
170&nbsp;&nbsp;[port = <i>number</i>,]<br>
171&nbsp;&nbsp;[type = <i>string</i>,]<br>
172&nbsp;&nbsp;[step = <i>LTN12 pump step</i>],<br>
148<b>}</b> 173<b>}</b>
149</p> 174</p>
150 175
151<p class=description> 176<p class=description>
152Upload a file to a FTP server. 177The <tt>put</tt> function has two forms. The simple form has fixed
178functionality: it uploads a string of content into a URL. The generic form
179allows a <em>lot</em> more control, as explained below.
153</p> 180</p>
154 181
155<p class=parameters> 182<p class=parameters>
156The function can be called directly with a 183If the argument of the <tt>put</tt> function is a table, the function
157<tt>url</tt> and <tt>content</tt> parameters, or with a 184expects at least the fields <tt>host</tt>, <tt>source</tt>, and one of
158<em>request table</em>. 185<tt>argument</tt> or <tt>path</tt> (<tt>argument</tt> takes
159Values passed explicitly in the request table override those present in 186precedence). <tt>Host</tt> is the server to connect to. <tt>Source</tt> is
160the <tt>url</tt>. The parameter <tt>type</tt> accept values 187the LTN12 source that will provide the contents to be uploaded.
161'<tt>a</tt>' (ASCII, the default) or '<tt>i</tt>' (binary) and 188<tt>Argument</tt> or
162determines the transfer type. If no <tt>user</tt> is provided, the 189<tt>path</tt> give the target path to the resource in the server. The
163function tries to log in as '<tt>anonymous</tt>'. 190optional arguments are the following:
164</p> 191</p>
192<ul>
193<li><tt>user</tt>, <tt>password</tt>: User name and password used for
194authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>";
195<li><tt>command</tt>: The FTP command used to obtain data. Defaults to
196"<tt>retr</tt>", but see example below;
197<li><tt>port</tt>: The port to contacct the server at. Defaults to 21;
198<li><tt>type</tt>: The transfer mode. Can take values "<tt>i</tt>" or
199"<tt>a</tt>". Defaults to whatever is the server default;
200<li><tt>step</tt>: LTN12 pump step function used to pass data from the
201server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function.
202</ul>
165 203
166<p class=return> 204<p class=return>
167If successful, the function returns 1. In case of error, the 205Both functions return 1 if successful, or <b><tt>nil</tt></b> and an error
168function returns <b><tt>nil</tt></b> followed by a string describing the error. 206message describing the reason for failure.
169</p> 207</p>
170 208
171<pre class=example> 209<pre class=example>
172-- Log as user "anonymous" on server "ftp.free.org" and store file 210-- load the ftp support
173-- "hello" with contents "hello world!", using binary mode for the transfer 211local ftp = require("ftp")
174r, e = socket.ftp.put("ftp://ftp.free.org/hello;type=i", "hello world!\n")
175
176-- Does exactly the same, but logging in as diego
177r, e = socket.ftp.put{
178 url = "ftp://ftp.free.org/hello",
179 type = "i",
180 user = "diego",
181 password = "nehab",
182 content = "hello world\n"
183}
184</pre>
185</blockquote>
186
187<!-- put_cb +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
188
189<p class=name id=put_cb>
190socket.ftp.<b>put_cb{</b><br>
191&nbsp;&nbsp;url = <i>string</i>,<br>
192&nbsp;&nbsp;type = <i>string</i>,<br>
193&nbsp;&nbsp;content_cb = <i>send-callback</i>,<br>
194&nbsp;&nbsp;user = <i>string</i>,<br>
195&nbsp;&nbsp;password = <i>string</i><br>
196<b>}</b>
197</p>
198
199<p class=description>
200Same as <a href="#put"><tt>put</tt></a>, but the
201library obtains the contents of the file to be uploaded using the send
202callback <tt>content_cb</tt>.
203</p>
204 212
205<p class=note> 213-- Log as user "diego" on server "ftp.tecgraf.puc-rio.br",
206Note: for more information on callbacks, refer to 214-- using password "nehab", and store a file "README" with contents
207<a href="stream.html#stream">Streaming with callbacks</a>. 215-- "wrong password, of course"
208</p> 216f, e = ftp.put("ftp://diego:nehab@ftp.tecgraf.puc-rio.br/README", "wrong password, of course")
217</pre>
209 218
210<pre class=example> 219<pre class=example>
211-- Log as user "anonymous" on server "ftp.free.org" and store file 220-- load the ftp support
212-- "hello" with contents of the same file in the current directory, 221local ftp = require("ftp")
213-- using binary mode for the transfer 222local ltn12 = require("ltn12")
214r, e = socket.ftp.put_cb{ 223
215 url = "ftp://ftp.free.org/hello", 224-- Log as user "diego" on server "ftp.tecgraf.puc-rio.br",
216 type = "i", 225-- using password "nehab", and append to the file "LOG", sending the
217 content_cb = socket.callback.send_file(io.open("hello", "r")) 226-- contents of a local file
227f, e = ftp.put{
228 host = "ftp.tecgraf.puc-rio.br",
229 user = "diego",
230 password = "nehab",
231 command = "appe",
232 argument = "LOG",
233 source = ltn12.source.file(io.open("LOCAL-LOG", "r"))
218} 234}
219</pre> 235</pre>
220</blockquote> 236
221 237
222<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 238<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
223 239
diff --git a/doc/ltn12.html b/doc/ltn12.html
new file mode 100644
index 0000000..363ce43
--- /dev/null
+++ b/doc/ltn12.html
@@ -0,0 +1,421 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2 "http://www.w3.org/TR/html4/strict.dtd">
3<html>
4
5<head>
6<title>LuaSocket: Network support for the Lua language</title>
7<link rel="stylesheet" href="reference.css" type="text/css">
8</head>
9
10<body>
11
12<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
13
14<div class=header>
15<hr>
16<center>
17<table summary="LuaSocket logo">
18<tr><td align=center><a href="http://www.lua.org">
19<img border=0 alt="LuaSocket" src="luasocket.png">
20</a></td></tr>
21<tr><td align=center valign=top>Network support for the Lua language
22</td></tr>
23</table>
24<p class=bar>
25<a href="home.html">home</a> &middot;
26<a href="home.html#download">download</a> &middot;
27<a href="introduction.html">introduction</a> &middot;
28<a href="reference.html">reference</a>
29</p>
30</center>
31<hr>
32</div>
33
34<!-- ltn12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
35
36<h2 id=ltn12>LTN12</h2>
37
38<p> The LTN12 module implements the ideas described in
39<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">
40LTN012, Filters sources and sinks</a>. This manual simply describe the
41functions. Please refer to the LTN for a deeper explanation of the
42functionality provided by this module.
43</p>
44
45<!-- filters ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
46
47<h3 id="filter">Filters</h3>
48
49<!-- chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
50
51<p class=name id="filter.chain">
52ltn12.filter.<b>chain(</b>filter<sub>1</sub>, filter<sub>2</sub>
53[, ... filter<sub>N</sub>]<b>)</b>
54</p>
55
56<p class=description>
57Returns a filter that passes all data it receives through each of a
58series of given filters.
59</p>
60
61<p class=parameters>
62<tt>Filter<sub>1</sub></tt> to <tt>filter<sub>N</sub></tt> are simple
63filters.
64</p>
65
66<p class=return>
67The function returns the chained filter.
68</p>
69
70<p class=note>
71The nesting of filters can be arbritrary. For instance, the useless filter
72below doesn't do anything but return the data that was passed to it,
73unaltered.
74</p>
75
76<pre class=example>
77-- load required modules
78ltn12 = require("ltn12")
79mime = require("mime")
80
81-- create a silly identity filter
82id = ltn12.filter.chain(
83 mime.encode("quoted-printable"),
84 mime.encode("base64"),
85 mime.decode("base64"),
86 mime.decode("quoted-printable")
87)
88</pre>
89
90<!-- cycle ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
91
92<p class=name id="filter.cycle">
93ltn12.filter.<b>cycle(</b>low [, ctx, extra]<b>)</b>
94</p>
95
96<p class=description>
97Returns a high-level filter that cycles though a low-level filter by
98passing it each chunk and updating a context between calls.
99</p>
100
101<p class=parameters>
102<tt>Low</tt> is the low-level filter to be cycled,
103<tt>ctx</tt> is the initial context and <tt>extra</tt> is any extra
104argument the low-level filter might take.
105</p>
106
107<p class=return>
108The function returns the high-level filter.
109</p>
110
111<pre class=example>
112-- load the ltn12 module
113local ltn12 = require("ltn12")
114
115-- the base64 mime filter factory
116encodet['base64'] = function()
117 return ltn12.filter.cycle(b64, "")
118end
119</pre>
120
121<!-- pumps ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
122
123<h3 id="pump">Pumps</h3>
124
125<!-- all ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
126
127<p class=name id="pump.all">
128ltn12.pump.<b>all(</b>source, sink<b>)</b>
129</p>
130
131<p class=description>
132Pumps <em>all</em> data from a <tt>source</tt> to a <tt>sink</tt>.
133</p>
134
135<p class=return>
136If successful, the function returns a value that evaluates to
137<b><tt>true</tt></b>. In case
138of error, the function returns a <b><tt>false</tt></b> value, followed by an error message.
139</p>
140
141<!-- step +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
142
143<p class=name id="pump.step">
144ltn12.pump.<b>step(</b>source, sink<b>)</b>
145</p>
146
147<p class=description>
148Pumps <em>one</em> chunk of data from a <tt>source</tt> to a <tt>sink</tt>.
149</p>
150
151<p class=return>
152If successful, the function returns a value that evaluates to
153<b><tt>true</tt></b>. In case
154of error, the function returns a <b><tt>false</tt></b> value, followed by an error message.
155</p>
156
157<!-- sinks ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
158
159<h3 id="sink">Sinks</h3>
160
161<!-- chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
162
163<p class=name id="sink.chain">
164ltn12.sink.<b>chain(</b>filter, sink<b>)</b>
165</p>
166
167<p class=description>
168Creates a new sink that passes data through a <tt>filter</tt> before sending
169it to a given <tt>sink</tt>.
170</p>
171
172<p class=return>
173The function returns the new sink.
174</p>
175
176<!-- error ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
177
178<p class=name id="sink.error">
179ltn12.sink.<b>error(</b>message<b>)</b>
180</p>
181
182<p class=description>
183Creates and returns a sink that aborts transmission with an error
184<tt>message</tt>.
185</p>
186
187<!-- file +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
188
189<p class=name id="sink.file">
190ltn12.sink.<b>file(</b>handle, message<b>)</b>
191</p>
192
193<p class=description>
194Creates a sink that sends data to a file.
195</p>
196
197<p class=parameters>
198<tt>Handle</tt> is a file handle. If <tt>handle</tt> is <tt><b>nil</b></tt>,
199<tt>message</tt> should give the reason for failure.
200</p>
201
202<p class=return>
203The function returns a sink that sends all data to the given <tt>handle</tt>
204and closes the file when done, or a sink that aborts the transmission with
205an error <tt>message</tt>
206</p>
207
208<p class=note>
209In the following example, notice how the prototype is designed to
210fit nicely with the <tt>io.open</tt> function.
211</p>
212
213<pre class=example>
214-- load the ltn12 module
215local ltn12 = require("ltn12")
216
217-- copy a file
218ltn12.pump.all(
219 ltn12.source.file(io.open("original.png")),
220 ltn12.sink.file(io.open("copy.png"))
221)
222</pre>
223
224<!-- null +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
225
226<p class=name id="sink.null">
227ltn12.sink.<b>null()</b>
228</p>
229
230<p class=description>
231Returns a sink that ignores all data it receives.
232</p>
233
234<!-- simplify +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
235
236<p class=name id="sink.simplify">
237ltn12.sink.<b>simplify(</b>sink<b>)</b>
238</p>
239
240<p class=description>
241Creates and returns a simple sink given a fancy <tt>sink</tt>.
242</p>
243
244<!-- table ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
245
246<p class=name id="sink.table">
247ltn12.sink.<b>table(</b>[table]<b>)</b>
248</p>
249
250<p class=description>
251Creates a sink that stores all chunks in a table. The chunks can later be
252efficiently concatenated into a single string.
253</p>
254
255<p class=parameters>
256<tt>Table</tt> is used to hold the chunks. If
257<tt><b>nil</b></tt>, the function creates its own table.
258</p>
259
260<p class=return>
261The function returns the sink and the table.
262</p>
263
264<pre class=example>
265-- load needed modules
266local http = require("http")
267local ltn12 = require("ltn12")
268
269-- the http.get function
270function get(u)
271 local t = {}
272 local respt = request{
273 url = u,
274 sink = ltn12.sink.table(t)
275 }
276 return table.concat(t), respt.headers, respt.code, respt.error
277end
278</pre>
279
280<!-- sinks ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
281
282<h3 id="source">Sources</h3>
283
284<!-- cat ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
285
286<p class=name id="source.cat">
287ltn12.source.<b>cat(</b>source<sub>1</sub> [, source<sub>2</sub>, ...,
288source<sub>N</sub>]<b>)</b>
289</p>
290
291<p class=description>
292Creates a new source that produces the concatenation of the data produced
293by a number of sources.
294</p>
295
296<p class=parameters>
297<tt>Source<sub>1</sub></tt> to <tt>source<sub>N</sub></tt> are the original
298sources.
299</p>
300
301<p class=return>
302The function returns the new source.
303</p>
304
305<!-- chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
306
307<p class=name id="source.chain">
308ltn12.source.<b>chain(</b>source, filter<b>)</b>
309</p>
310
311<p class=description>
312Creates a new <tt>source</tt> that passes data through a <tt>filter</tt>
313before returning it.
314</p>
315
316<p class=return>
317The function returns the new source.
318</p>
319
320<!-- empty ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
321
322<p class=name id="source.empty">
323ltn12.source.<b>empty()</b>
324</p>
325
326<p class=description>
327Creates and returns an empty source.
328</p>
329
330<!-- error ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
331
332<p class=name id="source.error">
333ltn12.source.<b>error(</b>message<b>)</b>
334</p>
335
336<p class=description>
337Creates and returns a source that aborts transmission with an error
338<tt>message</tt>.
339</p>
340
341<!-- file +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
342
343<p class=name id="source.file">
344ltn12.source.<b>file(</b>handle, message<b>)</b>
345</p>
346
347<p class=description>
348Creates a source that produces the contents of a file.
349</p>
350
351<p class=parameters>
352<tt>Handle</tt> is a file handle. If <tt>handle</tt> is <tt><b>nil</b></tt>,
353<tt>message</tt> should give the reason for failure.
354</p>
355
356<p class=return>
357The function returns a source that reads chunks of data from
358given <tt>handle</tt> and returns it to the user,
359closing the file when done, or a source that aborts the transmission with
360an error <tt>message</tt>
361</p>
362
363<p class=note>
364In the following example, notice how the prototype is designed to
365fit nicely with the <tt>io.open</tt> function.
366</p>
367
368<pre class=example>
369-- load the ltn12 module
370local ltn12 = require("ltn12")
371
372-- copy a file
373ltn12.pump.all(
374 ltn12.source.file(io.open("original.png")),
375 ltn12.sink.file(io.open("copy.png"))
376)
377</pre>
378
379<!-- simplify +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
380
381<p class=name id="source.simplify">
382ltn12.source.<b>simplify(</b>source<b>)</b>
383</p>
384
385<p class=description>
386Creates and returns a simple source given a fancy <tt>source</tt>.
387</p>
388
389<!-- string +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
390
391<p class=name id="source.string">
392ltn12.source.<b>string(</b>string<b>)</b>
393</p>
394
395<p class=description>
396Creates and returns a source that produces the contents of a
397<tt>string</tt>, chunk by chunk.
398</p>
399
400<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
401
402<div class=footer>
403<hr>
404<center>
405<p class=bar>
406<a href="home.html">home</a> &middot;
407<a href="home.html#down">download</a> &middot;
408<a href="introduction.html">introduction</a> &middot;
409<a href="reference.html">reference</a>
410</p>
411<p>
412<small>
413Last modified by Diego Nehab on <br>
414Sat Aug 9 01:00:41 PDT 2003
415</small>
416</p>
417</center>
418</div>
419
420</body>
421</html>
diff --git a/doc/mime.html b/doc/mime.html
new file mode 100644
index 0000000..d2fcc3c
--- /dev/null
+++ b/doc/mime.html
@@ -0,0 +1,428 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2 "http://www.w3.org/TR/html4/strict.dtd">
3<html>
4
5<head>
6<title>LuaSocket: Network support for the Lua language</title>
7<link rel="stylesheet" href="reference.css" type="text/css">
8</head>
9
10<body>
11
12<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
13
14<div class=header>
15<hr>
16<center>
17<table summary="LuaSocket logo">
18<tr><td align=center><a href="http://www.lua.org">
19<img border=0 alt="LuaSocket" src="luasocket.png">
20</a></td></tr>
21<tr><td align=center valign=top>Network support for the Lua language
22</td></tr>
23</table>
24<p class=bar>
25<a href="home.html">home</a> &middot;
26<a href="home.html#download">download</a> &middot;
27<a href="introduction.html">introduction</a> &middot;
28<a href="reference.html">reference</a>
29</p>
30</center>
31<hr>
32</div>
33
34<!-- mime +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
35
36<h2 id=mime>MIME</h2>
37
38<p>
39The MIME module offers filters that apply and remove common
40content transfer encodings, such as Base64 and Quoted-Printable.
41It also provides functions to break text into lines and change
42the end-of-line convention.
43MIME is described mainly in
44<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2045.txt">RFC 2045</a>,
45<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2046.txt">2046</a>,
46<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2047.txt">2047</a>,
47<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2047.txt">2048</a> and
48<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2048.txt">2049</a>.
49</p>
50
51<p>
52All functionality provided by the MIME module
53follows the ideas presented in
54<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">
55LTN012, Filters sources and sinks</a>.
56</p>
57
58<!-- High-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
59
60<h3 id=high>High-level filters</h3>
61
62<!-- normalize ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
63
64<p class=name id="normalize">
65mime.<b>normalize(</b>[marker]<b>)</b>
66</p>
67
68<p class=description>
69Converts most common end-of-line markers to a specific given marker.
70</p>
71
72<p class=parameters>
73<tt>Marker</tt> is the new marker. It defaults to CRLF, the canonic
74end-of-line marker defined by the MIME standard.
75</p>
76
77<p class=return>
78The function returns a filter that performs the conversion.
79</p>
80
81<p class=note>
82Note: There is no perfect solution to this problem. Different end-of-line
83markers are an evil that will probably plague developers forever.
84This function, however, will work perfectly for text created with any of
85the most common end-of-line markers, i.e. the MacOS (CR), the Unix (LF),
86or the DOS (CRLF) conventions. Even if the data has mixed end-of-line
87markers, the function will still work well, although it doesn't
88guarantee that the number of empty lines will be correct.
89</p>
90
91<!-- decode +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
92
93<p class=name id="decode">
94mime.<b>decode(</b>"base64"<b>)</b><br>
95mime.<b>decode(</b>"quoted-printable"<b>)</b>
96</p>
97
98<p class=description>
99Returns a filter that decodes data from a given transfer content
100encoding.
101</p>
102
103<p class=return>
104The function returns the created filter.
105</p>
106
107<!-- encode +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
108
109<p class=name id="encode">
110mime.<b>encode(</b>"base64"<b>)</b><br>
111mime.<b>encode(</b>"quoted-printable" [, mode])</b>
112</p>
113
114<p class=description>
115Returns a filter that encodes data according to a given transfer content
116encoding.
117</p>
118
119<p class=parameters>
120In the Quoted-Printable case, the user can specify whether the data is
121textual or binary, by passing the <tt>mode</tt> strings "<tt>text</tt>" or
122"<tt>binary</tt>". <tt>Mode</tt> defaults to "<tt>text</tt>".
123</p>
124
125<p class=return>
126The function returns the created filter.
127</p>
128
129<p class=note>
130Although both transfer content encodings specify a limit for the line
131length, the encoding filters do <em>not</em> break text into lines (for
132added flexibility).
133Below is a filter that converts binary data to the Base64 transfer content
134encoding and breaks it into lines of the correct size.
135</p>
136
137<pre class=example>
138base64 = ltn12.filter.chain(
139 mime.encode("base64"),
140 mime.wrap("base64")
141)
142</pre>
143
144<p class=note>
145Note: Text data <em>has</em> to be converted to canonic form
146<em>before</em> being encoded.
147</p>
148
149<pre class=example>
150base64 = ltn12.filter.chain(
151 mime.normalize(),
152 mime.encode("base64"),
153 mime.wrap("base64")
154)
155</pre>
156
157<!-- wrap +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
158
159<p class=name id="wrap">
160mime.<b>wrap(</b>"text" [, length]<b>)</b><br>
161mime.<b>wrap(</b>"base64"<b>)</b><br>
162mime.<b>wrap(</b>"quoted-printable"<b>)</b>
163</p>
164
165<p class=description>
166Returns a filter that breaks data into lines.
167</p>
168
169<p class=parameters>
170The "<tt>text</tt>" line-wrap filter simply breaks text into lines by
171inserting CRLF end-of-line markers at appropriate positions.
172<tt>Length</tt> defaults 76.
173The "<tt>base64</tt>" line-wrap filter works just like the default
174"<tt>text</tt>" line-wrap filter with default length.
175The function can also wrap "<tt>quoted-printable</tt>" lines, taking care
176not to break lines in the middle of an escaped character. In that case, the
177line length is fixed at 76.
178</p>
179
180<p class=return>
181The function returns the created filter.
182</p>
183
184<p class=note>
185For example, to create an encoding filter for the Quoted-Printable transfer content encoding of text data, do the following:
186</p>
187
188<pre class=example>
189qp = ltn12.filter.chain(
190 mime.normalize(),
191 mime.encode("quoted-printable"),
192 mime.wrap("quoted-printable")
193)
194</pre>
195
196<p class=note>
197Note: To break into lines with a different end-of-line convention, apply
198a normalization filter after the line break filter.
199</p>
200
201<!-- Low-level ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
202
203<h3 id=low>Low-level filters</h3>
204
205<!-- b64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
206
207<p class=name id="b64">
208A, B = mime.<b>b64(</b>C [, D]<b>)</b>
209</p>
210
211<p class=description>
212Low-level filter to perform Base64 encoding.
213</p>
214
215<p class=description>
216<tt>A</tt> is the encoded version of the largest prefix of
217<tt>C..D</tt>
218that can be encoded unambiguously. <tt>B</tt> has the remaining bytes of
219<tt>C..D</tt>, <em>before</em> encoding.
220If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> is padded with
221the encoding of the remaining bytes of <tt>C</tt>.
222</p>
223
224<p class=note>
225Note: The simplest use of this function is to encode a string into it's
226Base64 transfer content encoding. Notice the extra parenthesis around the
227call to <tt>mime.b64</tt>, to discard the second return value.
228</p>
229
230<pre class=example>
231print((mime.b64("diego:password")))
232--&gt; ZGllZ286cGFzc3dvcmQ=
233</pre>
234
235<!-- eol ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
236
237<p class=name id="eol">
238A, B = mime.<b>eol(</b>C [, D, marker]<b>)</b>
239</p>
240
241<p class=description>
242Low-level filter to perform end-of-line marker translation.
243For each chunk, the function needs to know if the last character of the
244previous chunk could be part of an end-of-line marker or not. This is the
245context the function receives besides the chunk. An updated version of
246the context is returned after each new chunk.
247</p>
248
249<p class=description>
250<tt>A</tt> is the translated version of <tt>D</tt>. <tt>C</tt> is the
251ASCII value of the last character of the previous chunk, if it was a
252candidate for line break, or 0 otherwise.
253<tt>B</tt> is the same as <tt>C</tt>, but for the current
254chunk. If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> includes a
255new end-of-line marker, depending on <tt>C</tt>.
256<tt>Marker</tt> gives the new end-of-line marker and defaults to CRLF.
257</p>
258
259<pre class=example>
260-- translates the end-of-line marker to UNIX
261unix = mime.eol(0, dos, "\n")
262</pre>
263
264<!-- qp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
265
266<p class=name id="qp">
267A, B = mime.<b>qp(</b>C [, D, marker]<b>)</b>
268</p>
269
270<p class=description>
271Low-level filter to perform Quoted-Printable encoding.
272</p>
273
274<p class=description>
275<tt>A</tt> is the encoded version of the largest prefix of
276<tt>C..D</tt>
277that can be encoded unambiguously. <tt>B</tt> has the remaining bytes of
278<tt>C..D</tt>, <em>before</em> encoding.
279If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> is padded with
280the encoding of the remaining bytes of <tt>C</tt>.
281Throughout encoding, occurences of CRLF are replaced by the
282<tt>marker</tt>, which itself defaults to CRLF.
283</p>
284
285<p class=note>
286Note: The simplest use of this function is to encode a string into it's
287Quoted-Printable transfer content encoding.
288Notice the extra parenthesis around the call to <tt>mime.qp</tt>, to discard the second return value.
289</p>
290
291<pre class=example>
292print((mime.qp("maçã")))
293--&gt; ma=E7=E3=
294</pre>
295
296<!-- qpwrp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
297
298<p class=name id="qpwrp">
299A, m = mime.<b>qpwrp(</b>n [, B, length]<b>)</b>
300</p>
301
302<p class=description>
303Low-level filter to break Quoted-Printable text into lines.
304</p>
305
306<p class=description>
307<tt>A</tt> is a copy of <tt>B</tt>, broken into lines of at most
308<tt>length</tt> bytes (defaults to 76).
309'<tt>n</tt>' should tell how many bytes are left for the first
310line of <tt>B</tt> and '<tt>m</tt>' returns the number of bytes
311left in the last line of <tt>A</tt>.
312</p>
313
314<p class=note>
315Note: Besides breaking text into lines, this function makes sure the line
316breaks don't fall in the middle of an escaped character combination. Also,
317this function only breaks lines that are bigger than <tt>length</tt> bytes.
318</p>
319
320<!-- unb64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
321
322<p class=name id="unb64">
323A, B = mime.<b>unb64(</b>C [, D]<b>)</b>
324</p>
325
326<p class=description>
327Low-level filter to perform Base64 decoding.
328</p>
329
330<p class=description>
331<tt>A</tt> is the decoded version of the largest prefix of
332<tt>C..D</tt>
333that can be decoded unambiguously. <tt>B</tt> has the remaining bytes of
334<tt>C..D</tt>, <em>before</em> decoding.
335If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> is the empty string
336and <tt>B</tt> returns whatever couldn't be decoded.
337</p>
338
339<p class=note>
340Note: The simplest use of this function is to decode a string from it's
341Base64 transfer content encoding.
342Notice the extra parenthesis around the call to <tt>mime.unqp</tt>, to discard the second return value.
343</p>
344
345<pre class=example>
346print((mime.unb64("ZGllZ286cGFzc3dvcmQ=")))
347--&gt; diego:password
348</pre>
349
350<!-- unqp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
351
352<p class=name id="unqp">
353A, B = mime.<b>unqp(</b>C [, D]<b>)</b>
354</p>
355
356<p class=description>
357Low-level filter to remove the Quoted-Printable transfer content encoding
358from data.
359</p>
360
361<p class=description>
362<tt>A</tt> is the decoded version of the largest prefix of
363<tt>C..D</tt>
364that can be decoded unambiguously. <tt>B</tt> has the remaining bytes of
365<tt>C..D</tt>, <em>before</em> decoding.
366If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> is augmented with
367the encoding of the remaining bytes of <tt>C</tt>.
368</p>
369
370<p class=note>
371Note: The simplest use of this function is to decode a string from it's
372Quoted-Printable transfer content encoding.
373Notice the extra parenthesis around the call to <tt>mime.unqp</tt>, to discard the second return value.
374</p>
375
376<pre class=example>
377print((mime.qp("ma=E7=E3=")))
378--&gt; maçã
379</pre>
380
381<!-- wrp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
382
383<p class=name id="wrp">
384A, m = mime.<b>wrp(</b>n [, B, length]<b>)</b>
385</p>
386
387<p class=description>
388Low-level filter to break text into lines with CRLF marker.
389Text is assumed to be in the <a href=#normalize><tt>normalize</tt></a> form.
390</p>
391
392<p class=description>
393<tt>A</tt> is a copy of <tt>B</tt>, broken into lines of at most
394<tt>length</tt> bytes (defaults to 76).
395'<tt>n</tt>' should tell how many bytes are left for the first
396line of <tt>B</tt> and '<tt>m</tt>' returns the number of bytes
397left in the last line of <tt>A</tt>.
398</p>
399
400<p class=note>
401Note: This function only breaks lines that are bigger than
402<tt>length</tt> bytes. The resulting line length does not include the CRLF
403marker.
404</p>
405
406
407<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
408
409<div class=footer>
410<hr>
411<center>
412<p class=bar>
413<a href="home.html">home</a> &middot;
414<a href="home.html#down">download</a> &middot;
415<a href="introduction.html">introduction</a> &middot;
416<a href="reference.html">reference</a>
417</p>
418<p>
419<small>
420Last modified by Diego Nehab on <br>
421Sat Aug 9 01:00:41 PDT 2003
422</small>
423</p>
424</center>
425</div>
426
427</body>
428</html>
diff --git a/doc/reference.css b/doc/reference.css
index 607ac4f..7c8148d 100644
--- a/doc/reference.css
+++ b/doc/reference.css
@@ -10,6 +10,9 @@ tt {
10 10
11h1, h2, h3, h4 { margin-left: 0em; } 11h1, h2, h3, h4 { margin-left: 0em; }
12 12
13
14h3 { padding-top: 1em; }
15
13p { margin-left: 1em; } 16p { margin-left: 1em; }
14 17
15p.name { 18p.name {
diff --git a/doc/reference.html b/doc/reference.html
index ba519c0..ebcfb5b 100644
--- a/doc/reference.html
+++ b/doc/reference.html
@@ -36,7 +36,7 @@
36<h2>Reference</h2> 36<h2>Reference</h2>
37 37
38<blockquote> 38<blockquote>
39<a href="dns.html">DNS services (socket.dns)</a> 39<a href="dns.html">DNS (in socket)</a>
40<blockquote> 40<blockquote>
41<a href="dns.html#toip">toip</a>, 41<a href="dns.html#toip">toip</a>,
42<a href="dns.html#tohostname">tohostname</a>, 42<a href="dns.html#tohostname">tohostname</a>,
@@ -47,31 +47,17 @@
47<!-- ftp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 47<!-- ftp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
48 48
49<blockquote> 49<blockquote>
50<a href="ftp.html">FTP (socket.ftp)</a> 50<a href="ftp.html">FTP</a>
51<blockquote> 51<blockquote>
52<a href="ftp.html#get">get</a>, 52<a href="ftp.html#get">get</a>,
53<a href="ftp.html#put">put</a>, 53<a href="ftp.html#put">put</a>
54<a href="ftp.html#open">open</a>.
55</blockquote> 54</blockquote>
56</blockquote> 55</blockquote>
57 56
58<!-- global +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
59
60<blockquote>
61<a href="global.html">Global symbols</a>
62<blockquote>
63<a href="global.html#LUASOCKET_LIBNAME">LUASOCKET_LIBNAME</a>,
64<a href="global.html#mime">mime</a>,
65<a href="global.html#ltn12">ltn12</a>,
66<a href="global.html#socket">socket</a>.
67</blockquote>
68</blockquote>
69</table>
70
71<!-- http +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 57<!-- http +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
72 58
73<blockquote> 59<blockquote>
74<a href="http.html">HTTP (socket.http)</a> 60<a href="http.html">HTTP</a>
75<blockquote> 61<blockquote>
76<a href="http.html#get">get</a>, 62<a href="http.html#get">get</a>,
77<a href="http.html#post">post</a>, 63<a href="http.html#post">post</a>,
@@ -82,46 +68,45 @@
82<!-- ltn12 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 68<!-- ltn12 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
83 69
84<blockquote> 70<blockquote>
85<a href="ltn12.html">LTN012 (ltn12)</a> 71<a href="ltn12.html">LTN12</a>
86<blockquote> 72<blockquote>
87<a href="ltn12.html#filter">filter</a>: 73<a href="ltn12.html#filter">filter</a>:
88<a href="ltn12.html#chain">chain</a>, 74<a href="ltn12.html#filter.chain">chain</a>,
89<a href="ltn12.html#cycle">cycle</a>. 75<a href="ltn12.html#filter.cycle">cycle</a>.
90</blockquote> 76</blockquote>
91<blockquote> 77<blockquote>
92<a href="ltn12.html#pump">pump</a>: 78<a href="ltn12.html#pump">pump</a>:
93<a href="ltn12.html#all">all</a>, 79<a href="ltn12.html#pump.all">all</a>,
94<a href="ltn12.html#step">step</a>. 80<a href="ltn12.html#pump.step">step</a>.
95</blockquote> 81</blockquote>
96<blockquote> 82<blockquote>
97<a href="ltn12.html#sink">sink</a>: 83<a href="ltn12.html#sink">sink</a>:
98<a href="ltn12.html#chain">chain</a>, 84<a href="ltn12.html#sink.chain">chain</a>,
99<a href="ltn12.html#error">error</a>, 85<a href="ltn12.html#sink.error">error</a>,
100<a href="ltn12.html#chain">file</a>, 86<a href="ltn12.html#sink.file">file</a>,
101<a href="ltn12.html#file">null</a>, 87<a href="ltn12.html#sink.null">null</a>,
102<a href="ltn12.html#simplify">simplify</a>, 88<a href="ltn12.html#sink.simplify">simplify</a>,
103<a href="ltn12.html#table">table</a>. 89<a href="ltn12.html#sink.table">table</a>.
104</blockquote> 90</blockquote>
105<blockquote> 91<blockquote>
106<a href="ltn12.html#source">source</a>: 92<a href="ltn12.html#source">source</a>:
107<a href="ltn12.html#cat">cat</a>, 93<a href="ltn12.html#source.cat">cat</a>,
108<a href="ltn12.html#chain">chain</a>, 94<a href="ltn12.html#source.chain">chain</a>,
109<a href="ltn12.html#empty">empty</a>, 95<a href="ltn12.html#source.empty">empty</a>,
110<a href="ltn12.html#file">file</a>, 96<a href="ltn12.html#source.error">error</a>,
111<a href="ltn12.html#simplify">simplify</a>, 97<a href="ltn12.html#source.file">file</a>,
112<a href="ltn12.html#simplify">rewind</a>, 98<a href="ltn12.html#source.simplify">simplify</a>,
113<a href="ltn12.html#simplify">string</a>. 99<a href="ltn12.html#source.string">string</a>.
114</blockquote> 100</blockquote>
115</blockquote> 101</blockquote>
116 102
117<!-- mime +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 103<!-- mime +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
118 104
119<blockquote> 105<blockquote>
120<a href="mime.html">MIME (mime) </a> 106<a href="mime.html">MIME</a>
121<blockquote> 107<blockquote>
122<a href="mime.html#high">high-level</a>: 108<a href="mime.html#high">high-level</a>:
123<a href="mime.html#normalize">normalize</a>, 109<a href="mime.html#normalize">normalize</a>,
124<a href="mime.html#chain">chain</a>,
125<a href="mime.html#decode">decode</a>, 110<a href="mime.html#decode">decode</a>,
126<a href="mime.html#encode">encode</a>, 111<a href="mime.html#encode">encode</a>,
127<a href="mime.html#wrap">wrap</a>. 112<a href="mime.html#wrap">wrap</a>.
@@ -141,9 +126,8 @@
141<!-- smtp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 126<!-- smtp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
142 127
143<blockquote> 128<blockquote>
144<a href="smtp.html">SMTP (socket.smtp)</a> 129<a href="smtp.html">SMTP</a>
145<blockquote> 130<blockquote>
146<a href="smtp.html#mail">open</a>,
147<a href="smtp.html#message">message</a>, 131<a href="smtp.html#message">message</a>,
148<a href="smtp.html#send">send</a>. 132<a href="smtp.html#send">send</a>.
149</blockquote> 133</blockquote>
@@ -152,26 +136,20 @@
152<!-- socket +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 136<!-- socket +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
153 137
154<blockquote> 138<blockquote>
155<a href="socket.html">The socket namespace (socket)</a> 139<a href="socket.html">Socket</a>
156<blockquote> 140<blockquote>
157<a href="tcp.html#bind">bind</a>, 141<a href="socket.html#debug">DEBUG</a>,
158<a href="tcp.html#connect">connect</a>,
159<a href="socket.html#debug">debug</a>,
160<a href="dns.html#dns">dns</a>, 142<a href="dns.html#dns">dns</a>,
161<a href="ftp.html#ftp">ftp</a>,
162<a href="http.html#http">http</a>,
163<a href="socket.html#protect">protect</a>, 143<a href="socket.html#protect">protect</a>,
164<a href="socket.html#select">select</a>, 144<a href="socket.html#select">select</a>,
165<a href="socket.html#sink">sink</a>, 145<a href="socket.html#sink">sink</a>,
166<a href="socket.html#source">source</a>, 146<a href="socket.html#source">source</a>,
167<a href="socket.html#sleep">sleep</a>, 147<a href="socket.html#sleep">sleep</a>,
168<a href="smtp.html#smtp">smtp</a>,
169<a href="socket.html#time">time</a>, 148<a href="socket.html#time">time</a>,
170<a href="tcp.html#tcp">tcp</a>, 149<a href="tcp.html#tcp">tcp</a>,
171<a href="socket.html#try">try</a>, 150<a href="socket.html#try">try</a>,
172<a href="udp.html#udp">udp</a>, 151<a href="udp.html#udp">udp</a>,
173<a href="url.html#url">url</a>, 152<a href="socket.html#version">VERSION</a>.
174<a href="socket.html#version">version</a>.
175</blockquote> 153</blockquote>
176</blockquote> 154</blockquote>
177</table> 155</table>
@@ -179,7 +157,7 @@
179<!-- tcp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 157<!-- tcp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
180 158
181<blockquote> 159<blockquote>
182<a href="tcp.html">TCP (socket.tcp)</a> 160<a href="tcp.html">TCP (in socket)</a>
183<blockquote> 161<blockquote>
184<a href="tcp.html#accept">accept</a>, 162<a href="tcp.html#accept">accept</a>,
185<a href="tcp.html#bind">bind</a>, 163<a href="tcp.html#bind">bind</a>,
@@ -198,7 +176,7 @@
198<!-- udp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 176<!-- udp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
199 177
200<blockquote> 178<blockquote>
201<a href="udp.html">UDP (socket.udp)</a> 179<a href="udp.html">UDP (in socket)</a>
202<blockquote> 180<blockquote>
203<a href="udp.html#close">close</a>, 181<a href="udp.html#close">close</a>,
204<a href="udp.html#getpeername">getpeername</a>, 182<a href="udp.html#getpeername">getpeername</a>,
@@ -210,23 +188,22 @@
210<a href="udp.html#setpeername">setpeername</a>, 188<a href="udp.html#setpeername">setpeername</a>,
211<a href="udp.html#setsockname">setsockname</a>, 189<a href="udp.html#setsockname">setsockname</a>,
212<a href="udp.html#setoption">setoption</a>, 190<a href="udp.html#setoption">setoption</a>,
213<a href="udp.html#settimeout">settimeout</a>, 191<a href="udp.html#settimeout">settimeout</a>.
214<a href="udp.html#settimeout">shutdown</a>.
215</blockquote> 192</blockquote>
216</blockquote> 193</blockquote>
217 194
218<!-- url ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 195<!-- url ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
219 196
220<blockquote> 197<blockquote>
221<a href="url.html">URL (socket.url) </a> 198<a href="url.html">URL</a>
222<blockquote> 199<blockquote>
223<a href="url.html#absolute">absolute</a>, 200<a href="url.html#absolute">absolute</a>,
224<a href="url.html#build">build</a>, 201<a href="url.html#build">build</a>,
225<a href="url.html#build_path">build_path</a>, 202<a href="url.html#build_path">build_path</a>,
226<a href="url.html#quote">quote</a>, 203<a href="url.html#escape">escape</a>,
227<a href="url.html#parse">parse</a>, 204<a href="url.html#parse">parse</a>,
228<a href="url.html#parse_path">parse_path</a>, 205<a href="url.html#parse_path">parse_path</a>,
229<a href="url.html#quote">unquote</a>. 206<a href="url.html#unescape">unescape</a>.
230</blockquote> 207</blockquote>
231</blockquote> 208</blockquote>
232 209
diff --git a/doc/smtp.html b/doc/smtp.html
index 0862de0..b0ae634 100644
--- a/doc/smtp.html
+++ b/doc/smtp.html
@@ -35,15 +35,22 @@
35 35
36<h2 id=smtp>SMTP</h2> 36<h2 id=smtp>SMTP</h2>
37 37
38<p> 38<p> The <tt>smtp.lua</tt> module provides functionality to send e-mail
39The <tt>smtp.lua</tt> module provides functionality to send e-mail
40messages. The implementation conforms to the Simple Mail Transfer Protocol, 39messages. The implementation conforms to the Simple Mail Transfer Protocol,
41<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2821.txt">RFC 2821</a>. 40<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2821.txt">RFC 2821</a>.
42The other RFC of interest in this implementation is 41Another RFC of interest is <a
43<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2822.txt">RFC 2822</a>, 42href="http://www.cs.princeton.edu/~diego/rfc/rfc2822.txt">RFC 2822</a>,
44which governs the Internet Message Format. 43which governs the Internet Message Format.
44Multipart messages (those that contain attatchments) are part
45of the MIME standard, but described mainly
46in <a href="http://www.cs.princeton.edu/~diego/rfc/rfc2046.txt">RFC
472046</a>
45 48
46</p> 49<p> In the description below, good understanding of <a
50href="http://lua-users.org/wiki/FiltersSourcesAndSinks"> LTN012, Filters
51sources and sinks</a> and the <a href=mime.html>MIME</a> module is
52assumed. In fact, the SMTP module was the main reason for their
53creation. </p>
47 54
48<p> 55<p>
49MIME headers are represented as a Lua table in the form: 56MIME headers are represented as a Lua table in the form:
@@ -78,29 +85,56 @@ Note: MIME headers are independent of order. Therefore, there is no problem
78in representing them in a Lua table. 85in representing them in a Lua table.
79</p> 86</p>
80 87
81<!-- mail +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 88<p>
89The following constants can be set to control the default behaviour of
90the SMTP module:
91</p>
82 92
83<p class=name id=mail> 93<ul>
84socket.smtp.<b>mail{</b><br> 94<li> <tt>DOMAIN</tt>: domain used to greet the server;
95<li> <tt>PORT</tt>: default port used for the connection;
96<li> <tt>SERVER</tt>: default server used for the connection;
97<li> <tt>TIMEOUT</tt>: default timeout for all I/O operations;
98<li> <tt>ZONE</tt>: default time zone.
99</ul>
100
101<!-- send +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
102
103<p class=name id=send>
104smtp.<b>send{</b><br>
85&nbsp;&nbsp;from = <i>string</i>,<br> 105&nbsp;&nbsp;from = <i>string</i>,<br>
86&nbsp;&nbsp;rcpt = <i>string</i> or <i>string-table</i>,<br> 106&nbsp;&nbsp;rcpt = <i>string</i> or <i>string-table</i>,<br>
87&nbsp;&nbsp;body = <i>string</i>,<br> 107&nbsp;&nbsp;source = <i>LTN12 source</i>,<br>
88&nbsp;&nbsp;headers = <i>headers-table</i>,<br> 108&nbsp;&nbsp;[server = <i>string</i>],<br>
89&nbsp;&nbsp;server = <i>string</i><br> 109&nbsp;&nbsp;[port = <i>string</i>]<br>
110&nbsp;&nbsp;[domain = <i>string</i>],<br>
111&nbsp;&nbsp;[step = <i>LTN12 pump step</i>],<br>
90<b>}</b> 112<b>}</b>
91</p> 113</p>
92 114
93<p class=description> 115<p class=description>
94Sends a message to a recipient list. 116Sends a message to a recipient list. Since sending messages is not as
117simple as downloading an URL from a FTP or HTTP server, this function
118doesn't have a simple interface. However, see the
119<a href=#message><tt>message</tt></a> source factory for
120a very powerful way to define the message contents.
95</p> 121</p>
96 122
97<p class=parameters> 123<p class=parameters>
98<tt>Rcpt</tt> is a Lua table with one entry for each recipient, or a string 124The sender is given by the e-mail address in the <tt>from</tt> field.
125<tt>Rcpt</tt> is a Lua table with one entry for each recipient e-mail
126address, or a string
99in case there is just one recipient. 127in case there is just one recipient.
100The sender is given by the e-mail address <tt>from</tt>. 128The contents of the message are given by a LTN12 <tt>source</tt>. Several
101The message is composed by the optional MIME Headers <tt>headers</tt> 129arguments are optional:
102and text <tt>body</tt>. The message is sent using the server 130<ul>
103<tt>server</tt>. 131<li> <tt>server</tt>: Server to connect to. Defaults to "localhost";
132<li> <tt>port</tt>: Port to connect to. Defaults to 25;
133<li> <tt>domain</tt>: Domain name used to greet the server; Defaults to the
134local machine host name;
135<li> <tt>step</tt>: LTN12 pump step function used to pass data from the
136source to the server. Defaults to the LTN12 <tt>pump.step</tt> function.
137</ul>
104</p> 138</p>
105 139
106<p class=return> 140<p class=return>
@@ -109,6 +143,13 @@ If successful, the function returns 1. Otherwise, the function returns
109</p> 143</p>
110 144
111<p class=note> 145<p class=note>
146Note: SMTP servers are can be very picky with the format of e-mail
147addresses. To be safe, use only addresses of the form
148"<tt>&lt;fulano@tecgraf.puc-rio.br&gt;</tt>" in the <tt>from</tt> and
149<tt>rcpt</tt> arguments to the <tt>send</tt> function. In headers, e-mail
150addresses can take whatever form you like. </p>
151
152<p class=note>
112Big note: There is a good deal of misconception with the use of the 153Big note: There is a good deal of misconception with the use of the
113destination address field headers, i.e., the '<tt>To</tt>', '<tt>Cc</tt>', 154destination address field headers, i.e., the '<tt>To</tt>', '<tt>Cc</tt>',
114and, more importantly, the '<tt>Bcc</tt>' headers. Do <em>not</em> add a 155and, more importantly, the '<tt>Bcc</tt>' headers. Do <em>not</em> add a
@@ -117,11 +158,12 @@ exact opposite of what you expect.
117</p> 158</p>
118 159
119<p class=note> 160<p class=note>
120Only recipients specified in the recipient list will receive a copy of the 161Only recipients specified in the <tt>rcpt</tt> list will receive a copy of the
121message. Each recipient of an SMTP mail message receives a copy of the 162message. Each recipient of an SMTP mail message receives a copy of the
122message body along with the headers, and nothing more. The headers are 163message body along with the headers, and nothing more. The headers
123considered as part of the message. The list of recipients is <em>not</em> 164<em>are</em> part of the message and should be produced by the LTN12
124part of the message. 165<tt>source</tt> function. The <tt>rcpt</tt> list is <em>not</em>
166part of the message and will not be sent to anyone.
125</p> 167</p>
126 168
127<p class=note> 169<p class=note>
@@ -143,9 +185,9 @@ Copy") contains addresses of recipients of the message whose addresses are not t
143</ul> 185</ul>
144 186
145<p class=note> 187<p class=note>
146The LuaSocket <tt>mail</tt> function does not interpret the headers you 188The LuaSocket <tt>send</tt> function does not care or interpret the
147pass to, but it gives you full control over what is sent and to whom 189headers you send, but it gives you full control over what is sent and
148it is sent: 190to whom it is sent:
149</p> 191</p>
150<ul> 192<ul>
151<li> If someone is to receive the message, the e-mail address <em>has</em> 193<li> If someone is to receive the message, the e-mail address <em>has</em>
@@ -171,36 +213,147 @@ and
171</p> 213</p>
172 214
173<pre class=example> 215<pre class=example>
216-- load the smtp support
217local smtp = require("smtp")
218
174-- Connects to server "localhost" and sends a message to users 219-- Connects to server "localhost" and sends a message to users
175-- "fulano@tecgraf.puc-rio.br", "beltrano@tecgraf.puc-rio.br", 220-- "fulano@tecgraf.puc-rio.br", "beltrano@tecgraf.puc-rio.br",
176-- and "sicrano@tecgraf.puc-rio.br". 221-- and "sicrano@tecgraf.puc-rio.br".
177-- Note that "fulano" is the primary recipient, "beltrano" receives a 222-- Note that "fulano" is the primary recipient, "beltrano" receives a
178-- carbon copy and neither of them knows that "sicrano" received a blind 223-- carbon copy and neither of them knows that "sicrano" received a blind
179-- carbon copy of the message. 224-- carbon copy of the message.
180headers = { 225from = "&lt;luasocket@tecgraf.puc-rio.br&gt;"
181 to = "fulano@tecgraf.puc-rio.br",
182 cc = "beltrano@tecgraf.puc-rio.br",
183 subject = "LuaSocket test message"
184}
185
186from = "luasocket@tecgraf.puc-rio.br"
187 226
188rcpt = { 227rcpt = {
189 "fulano@tecgraf.puc-rio.br", 228 "&lt;fulano@tecgraf.puc-rio.br&gt;",
190 "beltrano@tecgraf.puc-rio.br", 229 "&lt;beltrano@tecgraf.puc-rio.br&gt;",
191 "sicrano@tecgraf.puc-rio.br" 230 "&lt;sicrano@tecgraf.puc-rio.br&gt;"
192} 231}
193 232
194body = "This is a test message. Please ignore." 233mesgt = {
195 234 headers = {
196server = "localhost" 235 to = "Fulano da Silva &lt;fulano@tecgraf.puc-rio.br&gt;",
236 cc = '"Beltrano F. Nunes" &lt;beltrano@tecgraf.puc-rio.br&gt;',
237 subject = "My first message"
238 }
239 body = "I hope this works. If it does, I can send you another 1000 copies."
240}
197 241
198r, e = socket.smtp.mail{ 242r, e = smtp.send{
199 from = from, 243 from = from,
200 rcpt = rcpt, 244 rcpt = rcpt,
201 headers = headers, 245 source = smtp.message(mesgt)
202 body = body, 246}
203 server = server 247</pre>
248
249<!-- message ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
250
251<p class=name id=message>
252smtp.<b>message(</b>mesgt<b>)</b>
253</p>
254
255<p class=description>
256Returns a LTN12 source that sends an SMTP message body, possibly multipart
257(arbitrarily deep).
258</p>
259
260<p class=parameters>
261The only parameter of the function is a table describing the message.
262<tt>Mesgt</tt> has the following form (notice the recursive structure):
263</p>
264
265<blockquote>
266<table summary="Mesgt table structure">
267<tr><td><tt>
268mesgt = {<br>
269&nbsp;&nbsp;headers = <i>header-table</i>,<br>
270&nbsp;&nbsp;body = <i>LTN12 source</i> or <i>string</i> or
271<i>multipart-mesgt</i><br>
272}<br>
273&nbsp;<br>
274multipart-mesgt = {<br>
275&nbsp;&nbsp;preamble = <i>string</i><br>
276&nbsp;&nbsp;[1] = <i>mesgt</i>,<br>
277&nbsp;&nbsp;[2] = <i>mesgt</i>,<br>
278&nbsp;&nbsp;...<br>
279&nbsp;&nbsp;[<i>n</i>] = <i>mesgt</i>,<br>
280&nbsp;&nbsp;epilogue = <i>string</i>,<br>
281}<br>
282</tt></td></tr>
283</table>
284</blockquote>
285
286<p class=parameters>
287For a simple message, all that is needed is a set of <tt>headers</tt>
288and the <tt>body</tt>. The message <tt>body</tt> can be given as a string
289or as a LTN12 source. For multipart messages, the body is a table that
290recursively defines each part as an independent message, plus a preamble
291and an epilogue.
292</p>
293
294<p class=return>
295The function returns an LTN12 source that produces the message contents as
296defined by <tt>mesgt</tt>. Hopefuly, the following example will make
297things clear. When in doubt, refer to the appropriate RFC as listed in the
298introduction. </p>
299
300<pre class=example>
301-- load the smtp support and its friends
302local smtp = require("smtp")
303local mime = require("mime")
304local ltn12 = require("ltn12")
305
306-- creates a source to send a message with two parts. The first part is
307-- plain text, the second part is a PNG image, encoded as base64.
308source = smtp.message{
309 headers = {
310 -- Remember that headers are *ignored* by smtp.send.
311 from = "Sicrano de Oliveira &lt;sicrano@tecgraf.puc-rio.br&gt;",
312 to = "Fulano da Silva &lt;fulano@tecgraf.puc-rio.br&gt;",
313 subject = "Here is a message with attachments"
314 },
315 body = {
316 preamble = "If your client doesn't understand attachments, \r\n" ..
317 "it will still display the preamble and the epilogue.\r\n",
318 "Preamble might show up even in a MIME enabled client.",
319 -- first part: no headers means plain text, us-ascii.
320 -- The mime.eol low-level filter normalizes end-of-line markers.
321 [1] = {
322 body = mime.eol(0, [[
323 Lines in a message body should always end with CRLF.
324 The smtp module will *NOT* perform translation. It will
325 perform necessary stuffing or '.' characters, though.
326 ]])
327 },
328 -- second part: headers describe content to be a png image,
329 -- sent under the base64 transfer content encoding.
330 -- notice that nothing happens until the message is actually sent.
331 -- small chunks are loaded into memory right before transmission and
332 -- translation happens on the fly.
333 [2] = {
334 headers = {
335 ["content-type"] = 'image/png; name="image.png"',
336 ["content-disposition"] = 'attachment; filename="image.png"',
337 ["content-description"] = 'a beautiful image',
338 ["content-transfer-encoding"] = "BASE64"
339 },
340 body = ltn12.source.chain(
341 ltn12.source.file(io.open("image.png", "rb")),
342 ltn12.filter.chain(
343 mime.encode("base64"),
344 mime.wrap()
345 )
346 )
347 },
348 epilogue = "This might also show up, but after the attachments"
349 }
350}
351
352-- finally send it
353r, e = smtp.send{
354 from = "&lt;sicrano@tecgraf.puc-rio.br&gt;",
355 rcpt = "&lt;fulano@tecgraf.puc-rio.br&gt;",
356 source = source,
204} 357}
205</pre> 358</pre>
206 359
diff --git a/doc/socket.html b/doc/socket.html
index bde882b..eccc676 100644
--- a/doc/socket.html
+++ b/doc/socket.html
@@ -36,16 +36,13 @@
36<h2 id=socket>The socket namespace</h2> 36<h2 id=socket>The socket namespace</h2>
37 37
38<p> 38<p>
39The <tt>socket</tt> namespace contains the namespace tables for all 39The <tt>socket</tt> namespace contains the core functionality of LuaSocket.
40LuaSocket modules as well as function that didn't belong in any specific
41module, functions that are so commonly used that deserve a shortcut and a
42few constants.
43</p> 40</p>
44 41
45<!-- debug ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 42<!-- debug ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
46 43
47<p class=name id=debug> 44<p class=name id=debug>
48socket.<b>debug</b> 45socket.<b>DEBUG</b>
49</p> 46</p>
50 47
51<p class=description> 48<p class=description>
@@ -57,7 +54,7 @@ with debug support.
57<!-- protect +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 54<!-- protect +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
58 55
59<p class=name id=protect> 56<p class=name id=protect>
60socket.<b>protect(</b>function<b>)</b> 57socket.<b>protect(</b>func<b>)</b>
61</p> 58</p>
62 59
63<p class=description> 60<p class=description>
@@ -65,12 +62,12 @@ Converts a function that throws exceptions into a safe function.
65</p> 62</p>
66 63
67<p class=parameters> 64<p class=parameters>
68<tt>Function</tt> is a function that calls 65<tt>Funct</tt> is a function that calls
69<a href=#try><tt>try</tt></a> to throw exceptions. 66<a href=#try><tt>try</tt></a> to throw exceptions.
70</p> 67</p>
71 68
72<p class=return> 69<p class=return>
73The function an equivalent function that instead of throwing exceptoins, 70Returns an equivalent function that instead of throwing exceptions,
74returns <tt><b>nil</b></tt> followed by an error message. 71returns <tt><b>nil</b></tt> followed by an error message.
75</p> 72</p>
76 73
@@ -103,16 +100,16 @@ simplify the test if a specific socket has changed status.
103</p> 100</p>
104 101
105<p class=note> 102<p class=note>
106<b>Important Note</b>: a known bug in WinSock causes <tt>select</tt> to fail 103<b>Important note</b>: a known bug in WinSock causes <tt>select</tt> to fail
107on non-blocking TCP sockets. The function may return a socket as 104on non-blocking TCP sockets. The function may return a socket as
108writable even though the socket is <em>not</em> ready for sending. 105writable even though the socket is <em>not</em> ready for sending.
109</p> 106</p>
110 107
111<p class=note> 108<p class=note>
112<b>Important note</b>: calling select with a server socket in the receive 109<b>Another important note</b>: calling select with a server socket in the receive
113parameter before a call to accept does <em>not</em> guarantee 110parameter before a call to accept does <em>not</em> guarantee
114<a href=tcp.html#accept><tt>accept</tt></a> will return immediately. 111<a href=tcp.html#accept><tt>accept</tt></a> will return immediately.
115Use the <a href=tcp.html#timeout><tt>timeout</tt></a> 112Use the <a href=tcp.html#settimeout><tt>settimeout</tt></a>
116method or <tt>accept</tt> might block forever. 113method or <tt>accept</tt> might block forever.
117</p> 114</p>
118 115
@@ -131,7 +128,7 @@ socket.<b>sink(</b>mode, socket<b>)</b>
131 128
132<p class=description> 129<p class=description>
133Creates an 130Creates an
134<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN012</a> 131<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
135sink from a stream socket object. 132sink from a stream socket object.
136</p> 133</p>
137 134
@@ -163,7 +160,7 @@ socket.<b>source(</b>mode, socket [, length]<b>)</b>
163 160
164<p class=description> 161<p class=description>
165Creates an 162Creates an
166<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN012</a> 163<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
167source from a stream socket object. 164source from a stream socket object.
168</p> 165</p>
169 166
@@ -217,7 +214,7 @@ c = socket.try(socket.connect("localhost", 80))
217<!-- version ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 214<!-- version ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
218 215
219<p class=name id=version> 216<p class=name id=version>
220socket.<b>version</b> 217socket.<b>VERSION</b>
221</p> 218</p>
222 219
223<p class=description> 220<p class=description>
diff --git a/doc/tcp.html b/doc/tcp.html
index 34d6c6e..7a49660 100644
--- a/doc/tcp.html
+++ b/doc/tcp.html
@@ -241,18 +241,16 @@ method returns <b><tt>nil</tt></b> followed by an error message.
241<!-- receive ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 241<!-- receive ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
242 242
243<p class=name id=receive> 243<p class=name id=receive>
244client:<b>receive(</b>[pattern<sub>1</sub>, pattern<sub>2</sub>, 244client:<b>receive(</b>[pattern]<b>)</b>
245... pattern<sub>N</sub>]<b>)</b>
246</p> 245</p>
247 246
248<p class=description> 247<p class=description>
249Reads data from a client object, according to the specified <em>read 248Reads data from a client object, according to the specified <em>read
250patterns</em>. Patterns follow the Lua file I/O format, and the difference in performance between all patterns is negligible. 249pattern</em>. Patterns follow the Lua file I/O format, and the difference in performance between all patterns is negligible.
251</p> 250</p>
252 251
253<p class=parameters> 252<p class=parameters>
254The parameters <tt>pattern</tt><sub>1</sub>, <tt>pattern</tt><sub>2</sub>, ... 253<tt>Pattern</tt> can be any of the following:
255<tt>pattern</tt><sub>N</sub> can be any of the following:
256</p> 254</p>
257 255
258<ul> 256<ul>
@@ -267,16 +265,21 @@ of bytes from the socket.
267</ul> 265</ul>
268 266
269<p class=return> 267<p class=return>
270The method returns one value for each pattern, followed by a single 268If successful, the method returns the received pattern. In case of error,
271error code that can be <b><tt>nil</tt></b> in case of success, the string 269the method returns <tt><b>nil</b></tt> followed by an error message which
272'<tt>closed</tt>' in case the connection was closed before the 270can be the string '<tt>closed</tt>' in case the connection was
273transmission was completed or the string '<tt>timeout</tt>' in case 271closed before the transmission was completed or the string
274there was a timeout during the operation. 272'<tt>timeout</tt>' in case there was a timeout during the operation.
273Also, after the error message, the function returns the partial result of
274the transmission.
275</p> 275</p>
276 276
277<p class=note> 277<p class=note>
278Note: In case of error, the method always return everything it managed 278<b>Important note</b>: This function was changed <em>severely</em>. It used
279to download before the error condition was met. 279to support multiple patterns (but I have never seen this feature used) and
280partial results used to be returned in the same way as successful results.
281This last feature violated the idea that all functions should return
282<tt><b>nil</b></tt> on error. Thus the change.
280</p> 283</p>
281 284
282<!-- send +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 285<!-- send +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@@ -428,7 +431,7 @@ client:<b>shutdown(</b>mode<b>)</b><br>
428</p> 431</p>
429 432
430<p class=description> 433<p class=description>
431Shuts down part of a full duplex connection. 434Shuts down part of a full-duplex connection.
432</p> 435</p>
433 436
434<p class=parameters> 437<p class=parameters>
diff --git a/doc/udp.html b/doc/udp.html
index 9f5cf8f..5ae0a89 100644
--- a/doc/udp.html
+++ b/doc/udp.html
@@ -29,6 +29,11 @@
29<hr> 29<hr>
30</div> 30</div>
31 31
32
33<!-- udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
34
35<h2 id=udp>UDP</h2>
36
32<!-- socket.udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 37<!-- socket.udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
33 38
34<p class="name" id="socket.udp"> 39<p class="name" id="socket.udp">
diff --git a/doc/url.html b/doc/url.html
index f3a7cb7..cd699a2 100644
--- a/doc/url.html
+++ b/doc/url.html
@@ -59,7 +59,7 @@ An URL is defined by the following grammar:
59<!-- absolute +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 59<!-- absolute +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
60 60
61<p class=name id=absolute> 61<p class=name id=absolute>
62socket.url.<b>absolute(</b>base, relative<b>)</b> 62url.<b>absolute(</b>base, relative<b>)</b>
63</p> 63</p>
64 64
65<p class=description> 65<p class=description>
@@ -79,7 +79,7 @@ The function returns a string with the absolute URL.
79Note: The rules that 79Note: The rules that
80govern the composition are fairly complex, and are described in detail in 80govern the composition are fairly complex, and are described in detail in
81<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2396.txt">RFC 2396</a>. 81<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2396.txt">RFC 2396</a>.
82The example bellow should give an idea of what are the rules. 82The example bellow should give an idea of what the rules are.
83</p> 83</p>
84 84
85<pre class=example> 85<pre class=example>
@@ -114,7 +114,7 @@ g;x?y#s = http://a/b/c/g;x?y#s
114<!-- build ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 114<!-- build ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
115 115
116<p class=name id=build> 116<p class=name id=build>
117socket.url.<b>build(</b>parsed_url<b>)</b> 117url.<b>build(</b>parsed_url<b>)</b>
118</p> 118</p>
119 119
120<p class=description> 120<p class=description>
@@ -135,7 +135,7 @@ The function returns a string with the built URL.
135<!-- build_path +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 135<!-- build_path +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
136 136
137<p class=name id=build_path> 137<p class=name id=build_path>
138socket.url.<b>build_path(</b>segments, unsafe<b>)</b> 138url.<b>build_path(</b>segments, unsafe<b>)</b>
139</p> 139</p>
140 140
141<p class=description> 141<p class=description>
@@ -157,10 +157,39 @@ The function returns a string with the
157built <tt>&lt;path&gt;</tt> component. 157built <tt>&lt;path&gt;</tt> component.
158</p> 158</p>
159 159
160<!-- escape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
161
162<p class=name id="escape">
163url.<b>escape(</b>content<b>)</b>
164</p>
165
166<p class=description>
167Applies the URL escaping content coding to a string
168Each byte is encoded as a percent character followed
169by the two byte hexadecimal representation of its integer
170value.
171</p>
172
173<p class=parameters>
174<tt>Content</tt> is the string to be encoded.
175</p>
176
177<p class=result>
178The function returns the encoded string.
179</p>
180
181<pre class=example>
182-- load url module
183url = require("url")
184
185code = url.escape("/#?;")
186-- code = "%2f%23%3f%3b"
187</pre>
188
160<!-- parse ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 189<!-- parse ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
161 190
162<p class=name id=parse> 191<p class=name id=parse>
163socket.url.<b>parse(</b>url, default<b>)</b> 192url.<b>parse(</b>url, default<b>)</b>
164</p> 193</p>
165 194
166<p class=description> 195<p class=description>
@@ -196,7 +225,10 @@ parsed_url = {<br>
196</tt></blockquote> 225</tt></blockquote>
197 226
198<pre class=example> 227<pre class=example>
199parsed_url = socket.url.parse("http://www.puc-rio.br/~diego/index.lua?a=2#there") 228-- load url module
229url = require("url")
230
231parsed_url = url.parse("http://www.puc-rio.br/~diego/index.lua?a=2#there")
200-- parsed_url = { 232-- parsed_url = {
201-- scheme = "http", 233-- scheme = "http",
202-- authority = "www.puc-rio.br", 234-- authority = "www.puc-rio.br",
@@ -206,7 +238,7 @@ parsed_url = socket.url.parse("http://www.puc-rio.br/~diego/index.lua?a=2#there"
206-- host = "www.puc-rio.br", 238-- host = "www.puc-rio.br",
207-- } 239-- }
208 240
209parsed_url = socket.url.parse("ftp://root:passwd@unsafe.org/pub/virus.exe;type=i") 241parsed_url = url.parse("ftp://root:passwd@unsafe.org/pub/virus.exe;type=i")
210-- parsed_url = { 242-- parsed_url = {
211-- scheme = "ftp", 243-- scheme = "ftp",
212-- authority = "root:passwd@unsafe.org", 244-- authority = "root:passwd@unsafe.org",
@@ -222,7 +254,7 @@ parsed_url = socket.url.parse("ftp://root:passwd@unsafe.org/pub/virus.exe;type=i
222<!-- parse_path +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 254<!-- parse_path +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
223 255
224<p class=name id=parse_path> 256<p class=name id=parse_path>
225socket.url.<b>parse_path(</b>path<b>)</b> 257url.<b>parse_path(</b>path<b>)</b>
226</p> 258</p>
227 259
228<p class=description> 260<p class=description>
@@ -241,36 +273,10 @@ returning a list with all the parsed segments, the function unescapes all
241of them. 273of them.
242</p> 274</p>
243 275
244<!-- escape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
245
246<p class=name id="escape">
247socket.url.<b>escape(</b>content<b>)</b>
248</p>
249
250<p class=description>
251Applies the URL escaping content coding to a string
252Each byte is encoded as a percent character followed
253by the two byte hexadecimal representation of its integer
254value.
255</p>
256
257<p class=parameters>
258<tt>Content</tt> is the string to be encoded.
259</p>
260
261<p class=result>
262The function returns the encoded string.
263</p>
264
265<pre class=example>
266code = socket.url.escape("/#?;")
267-- code = "%2f%23%3f%3b"
268</pre>
269
270<!-- unescape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 276<!-- unescape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
271 277
272<p class=name id="unescape"> 278<p class=name id="unescape">
273socket.url.<b>unescape(</b>content<b>)</b> 279url.<b>unescape(</b>content<b>)</b>
274</p> 280</p>
275 281
276<p class=description> 282<p class=description>