mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 12:28:21 +01:00
Final push for release...
This commit is contained in:
parent
37f7af4b9f
commit
0c3cdd5ef2
11
FIX
11
FIX
@ -1,3 +1,14 @@
|
|||||||
|
fix smtp.send hang on source error
|
||||||
|
add create field to FTP and SMTP and fix HTTP ugliness
|
||||||
|
clean timeout argument to open functions in SMTP, HTTP and FTP
|
||||||
|
eliminate globals from namespaces created by module().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
url.absolute was not working when base_url was already parsed
|
url.absolute was not working when base_url was already parsed
|
||||||
http.request was redirecting even when the location header was empty
|
http.request was redirecting even when the location header was empty
|
||||||
tcp{client}:shutdown() was checking for group instead of class.
|
tcp{client}:shutdown() was checking for group instead of class.
|
||||||
|
36
TODO
36
TODO
@ -1,22 +1,13 @@
|
|||||||
|
new instalation scheme???
|
||||||
|
test empty socket.select no windows.
|
||||||
|
bug by mathew percival?
|
||||||
|
|
||||||
|
arranjar um jeito de fazer multipart/alternative
|
||||||
|
|
||||||
what the hell does __unload do?
|
what the hell does __unload do?
|
||||||
clean timeout argument to open functions in SMTP, HTTP and FTP
|
|
||||||
add create field to FTP and SMTP
|
|
||||||
talk about new create field in HTTP, FTP and SMTP
|
|
||||||
talk about the non-blocking connect in the manual
|
|
||||||
test it on Windows!!!
|
test it on Windows!!!
|
||||||
|
|
||||||
think about a dispatcher.
|
|
||||||
- it creates a server and receives a function that will do the work on
|
|
||||||
received connections
|
|
||||||
- this function is invoked with the client socket
|
|
||||||
- it calls special send and receive functions that yield on timeout
|
|
||||||
|
|
||||||
think about how to extend http, ftp, smtp to use special send and receive
|
|
||||||
functions for non-blocking so they can be used in the context of the
|
|
||||||
dispatcher!
|
|
||||||
|
|
||||||
adjust manual for new sock:send returns.
|
|
||||||
|
|
||||||
leave code for losers that don't have nanosleep
|
leave code for losers that don't have nanosleep
|
||||||
|
|
||||||
ftp.send/recv return bytes transfered?
|
ftp.send/recv return bytes transfered?
|
||||||
@ -41,7 +32,16 @@ testar os options!
|
|||||||
- proteger ou atomizar o conjunto (timedout, receive), (timedout, send)
|
- proteger ou atomizar o conjunto (timedout, receive), (timedout, send)
|
||||||
- inet_ntoa também é uma merda.
|
- inet_ntoa também é uma merda.
|
||||||
|
|
||||||
eliminate globals from namespaces created by module().
|
|
||||||
|
|
||||||
* BUG NO SET DO TINYIRC!!! SINISTRO.
|
* BUG NO SET DO TINYIRC!!! SINISTRO.
|
||||||
* _VERSION, _DEBUG, etc.
|
* _VERSION, _DEBUG, etc.
|
||||||
|
* talk about new create field in HTTP, FTP and SMTP
|
||||||
|
* talk about the non-blocking connect in the manual
|
||||||
|
* think about how to extend http, ftp, smtp to use special send and receive
|
||||||
|
* functions for non-blocking so they can be used in the context of the
|
||||||
|
* dispatcher!
|
||||||
|
* adjust manual for new sock:send returns.
|
||||||
|
* think about a dispatcher.
|
||||||
|
* - it creates a server and receives a function that will do the work on
|
||||||
|
* received connections
|
||||||
|
* - this function is invoked with the client socket
|
||||||
|
* - it calls special send and receive functions that yield on timeout
|
||||||
|
2
config
2
config
@ -21,7 +21,7 @@ LUALIB=
|
|||||||
#------
|
#------
|
||||||
# Compat-5.1 directory
|
# Compat-5.1 directory
|
||||||
#
|
#
|
||||||
COMPAT=compat-5.1r3
|
COMPAT=compat-5.1r4
|
||||||
|
|
||||||
#------
|
#------
|
||||||
# Top of your Lua installation
|
# Top of your Lua installation
|
||||||
|
10
doc/ftp.html
10
doc/ftp.html
@ -106,6 +106,7 @@ ftp.<b>get{</b><br>
|
|||||||
[port = <i>number</i>,]<br>
|
[port = <i>number</i>,]<br>
|
||||||
[type = <i>string</i>,]<br>
|
[type = <i>string</i>,]<br>
|
||||||
[step = <i>LTN12 pump step</i>,]<br>
|
[step = <i>LTN12 pump step</i>,]<br>
|
||||||
|
[create = <i>function</i>]<br>
|
||||||
<b>}</b>
|
<b>}</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -138,7 +139,9 @@ authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>";
|
|||||||
<li><tt>step</tt>:
|
<li><tt>step</tt>:
|
||||||
<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
|
<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
|
||||||
pump step function used to pass data from the
|
pump step function used to pass data from the
|
||||||
server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function.
|
server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function;
|
||||||
|
<li><tt>accept</tt>: An optional function to be used instead of
|
||||||
|
<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
@ -188,6 +191,7 @@ ftp.<b>put{</b><br>
|
|||||||
[port = <i>number</i>,]<br>
|
[port = <i>number</i>,]<br>
|
||||||
[type = <i>string</i>,]<br>
|
[type = <i>string</i>,]<br>
|
||||||
[step = <i>LTN12 pump step</i>,]<br>
|
[step = <i>LTN12 pump step</i>,]<br>
|
||||||
|
[create = <i>function</i>]<br>
|
||||||
<b>}</b>
|
<b>}</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -220,7 +224,9 @@ authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>";
|
|||||||
<li><tt>step</tt>:
|
<li><tt>step</tt>:
|
||||||
<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
|
<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
|
||||||
pump step function used to pass data from the
|
pump step function used to pass data from the
|
||||||
server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function.
|
server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function;
|
||||||
|
<li><tt>accept</tt>: An optional function to be used instead of
|
||||||
|
<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
|
@ -131,7 +131,8 @@ http.<b>request{</b><br>
|
|||||||
[source = <i>LTN12 source</i>],<br>
|
[source = <i>LTN12 source</i>],<br>
|
||||||
[step = <i>LTN12 pump step</i>,]<br>
|
[step = <i>LTN12 pump step</i>,]<br>
|
||||||
[proxy = <i>string</i>,]<br>
|
[proxy = <i>string</i>,]<br>
|
||||||
[redirect = <i>boolean</i>]<br>
|
[redirect = <i>boolean</i>,]<br>
|
||||||
|
[create = <i>function</i>]<br>
|
||||||
<b>}</b>
|
<b>}</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -178,7 +179,9 @@ pump step function used to move data.
|
|||||||
Defaults to the LTN12 <tt>pump.step</tt> function.
|
Defaults to the LTN12 <tt>pump.step</tt> function.
|
||||||
<li><tt>proxy</tt>: The URL of a proxy server to use. Defaults to no proxy;
|
<li><tt>proxy</tt>: The URL of a proxy server to use. Defaults to no proxy;
|
||||||
<li><tt>redirect</tt>: Set to <tt><b>false</b></tt> to prevent the
|
<li><tt>redirect</tt>: Set to <tt><b>false</b></tt> to prevent the
|
||||||
function from automatically following 301 or 302 server redirect messages.
|
function from automatically following 301 or 302 server redirect messages;
|
||||||
|
<li><tt>accept</tt>: An optional function to be used instead of
|
||||||
|
<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
|
@ -168,6 +168,7 @@ support.
|
|||||||
<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;
|
<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;
|
||||||
<li> Improved: HTTP, SMTP, and FTP functions to accept a new field
|
<li> Improved: HTTP, SMTP, and FTP functions to accept a new field
|
||||||
<tt>create</tt> that overrides the function used to create socket objects;
|
<tt>create</tt> that overrides the function used to create socket objects;
|
||||||
|
<li> Fixed: <tt>smtp.send</tt> was hanging on errors returned by LTN12 sources;
|
||||||
<li> Fixed: <tt>url.absolute()</tt> to work when <tt>base_url</tt> is in
|
<li> Fixed: <tt>url.absolute()</tt> to work when <tt>base_url</tt> is in
|
||||||
parsed form;
|
parsed form;
|
||||||
<li> Fixed: <tt>http.request()</tt> not to redirect when the location
|
<li> Fixed: <tt>http.request()</tt> not to redirect when the location
|
||||||
@ -194,7 +195,8 @@ with descriptor 0 to be ignored (Renato Maia);
|
|||||||
<li> Fixed: "Bug" that caused <tt>gethostbyname</tt> to crash under VMS
|
<li> Fixed: "Bug" that caused <tt>gethostbyname</tt> to crash under VMS
|
||||||
(Renato Maia);
|
(Renato Maia);
|
||||||
<li> Fixed: <tt>tcp:send("")</tt> to return 0 bytes sent (Alexander Marinov);
|
<li> Fixed: <tt>tcp:send("")</tt> to return 0 bytes sent (Alexander Marinov);
|
||||||
<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.
|
<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;
|
||||||
|
<li> Improved: <tt>socket.select</tt> now works on empty sets on Windows.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- incompatible +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- incompatible +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
@ -71,11 +71,11 @@ Here is the standard LuaSocket distribution directory structure:</p>
|
|||||||
|
|
||||||
<pre class=example>
|
<pre class=example>
|
||||||
<ROOT>/compat-5.1.lua
|
<ROOT>/compat-5.1.lua
|
||||||
<ROOT>/socket.lua
|
|
||||||
<ROOT>/lsocket.dll
|
|
||||||
<ROOT>/mime.lua
|
|
||||||
<ROOT>/lmime.dll
|
|
||||||
<ROOT>/ltn12.lua
|
<ROOT>/ltn12.lua
|
||||||
|
<ROOT>/mime/init.lua
|
||||||
|
<ROOT>/mime/core.dll
|
||||||
|
<ROOT>/socket/init.lua
|
||||||
|
<ROOT>/socket/core.dll
|
||||||
<ROOT>/socket/http.lua
|
<ROOT>/socket/http.lua
|
||||||
<ROOT>/socket/tp.lua
|
<ROOT>/socket/tp.lua
|
||||||
<ROOT>/socket/ftp.lua
|
<ROOT>/socket/ftp.lua
|
||||||
@ -83,10 +83,8 @@ Here is the standard LuaSocket distribution directory structure:</p>
|
|||||||
<ROOT>/socket/url.lua
|
<ROOT>/socket/url.lua
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p> Naturally, on Unix systems, <tt>lsocket.dll</tt> and <tt>lmime.dll</tt>
|
<p> Naturally, on Unix systems, <tt>core.dll</tt>
|
||||||
would be replaced by <tt>lsocket.so</tt> and <tt>lmime.so</tt>. In Mac OS
|
would be replaced by <tt>core.so</tt>.
|
||||||
X, they would be replaced by <tt>lsocket.dylib</tt> and
|
|
||||||
<tt>lmime.dylib</tt>. </p>
|
|
||||||
|
|
||||||
<p> In order for the interpreter to find all LuaSocket components, three
|
<p> In order for the interpreter to find all LuaSocket components, three
|
||||||
environment variables need to be set. The first environment variable tells
|
environment variables need to be set. The first environment variable tells
|
||||||
|
@ -142,7 +142,7 @@ Support, Manual">
|
|||||||
<blockquote>
|
<blockquote>
|
||||||
<a href="socket.html">Socket</a>
|
<a href="socket.html">Socket</a>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<a href="socket.html#_debug">_DEBUG</a>,
|
<a href="socket.html#debug">_DEBUG</a>,
|
||||||
<a href="dns.html#dns">dns</a>,
|
<a href="dns.html#dns">dns</a>,
|
||||||
<a href="socket.html#gettime">gettime</a>,
|
<a href="socket.html#gettime">gettime</a>,
|
||||||
<a href="socket.html#newtry">newtry</a>,
|
<a href="socket.html#newtry">newtry</a>,
|
||||||
@ -155,7 +155,7 @@ Support, Manual">
|
|||||||
<a href="tcp.html#tcp">tcp</a>,
|
<a href="tcp.html#tcp">tcp</a>,
|
||||||
<a href="socket.html#try">try</a>,
|
<a href="socket.html#try">try</a>,
|
||||||
<a href="udp.html#udp">udp</a>,
|
<a href="udp.html#udp">udp</a>,
|
||||||
<a href="socket.html#_version">_VERSION</a>.
|
<a href="socket.html#version">_VERSION</a>.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
@ -127,6 +127,7 @@ smtp.<b>send{</b><br>
|
|||||||
[port = <i>number</i>,]<br>
|
[port = <i>number</i>,]<br>
|
||||||
[domain = <i>string</i>,]<br>
|
[domain = <i>string</i>,]<br>
|
||||||
[step = <i>LTN12 pump step</i>,]<br>
|
[step = <i>LTN12 pump step</i>,]<br>
|
||||||
|
[create = <i>function</i>]<br>
|
||||||
<b>}</b>
|
<b>}</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -138,6 +139,7 @@ doesn't have a simple interface. However, see the
|
|||||||
a very powerful way to define the message contents.
|
a very powerful way to define the message contents.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<p class=parameters>
|
<p class=parameters>
|
||||||
The sender is given by the e-mail address in the <tt>from</tt> field.
|
The sender is given by the e-mail address in the <tt>from</tt> field.
|
||||||
<tt>Rcpt</tt> is a Lua table with one entry for each recipient e-mail
|
<tt>Rcpt</tt> is a Lua table with one entry for each recipient e-mail
|
||||||
@ -158,7 +160,9 @@ local machine host name;
|
|||||||
<li> <tt>step</tt>:
|
<li> <tt>step</tt>:
|
||||||
<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
|
<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a>
|
||||||
pump step function used to pass data from the
|
pump step function used to pass data from the
|
||||||
source to the server. Defaults to the LTN12 <tt>pump.step</tt> function.
|
source to the server. Defaults to the LTN12 <tt>pump.step</tt> function;
|
||||||
|
<li><tt>accept</tt>: An optional function to be used instead of
|
||||||
|
<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
@ -167,7 +171,7 @@ If successful, the function returns 1. Otherwise, the function returns
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=note>
|
<p class=note>
|
||||||
Note: SMTP servers are can be very picky with the format of e-mail
|
Note: SMTP servers can be very picky with the format of e-mail
|
||||||
addresses. To be safe, use only addresses of the form
|
addresses. To be safe, use only addresses of the form
|
||||||
"<tt><fulano@example.com></tt>" in the <tt>from</tt> and
|
"<tt><fulano@example.com></tt>" in the <tt>from</tt> and
|
||||||
<tt>rcpt</tt> arguments to the <tt>send</tt> function. In headers, e-mail
|
<tt>rcpt</tt> arguments to the <tt>send</tt> function. In headers, e-mail
|
||||||
|
@ -80,12 +80,12 @@ socket.<b>connect(</b>address, port [, locaddr, locport]<b>)</b>
|
|||||||
This function is a shortcut that creates and returns a TCP client object
|
This function is a shortcut that creates and returns a TCP client object
|
||||||
connected to a remote <tt>host</tt> at a given <tt>port</tt>. Optionally,
|
connected to a remote <tt>host</tt> at a given <tt>port</tt>. Optionally,
|
||||||
the user can also specify the local address and port to bind
|
the user can also specify the local address and port to bind
|
||||||
(<tt>locaddr</tt> and </tt>locport</tt>).
|
(<tt>locaddr</tt> and <tt>locport</tt>).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- debug ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- debug ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<p class=name id=_debug>
|
<p class=name id=debug>
|
||||||
socket.<b>_DEBUG</b>
|
socket.<b>_DEBUG</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -372,7 +372,7 @@ c = socket.try(socket.connect("localhost", 80))
|
|||||||
|
|
||||||
<!-- version ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- version ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<p class=name id=_version>
|
<p class=name id=version>
|
||||||
socket.<b>_VERSION</b>
|
socket.<b>_VERSION</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
21
doc/tcp.html
21
doc/tcp.html
@ -79,7 +79,7 @@ reported by <b><tt>nil</tt></b> followed by a message describing the error.
|
|||||||
<p class=note>
|
<p class=note>
|
||||||
Note: calling <a href=socket.html#select><tt>socket.select</tt></a>
|
Note: calling <a href=socket.html#select><tt>socket.select</tt></a>
|
||||||
with a server object in
|
with a server object in
|
||||||
the <tt>receive</tt> parameter before a call to <tt>accept</tt> does
|
the <tt>recvt</tt> parameter before a call to <tt>accept</tt> does
|
||||||
<em>not</em> guarantee <tt>accept</tt> will return immediately. Use the <a
|
<em>not</em> guarantee <tt>accept</tt> will return immediately. Use the <a
|
||||||
href=#settimeout><tt>settimeout</tt></a> method or <tt>accept</tt>
|
href=#settimeout><tt>settimeout</tt></a> method or <tt>accept</tt>
|
||||||
might block until <em>another</em> client shows up.
|
might block until <em>another</em> client shows up.
|
||||||
@ -111,7 +111,7 @@ method returns <b><tt>nil</tt></b> followed by an error message.
|
|||||||
|
|
||||||
<p class=note>
|
<p class=note>
|
||||||
Note: The function <a href=socket.html#bind><tt>socket.bind</tt></a>
|
Note: The function <a href=socket.html#bind><tt>socket.bind</tt></a>
|
||||||
is available and is a shortcut for the creation server sockets.
|
is available and is a shortcut for the creation of server sockets.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- close ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- close ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
@ -173,8 +173,11 @@ is available and is a shortcut for the creation of client sockets.
|
|||||||
<p class=note>
|
<p class=note>
|
||||||
Note: Starting with LuaSocket 2.0,
|
Note: Starting with LuaSocket 2.0,
|
||||||
the <a href=#settimeout><tt>settimeout</tt></a>
|
the <a href=#settimeout><tt>settimeout</tt></a>
|
||||||
method affects the behavior of connect, causing it to return in case of
|
method affects the behavior of <tt>connect</tt>, causing it to return
|
||||||
a timeout.
|
with an error in case of a timeout. If that happens, you can still call <a
|
||||||
|
href=socket.html#select><tt>socket.select</tt></a> with the socket in the
|
||||||
|
<tt>sendt</tt> table. The socket will be writable when the connection is
|
||||||
|
stablished.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- getpeername ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- getpeername ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
@ -328,11 +331,11 @@ substring to be sent.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
If successful, the method returns the number of bytes accepted by
|
If successful, the method returns the number of bytes sent.
|
||||||
the transport layer. In case of error, the method returns
|
In case of error, the method returns
|
||||||
<b><tt>nil</tt></b>, followed by an error message, followed by the
|
<b><tt>nil</tt></b>, followed by an error message, followed by the
|
||||||
partial number of bytes accepted by the transport layer.
|
index of the first character within <tt>[i, j]</tt> that has not been sent yet
|
||||||
The error message can be '<tt>closed</tt>' in case
|
(you might want to try again from then on). The error message can be '<tt>closed</tt>' in case
|
||||||
the connection was closed before the transmission was completed or the
|
the connection was closed before the transmission was completed or the
|
||||||
string '<tt>timeout</tt>' in case there was a timeout during the
|
string '<tt>timeout</tt>' in case there was a timeout during the
|
||||||
operation.
|
operation.
|
||||||
@ -433,7 +436,7 @@ of bandwidth.
|
|||||||
<p class=parameters>
|
<p class=parameters>
|
||||||
<tt>Received</tt> is a number with the new number of bytes received.
|
<tt>Received</tt> is a number with the new number of bytes received.
|
||||||
<tt>Sent</tt> is a number with the new number of bytes sent.
|
<tt>Sent</tt> is a number with the new number of bytes sent.
|
||||||
<tt>Age</tt> is the new age in seconds</tt>
|
<tt>Age</tt> is the new age in seconds.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
|
@ -84,17 +84,22 @@ function newcreate(thread)
|
|||||||
first = (first or 1) - 1
|
first = (first or 1) - 1
|
||||||
local result, error
|
local result, error
|
||||||
while true do
|
while true do
|
||||||
|
-- tell dispatcher we want to keep sending before we
|
||||||
|
-- yield control
|
||||||
|
sending:insert(tcp)
|
||||||
|
-- return control to dispatcher
|
||||||
|
-- if upon return the dispatcher tells us we timed out,
|
||||||
|
-- return an error to whoever called us
|
||||||
|
if coroutine.yield() == "timeout" then
|
||||||
|
return nil, "timeout"
|
||||||
|
end
|
||||||
|
-- mark time we started waiting
|
||||||
|
context[tcp].last = socket.gettime()
|
||||||
|
-- try sending
|
||||||
result, error, first = tcp:send(data, first+1, last)
|
result, error, first = tcp:send(data, first+1, last)
|
||||||
if error == "timeout" then
|
-- if we are done, or there was an unexpected error,
|
||||||
-- tell dispatcher we want to keep sending
|
-- break away from loop
|
||||||
sending:insert(tcp)
|
if error ~= "timeout" then return result, error, first end
|
||||||
-- mark time we started waiting
|
|
||||||
context[tcp].last = socket.gettime()
|
|
||||||
-- return control to dispatcher
|
|
||||||
if coroutine.yield() == "timeout" then
|
|
||||||
return nil, "timeout"
|
|
||||||
end
|
|
||||||
else return result, error, first end
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
-- receive in non-blocking mode and yield on timeout
|
-- receive in non-blocking mode and yield on timeout
|
||||||
@ -102,28 +107,35 @@ function newcreate(thread)
|
|||||||
local error, partial = "timeout", ""
|
local error, partial = "timeout", ""
|
||||||
local value
|
local value
|
||||||
while true do
|
while true do
|
||||||
|
-- tell dispatcher we want to keep receiving before we
|
||||||
|
-- yield control
|
||||||
|
receiving:insert(tcp)
|
||||||
|
-- return control to dispatcher
|
||||||
|
-- if upon return the dispatcher tells us we timed out,
|
||||||
|
-- return an error to whoever called us
|
||||||
|
if coroutine.yield() == "timeout" then
|
||||||
|
return nil, "timeout"
|
||||||
|
end
|
||||||
|
-- mark time we started waiting
|
||||||
|
context[tcp].last = socket.gettime()
|
||||||
|
-- try receiving
|
||||||
value, error, partial = tcp:receive(pattern, partial)
|
value, error, partial = tcp:receive(pattern, partial)
|
||||||
if error == "timeout" then
|
-- if we are done, or there was an unexpected error,
|
||||||
-- tell dispatcher we want to keep receiving
|
-- break away from loop
|
||||||
receiving:insert(tcp)
|
if error ~= "timeout" then return value, error, partial end
|
||||||
-- mark time we started waiting
|
|
||||||
context[tcp].last = socket.gettime()
|
|
||||||
-- return control to dispatcher
|
|
||||||
if coroutine.yield() == "timeout" then
|
|
||||||
return nil, "timeout"
|
|
||||||
end
|
|
||||||
else return value, error, partial end
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
-- connect in non-blocking mode and yield on timeout
|
-- connect in non-blocking mode and yield on timeout
|
||||||
connect = function(self, host, port)
|
connect = function(self, host, port)
|
||||||
local result, error = tcp:connect(host, port)
|
local result, error = tcp:connect(host, port)
|
||||||
|
-- mark time we started waiting
|
||||||
|
context[tcp].last = socket.gettime()
|
||||||
if error == "timeout" then
|
if error == "timeout" then
|
||||||
-- tell dispatcher we will be able to write uppon connection
|
-- tell dispatcher we will be able to write uppon connection
|
||||||
sending:insert(tcp)
|
sending:insert(tcp)
|
||||||
-- mark time we started waiting
|
|
||||||
context[tcp].last = socket.gettime()
|
|
||||||
-- return control to dispatcher
|
-- return control to dispatcher
|
||||||
|
-- if upon return the dispatcher tells us we have a
|
||||||
|
-- timeout, just abort
|
||||||
if coroutine.yield() == "timeout" then
|
if coroutine.yield() == "timeout" then
|
||||||
return nil, "timeout"
|
return nil, "timeout"
|
||||||
end
|
end
|
||||||
@ -148,10 +160,10 @@ function newcreate(thread)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the status of a URL, non-blocking
|
-- get the status of a URL, non-blocking
|
||||||
function getstatus(from, link)
|
function getstatus(link)
|
||||||
local parsed = url.parse(link, {scheme = "file"})
|
local parsed = url.parse(link, {scheme = "file"})
|
||||||
if parsed.scheme == "http" then
|
if parsed.scheme == "http" then
|
||||||
local thread = coroutine.create(function(thread, from, link)
|
local thread = coroutine.create(function(thread, link)
|
||||||
local r, c, h, s = http.request{
|
local r, c, h, s = http.request{
|
||||||
method = "HEAD",
|
method = "HEAD",
|
||||||
url = link,
|
url = link,
|
||||||
@ -162,7 +174,7 @@ function getstatus(from, link)
|
|||||||
nthreads = nthreads - 1
|
nthreads = nthreads - 1
|
||||||
end)
|
end)
|
||||||
nthreads = nthreads + 1
|
nthreads = nthreads + 1
|
||||||
assert(coroutine.resume(thread, thread, from, link))
|
assert(coroutine.resume(thread, thread, link))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -190,6 +202,8 @@ function dispatch()
|
|||||||
local now = socket.gettime()
|
local now = socket.gettime()
|
||||||
for who, data in pairs(context) do
|
for who, data in pairs(context) do
|
||||||
if data.last and now - data.last > TIMEOUT then
|
if data.last and now - data.last > TIMEOUT then
|
||||||
|
sending:remove(who)
|
||||||
|
receiving:remove(who)
|
||||||
assert(coroutine.resume(context[who].thread, "timeout"))
|
assert(coroutine.resume(context[who].thread, "timeout"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -206,14 +220,15 @@ function readfile(path)
|
|||||||
else return nil, error end
|
else return nil, error end
|
||||||
end
|
end
|
||||||
|
|
||||||
function retrieve(u)
|
function load(u)
|
||||||
local parsed = url.parse(u, { scheme = "file" })
|
local parsed = url.parse(u, { scheme = "file" })
|
||||||
local body, headers, code, error
|
local body, headers, code, error
|
||||||
local base = u
|
local base = u
|
||||||
if parsed.scheme == "http" then
|
if parsed.scheme == "http" then
|
||||||
body, code, headers = http.request(u)
|
body, code, headers = http.request(u)
|
||||||
if code == 200 then
|
if code == 200 then
|
||||||
base = base or headers.location
|
-- if there was a redirect, update base to reflect it
|
||||||
|
base = headers.location or base
|
||||||
end
|
end
|
||||||
if not body then
|
if not body then
|
||||||
error = code
|
error = code
|
||||||
@ -241,12 +256,13 @@ function getlinks(body, base)
|
|||||||
return links
|
return links
|
||||||
end
|
end
|
||||||
|
|
||||||
function checklinks(from)
|
function checklinks(address)
|
||||||
local base, body, error = retrieve(from)
|
local base, body, error = load(address)
|
||||||
if not body then print(error) return end
|
if not body then print(error) return end
|
||||||
|
print("Checking ", base)
|
||||||
local links = getlinks(body, base)
|
local links = getlinks(body, base)
|
||||||
for _, link in ipairs(links) do
|
for _, link in ipairs(links) do
|
||||||
getstatus(from, link)
|
getstatus(link)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -255,8 +271,7 @@ if table.getn(arg) < 1 then
|
|||||||
print("Usage:\n luasocket check-links.lua {<url>}")
|
print("Usage:\n luasocket check-links.lua {<url>}")
|
||||||
exit()
|
exit()
|
||||||
end
|
end
|
||||||
for _, a in ipairs(arg) do
|
for _, address in ipairs(arg) do
|
||||||
print("Checking ", a)
|
checklinks(url.absolute("file:", address))
|
||||||
checklinks(url.absolute("file:", a))
|
|
||||||
end
|
end
|
||||||
dispatch()
|
dispatch()
|
||||||
|
@ -37,7 +37,7 @@ function retrieve(u)
|
|||||||
if parsed.scheme == "http" then
|
if parsed.scheme == "http" then
|
||||||
body, code, headers = http.request(u)
|
body, code, headers = http.request(u)
|
||||||
if code == 200 then
|
if code == 200 then
|
||||||
base = base or headers.location
|
base = headers.location or base
|
||||||
end
|
end
|
||||||
if not body then
|
if not body then
|
||||||
error = code
|
error = code
|
||||||
|
@ -16,6 +16,7 @@ local url = require("socket.url")
|
|||||||
local tp = require("socket.tp")
|
local tp = require("socket.tp")
|
||||||
|
|
||||||
module("socket.dict")
|
module("socket.dict")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Globals
|
-- Globals
|
||||||
@ -151,4 +152,3 @@ get = socket.protect(function(gett)
|
|||||||
else return tget(gett) end
|
else return tget(gett) end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
@ -15,6 +15,7 @@ local string = require("string")
|
|||||||
local socket = require("socket")
|
local socket = require("socket")
|
||||||
local ltn12 = require("ltn12")
|
local ltn12 = require("ltn12")
|
||||||
module("socket.lp")
|
module("socket.lp")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-- default port
|
-- default port
|
||||||
PORT = 515
|
PORT = 515
|
||||||
@ -318,4 +319,3 @@ query = socket.protect(function(p)
|
|||||||
return data
|
return data
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
@ -16,6 +16,7 @@ local socket = require("socket")
|
|||||||
local ltn12 = require("ltn12")
|
local ltn12 = require("ltn12")
|
||||||
local url = require("socket.url")
|
local url = require("socket.url")
|
||||||
module("socket.tftp")
|
module("socket.tftp")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Program constants
|
-- Program constants
|
||||||
@ -153,4 +154,3 @@ get = socket.protect(function(gett)
|
|||||||
else return tget(gett) end
|
else return tget(gett) end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
52
makefile
Normal file
52
makefile
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#------
|
||||||
|
# Load configuration
|
||||||
|
#
|
||||||
|
include config
|
||||||
|
|
||||||
|
#------
|
||||||
|
# Hopefully no need to change anything below this line
|
||||||
|
#
|
||||||
|
INSTALL_SOCKET=$(INSTALL_TOP)/socket
|
||||||
|
INSTALL_MIME=$(INSTALL_TOP)/mime
|
||||||
|
|
||||||
|
all clean:
|
||||||
|
cd src; $(MAKE) $@
|
||||||
|
|
||||||
|
#------
|
||||||
|
# Files to install
|
||||||
|
#
|
||||||
|
TO_SOCKET:= \
|
||||||
|
socket.lua \
|
||||||
|
http.lua \
|
||||||
|
url.lua \
|
||||||
|
tp.lua \
|
||||||
|
ftp.lua \
|
||||||
|
smtp.lua
|
||||||
|
|
||||||
|
TO_TOP:= \
|
||||||
|
ltn12.lua
|
||||||
|
|
||||||
|
TO_MIME:= \
|
||||||
|
$(MIME_SO) \
|
||||||
|
mime.lua
|
||||||
|
|
||||||
|
#------
|
||||||
|
# Install LuaSocket according to recommendation
|
||||||
|
#
|
||||||
|
install: all
|
||||||
|
cd src; mkdir -p $(INSTALL_TOP)
|
||||||
|
cd src; $(INSTALL_DATA) $(COMPAT)/compat-5.1.lua $(INSTALL_TOP)
|
||||||
|
cd src; $(INSTALL_DATA) ltn12.lua $(INSTALL_TOP)
|
||||||
|
cd src; mkdir -p $(INSTALL_SOCKET)
|
||||||
|
cd src; $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET)
|
||||||
|
cd src; $(INSTALL_DATA) $(TO_SOCKET) $(INSTALL_SOCKET)
|
||||||
|
cd src; cd $(INSTALL_SOCKET); $(INSTALL_LINK) -s $(SOCKET_SO) core.$(EXT)
|
||||||
|
cd src; cd $(INSTALL_SOCKET); $(INSTALL_LINK) -s socket.lua init.lua
|
||||||
|
cd src; mkdir -p $(INSTALL_MIME)
|
||||||
|
cd src; $(INSTALL_DATA) $(TO_MIME) $(INSTALL_MIME)
|
||||||
|
cd src; cd $(INSTALL_MIME); $(INSTALL_LINK) -s $(MIME_SO) core.$(EXT)
|
||||||
|
cd src; cd $(INSTALL_MIME); $(INSTALL_LINK) -s mime.lua init.lua
|
||||||
|
|
||||||
|
#------
|
||||||
|
# End of makefile
|
||||||
|
#
|
12
src/ftp.lua
12
src/ftp.lua
@ -17,6 +17,7 @@ local url = require("socket.url")
|
|||||||
local tp = require("socket.tp")
|
local tp = require("socket.tp")
|
||||||
local ltn12 = require("ltn12")
|
local ltn12 = require("ltn12")
|
||||||
module("socket.ftp")
|
module("socket.ftp")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Program constants
|
-- Program constants
|
||||||
@ -35,8 +36,8 @@ PASSWORD = "anonymous@anonymous.org"
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
local metat = { __index = {} }
|
local metat = { __index = {} }
|
||||||
|
|
||||||
function open(server, port)
|
function open(server, port, create)
|
||||||
local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT))
|
local tp = socket.try(tp.connect(server, port or PORT, create, TIMEOUT))
|
||||||
local f = base.setmetatable({ tp = tp }, metat)
|
local f = base.setmetatable({ tp = tp }, metat)
|
||||||
-- make sure everything gets closed in an exception
|
-- make sure everything gets closed in an exception
|
||||||
f.try = socket.newtry(function() f:close() end)
|
f.try = socket.newtry(function() f:close() end)
|
||||||
@ -199,7 +200,7 @@ end
|
|||||||
local function tput(putt)
|
local function tput(putt)
|
||||||
putt = override(putt)
|
putt = override(putt)
|
||||||
socket.try(putt.host, "missing hostname")
|
socket.try(putt.host, "missing hostname")
|
||||||
local f = open(putt.host, putt.port)
|
local f = open(putt.host, putt.port, putt.create)
|
||||||
f:greet()
|
f:greet()
|
||||||
f:login(putt.user, putt.password)
|
f:login(putt.user, putt.password)
|
||||||
if putt.type then f:type(putt.type) end
|
if putt.type then f:type(putt.type) end
|
||||||
@ -242,7 +243,7 @@ end)
|
|||||||
local function tget(gett)
|
local function tget(gett)
|
||||||
gett = override(gett)
|
gett = override(gett)
|
||||||
socket.try(gett.host, "missing hostname")
|
socket.try(gett.host, "missing hostname")
|
||||||
local f = open(gett.host, gett.port)
|
local f = open(gett.host, gett.port, gett.create)
|
||||||
f:greet()
|
f:greet()
|
||||||
f:login(gett.user, gett.password)
|
f:login(gett.user, gett.password)
|
||||||
if gett.type then f:type(gett.type) end
|
if gett.type then f:type(gett.type) end
|
||||||
@ -264,7 +265,7 @@ command = socket.protect(function(cmdt)
|
|||||||
cmdt = override(cmdt)
|
cmdt = override(cmdt)
|
||||||
socket.try(cmdt.host, "missing hostname")
|
socket.try(cmdt.host, "missing hostname")
|
||||||
socket.try(cmdt.command, "missing command")
|
socket.try(cmdt.command, "missing command")
|
||||||
local f = open(cmdt.host, cmdt.port)
|
local f = open(cmdt.host, cmdt.port, cmdt.create)
|
||||||
f:greet()
|
f:greet()
|
||||||
f:login(cmdt.user, cmdt.password)
|
f:login(cmdt.user, cmdt.password)
|
||||||
f.try(f.tp:command(cmdt.command, cmdt.argument))
|
f.try(f.tp:command(cmdt.command, cmdt.argument))
|
||||||
@ -278,4 +279,3 @@ get = socket.protect(function(gett)
|
|||||||
else return tget(gett) end
|
else return tget(gett) end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
45
src/http.lua
45
src/http.lua
@ -16,6 +16,7 @@ local string = require("string")
|
|||||||
local base = _G
|
local base = _G
|
||||||
local table = require("table")
|
local table = require("table")
|
||||||
module("socket.http")
|
module("socket.http")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Program constants
|
-- Program constants
|
||||||
@ -105,26 +106,16 @@ end
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
local metat = { __index = {} }
|
local metat = { __index = {} }
|
||||||
|
|
||||||
-- default connect function, respecting the timeout
|
|
||||||
local function connect(host, port, create)
|
|
||||||
local c, e = (create or socket.tcp)()
|
|
||||||
if not c then return nil, e end
|
|
||||||
c:settimeout(TIMEOUT)
|
|
||||||
local r, e = c:connect(host, port or PORT)
|
|
||||||
if not r then
|
|
||||||
c:close()
|
|
||||||
return nil, e
|
|
||||||
end
|
|
||||||
return c
|
|
||||||
end
|
|
||||||
|
|
||||||
function open(host, port, create)
|
function open(host, port, create)
|
||||||
-- create socket with user connect function, or with default
|
-- create socket with user connect function, or with default
|
||||||
local c = socket.try(connect(host, port, create))
|
local c = socket.try(create or socket.tcp)()
|
||||||
-- create our http request object, pointing to the socket
|
|
||||||
local h = base.setmetatable({ c = c }, metat)
|
local h = base.setmetatable({ c = c }, metat)
|
||||||
-- make sure the object close gets called on exception
|
-- create finalized try
|
||||||
h.try = socket.newtry(function() h:close() end)
|
h.try = socket.newtry(function() h:close() end)
|
||||||
|
-- set timeout before connecting
|
||||||
|
h.try(c:settimeout(TIMEOUT))
|
||||||
|
h.try(c:connect(host, port or PORT))
|
||||||
|
-- here everything worked
|
||||||
return h
|
return h
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -134,11 +125,11 @@ function metat.__index:sendrequestline(method, uri)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function metat.__index:sendheaders(headers)
|
function metat.__index:sendheaders(headers)
|
||||||
|
local h = "\r\n"
|
||||||
for i, v in base.pairs(headers) do
|
for i, v in base.pairs(headers) do
|
||||||
self.try(self.c:send(i .. ": " .. v .. "\r\n"))
|
h = i .. ": " .. v .. "\r\n" .. h
|
||||||
end
|
end
|
||||||
-- mark end of request headers
|
self.try(self.c:send(h))
|
||||||
self.try(self.c:send("\r\n"))
|
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -213,7 +204,7 @@ local function adjustheaders(headers, host)
|
|||||||
["te"] = "trailers"
|
["te"] = "trailers"
|
||||||
}
|
}
|
||||||
-- override with user headers
|
-- override with user headers
|
||||||
for i,v in pairs(headers or lower) do
|
for i,v in base.pairs(headers or lower) do
|
||||||
lower[string.lower(i)] = v
|
lower[string.lower(i)] = v
|
||||||
end
|
end
|
||||||
return lower
|
return lower
|
||||||
@ -232,7 +223,7 @@ local function adjustrequest(reqt)
|
|||||||
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
|
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
|
||||||
local t = url.parse(reqt.url, default)
|
local t = url.parse(reqt.url, default)
|
||||||
-- explicit components override url
|
-- explicit components override url
|
||||||
for i,v in pairs(reqt) do nreqt[i] = v end
|
for i,v in base.pairs(reqt) do nreqt[i] = v end
|
||||||
socket.try(nreqt.host, "invalid host '" .. base.tostring(nreqt.host) .. "'")
|
socket.try(nreqt.host, "invalid host '" .. base.tostring(nreqt.host) .. "'")
|
||||||
-- compute uri if user hasn't overriden
|
-- compute uri if user hasn't overriden
|
||||||
nreqt.uri = reqt.uri or adjusturi(nreqt)
|
nreqt.uri = reqt.uri or adjusturi(nreqt)
|
||||||
@ -276,11 +267,11 @@ function tauthorize(reqt)
|
|||||||
return trequest(reqt)
|
return trequest(reqt)
|
||||||
end
|
end
|
||||||
|
|
||||||
function tredirect(reqt, headers)
|
function tredirect(reqt, location)
|
||||||
return trequest {
|
local result, code, headers, status = trequest {
|
||||||
-- the RFC says the redirect URL has to be absolute, but some
|
-- the RFC says the redirect URL has to be absolute, but some
|
||||||
-- servers do not respect that
|
-- servers do not respect that
|
||||||
url = url.absolute(reqt, headers["location"]),
|
url = url.absolute(reqt, location),
|
||||||
source = reqt.source,
|
source = reqt.source,
|
||||||
sink = reqt.sink,
|
sink = reqt.sink,
|
||||||
headers = reqt.headers,
|
headers = reqt.headers,
|
||||||
@ -288,6 +279,9 @@ function tredirect(reqt, headers)
|
|||||||
nredirects = (reqt.nredirects or 0) + 1,
|
nredirects = (reqt.nredirects or 0) + 1,
|
||||||
connect = reqt.connect
|
connect = reqt.connect
|
||||||
}
|
}
|
||||||
|
-- pass location header back as a hint we redirected
|
||||||
|
headers.location = headers.location or location
|
||||||
|
return result, code, headers, status
|
||||||
end
|
end
|
||||||
|
|
||||||
function trequest(reqt)
|
function trequest(reqt)
|
||||||
@ -301,7 +295,7 @@ function trequest(reqt)
|
|||||||
headers = h:receiveheaders()
|
headers = h:receiveheaders()
|
||||||
if shouldredirect(reqt, code, headers) then
|
if shouldredirect(reqt, code, headers) then
|
||||||
h:close()
|
h:close()
|
||||||
return tredirect(reqt, headers)
|
return tredirect(reqt, headers.location)
|
||||||
elseif shouldauthorize(reqt, code) then
|
elseif shouldauthorize(reqt, code) then
|
||||||
h:close()
|
h:close()
|
||||||
return tauthorize(reqt)
|
return tauthorize(reqt)
|
||||||
@ -332,4 +326,3 @@ request = socket.protect(function(reqt, body)
|
|||||||
else return trequest(reqt) end
|
else return trequest(reqt) end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
@ -12,6 +12,7 @@ local string = require("string")
|
|||||||
local table = require("table")
|
local table = require("table")
|
||||||
local base = _G
|
local base = _G
|
||||||
module("ltn12")
|
module("ltn12")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
filter = {}
|
filter = {}
|
||||||
source = {}
|
source = {}
|
||||||
@ -134,8 +135,6 @@ function source.rewind(src)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local print = print
|
|
||||||
|
|
||||||
-- chains a source with a filter
|
-- chains a source with a filter
|
||||||
function source.chain(src, f)
|
function source.chain(src, f)
|
||||||
base.assert(src and f)
|
base.assert(src and f)
|
||||||
@ -258,7 +257,8 @@ end
|
|||||||
function pump.step(src, snk)
|
function pump.step(src, snk)
|
||||||
local chunk, src_err = src()
|
local chunk, src_err = src()
|
||||||
local ret, snk_err = snk(chunk, src_err)
|
local ret, snk_err = snk(chunk, src_err)
|
||||||
return chunk and ret and not src_err and not snk_err, src_err or snk_err
|
if chunk and ret then return 1
|
||||||
|
else return nil, src_err or snk_err end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- pumps all data from a source to a sink, using a step function
|
-- pumps all data from a source to a sink, using a step function
|
||||||
@ -267,8 +267,10 @@ function pump.all(src, snk, step)
|
|||||||
step = step or pump.step
|
step = step or pump.step
|
||||||
while true do
|
while true do
|
||||||
local ret, err = step(src, snk)
|
local ret, err = step(src, snk)
|
||||||
if not ret then return not err, err end
|
if not ret then
|
||||||
|
if err then return nil, err
|
||||||
|
else return 1 end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
@ -108,7 +108,7 @@ static int base_open(lua_State *L) {
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes all library modules.
|
* Initializes all library modules.
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
LUASOCKET_API int luaopen_socketcore(lua_State *L) {
|
LUASOCKET_API int luaopen_socket_core(lua_State *L) {
|
||||||
int i;
|
int i;
|
||||||
base_open(L);
|
base_open(L);
|
||||||
for (i = 0; mod[i].name; i++) mod[i].func(L);
|
for (i = 0; mod[i].name; i++) mod[i].func(L);
|
||||||
|
87
src/makefile
Normal file
87
src/makefile
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#------
|
||||||
|
# Load configuration
|
||||||
|
#
|
||||||
|
include ../config
|
||||||
|
|
||||||
|
#------
|
||||||
|
# Hopefully no need to change anything below this line
|
||||||
|
#
|
||||||
|
|
||||||
|
#------
|
||||||
|
# Modules belonging to socket-core
|
||||||
|
#
|
||||||
|
SOCKET_OBJS:= \
|
||||||
|
luasocket.o \
|
||||||
|
timeout.o \
|
||||||
|
buffer.o \
|
||||||
|
io.o \
|
||||||
|
auxiliar.o \
|
||||||
|
options.o \
|
||||||
|
inet.o \
|
||||||
|
tcp.o \
|
||||||
|
udp.o \
|
||||||
|
except.o \
|
||||||
|
select.o \
|
||||||
|
$(COMPAT)/compat-5.1.o \
|
||||||
|
usocket.o
|
||||||
|
|
||||||
|
#------
|
||||||
|
# Modules belonging mime-core
|
||||||
|
#
|
||||||
|
MIME_OBJS:=\
|
||||||
|
mime.o \
|
||||||
|
$(COMPAT)/compat-5.1.o
|
||||||
|
|
||||||
|
#------
|
||||||
|
# Modules belonging unix (local domain sockets)
|
||||||
|
#
|
||||||
|
UNIX_OBJS:=\
|
||||||
|
buffer.o \
|
||||||
|
auxiliar.o \
|
||||||
|
options.o \
|
||||||
|
timeout.o \
|
||||||
|
io.o \
|
||||||
|
usocket.o \
|
||||||
|
unix.o
|
||||||
|
|
||||||
|
all: $(SOCKET_SO) $(MIME_SO)
|
||||||
|
|
||||||
|
$(SOCKET_SO): $(SOCKET_OBJS)
|
||||||
|
$(LD) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
$(MIME_SO): $(MIME_OBJS)
|
||||||
|
$(LD) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
$(UNIX_SO): $(UNIX_OBJS)
|
||||||
|
$(LD) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
#------
|
||||||
|
# List of dependencies
|
||||||
|
#
|
||||||
|
auxiliar.o: auxiliar.c auxiliar.h
|
||||||
|
buffer.o: buffer.c buffer.h io.h timeout.h
|
||||||
|
except.o: except.c except.h
|
||||||
|
inet.o: inet.c inet.h socket.h io.h timeout.h usocket.h
|
||||||
|
io.o: io.c io.h timeout.h
|
||||||
|
luasocket.o: luasocket.c luasocket.h auxiliar.h except.h timeout.h \
|
||||||
|
buffer.h io.h inet.h socket.h usocket.h tcp.h udp.h select.h
|
||||||
|
mime.o: mime.c mime.h
|
||||||
|
options.o: options.c auxiliar.h options.h socket.h io.h timeout.h \
|
||||||
|
usocket.h inet.h
|
||||||
|
select.o: select.c socket.h io.h timeout.h usocket.h select.h
|
||||||
|
tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \
|
||||||
|
options.h tcp.h buffer.h
|
||||||
|
timeout.o: timeout.c auxiliar.h timeout.h
|
||||||
|
udp.o: udp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \
|
||||||
|
options.h udp.h
|
||||||
|
unix.o: unix.c auxiliar.h socket.h io.h timeout.h usocket.h options.h \
|
||||||
|
unix.h buffer.h
|
||||||
|
usocket.o: usocket.c socket.h io.h timeout.h usocket.h
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(SOCKET_SO) $(SOCKET_OBJS)
|
||||||
|
rm -f $(MIME_SO) $(UNIX_SO) $(MIME_OBJS) $(UNIX_OBJS)
|
||||||
|
|
||||||
|
#------
|
||||||
|
# End of makefile configuration
|
||||||
|
#
|
@ -14,6 +14,7 @@ local mime = require("mime.core")
|
|||||||
local io = require("io")
|
local io = require("io")
|
||||||
local string = require("string")
|
local string = require("string")
|
||||||
module("mime")
|
module("mime")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-- encode, decode and wrap algorithm tables
|
-- encode, decode and wrap algorithm tables
|
||||||
encodet = {}
|
encodet = {}
|
||||||
@ -84,5 +85,3 @@ end
|
|||||||
function stuff()
|
function stuff()
|
||||||
return ltn12.filter.cycle(dot, 2)
|
return ltn12.filter.cycle(dot, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
29
src/smtp.lua
29
src/smtp.lua
@ -18,6 +18,7 @@ local tp = require("socket.tp")
|
|||||||
local ltn12 = require("ltn12")
|
local ltn12 = require("ltn12")
|
||||||
local mime = require("mime")
|
local mime = require("mime")
|
||||||
module("socket.smtp")
|
module("socket.smtp")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Program constants
|
-- Program constants
|
||||||
@ -111,12 +112,12 @@ function metat.__index:send(mailt)
|
|||||||
self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
|
self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
|
||||||
end
|
end
|
||||||
|
|
||||||
function open(server, port)
|
function open(server, port, create)
|
||||||
local tp = socket.try(tp.connect(server or SERVER, port or PORT, TIMEOUT))
|
local tp = socket.try(tp.connect(server or SERVER, port or PORT,
|
||||||
|
create, TIMEOUT))
|
||||||
local s = base.setmetatable({tp = tp}, metat)
|
local s = base.setmetatable({tp = tp}, metat)
|
||||||
-- make sure tp is closed if we get an exception
|
-- make sure tp is closed if we get an exception
|
||||||
s.try = socket.newtry(function()
|
s.try = socket.newtry(function()
|
||||||
if s.tp:command("QUIT") then s.tp:check("2..") end
|
|
||||||
s:close()
|
s:close()
|
||||||
end)
|
end)
|
||||||
return s
|
return s
|
||||||
@ -165,10 +166,9 @@ end
|
|||||||
local function send_source(mesgt)
|
local function send_source(mesgt)
|
||||||
-- set content-type if user didn't override
|
-- set content-type if user didn't override
|
||||||
if not mesgt.headers or not mesgt.headers["content-type"] then
|
if not mesgt.headers or not mesgt.headers["content-type"] then
|
||||||
coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n')
|
coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n\r\n')
|
||||||
end
|
else coroutine.yield("\r\n") end
|
||||||
-- finish headers
|
-- finish headers
|
||||||
coroutine.yield("\r\n")
|
|
||||||
-- send body from source
|
-- send body from source
|
||||||
while true do
|
while true do
|
||||||
local chunk, err = mesgt.body()
|
local chunk, err = mesgt.body()
|
||||||
@ -182,21 +182,20 @@ end
|
|||||||
local function send_string(mesgt)
|
local function send_string(mesgt)
|
||||||
-- set content-type if user didn't override
|
-- set content-type if user didn't override
|
||||||
if not mesgt.headers or not mesgt.headers["content-type"] then
|
if not mesgt.headers or not mesgt.headers["content-type"] then
|
||||||
coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n')
|
coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n\r\n')
|
||||||
end
|
else coroutine.yield("\r\n") end
|
||||||
-- finish headers
|
|
||||||
coroutine.yield("\r\n")
|
|
||||||
-- send body from string
|
-- send body from string
|
||||||
coroutine.yield(mesgt.body)
|
coroutine.yield(mesgt.body)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- yield the headers one by one
|
-- yield the headers all at once
|
||||||
local function send_headers(mesgt)
|
local function send_headers(mesgt)
|
||||||
if mesgt.headers then
|
if mesgt.headers then
|
||||||
|
local h = ""
|
||||||
for i,v in base.pairs(mesgt.headers) do
|
for i,v in base.pairs(mesgt.headers) do
|
||||||
coroutine.yield(i .. ':' .. v .. "\r\n")
|
h = i .. ': ' .. v .. "\r\n" .. h
|
||||||
end
|
end
|
||||||
|
coroutine.yield(h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -237,12 +236,10 @@ end
|
|||||||
-- High level SMTP API
|
-- High level SMTP API
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
send = socket.protect(function(mailt)
|
send = socket.protect(function(mailt)
|
||||||
local s = open(mailt.server, mailt.port)
|
local s = open(mailt.server, mailt.port, mailt.create)
|
||||||
local ext = s:greet(mailt.domain)
|
local ext = s:greet(mailt.domain)
|
||||||
s:auth(mailt.user, mailt.password, ext)
|
s:auth(mailt.user, mailt.password, ext)
|
||||||
s:send(mailt)
|
s:send(mailt)
|
||||||
s:quit()
|
s:quit()
|
||||||
return s:close()
|
return s:close()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
@ -12,6 +12,7 @@ local string = require("string")
|
|||||||
local math = require("math")
|
local math = require("math")
|
||||||
local socket = require("socket.core")
|
local socket = require("socket.core")
|
||||||
module("socket")
|
module("socket")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Exported auxiliar functions
|
-- Exported auxiliar functions
|
||||||
@ -131,5 +132,3 @@ sourcet["default"] = sourcet["until-closed"]
|
|||||||
|
|
||||||
source = choose(sourcet)
|
source = choose(sourcet)
|
||||||
|
|
||||||
-- clear globals from namespace
|
|
||||||
getmetatable(_M).__index = nil
|
|
||||||
|
70
src/ssl.c
70
src/ssl.c
@ -1,70 +0,0 @@
|
|||||||
/*=========================================================================*\
|
|
||||||
* Simple client SSL support
|
|
||||||
* LuaSocket toolkit
|
|
||||||
*
|
|
||||||
* RCS ID: $Id$
|
|
||||||
\*=========================================================================*/
|
|
||||||
#include <lua.h>
|
|
||||||
#include <lauxlib.h>
|
|
||||||
|
|
||||||
#include "ssl.h"
|
|
||||||
|
|
||||||
/*=========================================================================*\
|
|
||||||
* Internal function prototypes
|
|
||||||
\*=========================================================================*/
|
|
||||||
static int global_wrap(lua_State *L);
|
|
||||||
|
|
||||||
/* functions in library namespace */
|
|
||||||
static luaL_reg func[] = {
|
|
||||||
{"wrap", global_create},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static luaL_reg wrap[] = {
|
|
||||||
{"__tostring", aux_tostring},
|
|
||||||
{"__gc", meth_close},
|
|
||||||
{"close", meth_close},
|
|
||||||
{"receive", meth_receive},
|
|
||||||
{"send", meth_send},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static luaL_reg owned[] = {
|
|
||||||
{"__tostring", aux_tostring},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
|
||||||
* Initializes module
|
|
||||||
\*-------------------------------------------------------------------------*/
|
|
||||||
int ssl_open(lua_State *L)
|
|
||||||
{
|
|
||||||
aux_newclass(L, "ssl{wraper}", wrap);
|
|
||||||
aux_newclass(L, "ssl{owned}", owned);
|
|
||||||
lua_pushstring(L, "ssl")
|
|
||||||
lua_newtable(L);
|
|
||||||
luaL_openlib(L, NULL, func, 0);
|
|
||||||
lua_settable(L, -3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*=========================================================================*\
|
|
||||||
* Library functions
|
|
||||||
\*=========================================================================*/
|
|
||||||
/*-------------------------------------------------------------------------*\
|
|
||||||
* Wraps a tcp object into an SSL object
|
|
||||||
\*-------------------------------------------------------------------------*/
|
|
||||||
static int global_wrap(lua_State *L) {
|
|
||||||
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1);
|
|
||||||
/* change class of tcp object */
|
|
||||||
aux_setclass(L, "ssl{owned}", 1);
|
|
||||||
/* create wrapper */
|
|
||||||
p_wrap wrap = (p_wrap) lua_newuserdata(L, sizeof(t_wrap));
|
|
||||||
/* lock reference */
|
|
||||||
lua_pushvalue(L, 1);
|
|
||||||
wrap->ref = lua_ref(L, 1);
|
|
||||||
/* initialize wrapper */
|
|
||||||
wrap->tcp = tcp;
|
|
||||||
io_init(&tcp->io, wrap_send, wrap_recv, wrap);
|
|
||||||
return 1;
|
|
||||||
}
|
|
29
src/ssl.h
29
src/ssl.h
@ -1,29 +0,0 @@
|
|||||||
#ifndef SSL_H
|
|
||||||
#define SSL_H
|
|
||||||
/*=========================================================================*\
|
|
||||||
* Simple client SSL support
|
|
||||||
* LuaSocket toolkit
|
|
||||||
*
|
|
||||||
* This is just a simple example to show how to extend LuaSocket
|
|
||||||
*
|
|
||||||
* RCS ID: $Id$
|
|
||||||
\*=========================================================================*/
|
|
||||||
#include <lua.h>
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
|
|
||||||
#include "buffer.h"
|
|
||||||
#include "timeout.h"
|
|
||||||
#include "socket.h"
|
|
||||||
#include "tcp.h"
|
|
||||||
|
|
||||||
typedef struct t_wrap_ {
|
|
||||||
p_tcp tcp;
|
|
||||||
SSL* ssl;
|
|
||||||
int ref;
|
|
||||||
} t_wrap;
|
|
||||||
|
|
||||||
typedef t_wrap *p_wrap;
|
|
||||||
|
|
||||||
int ssl_open(lua_State *L);
|
|
||||||
|
|
||||||
#endif /* SSL_H */
|
|
@ -13,6 +13,7 @@ local string = require("string")
|
|||||||
local socket = require("socket")
|
local socket = require("socket")
|
||||||
local ltn12 = require("ltn12")
|
local ltn12 = require("ltn12")
|
||||||
module("socket.tp")
|
module("socket.tp")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Program constants
|
-- Program constants
|
||||||
@ -98,7 +99,8 @@ end
|
|||||||
|
|
||||||
function metat.__index:source(source, step)
|
function metat.__index:source(source, step)
|
||||||
local sink = socket.sink("keep-open", self.c)
|
local sink = socket.sink("keep-open", self.c)
|
||||||
return ltn12.pump.all(source, sink, step or ltn12.pump.step)
|
local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step)
|
||||||
|
return ret, err
|
||||||
end
|
end
|
||||||
|
|
||||||
-- closes the underlying c
|
-- closes the underlying c
|
||||||
@ -108,8 +110,8 @@ function metat.__index:close()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- connect with server and return c object
|
-- connect with server and return c object
|
||||||
function connect(host, port, timeout)
|
function connect(host, port, create, timeout)
|
||||||
local c, e = socket.tcp()
|
local c, e = (create or socket.tcp())
|
||||||
if not c then return nil, e end
|
if not c then return nil, e end
|
||||||
c:settimeout(timeout or TIMEOUT)
|
c:settimeout(timeout or TIMEOUT)
|
||||||
local r, e = c:connect(host, port)
|
local r, e = c:connect(host, port)
|
||||||
@ -120,4 +122,3 @@ function connect(host, port, timeout)
|
|||||||
return base.setmetatable({c = c}, metat)
|
return base.setmetatable({c = c}, metat)
|
||||||
end
|
end
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
@ -12,6 +12,7 @@ local string = require("string")
|
|||||||
local base = _G
|
local base = _G
|
||||||
local table = require("table")
|
local table = require("table")
|
||||||
module("socket.url")
|
module("socket.url")
|
||||||
|
getmetatable(_M).__index = nil
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Encodes a string into its escaped hexadecimal representation
|
-- Encodes a string into its escaped hexadecimal representation
|
||||||
@ -279,4 +280,3 @@ function build_path(parsed, unsafe)
|
|||||||
return path
|
return path
|
||||||
end
|
end
|
||||||
|
|
||||||
--getmetatable(_M).__index = nil
|
|
||||||
|
@ -74,7 +74,10 @@ int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_tm tm) {
|
|||||||
double t = tm_get(tm);
|
double t = tm_get(tm);
|
||||||
tv.tv_sec = (int) t;
|
tv.tv_sec = (int) t;
|
||||||
tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
|
tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
|
||||||
return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
|
if (n <= 0) {
|
||||||
|
Sleep(1000*t);
|
||||||
|
return 0;
|
||||||
|
} else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
|
@ -48,18 +48,19 @@ source = smtp.message{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
--[[
|
function filter(s)
|
||||||
sink = ltn12.sink.file(io.stdout)
|
if s then io.write(s) end
|
||||||
ltn12.pump.all(source, sink)
|
return s
|
||||||
]]
|
end
|
||||||
|
|
||||||
-- finally send it
|
|
||||||
r, e = smtp.send{
|
r, e = smtp.send{
|
||||||
rcpt = {"<diego@tecgraf.puc-rio.br>",
|
rcpt = {"<diego@tecgraf.puc-rio.br>",
|
||||||
"<diego@princeton.edu>" },
|
"<diego@princeton.edu>" },
|
||||||
from = "<diego@princeton.edu>",
|
from = "<diego@princeton.edu>",
|
||||||
source = source,
|
source = ltn12.source.chain(source, filter),
|
||||||
server = "mail.cs.princeton.edu"
|
--server = "mail.cs.princeton.edu"
|
||||||
|
server = "localhost",
|
||||||
|
port = 2525
|
||||||
}
|
}
|
||||||
|
|
||||||
print(r, e)
|
print(r, e)
|
||||||
|
Loading…
Reference in New Issue
Block a user