aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2005-08-12 05:56:32 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2005-08-12 05:56:32 +0000
commit0c3cdd5ef2485a79d6fec9261f2850c41577d5b3 (patch)
treed69164c9f815e2d0308ba3f0d15b18e67163d879
parent37f7af4b9f1250e3c3439df03d43cf291a4d6f37 (diff)
downloadluasocket-0c3cdd5ef2485a79d6fec9261f2850c41577d5b3.tar.gz
luasocket-0c3cdd5ef2485a79d6fec9261f2850c41577d5b3.tar.bz2
luasocket-0c3cdd5ef2485a79d6fec9261f2850c41577d5b3.zip
Final push for release...
-rw-r--r--FIX11
-rw-r--r--TODO34
-rw-r--r--config2
-rw-r--r--doc/ftp.html10
-rw-r--r--doc/http.html7
-rw-r--r--doc/index.html4
-rw-r--r--doc/installation.html14
-rw-r--r--doc/reference.html4
-rw-r--r--doc/smtp.html8
-rw-r--r--doc/socket.html6
-rw-r--r--doc/tcp.html21
-rw-r--r--etc/check-links-nb.lua81
-rw-r--r--etc/check-links.lua2
-rw-r--r--etc/dict.lua2
-rw-r--r--etc/lp.lua2
-rw-r--r--etc/tftp.lua2
-rw-r--r--makefile52
-rw-r--r--src/ftp.lua12
-rw-r--r--src/http.lua45
-rw-r--r--src/ltn12.lua12
-rw-r--r--src/luasocket.c2
-rw-r--r--src/makefile87
-rw-r--r--src/mime.lua3
-rw-r--r--src/smtp.lua29
-rw-r--r--src/socket.lua3
-rw-r--r--src/ssl.c70
-rw-r--r--src/ssl.h29
-rw-r--r--src/tp.lua9
-rw-r--r--src/url.lua2
-rw-r--r--src/wsocket.c5
-rw-r--r--test/testmesg.lua15
31 files changed, 331 insertions, 254 deletions
diff --git a/FIX b/FIX
index 3d0b3de..84504f0 100644
--- a/FIX
+++ b/FIX
@@ -1,3 +1,14 @@
1fix smtp.send hang on source error
2add create field to FTP and SMTP and fix HTTP ugliness
3clean timeout argument to open functions in SMTP, HTTP and FTP
4eliminate globals from namespaces created by module().
5
6
7
8
9
10
11
1url.absolute was not working when base_url was already parsed 12url.absolute was not working when base_url was already parsed
2http.request was redirecting even when the location header was empty 13http.request was redirecting even when the location header was empty
3tcp{client}:shutdown() was checking for group instead of class. 14tcp{client}:shutdown() was checking for group instead of class.
diff --git a/TODO b/TODO
index cb5ac32..b2a167e 100644
--- a/TODO
+++ b/TODO
@@ -1,21 +1,12 @@
1what the hell does __unload do? 1new instalation scheme???
2clean timeout argument to open functions in SMTP, HTTP and FTP 2test empty socket.select no windows.
3add create field to FTP and SMTP 3bug by mathew percival?
4talk about new create field in HTTP, FTP and SMTP
5talk about the non-blocking connect in the manual
6test it on Windows!!!
7 4
8think about a dispatcher. 5arranjar um jeito de fazer multipart/alternative
9 - it creates a server and receives a function that will do the work on
10 received connections
11 - this function is invoked with the client socket
12 - it calls special send and receive functions that yield on timeout
13 6
14think about how to extend http, ftp, smtp to use special send and receive 7what the hell does __unload do?
15functions for non-blocking so they can be used in the context of the
16dispatcher!
17 8
18adjust manual for new sock:send returns. 9test it on Windows!!!
19 10
20leave code for losers that don't have nanosleep 11leave code for losers that don't have nanosleep
21 12
@@ -41,7 +32,16 @@ testar os options!
41 - proteger ou atomizar o conjunto (timedout, receive), (timedout, send) 32 - proteger ou atomizar o conjunto (timedout, receive), (timedout, send)
42 - inet_ntoa também é uma merda. 33 - inet_ntoa também é uma merda.
43 34
44eliminate globals from namespaces created by module().
45
46* BUG NO SET DO TINYIRC!!! SINISTRO. 35* BUG NO SET DO TINYIRC!!! SINISTRO.
47* _VERSION, _DEBUG, etc. 36* _VERSION, _DEBUG, etc.
37* talk about new create field in HTTP, FTP and SMTP
38* talk about the non-blocking connect in the manual
39* think about how to extend http, ftp, smtp to use special send and receive
40* functions for non-blocking so they can be used in the context of the
41* dispatcher!
42* adjust manual for new sock:send returns.
43* think about a dispatcher.
44 * - it creates a server and receives a function that will do the work on
45 * received connections
46 * - this function is invoked with the client socket
47 * - it calls special send and receive functions that yield on timeout
diff --git a/config b/config
index dcc3955..da9fdf4 100644
--- a/config
+++ b/config
@@ -21,7 +21,7 @@ LUALIB=
21#------ 21#------
22# Compat-5.1 directory 22# Compat-5.1 directory
23# 23#
24COMPAT=compat-5.1r3 24COMPAT=compat-5.1r4
25 25
26#------ 26#------
27# Top of your Lua installation 27# Top of your Lua installation
diff --git a/doc/ftp.html b/doc/ftp.html
index 7860c27..8b7ed96 100644
--- a/doc/ftp.html
+++ b/doc/ftp.html
@@ -106,6 +106,7 @@ ftp.<b>get{</b><br>
106&nbsp;&nbsp;[port = <i>number</i>,]<br> 106&nbsp;&nbsp;[port = <i>number</i>,]<br>
107&nbsp;&nbsp;[type = <i>string</i>,]<br> 107&nbsp;&nbsp;[type = <i>string</i>,]<br>
108&nbsp;&nbsp;[step = <i>LTN12 pump step</i>,]<br> 108&nbsp;&nbsp;[step = <i>LTN12 pump step</i>,]<br>
109&nbsp;&nbsp;[create = <i>function</i>]<br>
109<b>}</b> 110<b>}</b>
110</p> 111</p>
111 112
@@ -138,7 +139,9 @@ authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>";
138<li><tt>step</tt>: 139<li><tt>step</tt>:
139<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> 140<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
140pump step function used to pass data from the 141pump step function used to pass data from the
141server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function. 142server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function;
143<li><tt>accept</tt>: An optional function to be used instead of
144<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created.
142</ul> 145</ul>
143 146
144<p class=return> 147<p class=return>
@@ -188,6 +191,7 @@ ftp.<b>put{</b><br>
188&nbsp;&nbsp;[port = <i>number</i>,]<br> 191&nbsp;&nbsp;[port = <i>number</i>,]<br>
189&nbsp;&nbsp;[type = <i>string</i>,]<br> 192&nbsp;&nbsp;[type = <i>string</i>,]<br>
190&nbsp;&nbsp;[step = <i>LTN12 pump step</i>,]<br> 193&nbsp;&nbsp;[step = <i>LTN12 pump step</i>,]<br>
194&nbsp;&nbsp;[create = <i>function</i>]<br>
191<b>}</b> 195<b>}</b>
192</p> 196</p>
193 197
@@ -220,7 +224,9 @@ authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>";
220<li><tt>step</tt>: 224<li><tt>step</tt>:
221<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> 225<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
222pump step function used to pass data from the 226pump step function used to pass data from the
223server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function. 227server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function;
228<li><tt>accept</tt>: An optional function to be used instead of
229<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created.
224</ul> 230</ul>
225 231
226<p class=return> 232<p class=return>
diff --git a/doc/http.html b/doc/http.html
index af58571..27942b1 100644
--- a/doc/http.html
+++ b/doc/http.html
@@ -131,7 +131,8 @@ http.<b>request{</b><br>
131&nbsp;&nbsp;[source = <i>LTN12 source</i>],<br> 131&nbsp;&nbsp;[source = <i>LTN12 source</i>],<br>
132&nbsp;&nbsp;[step = <i>LTN12 pump step</i>,]<br> 132&nbsp;&nbsp;[step = <i>LTN12 pump step</i>,]<br>
133&nbsp;&nbsp;[proxy = <i>string</i>,]<br> 133&nbsp;&nbsp;[proxy = <i>string</i>,]<br>
134&nbsp;&nbsp;[redirect = <i>boolean</i>]<br> 134&nbsp;&nbsp;[redirect = <i>boolean</i>,]<br>
135&nbsp;&nbsp;[create = <i>function</i>]<br>
135<b>}</b> 136<b>}</b>
136</p> 137</p>
137 138
@@ -178,7 +179,9 @@ pump step function used to move data.
178Defaults to the LTN12 <tt>pump.step</tt> function. 179Defaults to the LTN12 <tt>pump.step</tt> function.
179<li><tt>proxy</tt>: The URL of a proxy server to use. Defaults to no proxy; 180<li><tt>proxy</tt>: The URL of a proxy server to use. Defaults to no proxy;
180<li><tt>redirect</tt>: Set to <tt><b>false</b></tt> to prevent the 181<li><tt>redirect</tt>: Set to <tt><b>false</b></tt> to prevent the
181function from automatically following 301 or 302 server redirect messages. 182function from automatically following 301 or 302 server redirect messages;
183<li><tt>accept</tt>: An optional function to be used instead of
184<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created.
182</ul> 185</ul>
183 186
184<p class=return> 187<p class=return>
diff --git a/doc/index.html b/doc/index.html
index 933fa5f..e596f8e 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -168,6 +168,7 @@ support.
168<li> Improved: <tt>tcp:send(data, i, j)</tt> to return <tt>(i+sent-1)</tt>. This is great for non-blocking I/O, but might break some code; 168<li> Improved: <tt>tcp:send(data, i, j)</tt> to return <tt>(i+sent-1)</tt>. This is great for non-blocking I/O, but might break some code;
169<li> Improved: HTTP, SMTP, and FTP functions to accept a new field 169<li> Improved: HTTP, SMTP, and FTP functions to accept a new field
170<tt>create</tt> that overrides the function used to create socket objects; 170<tt>create</tt> that overrides the function used to create socket objects;
171<li> Fixed: <tt>smtp.send</tt> was hanging on errors returned by LTN12 sources;
171<li> Fixed: <tt>url.absolute()</tt> to work when <tt>base_url</tt> is in 172<li> Fixed: <tt>url.absolute()</tt> to work when <tt>base_url</tt> is in
172parsed form; 173parsed form;
173<li> Fixed: <tt>http.request()</tt> not to redirect when the location 174<li> Fixed: <tt>http.request()</tt> not to redirect when the location
@@ -194,7 +195,8 @@ with descriptor 0 to be ignored (Renato Maia);
194<li> Fixed: "Bug" that caused <tt>gethostbyname</tt> to crash under VMS 195<li> Fixed: "Bug" that caused <tt>gethostbyname</tt> to crash under VMS
195(Renato Maia); 196(Renato Maia);
196<li> Fixed: <tt>tcp:send("")</tt> to return 0 bytes sent (Alexander Marinov); 197<li> Fixed: <tt>tcp:send("")</tt> to return 0 bytes sent (Alexander Marinov);
197<li> Improved: <tt>socket.DEBUG</tt> and <tt>socket.VERSION</tt> became <tt>socket._DEBUGs</tt> and <tt>socket._VERSION</tt> for uniformity with other libraries. 198<li> Improved: <tt>socket.DEBUG</tt> and <tt>socket.VERSION</tt> became <tt>socket._DEBUGs</tt> and <tt>socket._VERSION</tt> for uniformity with other libraries;
199<li> Improved: <tt>socket.select</tt> now works on empty sets on Windows.
198</ul> 200</ul>
199 201
200<!-- incompatible +++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 202<!-- incompatible +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
diff --git a/doc/installation.html b/doc/installation.html
index 59815fa..62604ed 100644
--- a/doc/installation.html
+++ b/doc/installation.html
@@ -71,11 +71,11 @@ Here is the standard LuaSocket distribution directory structure:</p>
71 71
72<pre class=example> 72<pre class=example>
73&lt;ROOT&gt;/compat-5.1.lua 73&lt;ROOT&gt;/compat-5.1.lua
74&lt;ROOT&gt;/socket.lua
75&lt;ROOT&gt;/lsocket.dll
76&lt;ROOT&gt;/mime.lua
77&lt;ROOT&gt;/lmime.dll
78&lt;ROOT&gt;/ltn12.lua 74&lt;ROOT&gt;/ltn12.lua
75&lt;ROOT&gt;/mime/init.lua
76&lt;ROOT&gt;/mime/core.dll
77&lt;ROOT&gt;/socket/init.lua
78&lt;ROOT&gt;/socket/core.dll
79&lt;ROOT&gt;/socket/http.lua 79&lt;ROOT&gt;/socket/http.lua
80&lt;ROOT&gt;/socket/tp.lua 80&lt;ROOT&gt;/socket/tp.lua
81&lt;ROOT&gt;/socket/ftp.lua 81&lt;ROOT&gt;/socket/ftp.lua
@@ -83,10 +83,8 @@ Here is the standard LuaSocket distribution directory structure:</p>
83&lt;ROOT&gt;/socket/url.lua 83&lt;ROOT&gt;/socket/url.lua
84</pre> 84</pre>
85 85
86<p> Naturally, on Unix systems, <tt>lsocket.dll</tt> and <tt>lmime.dll</tt> 86<p> Naturally, on Unix systems, <tt>core.dll</tt>
87would be replaced by <tt>lsocket.so</tt> and <tt>lmime.so</tt>. In Mac OS 87would be replaced by <tt>core.so</tt>.
88X, they would be replaced by <tt>lsocket.dylib</tt> and
89<tt>lmime.dylib</tt>. </p>
90 88
91<p> In order for the interpreter to find all LuaSocket components, three 89<p> In order for the interpreter to find all LuaSocket components, three
92environment variables need to be set. The first environment variable tells 90environment variables need to be set. The first environment variable tells
diff --git a/doc/reference.html b/doc/reference.html
index fd5140b..b4b2f1d 100644
--- a/doc/reference.html
+++ b/doc/reference.html
@@ -142,7 +142,7 @@ Support, Manual">
142<blockquote> 142<blockquote>
143<a href="socket.html">Socket</a> 143<a href="socket.html">Socket</a>
144<blockquote> 144<blockquote>
145<a href="socket.html#_debug">_DEBUG</a>, 145<a href="socket.html#debug">_DEBUG</a>,
146<a href="dns.html#dns">dns</a>, 146<a href="dns.html#dns">dns</a>,
147<a href="socket.html#gettime">gettime</a>, 147<a href="socket.html#gettime">gettime</a>,
148<a href="socket.html#newtry">newtry</a>, 148<a href="socket.html#newtry">newtry</a>,
@@ -155,7 +155,7 @@ Support, Manual">
155<a href="tcp.html#tcp">tcp</a>, 155<a href="tcp.html#tcp">tcp</a>,
156<a href="socket.html#try">try</a>, 156<a href="socket.html#try">try</a>,
157<a href="udp.html#udp">udp</a>, 157<a href="udp.html#udp">udp</a>,
158<a href="socket.html#_version">_VERSION</a>. 158<a href="socket.html#version">_VERSION</a>.
159</blockquote> 159</blockquote>
160</blockquote> 160</blockquote>
161 161
diff --git a/doc/smtp.html b/doc/smtp.html
index bd18bfa..1e1523b 100644
--- a/doc/smtp.html
+++ b/doc/smtp.html
@@ -127,6 +127,7 @@ smtp.<b>send{</b><br>
127&nbsp;&nbsp;[port = <i>number</i>,]<br> 127&nbsp;&nbsp;[port = <i>number</i>,]<br>
128&nbsp;&nbsp;[domain = <i>string</i>,]<br> 128&nbsp;&nbsp;[domain = <i>string</i>,]<br>
129&nbsp;&nbsp;[step = <i>LTN12 pump step</i>,]<br> 129&nbsp;&nbsp;[step = <i>LTN12 pump step</i>,]<br>
130&nbsp;&nbsp;[create = <i>function</i>]<br>
130<b>}</b> 131<b>}</b>
131</p> 132</p>
132 133
@@ -138,6 +139,7 @@ doesn't have a simple interface. However, see the
138a very powerful way to define the message contents. 139a very powerful way to define the message contents.
139</p> 140</p>
140 141
142
141<p class=parameters> 143<p class=parameters>
142The sender is given by the e-mail address in the <tt>from</tt> field. 144The sender is given by the e-mail address in the <tt>from</tt> field.
143<tt>Rcpt</tt> is a Lua table with one entry for each recipient e-mail 145<tt>Rcpt</tt> is a Lua table with one entry for each recipient e-mail
@@ -158,7 +160,9 @@ local machine host name;
158<li> <tt>step</tt>: 160<li> <tt>step</tt>:
159<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> 161<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
160pump step function used to pass data from the 162pump step function used to pass data from the
161source to the server. Defaults to the LTN12 <tt>pump.step</tt> function. 163source to the server. Defaults to the LTN12 <tt>pump.step</tt> function;
164<li><tt>accept</tt>: An optional function to be used instead of
165<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created.
162</ul> 166</ul>
163 167
164<p class=return> 168<p class=return>
@@ -167,7 +171,7 @@ If successful, the function returns 1. Otherwise, the function returns
167</p> 171</p>
168 172
169<p class=note> 173<p class=note>
170Note: SMTP servers are can be very picky with the format of e-mail 174Note: SMTP servers can be very picky with the format of e-mail
171addresses. To be safe, use only addresses of the form 175addresses. To be safe, use only addresses of the form
172"<tt>&lt;fulano@example.com&gt;</tt>" in the <tt>from</tt> and 176"<tt>&lt;fulano@example.com&gt;</tt>" in the <tt>from</tt> and
173<tt>rcpt</tt> arguments to the <tt>send</tt> function. In headers, e-mail 177<tt>rcpt</tt> arguments to the <tt>send</tt> function. In headers, e-mail
diff --git a/doc/socket.html b/doc/socket.html
index 5cc7157..54b12cb 100644
--- a/doc/socket.html
+++ b/doc/socket.html
@@ -80,12 +80,12 @@ socket.<b>connect(</b>address, port [, locaddr, locport]<b>)</b>
80This function is a shortcut that creates and returns a TCP client object 80This function is a shortcut that creates and returns a TCP client object
81connected to a remote <tt>host</tt> at a given <tt>port</tt>. Optionally, 81connected to a remote <tt>host</tt> at a given <tt>port</tt>. Optionally,
82the user can also specify the local address and port to bind 82the user can also specify the local address and port to bind
83(<tt>locaddr</tt> and </tt>locport</tt>). 83(<tt>locaddr</tt> and <tt>locport</tt>).
84</p> 84</p>
85 85
86<!-- debug ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 86<!-- debug ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
87 87
88<p class=name id=_debug> 88<p class=name id=debug>
89socket.<b>_DEBUG</b> 89socket.<b>_DEBUG</b>
90</p> 90</p>
91 91
@@ -372,7 +372,7 @@ c = socket.try(socket.connect("localhost", 80))
372 372
373<!-- version ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 373<!-- version ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
374 374
375<p class=name id=_version> 375<p class=name id=version>
376socket.<b>_VERSION</b> 376socket.<b>_VERSION</b>
377</p> 377</p>
378 378
diff --git a/doc/tcp.html b/doc/tcp.html
index ae8efd5..5c810de 100644
--- a/doc/tcp.html
+++ b/doc/tcp.html
@@ -79,7 +79,7 @@ reported by <b><tt>nil</tt></b> followed by a message describing the error.
79<p class=note> 79<p class=note>
80Note: calling <a href=socket.html#select><tt>socket.select</tt></a> 80Note: calling <a href=socket.html#select><tt>socket.select</tt></a>
81with a server object in 81with a server object in
82the <tt>receive</tt> parameter before a call to <tt>accept</tt> does 82the <tt>recvt</tt> parameter before a call to <tt>accept</tt> does
83<em>not</em> guarantee <tt>accept</tt> will return immediately. Use the <a 83<em>not</em> guarantee <tt>accept</tt> will return immediately. Use the <a
84href=#settimeout><tt>settimeout</tt></a> method or <tt>accept</tt> 84href=#settimeout><tt>settimeout</tt></a> method or <tt>accept</tt>
85might block until <em>another</em> client shows up. 85might block until <em>another</em> client shows up.
@@ -111,7 +111,7 @@ method returns <b><tt>nil</tt></b> followed by an error message.
111 111
112<p class=note> 112<p class=note>
113Note: The function <a href=socket.html#bind><tt>socket.bind</tt></a> 113Note: The function <a href=socket.html#bind><tt>socket.bind</tt></a>
114is available and is a shortcut for the creation server sockets. 114is available and is a shortcut for the creation of server sockets.
115</p> 115</p>
116 116
117<!-- close ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 117<!-- close ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@@ -173,8 +173,11 @@ is available and is a shortcut for the creation of client sockets.
173<p class=note> 173<p class=note>
174Note: Starting with LuaSocket 2.0, 174Note: Starting with LuaSocket 2.0,
175the <a href=#settimeout><tt>settimeout</tt></a> 175the <a href=#settimeout><tt>settimeout</tt></a>
176method affects the behavior of connect, causing it to return in case of 176method affects the behavior of <tt>connect</tt>, causing it to return
177a timeout. 177with an error in case of a timeout. If that happens, you can still call <a
178href=socket.html#select><tt>socket.select</tt></a> with the socket in the
179<tt>sendt</tt> table. The socket will be writable when the connection is
180stablished.
178</p> 181</p>
179 182
180<!-- getpeername ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 183<!-- getpeername ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@@ -328,11 +331,11 @@ substring to be sent.
328</p> 331</p>
329 332
330<p class=return> 333<p class=return>
331If successful, the method returns the number of bytes accepted by 334If successful, the method returns the number of bytes sent.
332the transport layer. In case of error, the method returns 335In case of error, the method returns
333<b><tt>nil</tt></b>, followed by an error message, followed by the 336<b><tt>nil</tt></b>, followed by an error message, followed by the
334partial number of bytes accepted by the transport layer. 337index of the first character within <tt>[i, j]</tt> that has not been sent yet
335The error message can be '<tt>closed</tt>' in case 338(you might want to try again from then on). The error message can be '<tt>closed</tt>' in case
336the connection was closed before the transmission was completed or the 339the connection was closed before the transmission was completed or the
337string '<tt>timeout</tt>' in case there was a timeout during the 340string '<tt>timeout</tt>' in case there was a timeout during the
338operation. 341operation.
@@ -433,7 +436,7 @@ of bandwidth.
433<p class=parameters> 436<p class=parameters>
434<tt>Received</tt> is a number with the new number of bytes received. 437<tt>Received</tt> is a number with the new number of bytes received.
435<tt>Sent</tt> is a number with the new number of bytes sent. 438<tt>Sent</tt> is a number with the new number of bytes sent.
436<tt>Age</tt> is the new age in seconds</tt> 439<tt>Age</tt> is the new age in seconds.
437</p> 440</p>
438 441
439<p class=return> 442<p class=return>
diff --git a/etc/check-links-nb.lua b/etc/check-links-nb.lua
index 7e8df1b..c379e9a 100644
--- a/etc/check-links-nb.lua
+++ b/etc/check-links-nb.lua
@@ -84,17 +84,22 @@ function newcreate(thread)
84 first = (first or 1) - 1 84 first = (first or 1) - 1
85 local result, error 85 local result, error
86 while true do 86 while true do
87 -- tell dispatcher we want to keep sending before we
88 -- yield control
89 sending:insert(tcp)
90 -- return control to dispatcher
91 -- if upon return the dispatcher tells us we timed out,
92 -- return an error to whoever called us
93 if coroutine.yield() == "timeout" then
94 return nil, "timeout"
95 end
96 -- mark time we started waiting
97 context[tcp].last = socket.gettime()
98 -- try sending
87 result, error, first = tcp:send(data, first+1, last) 99 result, error, first = tcp:send(data, first+1, last)
88 if error == "timeout" then 100 -- if we are done, or there was an unexpected error,
89 -- tell dispatcher we want to keep sending 101 -- break away from loop
90 sending:insert(tcp) 102 if error ~= "timeout" then return result, error, first end
91 -- mark time we started waiting
92 context[tcp].last = socket.gettime()
93 -- return control to dispatcher
94 if coroutine.yield() == "timeout" then
95 return nil, "timeout"
96 end
97 else return result, error, first end
98 end 103 end
99 end, 104 end,
100 -- receive in non-blocking mode and yield on timeout 105 -- receive in non-blocking mode and yield on timeout
@@ -102,28 +107,35 @@ function newcreate(thread)
102 local error, partial = "timeout", "" 107 local error, partial = "timeout", ""
103 local value 108 local value
104 while true do 109 while true do
110 -- tell dispatcher we want to keep receiving before we
111 -- yield control
112 receiving:insert(tcp)
113 -- return control to dispatcher
114 -- if upon return the dispatcher tells us we timed out,
115 -- return an error to whoever called us
116 if coroutine.yield() == "timeout" then
117 return nil, "timeout"
118 end
119 -- mark time we started waiting
120 context[tcp].last = socket.gettime()
121 -- try receiving
105 value, error, partial = tcp:receive(pattern, partial) 122 value, error, partial = tcp:receive(pattern, partial)
106 if error == "timeout" then 123 -- if we are done, or there was an unexpected error,
107 -- tell dispatcher we want to keep receiving 124 -- break away from loop
108 receiving:insert(tcp) 125 if error ~= "timeout" then return value, error, partial end
109 -- mark time we started waiting
110 context[tcp].last = socket.gettime()
111 -- return control to dispatcher
112 if coroutine.yield() == "timeout" then
113 return nil, "timeout"
114 end
115 else return value, error, partial end
116 end 126 end
117 end, 127 end,
118 -- connect in non-blocking mode and yield on timeout 128 -- connect in non-blocking mode and yield on timeout
119 connect = function(self, host, port) 129 connect = function(self, host, port)
120 local result, error = tcp:connect(host, port) 130 local result, error = tcp:connect(host, port)
131 -- mark time we started waiting
132 context[tcp].last = socket.gettime()
121 if error == "timeout" then 133 if error == "timeout" then
122 -- tell dispatcher we will be able to write uppon connection 134 -- tell dispatcher we will be able to write uppon connection
123 sending:insert(tcp) 135 sending:insert(tcp)
124 -- mark time we started waiting
125 context[tcp].last = socket.gettime()
126 -- return control to dispatcher 136 -- return control to dispatcher
137 -- if upon return the dispatcher tells us we have a
138 -- timeout, just abort
127 if coroutine.yield() == "timeout" then 139 if coroutine.yield() == "timeout" then
128 return nil, "timeout" 140 return nil, "timeout"
129 end 141 end
@@ -148,10 +160,10 @@ function newcreate(thread)
148end 160end
149 161
150-- get the status of a URL, non-blocking 162-- get the status of a URL, non-blocking
151function getstatus(from, link) 163function getstatus(link)
152 local parsed = url.parse(link, {scheme = "file"}) 164 local parsed = url.parse(link, {scheme = "file"})
153 if parsed.scheme == "http" then 165 if parsed.scheme == "http" then
154 local thread = coroutine.create(function(thread, from, link) 166 local thread = coroutine.create(function(thread, link)
155 local r, c, h, s = http.request{ 167 local r, c, h, s = http.request{
156 method = "HEAD", 168 method = "HEAD",
157 url = link, 169 url = link,
@@ -162,7 +174,7 @@ function getstatus(from, link)
162 nthreads = nthreads - 1 174 nthreads = nthreads - 1
163 end) 175 end)
164 nthreads = nthreads + 1 176 nthreads = nthreads + 1
165 assert(coroutine.resume(thread, thread, from, link)) 177 assert(coroutine.resume(thread, thread, link))
166 end 178 end
167end 179end
168 180
@@ -190,6 +202,8 @@ function dispatch()
190 local now = socket.gettime() 202 local now = socket.gettime()
191 for who, data in pairs(context) do 203 for who, data in pairs(context) do
192 if data.last and now - data.last > TIMEOUT then 204 if data.last and now - data.last > TIMEOUT then
205 sending:remove(who)
206 receiving:remove(who)
193 assert(coroutine.resume(context[who].thread, "timeout")) 207 assert(coroutine.resume(context[who].thread, "timeout"))
194 end 208 end
195 end 209 end
@@ -206,14 +220,15 @@ function readfile(path)
206 else return nil, error end 220 else return nil, error end
207end 221end
208 222
209function retrieve(u) 223function load(u)
210 local parsed = url.parse(u, { scheme = "file" }) 224 local parsed = url.parse(u, { scheme = "file" })
211 local body, headers, code, error 225 local body, headers, code, error
212 local base = u 226 local base = u
213 if parsed.scheme == "http" then 227 if parsed.scheme == "http" then
214 body, code, headers = http.request(u) 228 body, code, headers = http.request(u)
215 if code == 200 then 229 if code == 200 then
216 base = base or headers.location 230 -- if there was a redirect, update base to reflect it
231 base = headers.location or base
217 end 232 end
218 if not body then 233 if not body then
219 error = code 234 error = code
@@ -241,12 +256,13 @@ function getlinks(body, base)
241 return links 256 return links
242end 257end
243 258
244function checklinks(from) 259function checklinks(address)
245 local base, body, error = retrieve(from) 260 local base, body, error = load(address)
246 if not body then print(error) return end 261 if not body then print(error) return end
262 print("Checking ", base)
247 local links = getlinks(body, base) 263 local links = getlinks(body, base)
248 for _, link in ipairs(links) do 264 for _, link in ipairs(links) do
249 getstatus(from, link) 265 getstatus(link)
250 end 266 end
251end 267end
252 268
@@ -255,8 +271,7 @@ if table.getn(arg) < 1 then
255 print("Usage:\n luasocket check-links.lua {<url>}") 271 print("Usage:\n luasocket check-links.lua {<url>}")
256 exit() 272 exit()
257end 273end
258for _, a in ipairs(arg) do 274for _, address in ipairs(arg) do
259 print("Checking ", a) 275 checklinks(url.absolute("file:", address))
260 checklinks(url.absolute("file:", a))
261end 276end
262dispatch() 277dispatch()
diff --git a/etc/check-links.lua b/etc/check-links.lua
index 79e6a54..9d837e4 100644
--- a/etc/check-links.lua
+++ b/etc/check-links.lua
@@ -37,7 +37,7 @@ function retrieve(u)
37 if parsed.scheme == "http" then 37 if parsed.scheme == "http" then
38 body, code, headers = http.request(u) 38 body, code, headers = http.request(u)
39 if code == 200 then 39 if code == 200 then
40 base = base or headers.location 40 base = headers.location or base
41 end 41 end
42 if not body then 42 if not body then
43 error = code 43 error = code
diff --git a/etc/dict.lua b/etc/dict.lua
index 76b254a..62d6913 100644
--- a/etc/dict.lua
+++ b/etc/dict.lua
@@ -16,6 +16,7 @@ local url = require("socket.url")
16local tp = require("socket.tp") 16local tp = require("socket.tp")
17 17
18module("socket.dict") 18module("socket.dict")
19getmetatable(_M).__index = nil
19 20
20----------------------------------------------------------------------------- 21-----------------------------------------------------------------------------
21-- Globals 22-- Globals
@@ -151,4 +152,3 @@ get = socket.protect(function(gett)
151 else return tget(gett) end 152 else return tget(gett) end
152end) 153end)
153 154
154--getmetatable(_M).__index = nil
diff --git a/etc/lp.lua b/etc/lp.lua
index 2ba7954..66a9692 100644
--- a/etc/lp.lua
+++ b/etc/lp.lua
@@ -15,6 +15,7 @@ local string = require("string")
15local socket = require("socket") 15local socket = require("socket")
16local ltn12 = require("ltn12") 16local ltn12 = require("ltn12")
17module("socket.lp") 17module("socket.lp")
18getmetatable(_M).__index = nil
18 19
19-- default port 20-- default port
20PORT = 515 21PORT = 515
@@ -318,4 +319,3 @@ query = socket.protect(function(p)
318 return data 319 return data
319end) 320end)
320 321
321--getmetatable(_M).__index = nil
diff --git a/etc/tftp.lua b/etc/tftp.lua
index 60658f7..b974db8 100644
--- a/etc/tftp.lua
+++ b/etc/tftp.lua
@@ -16,6 +16,7 @@ local socket = require("socket")
16local ltn12 = require("ltn12") 16local ltn12 = require("ltn12")
17local url = require("socket.url") 17local url = require("socket.url")
18module("socket.tftp") 18module("socket.tftp")
19getmetatable(_M).__index = nil
19 20
20----------------------------------------------------------------------------- 21-----------------------------------------------------------------------------
21-- Program constants 22-- Program constants
@@ -153,4 +154,3 @@ get = socket.protect(function(gett)
153 else return tget(gett) end 154 else return tget(gett) end
154end) 155end)
155 156
156--getmetatable(_M).__index = nil
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..234e162
--- /dev/null
+++ b/makefile
@@ -0,0 +1,52 @@
1#------
2# Load configuration
3#
4include config
5
6#------
7# Hopefully no need to change anything below this line
8#
9INSTALL_SOCKET=$(INSTALL_TOP)/socket
10INSTALL_MIME=$(INSTALL_TOP)/mime
11
12all clean:
13 cd src; $(MAKE) $@
14
15#------
16# Files to install
17#
18TO_SOCKET:= \
19 socket.lua \
20 http.lua \
21 url.lua \
22 tp.lua \
23 ftp.lua \
24 smtp.lua
25
26TO_TOP:= \
27 ltn12.lua
28
29TO_MIME:= \
30 $(MIME_SO) \
31 mime.lua
32
33#------
34# Install LuaSocket according to recommendation
35#
36install: all
37 cd src; mkdir -p $(INSTALL_TOP)
38 cd src; $(INSTALL_DATA) $(COMPAT)/compat-5.1.lua $(INSTALL_TOP)
39 cd src; $(INSTALL_DATA) ltn12.lua $(INSTALL_TOP)
40 cd src; mkdir -p $(INSTALL_SOCKET)
41 cd src; $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET)
42 cd src; $(INSTALL_DATA) $(TO_SOCKET) $(INSTALL_SOCKET)
43 cd src; cd $(INSTALL_SOCKET); $(INSTALL_LINK) -s $(SOCKET_SO) core.$(EXT)
44 cd src; cd $(INSTALL_SOCKET); $(INSTALL_LINK) -s socket.lua init.lua
45 cd src; mkdir -p $(INSTALL_MIME)
46 cd src; $(INSTALL_DATA) $(TO_MIME) $(INSTALL_MIME)
47 cd src; cd $(INSTALL_MIME); $(INSTALL_LINK) -s $(MIME_SO) core.$(EXT)
48 cd src; cd $(INSTALL_MIME); $(INSTALL_LINK) -s mime.lua init.lua
49
50#------
51# End of makefile
52#
diff --git a/src/ftp.lua b/src/ftp.lua
index 841df5f..226e04c 100644
--- a/src/ftp.lua
+++ b/src/ftp.lua
@@ -17,6 +17,7 @@ local url = require("socket.url")
17local tp = require("socket.tp") 17local tp = require("socket.tp")
18local ltn12 = require("ltn12") 18local ltn12 = require("ltn12")
19module("socket.ftp") 19module("socket.ftp")
20getmetatable(_M).__index = nil
20 21
21----------------------------------------------------------------------------- 22-----------------------------------------------------------------------------
22-- Program constants 23-- Program constants
@@ -35,8 +36,8 @@ PASSWORD = "anonymous@anonymous.org"
35----------------------------------------------------------------------------- 36-----------------------------------------------------------------------------
36local metat = { __index = {} } 37local metat = { __index = {} }
37 38
38function open(server, port) 39function open(server, port, create)
39 local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT)) 40 local tp = socket.try(tp.connect(server, port or PORT, create, TIMEOUT))
40 local f = base.setmetatable({ tp = tp }, metat) 41 local f = base.setmetatable({ tp = tp }, metat)
41 -- make sure everything gets closed in an exception 42 -- make sure everything gets closed in an exception
42 f.try = socket.newtry(function() f:close() end) 43 f.try = socket.newtry(function() f:close() end)
@@ -199,7 +200,7 @@ end
199local function tput(putt) 200local function tput(putt)
200 putt = override(putt) 201 putt = override(putt)
201 socket.try(putt.host, "missing hostname") 202 socket.try(putt.host, "missing hostname")
202 local f = open(putt.host, putt.port) 203 local f = open(putt.host, putt.port, putt.create)
203 f:greet() 204 f:greet()
204 f:login(putt.user, putt.password) 205 f:login(putt.user, putt.password)
205 if putt.type then f:type(putt.type) end 206 if putt.type then f:type(putt.type) end
@@ -242,7 +243,7 @@ end)
242local function tget(gett) 243local function tget(gett)
243 gett = override(gett) 244 gett = override(gett)
244 socket.try(gett.host, "missing hostname") 245 socket.try(gett.host, "missing hostname")
245 local f = open(gett.host, gett.port) 246 local f = open(gett.host, gett.port, gett.create)
246 f:greet() 247 f:greet()
247 f:login(gett.user, gett.password) 248 f:login(gett.user, gett.password)
248 if gett.type then f:type(gett.type) end 249 if gett.type then f:type(gett.type) end
@@ -264,7 +265,7 @@ command = socket.protect(function(cmdt)
264 cmdt = override(cmdt) 265 cmdt = override(cmdt)
265 socket.try(cmdt.host, "missing hostname") 266 socket.try(cmdt.host, "missing hostname")
266 socket.try(cmdt.command, "missing command") 267 socket.try(cmdt.command, "missing command")
267 local f = open(cmdt.host, cmdt.port) 268 local f = open(cmdt.host, cmdt.port, cmdt.create)
268 f:greet() 269 f:greet()
269 f:login(cmdt.user, cmdt.password) 270 f:login(cmdt.user, cmdt.password)
270 f.try(f.tp:command(cmdt.command, cmdt.argument)) 271 f.try(f.tp:command(cmdt.command, cmdt.argument))
@@ -278,4 +279,3 @@ get = socket.protect(function(gett)
278 else return tget(gett) end 279 else return tget(gett) end
279end) 280end)
280 281
281--getmetatable(_M).__index = nil
diff --git a/src/http.lua b/src/http.lua
index 91c52da..9434d97 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -16,6 +16,7 @@ local string = require("string")
16local base = _G 16local base = _G
17local table = require("table") 17local table = require("table")
18module("socket.http") 18module("socket.http")
19getmetatable(_M).__index = nil
19 20
20----------------------------------------------------------------------------- 21-----------------------------------------------------------------------------
21-- Program constants 22-- Program constants
@@ -105,26 +106,16 @@ end
105----------------------------------------------------------------------------- 106-----------------------------------------------------------------------------
106local metat = { __index = {} } 107local metat = { __index = {} }
107 108
108-- default connect function, respecting the timeout
109local function connect(host, port, create)
110 local c, e = (create or socket.tcp)()
111 if not c then return nil, e end
112 c:settimeout(TIMEOUT)
113 local r, e = c:connect(host, port or PORT)
114 if not r then
115 c:close()
116 return nil, e
117 end
118 return c
119end
120
121function open(host, port, create) 109function open(host, port, create)
122 -- create socket with user connect function, or with default 110 -- create socket with user connect function, or with default
123 local c = socket.try(connect(host, port, create)) 111 local c = socket.try(create or socket.tcp)()
124 -- create our http request object, pointing to the socket
125 local h = base.setmetatable({ c = c }, metat) 112 local h = base.setmetatable({ c = c }, metat)
126 -- make sure the object close gets called on exception 113 -- create finalized try
127 h.try = socket.newtry(function() h:close() end) 114 h.try = socket.newtry(function() h:close() end)
115 -- set timeout before connecting
116 h.try(c:settimeout(TIMEOUT))
117 h.try(c:connect(host, port or PORT))
118 -- here everything worked
128 return h 119 return h
129end 120end
130 121
@@ -134,11 +125,11 @@ function metat.__index:sendrequestline(method, uri)
134end 125end
135 126
136function metat.__index:sendheaders(headers) 127function metat.__index:sendheaders(headers)
128 local h = "\r\n"
137 for i, v in base.pairs(headers) do 129 for i, v in base.pairs(headers) do
138 self.try(self.c:send(i .. ": " .. v .. "\r\n")) 130 h = i .. ": " .. v .. "\r\n" .. h
139 end 131 end
140 -- mark end of request headers 132 self.try(self.c:send(h))
141 self.try(self.c:send("\r\n"))
142 return 1 133 return 1
143end 134end
144 135
@@ -213,7 +204,7 @@ local function adjustheaders(headers, host)
213 ["te"] = "trailers" 204 ["te"] = "trailers"
214 } 205 }
215 -- override with user headers 206 -- override with user headers
216 for i,v in pairs(headers or lower) do 207 for i,v in base.pairs(headers or lower) do
217 lower[string.lower(i)] = v 208 lower[string.lower(i)] = v
218 end 209 end
219 return lower 210 return lower
@@ -232,7 +223,7 @@ local function adjustrequest(reqt)
232 local nreqt = reqt.url and url.parse(reqt.url, default) or {} 223 local nreqt = reqt.url and url.parse(reqt.url, default) or {}
233 local t = url.parse(reqt.url, default) 224 local t = url.parse(reqt.url, default)
234 -- explicit components override url 225 -- explicit components override url
235 for i,v in pairs(reqt) do nreqt[i] = v end 226 for i,v in base.pairs(reqt) do nreqt[i] = v end
236 socket.try(nreqt.host, "invalid host '" .. base.tostring(nreqt.host) .. "'") 227 socket.try(nreqt.host, "invalid host '" .. base.tostring(nreqt.host) .. "'")
237 -- compute uri if user hasn't overriden 228 -- compute uri if user hasn't overriden
238 nreqt.uri = reqt.uri or adjusturi(nreqt) 229 nreqt.uri = reqt.uri or adjusturi(nreqt)
@@ -276,11 +267,11 @@ function tauthorize(reqt)
276 return trequest(reqt) 267 return trequest(reqt)
277end 268end
278 269
279function tredirect(reqt, headers) 270function tredirect(reqt, location)
280 return trequest { 271 local result, code, headers, status = trequest {
281 -- the RFC says the redirect URL has to be absolute, but some 272 -- the RFC says the redirect URL has to be absolute, but some
282 -- servers do not respect that 273 -- servers do not respect that
283 url = url.absolute(reqt, headers["location"]), 274 url = url.absolute(reqt, location),
284 source = reqt.source, 275 source = reqt.source,
285 sink = reqt.sink, 276 sink = reqt.sink,
286 headers = reqt.headers, 277 headers = reqt.headers,
@@ -288,6 +279,9 @@ function tredirect(reqt, headers)
288 nredirects = (reqt.nredirects or 0) + 1, 279 nredirects = (reqt.nredirects or 0) + 1,
289 connect = reqt.connect 280 connect = reqt.connect
290 } 281 }
282 -- pass location header back as a hint we redirected
283 headers.location = headers.location or location
284 return result, code, headers, status
291end 285end
292 286
293function trequest(reqt) 287function trequest(reqt)
@@ -301,7 +295,7 @@ function trequest(reqt)
301 headers = h:receiveheaders() 295 headers = h:receiveheaders()
302 if shouldredirect(reqt, code, headers) then 296 if shouldredirect(reqt, code, headers) then
303 h:close() 297 h:close()
304 return tredirect(reqt, headers) 298 return tredirect(reqt, headers.location)
305 elseif shouldauthorize(reqt, code) then 299 elseif shouldauthorize(reqt, code) then
306 h:close() 300 h:close()
307 return tauthorize(reqt) 301 return tauthorize(reqt)
@@ -332,4 +326,3 @@ request = socket.protect(function(reqt, body)
332 else return trequest(reqt) end 326 else return trequest(reqt) end
333end) 327end)
334 328
335--getmetatable(_M).__index = nil
diff --git a/src/ltn12.lua b/src/ltn12.lua
index fbc9dce..633e0d7 100644
--- a/src/ltn12.lua
+++ b/src/ltn12.lua
@@ -12,6 +12,7 @@ local string = require("string")
12local table = require("table") 12local table = require("table")
13local base = _G 13local base = _G
14module("ltn12") 14module("ltn12")
15getmetatable(_M).__index = nil
15 16
16filter = {} 17filter = {}
17source = {} 18source = {}
@@ -134,8 +135,6 @@ function source.rewind(src)
134 end 135 end
135end 136end
136 137
137local print = print
138
139-- chains a source with a filter 138-- chains a source with a filter
140function source.chain(src, f) 139function source.chain(src, f)
141 base.assert(src and f) 140 base.assert(src and f)
@@ -258,7 +257,8 @@ end
258function pump.step(src, snk) 257function pump.step(src, snk)
259 local chunk, src_err = src() 258 local chunk, src_err = src()
260 local ret, snk_err = snk(chunk, src_err) 259 local ret, snk_err = snk(chunk, src_err)
261 return chunk and ret and not src_err and not snk_err, src_err or snk_err 260 if chunk and ret then return 1
261 else return nil, src_err or snk_err end
262end 262end
263 263
264-- pumps all data from a source to a sink, using a step function 264-- pumps all data from a source to a sink, using a step function
@@ -267,8 +267,10 @@ function pump.all(src, snk, step)
267 step = step or pump.step 267 step = step or pump.step
268 while true do 268 while true do
269 local ret, err = step(src, snk) 269 local ret, err = step(src, snk)
270 if not ret then return not err, err end 270 if not ret then
271 if err then return nil, err
272 else return 1 end
273 end
271 end 274 end
272end 275end
273 276
274--getmetatable(_M).__index = nil
diff --git a/src/luasocket.c b/src/luasocket.c
index ed26b1f..94ea05b 100644
--- a/src/luasocket.c
+++ b/src/luasocket.c
@@ -108,7 +108,7 @@ static int base_open(lua_State *L) {
108/*-------------------------------------------------------------------------*\ 108/*-------------------------------------------------------------------------*\
109* Initializes all library modules. 109* Initializes all library modules.
110\*-------------------------------------------------------------------------*/ 110\*-------------------------------------------------------------------------*/
111LUASOCKET_API int luaopen_socketcore(lua_State *L) { 111LUASOCKET_API int luaopen_socket_core(lua_State *L) {
112 int i; 112 int i;
113 base_open(L); 113 base_open(L);
114 for (i = 0; mod[i].name; i++) mod[i].func(L); 114 for (i = 0; mod[i].name; i++) mod[i].func(L);
diff --git a/src/makefile b/src/makefile
new file mode 100644
index 0000000..7ef18bf
--- /dev/null
+++ b/src/makefile
@@ -0,0 +1,87 @@
1#------
2# Load configuration
3#
4include ../config
5
6#------
7# Hopefully no need to change anything below this line
8#
9
10#------
11# Modules belonging to socket-core
12#
13SOCKET_OBJS:= \
14 luasocket.o \
15 timeout.o \
16 buffer.o \
17 io.o \
18 auxiliar.o \
19 options.o \
20 inet.o \
21 tcp.o \
22 udp.o \
23 except.o \
24 select.o \
25 $(COMPAT)/compat-5.1.o \
26 usocket.o
27
28#------
29# Modules belonging mime-core
30#
31MIME_OBJS:=\
32 mime.o \
33 $(COMPAT)/compat-5.1.o
34
35#------
36# Modules belonging unix (local domain sockets)
37#
38UNIX_OBJS:=\
39 buffer.o \
40 auxiliar.o \
41 options.o \
42 timeout.o \
43 io.o \
44 usocket.o \
45 unix.o
46
47all: $(SOCKET_SO) $(MIME_SO)
48
49$(SOCKET_SO): $(SOCKET_OBJS)
50 $(LD) $(LDFLAGS) -o $@ $^
51
52$(MIME_SO): $(MIME_OBJS)
53 $(LD) $(LDFLAGS) -o $@ $^
54
55$(UNIX_SO): $(UNIX_OBJS)
56 $(LD) $(LDFLAGS) -o $@ $^
57
58#------
59# List of dependencies
60#
61auxiliar.o: auxiliar.c auxiliar.h
62buffer.o: buffer.c buffer.h io.h timeout.h
63except.o: except.c except.h
64inet.o: inet.c inet.h socket.h io.h timeout.h usocket.h
65io.o: io.c io.h timeout.h
66luasocket.o: luasocket.c luasocket.h auxiliar.h except.h timeout.h \
67 buffer.h io.h inet.h socket.h usocket.h tcp.h udp.h select.h
68mime.o: mime.c mime.h
69options.o: options.c auxiliar.h options.h socket.h io.h timeout.h \
70 usocket.h inet.h
71select.o: select.c socket.h io.h timeout.h usocket.h select.h
72tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \
73 options.h tcp.h buffer.h
74timeout.o: timeout.c auxiliar.h timeout.h
75udp.o: udp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \
76 options.h udp.h
77unix.o: unix.c auxiliar.h socket.h io.h timeout.h usocket.h options.h \
78 unix.h buffer.h
79usocket.o: usocket.c socket.h io.h timeout.h usocket.h
80
81clean:
82 rm -f $(SOCKET_SO) $(SOCKET_OBJS)
83 rm -f $(MIME_SO) $(UNIX_SO) $(MIME_OBJS) $(UNIX_OBJS)
84
85#------
86# End of makefile configuration
87#
diff --git a/src/mime.lua b/src/mime.lua
index e112f8a..af42dcd 100644
--- a/src/mime.lua
+++ b/src/mime.lua
@@ -14,6 +14,7 @@ local mime = require("mime.core")
14local io = require("io") 14local io = require("io")
15local string = require("string") 15local string = require("string")
16module("mime") 16module("mime")
17getmetatable(_M).__index = nil
17 18
18-- encode, decode and wrap algorithm tables 19-- encode, decode and wrap algorithm tables
19encodet = {} 20encodet = {}
@@ -84,5 +85,3 @@ end
84function stuff() 85function stuff()
85 return ltn12.filter.cycle(dot, 2) 86 return ltn12.filter.cycle(dot, 2)
86end 87end
87
88--getmetatable(_M).__index = nil
diff --git a/src/smtp.lua b/src/smtp.lua
index 6850f7f..46df1ab 100644
--- a/src/smtp.lua
+++ b/src/smtp.lua
@@ -18,6 +18,7 @@ local tp = require("socket.tp")
18local ltn12 = require("ltn12") 18local ltn12 = require("ltn12")
19local mime = require("mime") 19local mime = require("mime")
20module("socket.smtp") 20module("socket.smtp")
21getmetatable(_M).__index = nil
21 22
22----------------------------------------------------------------------------- 23-----------------------------------------------------------------------------
23-- Program constants 24-- Program constants
@@ -111,12 +112,12 @@ function metat.__index:send(mailt)
111 self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step) 112 self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
112end 113end
113 114
114function open(server, port) 115function open(server, port, create)
115 local tp = socket.try(tp.connect(server or SERVER, port or PORT, TIMEOUT)) 116 local tp = socket.try(tp.connect(server or SERVER, port or PORT,
117 create, TIMEOUT))
116 local s = base.setmetatable({tp = tp}, metat) 118 local s = base.setmetatable({tp = tp}, metat)
117 -- make sure tp is closed if we get an exception 119 -- make sure tp is closed if we get an exception
118 s.try = socket.newtry(function() 120 s.try = socket.newtry(function()
119 if s.tp:command("QUIT") then s.tp:check("2..") end
120 s:close() 121 s:close()
121 end) 122 end)
122 return s 123 return s
@@ -165,10 +166,9 @@ end
165local function send_source(mesgt) 166local function send_source(mesgt)
166 -- set content-type if user didn't override 167 -- set content-type if user didn't override
167 if not mesgt.headers or not mesgt.headers["content-type"] then 168 if not mesgt.headers or not mesgt.headers["content-type"] then
168 coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n') 169 coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n\r\n')
169 end 170 else coroutine.yield("\r\n") end
170 -- finish headers 171 -- finish headers
171 coroutine.yield("\r\n")
172 -- send body from source 172 -- send body from source
173 while true do 173 while true do
174 local chunk, err = mesgt.body() 174 local chunk, err = mesgt.body()
@@ -182,21 +182,20 @@ end
182local function send_string(mesgt) 182local function send_string(mesgt)
183 -- set content-type if user didn't override 183 -- set content-type if user didn't override
184 if not mesgt.headers or not mesgt.headers["content-type"] then 184 if not mesgt.headers or not mesgt.headers["content-type"] then
185 coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n') 185 coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n\r\n')
186 end 186 else coroutine.yield("\r\n") end
187 -- finish headers
188 coroutine.yield("\r\n")
189 -- send body from string 187 -- send body from string
190 coroutine.yield(mesgt.body) 188 coroutine.yield(mesgt.body)
191
192end 189end
193 190
194-- yield the headers one by one 191-- yield the headers all at once
195local function send_headers(mesgt) 192local function send_headers(mesgt)
196 if mesgt.headers then 193 if mesgt.headers then
194 local h = ""
197 for i,v in base.pairs(mesgt.headers) do 195 for i,v in base.pairs(mesgt.headers) do
198 coroutine.yield(i .. ':' .. v .. "\r\n") 196 h = i .. ': ' .. v .. "\r\n" .. h
199 end 197 end
198 coroutine.yield(h)
200 end 199 end
201end 200end
202 201
@@ -237,12 +236,10 @@ end
237-- High level SMTP API 236-- High level SMTP API
238----------------------------------------------------------------------------- 237-----------------------------------------------------------------------------
239send = socket.protect(function(mailt) 238send = socket.protect(function(mailt)
240 local s = open(mailt.server, mailt.port) 239 local s = open(mailt.server, mailt.port, mailt.create)
241 local ext = s:greet(mailt.domain) 240 local ext = s:greet(mailt.domain)
242 s:auth(mailt.user, mailt.password, ext) 241 s:auth(mailt.user, mailt.password, ext)
243 s:send(mailt) 242 s:send(mailt)
244 s:quit() 243 s:quit()
245 return s:close() 244 return s:close()
246end) 245end)
247
248--getmetatable(_M).__index = nil
diff --git a/src/socket.lua b/src/socket.lua
index 13b474d..be01667 100644
--- a/src/socket.lua
+++ b/src/socket.lua
@@ -12,6 +12,7 @@ local string = require("string")
12local math = require("math") 12local math = require("math")
13local socket = require("socket.core") 13local socket = require("socket.core")
14module("socket") 14module("socket")
15getmetatable(_M).__index = nil
15 16
16----------------------------------------------------------------------------- 17-----------------------------------------------------------------------------
17-- Exported auxiliar functions 18-- Exported auxiliar functions
@@ -131,5 +132,3 @@ sourcet["default"] = sourcet["until-closed"]
131 132
132source = choose(sourcet) 133source = choose(sourcet)
133 134
134-- clear globals from namespace
135getmetatable(_M).__index = nil
diff --git a/src/ssl.c b/src/ssl.c
deleted file mode 100644
index 8e2ce00..0000000
--- a/src/ssl.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/*=========================================================================*\
2* Simple client SSL support
3* LuaSocket toolkit
4*
5* RCS ID: $Id$
6\*=========================================================================*/
7#include <lua.h>
8#include <lauxlib.h>
9
10#include "ssl.h"
11
12/*=========================================================================*\
13* Internal function prototypes
14\*=========================================================================*/
15static int global_wrap(lua_State *L);
16
17/* functions in library namespace */
18static luaL_reg func[] = {
19 {"wrap", global_create},
20 {NULL, NULL}
21};
22
23static luaL_reg wrap[] = {
24 {"__tostring", aux_tostring},
25 {"__gc", meth_close},
26 {"close", meth_close},
27 {"receive", meth_receive},
28 {"send", meth_send},
29 {NULL, NULL}
30};
31
32static luaL_reg owned[] = {
33 {"__tostring", aux_tostring},
34 {NULL, NULL}
35};
36
37/*-------------------------------------------------------------------------*\
38* Initializes module
39\*-------------------------------------------------------------------------*/
40int ssl_open(lua_State *L)
41{
42 aux_newclass(L, "ssl{wraper}", wrap);
43 aux_newclass(L, "ssl{owned}", owned);
44 lua_pushstring(L, "ssl")
45 lua_newtable(L);
46 luaL_openlib(L, NULL, func, 0);
47 lua_settable(L, -3);
48 return 0;
49}
50
51/*=========================================================================*\
52* Library functions
53\*=========================================================================*/
54/*-------------------------------------------------------------------------*\
55* Wraps a tcp object into an SSL object
56\*-------------------------------------------------------------------------*/
57static int global_wrap(lua_State *L) {
58 p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1);
59 /* change class of tcp object */
60 aux_setclass(L, "ssl{owned}", 1);
61 /* create wrapper */
62 p_wrap wrap = (p_wrap) lua_newuserdata(L, sizeof(t_wrap));
63 /* lock reference */
64 lua_pushvalue(L, 1);
65 wrap->ref = lua_ref(L, 1);
66 /* initialize wrapper */
67 wrap->tcp = tcp;
68 io_init(&tcp->io, wrap_send, wrap_recv, wrap);
69 return 1;
70}
diff --git a/src/ssl.h b/src/ssl.h
deleted file mode 100644
index 13ce97b..0000000
--- a/src/ssl.h
+++ /dev/null
@@ -1,29 +0,0 @@
1#ifndef SSL_H
2#define SSL_H
3/*=========================================================================*\
4* Simple client SSL support
5* LuaSocket toolkit
6*
7* This is just a simple example to show how to extend LuaSocket
8*
9* RCS ID: $Id$
10\*=========================================================================*/
11#include <lua.h>
12#include <openssl/ssl.h>
13
14#include "buffer.h"
15#include "timeout.h"
16#include "socket.h"
17#include "tcp.h"
18
19typedef struct t_wrap_ {
20 p_tcp tcp;
21 SSL* ssl;
22 int ref;
23} t_wrap;
24
25typedef t_wrap *p_wrap;
26
27int ssl_open(lua_State *L);
28
29#endif /* SSL_H */
diff --git a/src/tp.lua b/src/tp.lua
index c51d123..7823699 100644
--- a/src/tp.lua
+++ b/src/tp.lua
@@ -13,6 +13,7 @@ local string = require("string")
13local socket = require("socket") 13local socket = require("socket")
14local ltn12 = require("ltn12") 14local ltn12 = require("ltn12")
15module("socket.tp") 15module("socket.tp")
16getmetatable(_M).__index = nil
16 17
17----------------------------------------------------------------------------- 18-----------------------------------------------------------------------------
18-- Program constants 19-- Program constants
@@ -98,7 +99,8 @@ end
98 99
99function metat.__index:source(source, step) 100function metat.__index:source(source, step)
100 local sink = socket.sink("keep-open", self.c) 101 local sink = socket.sink("keep-open", self.c)
101 return ltn12.pump.all(source, sink, step or ltn12.pump.step) 102 local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step)
103 return ret, err
102end 104end
103 105
104-- closes the underlying c 106-- closes the underlying c
@@ -108,8 +110,8 @@ function metat.__index:close()
108end 110end
109 111
110-- connect with server and return c object 112-- connect with server and return c object
111function connect(host, port, timeout) 113function connect(host, port, create, timeout)
112 local c, e = socket.tcp() 114 local c, e = (create or socket.tcp())
113 if not c then return nil, e end 115 if not c then return nil, e end
114 c:settimeout(timeout or TIMEOUT) 116 c:settimeout(timeout or TIMEOUT)
115 local r, e = c:connect(host, port) 117 local r, e = c:connect(host, port)
@@ -120,4 +122,3 @@ function connect(host, port, timeout)
120 return base.setmetatable({c = c}, metat) 122 return base.setmetatable({c = c}, metat)
121end 123end
122 124
123--getmetatable(_M).__index = nil
diff --git a/src/url.lua b/src/url.lua
index 0db111b..bd39d98 100644
--- a/src/url.lua
+++ b/src/url.lua
@@ -12,6 +12,7 @@ local string = require("string")
12local base = _G 12local base = _G
13local table = require("table") 13local table = require("table")
14module("socket.url") 14module("socket.url")
15getmetatable(_M).__index = nil
15 16
16----------------------------------------------------------------------------- 17-----------------------------------------------------------------------------
17-- Encodes a string into its escaped hexadecimal representation 18-- Encodes a string into its escaped hexadecimal representation
@@ -279,4 +280,3 @@ function build_path(parsed, unsafe)
279 return path 280 return path
280end 281end
281 282
282--getmetatable(_M).__index = nil
diff --git a/src/wsocket.c b/src/wsocket.c
index 2cbd073..c4c51b4 100644
--- a/src/wsocket.c
+++ b/src/wsocket.c
@@ -74,7 +74,10 @@ int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_tm tm) {
74 double t = tm_get(tm); 74 double t = tm_get(tm);
75 tv.tv_sec = (int) t; 75 tv.tv_sec = (int) t;
76 tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6); 76 tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
77 return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL); 77 if (n <= 0) {
78 Sleep(1000*t);
79 return 0;
80 } else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
78} 81}
79 82
80/*-------------------------------------------------------------------------*\ 83/*-------------------------------------------------------------------------*\
diff --git a/test/testmesg.lua b/test/testmesg.lua
index 5350921..37e8c11 100644
--- a/test/testmesg.lua
+++ b/test/testmesg.lua
@@ -48,18 +48,19 @@ source = smtp.message{
48 } 48 }
49} 49}
50 50
51--[[ 51function filter(s)
52sink = ltn12.sink.file(io.stdout) 52 if s then io.write(s) end
53ltn12.pump.all(source, sink) 53 return s
54]] 54end
55 55
56-- finally send it
57r, e = smtp.send{ 56r, e = smtp.send{
58 rcpt = {"<diego@tecgraf.puc-rio.br>", 57 rcpt = {"<diego@tecgraf.puc-rio.br>",
59 "<diego@princeton.edu>" }, 58 "<diego@princeton.edu>" },
60 from = "<diego@princeton.edu>", 59 from = "<diego@princeton.edu>",
61 source = source, 60 source = ltn12.source.chain(source, filter),
62 server = "mail.cs.princeton.edu" 61 --server = "mail.cs.princeton.edu"
62 server = "localhost",
63 port = 2525
63} 64}
64 65
65print(r, e) 66print(r, e)