mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-11-16 02:08:21 +01:00
Worked on the manual.
Implemented stuffing (needs test) Added cddb and qp examples.
This commit is contained in:
parent
f67864f86c
commit
0b2542d1a6
62
TODO
62
TODO
@ -1,7 +1,36 @@
|
|||||||
|
* should be interrupt-safe
|
||||||
|
* notice the change in callback conventions
|
||||||
|
* new mime module replacing old code module (faster, more functionality)
|
||||||
|
* new socket options (many)
|
||||||
|
* only allocate in case of success
|
||||||
|
* optimize for success (only call select if fails)
|
||||||
|
* add proxy support to http
|
||||||
|
* add gethostname
|
||||||
|
* local connect
|
||||||
|
* connect with timeout
|
||||||
|
* change code to mime
|
||||||
|
* change stay to redirect
|
||||||
|
* add shutdown
|
||||||
|
* change send/recv to avoid using select
|
||||||
|
* O location do "redirect" pode ser relativo ao servidor atual (não pode,
|
||||||
|
mas os servidores fazem merda...)
|
||||||
|
* Ajeitar para Lua 5.0
|
||||||
|
* Padronizar os retornos de funccao
|
||||||
|
* Separar as classes em arquivos
|
||||||
|
* Retorno de sendto em datagram sockets pode ser refused
|
||||||
|
|
||||||
|
|
||||||
|
check garbage collection in test*.lua
|
||||||
|
pop3???
|
||||||
|
|
||||||
|
add socket.TIMEOUT to be default timeout?
|
||||||
|
|
||||||
manual
|
manual
|
||||||
|
add socket.connect and socket.bind to the manual
|
||||||
|
say what a nil callback does for http
|
||||||
check all occurences of it's
|
check all occurences of it's
|
||||||
add shutdown
|
- add shutdown
|
||||||
add gethostname
|
- add gethostname
|
||||||
the need of a content-length header in the post method...
|
the need of a content-length header in the post method...
|
||||||
notice the change in callback conventions
|
notice the change in callback conventions
|
||||||
the callback.lua module and the new mime module.
|
the callback.lua module and the new mime module.
|
||||||
@ -9,11 +38,11 @@ manual
|
|||||||
add timeout and proxy to request table
|
add timeout and proxy to request table
|
||||||
change stay to redirect
|
change stay to redirect
|
||||||
socket.time and socket.sleep
|
socket.time and socket.sleep
|
||||||
connect with timeout
|
- connect with timeout
|
||||||
local connect
|
local connect
|
||||||
add thanks to 'carlos cassino' and 'david burgess'
|
add thanks to 'carlos cassino' and 'david burgess'
|
||||||
add new ip- options and reuseaddr option
|
add new ip- options and reuseaddr option
|
||||||
add listen to manual
|
- add listen to manual
|
||||||
bind method doesn't do listen anymore
|
bind method doesn't do listen anymore
|
||||||
bind doesn't turn an object into a server object: listen does.
|
bind doesn't turn an object into a server object: listen does.
|
||||||
|
|
||||||
@ -23,6 +52,9 @@ tests
|
|||||||
checar garbage collection
|
checar garbage collection
|
||||||
check for interrupts
|
check for interrupts
|
||||||
|
|
||||||
|
wrp can't break lines in the middle of a line break.
|
||||||
|
call select before accept, not after, dumbass!
|
||||||
|
get rid of setnonblocking/setblocking in the bind function
|
||||||
close has to block...
|
close has to block...
|
||||||
fmt is not a good name
|
fmt is not a good name
|
||||||
change wrap() to accept a number and default to "character"
|
change wrap() to accept a number and default to "character"
|
||||||
@ -76,30 +108,10 @@ Ajeitar o protocolo da luaopen_socket()... sei l
|
|||||||
|
|
||||||
- adicionar exemplos de expansão: pipe, local, named pipe
|
- adicionar exemplos de expansão: pipe, local, named pipe
|
||||||
|
|
||||||
* should be interrupt-safe
|
|
||||||
* notice the change in callback conventions
|
|
||||||
* new mime module replacing old code module (faster, more functionality)
|
|
||||||
* new socket options (many)
|
|
||||||
* only allocate in case of success
|
|
||||||
* optimize for success (only call select if fails)
|
|
||||||
* add proxy support to http
|
|
||||||
* add gethostname
|
|
||||||
* local connect
|
|
||||||
* connect with timeout
|
|
||||||
* change code to mime
|
|
||||||
* change stay to redirect
|
|
||||||
* add shutdown
|
|
||||||
* change send/recv to avoid using select
|
|
||||||
* O location do "redirect" pode ser relativo ao servidor atual (não pode,
|
|
||||||
mas os servidores fazem merda...)
|
|
||||||
* Ajeitar para Lua 5.0
|
|
||||||
* Padronizar os retornos de funccao
|
|
||||||
* Separar as classes em arquivos
|
|
||||||
* Retorno de sendto em datagram sockets pode ser refused
|
|
||||||
|
|
||||||
- Fazer compilar com g++
|
- Fazer compilar com g++
|
||||||
- Thread-safe
|
- Thread-safe
|
||||||
- proteger gethostby*.* com um mutex GLOBAL!
|
- proteger get*by*.* com um mutex GLOBAL!
|
||||||
- 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.
|
||||||
- SSL
|
- SSL
|
||||||
|
@ -31,16 +31,16 @@
|
|||||||
<hr>
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- stream ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- stream ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<h2 id=stream>Streaming with Callbacks</h2>
|
<h2 id=stream>Callbacks</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
HTTP, FTP, and SMTP transfers sometimes involve large amounts of
|
HTTP, FTP, and SMTP transfers sometimes involve large amounts of
|
||||||
information. Sometimes an application needs to generate outgoing data
|
information. Sometimes an application needs to generate outgoing data
|
||||||
in real time, or needs to process incoming information as it is being
|
in real time, or needs to process incoming information as it is being
|
||||||
received. To address these problems, LuaSocket allows HTTP and SMTP message
|
received. To address these problems, LuaSocket allows HTTP and SMTP message
|
||||||
bodies and FTP file contents to be received or sent through the
|
bodies and FTP file contents to be streamed through the
|
||||||
callback mechanism outlined below.
|
callback mechanism outlined below.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ chunks of data, as the data becomes available. Conversely, the <em>send
|
|||||||
callback</em> mechanism can be used when the application wants to incrementally provide LuaSocket with the data to be sent.
|
callback</em> mechanism can be used when the application wants to incrementally provide LuaSocket with the data to be sent.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- receive +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<p class=name id=receive>
|
<p class=name id=receive>
|
||||||
<b>receive_cb(</b>chunk, err<b>)</b>
|
<b>receive_cb(</b>chunk, err<b>)</b>
|
||||||
@ -60,7 +60,7 @@ callback</em> mechanism can be used when the application wants to incrementally
|
|||||||
|
|
||||||
<p class=description>
|
<p class=description>
|
||||||
A receive callback will be repeatedly called by
|
A receive callback will be repeatedly called by
|
||||||
LuaSocket wheneve new data is available. Each time it is called, the
|
LuaSocket whenever new data is available. Each time it is called, the
|
||||||
callback receives successive chunks of downloaded data.
|
callback receives successive chunks of downloaded data.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -113,10 +113,129 @@ Together, these two modules provide a powerful interface to send and
|
|||||||
receive information.
|
receive information.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<!-- done +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<p class=name id=done>
|
||||||
|
socket.callback.<b>done()</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=description>
|
||||||
|
This function creates and returns a callback that successfully terminates
|
||||||
|
the transmission.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- fail +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<p class=name id=fail>
|
||||||
|
socket.callback.<b>fail(</b>message<b>)</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=description>
|
||||||
|
This function creates and returns a callback that aborts the
|
||||||
|
transmission with a given error <tt>message</tt>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- receive.concat +++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<p class=name id=receive.concat>
|
||||||
|
socket.callback.<b>receive.concat(</b>cat<b>)</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=description>
|
||||||
|
This function creates a receive callback that stores whatever it receives
|
||||||
|
into a concat object. When done, the application can get the contents
|
||||||
|
received as a single string, directly from the concat object.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=parameters>
|
||||||
|
<tt>Cat</tt> is the target concat object, or <b><tt>nil</tt></b>.
|
||||||
|
If <tt>cat</tt> is <b><tt>nil</tt></b>, the function creates its own
|
||||||
|
concat object.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=return>
|
||||||
|
The function returns a receive callback for the file, and the concat object
|
||||||
|
that will be used to store the received contents.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- receive.file +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<p class=name id=receive.file>
|
||||||
|
socket.callback.<b>receive.file(</b>file, io_err<b>)</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=description>
|
||||||
|
This function creates a receive callback that stores whatever it receives
|
||||||
|
into a file. When done, the callback closes the file.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=parameters>
|
||||||
|
<tt>File</tt> is a file handle opened for writing. If <tt>file</tt> is
|
||||||
|
<b><tt>nil</tt></b>, <tt>io_err</tt> can contain an error message. In this
|
||||||
|
case, the function returns a callback that just aborts
|
||||||
|
transmission with the error message.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=return>
|
||||||
|
The function returns a receive callback for the file.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=note>
|
||||||
|
Note: This function is designed so that it directly accepts the return
|
||||||
|
values of Lua's IO <tt>io.open</tt> library function.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- receive.chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<p class=name id=receive.chain>
|
||||||
|
socket.callback.<b>receive.chain(</b>filter, receive_cb<b>)</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=description>
|
||||||
|
This function creates a receive callback that passes all received data
|
||||||
|
through a filter, before handing it to a given receive callback.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=parameters>
|
||||||
|
<tt>Cat</tt> is the target concat object, or <b><tt>nil</tt></b>.
|
||||||
|
If <tt>cat</tt> is <b><tt>nil</tt></b>, the function creates its own
|
||||||
|
concat object.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=return>
|
||||||
|
The function returns a receive callback for the file, and the concat object
|
||||||
|
that will be used to store the received contents.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=note>
|
||||||
|
Note: Several filters are defined in the <a href=mime.html>MIME</a>
|
||||||
|
module. Below is an example that creates a receive callback that
|
||||||
|
creates a string from the received contents, after decoding the
|
||||||
|
Quoted-Printable transfer content encoding.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre class=example>
|
||||||
|
string_cb, concat = socket.callback.receive.concat()
|
||||||
|
receive_cb = socket.callback.receive.chain(
|
||||||
|
socket.mime.decode("quoted-printable"),
|
||||||
|
string_cb
|
||||||
|
)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p class=note>
|
||||||
|
The call to <tt>callback.chain</tt> creates a chained
|
||||||
|
receive callback that decodes data using the
|
||||||
|
<tt><a href=mime.html#decode>mime.decode</a></tt>
|
||||||
|
Quoted-Printable MIME filter and
|
||||||
|
hands the decoded data to a concat receive callback.
|
||||||
|
The concatenated decoded data can be retrieved later
|
||||||
|
from the associated concat object.
|
||||||
|
</p>
|
||||||
|
|
||||||
<!-- send.file ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- send.file ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<p class=name id=send.file>
|
<p class=name id=send.file>
|
||||||
<b>send.file</b>(file, io_err<b>)</b>
|
socket.callback.<b>send.file(</b>file, io_err<b>)</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=description>
|
<p class=description>
|
||||||
@ -126,25 +245,25 @@ When done, the callback closes the file.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=parameters>
|
<p class=parameters>
|
||||||
<tt>File</tt> is a file opened for reading. If <tt>file</tt> is
|
<tt>File</tt> is a file handle opened for reading. If <tt>file</tt> is
|
||||||
<b><tt>nil</tt></b>, <tt>io_err</tt> can contain an error message. In this
|
<b><tt>nil</tt></b>, <tt>io_err</tt> can contain an error message. In this
|
||||||
case, the function returns a callback that just aborts
|
case, the function returns a callback that just aborts
|
||||||
transmission with the error message.
|
transmission with the error message.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
Returns a send callback for the file.
|
The function returns a send callback for the file.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=note>
|
<p class=note>
|
||||||
Note: This function is designed so that it directly accepts the return
|
Note: This function is designed so that it directly accepts the return
|
||||||
values of the <tt>io.open</tt> function.
|
values of Lua's IO <tt>io.open</tt> library function.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- send.string ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- send.string ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<p class=name id=send.string>
|
<p class=name id=send.string>
|
||||||
<b>send.string(</b>str, err<b>)</b>
|
socket.callback.<b>send.string(</b>str, err<b>)</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=description>
|
<p class=description>
|
||||||
@ -154,26 +273,17 @@ the contents of a string.
|
|||||||
|
|
||||||
<p class=parameters>
|
<p class=parameters>
|
||||||
<tt>Str</tt> is the string to be sent.
|
<tt>Str</tt> is the string to be sent.
|
||||||
<!--
|
|
||||||
If <tt>str</tt> is
|
|
||||||
<b><tt>nil</tt></b>, <tt>err</tt> can optionally contain an error message.
|
|
||||||
-->
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
Returns a send callback for the string, or <b><tt>nil</tt></b> if the string is
|
It returns a send callback for the string,
|
||||||
<b><tt>nil</tt></b>.
|
or <b><tt>nil</tt></b> if <tt>str</tt> is <b><tt>nil</tt></b>.
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class=note>
|
|
||||||
Note: A <tt>nil</tt></b>
|
|
||||||
send callback is equivalent to a callback that returns the empty string.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- send.chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- send.chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<p class=name id=send.chain>
|
<p class=name id=send.chain>
|
||||||
<b>send.chain(</b>send_cb, filter<b>)</b>
|
socket.callback.<b>send.chain(</b>send_cb, filter<b>)</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=description>
|
<p class=description>
|
||||||
@ -207,9 +317,9 @@ send_cb = socket.callback.send.chain(
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p class=note>
|
<p class=note>
|
||||||
The call to <a href=mime.html#chain><tt>socket.mime.chain</tt></a>
|
The call to <a href=mime.html#chain><tt>mime.chain</tt></a>
|
||||||
creates a chained filter that encodes it's input and then breaks it
|
creates a chained filter that encodes it's input and then breaks it
|
||||||
into lines. The call to <tt>socket.callback.chain</tt> creates a chained
|
into lines. The call to <tt>callback.chain</tt> creates a chained
|
||||||
send callback that reads the file from disk and passes it through the
|
send callback that reads the file from disk and passes it through the
|
||||||
filter before sending it.
|
filter before sending it.
|
||||||
</p>
|
</p>
|
||||||
|
19
doc/dns.html
19
doc/dns.html
@ -36,8 +36,7 @@
|
|||||||
<h2 id=dns>DNS</h2>
|
<h2 id=dns>DNS</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The following functions can be used to convert between host names and IP
|
Name resolution function return <em>all</em> information returned by the
|
||||||
addresses. Both functions return <em>all</em> information returned by the
|
|
||||||
resolver in a table of the form:
|
resolver in a table of the form:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -53,6 +52,21 @@ resolved = {<br>
|
|||||||
Note that the <tt>alias</tt> list can be empty.
|
Note that the <tt>alias</tt> list can be empty.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<!-- gethostname ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<p class=name id=gethostname>
|
||||||
|
socket.dns.<b>gethostname()</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=description>
|
||||||
|
Returns the standard host name for the machine.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=return>
|
||||||
|
The function returns a string with the host name.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<p class=name id=tohostname>
|
<p class=name id=tohostname>
|
||||||
@ -74,7 +88,6 @@ the resolver. In case of error, the function returns <b><tt>nil</tt></b>
|
|||||||
followed by an error message.
|
followed by an error message.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<!-- toip +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- toip +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<p class=name id=toip>
|
<p class=name id=toip>
|
||||||
|
@ -40,7 +40,8 @@ LuaSocket is a <a href="http://www.lua.org">Lua</a> extension library
|
|||||||
that is composed by two parts: a C layer that provides support for the TCP
|
that is composed by two parts: a C layer that provides support for the TCP
|
||||||
and UDP transport layers, and a set of Lua modules that add support for
|
and UDP transport layers, and a set of Lua modules that add support for
|
||||||
the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and
|
the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and
|
||||||
downloading files) protocols.
|
downloading files) protocols and other functionality commonly needed by
|
||||||
|
applications that deal with the Internet.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -106,10 +107,25 @@ This binary has been compiled with the <tt>LUASOCKET_DEBUG</tt>
|
|||||||
option, and should be able to run the automatic test procedures.
|
option, and should be able to run the automatic test procedures.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<!-- thanks +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<h2 id=thanks>Special thanks</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Throughout LuaSocket its history, many people gave sugestions that helped
|
||||||
|
improve it. For that, I thank the Lua comunity.
|
||||||
|
Special thanks go to
|
||||||
|
David Burgess, who has pushed the library to a new level of quality and
|
||||||
|
from whom I have learned a lot stuff that doesn't show up in RFCs.
|
||||||
|
Special thanks also to Carlos Cassino, who played a big part in the
|
||||||
|
extensible design seen in the C core of LuaSocket 2.0.
|
||||||
|
</p>
|
||||||
|
|
||||||
<!-- whatsnew +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- whatsnew +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<h2 id=new>What's New</h2>
|
<h2 id=new>What's New</h2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Most of the changes for 2.0 happened in the C layer, which
|
Most of the changes for 2.0 happened in the C layer, which
|
||||||
has been almost completely rewritten. The code has been ported to Lua 5.0
|
has been almost completely rewritten. The code has been ported to Lua 5.0
|
||||||
|
@ -40,6 +40,10 @@
|
|||||||
<blockquote>
|
<blockquote>
|
||||||
<a href="callback.html">Callbacks (socket.callback)</a>
|
<a href="callback.html">Callbacks (socket.callback)</a>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
<a href="callback.html#done">done</a>,
|
||||||
|
<a href="callback.html#fail">fail</a>.
|
||||||
|
</blockquote>
|
||||||
|
<blockquote>
|
||||||
<a href="callback.html#send">send</a>:
|
<a href="callback.html#send">send</a>:
|
||||||
<a href="callback.html#send.chain">chain</a>,
|
<a href="callback.html#send.chain">chain</a>,
|
||||||
<a href="callback.html#send.file">file</a>,
|
<a href="callback.html#send.file">file</a>,
|
||||||
@ -121,7 +125,7 @@
|
|||||||
<blockquote>
|
<blockquote>
|
||||||
<a href="mime.html">MIME (socket.mime) </a>
|
<a href="mime.html">MIME (socket.mime) </a>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<a href="mime.html#filters">filters</a>:
|
<a href="mime.html#high">high-level</a>:
|
||||||
<a href="mime.html#decode">canonic</a>,
|
<a href="mime.html#decode">canonic</a>,
|
||||||
<a href="mime.html#chain">chain</a>,
|
<a href="mime.html#chain">chain</a>,
|
||||||
<a href="mime.html#decode">decode</a>,
|
<a href="mime.html#decode">decode</a>,
|
||||||
@ -129,7 +133,7 @@
|
|||||||
<a href="mime.html#wrap">wrap</a>.
|
<a href="mime.html#wrap">wrap</a>.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<a href="mime.html#low-level">low-level</a>:
|
<a href="mime.html#low">low-level</a>:
|
||||||
<a href="mime.html#b64">b64</a>,
|
<a href="mime.html#b64">b64</a>,
|
||||||
<a href="mime.html#unb64">unb64</a>,
|
<a href="mime.html#unb64">unb64</a>,
|
||||||
<a href="mime.html#eol">eol</a>,
|
<a href="mime.html#eol">eol</a>,
|
||||||
|
146
doc/tcp.html
146
doc/tcp.html
@ -44,10 +44,11 @@ socket.<b>tcp()</b>
|
|||||||
<p class=description>
|
<p class=description>
|
||||||
Creates and returns a TCP master object. A master object can
|
Creates and returns a TCP master object. A master object can
|
||||||
be transformed into a server object with the method
|
be transformed into a server object with the method
|
||||||
<a href=#bind><tt>bind</tt></a> or into a client object with the method
|
<a href=#listen><tt>listen</tt></a> (after a call to <a
|
||||||
<a href=#connect><tt>connect</tt></a>. The only other method
|
href=#bind><tt>bind</tt></a>) or into a client object with
|
||||||
supported by a master object is the <a href=#close><tt>close</tt></a>
|
the method <a href=#connect><tt>connect</tt></a>. The only other
|
||||||
method.</p>
|
method supported by a master object is the
|
||||||
|
<a href=#close><tt>close</tt></a> method.</p>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
In case of success, a new master object is returned. In case of error,
|
In case of success, a new master object is returned. In case of error,
|
||||||
@ -67,8 +68,9 @@ object and returns a client object representing that connection.
|
|||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
If a connection is successfully initiated, a client object is returned.
|
If a connection is successfully initiated, a client object is returned.
|
||||||
If a timeout condition is met, the method returns <b><tt>nil</tt></b> followed
|
If a timeout condition is met, the method returns <b><tt>nil</tt></b>
|
||||||
by the error string '<tt>timeout</tt>'.
|
followed by the error string '<tt>timeout</tt>'. Other errors are
|
||||||
|
reported by <b><tt>nil</tt></b> followed by a message describing the error.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=note>
|
<p class=note>
|
||||||
@ -83,19 +85,12 @@ might block until <em>another</em> client shows up.
|
|||||||
<!-- bind +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- bind +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<p class=name id=bind>
|
<p class=name id=bind>
|
||||||
master:<b>bind(</b>address, port [, backlog]<b>)</b>
|
master:<b>bind(</b>address, port<b>)</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=description>
|
<p class=description>
|
||||||
Binds a master object to <tt>address</tt> and <tt>port</tt> on the
|
Binds a master object to <tt>address</tt> and <tt>port</tt> on the
|
||||||
local host, transforming it into a server object. Server
|
local host.
|
||||||
objects support the
|
|
||||||
<a href=#accept><tt>accept</tt></a>,
|
|
||||||
<a href=#getsockname><tt>getsockname</tt></a>,
|
|
||||||
<a href=#setoption><tt>setoption</tt></a>,
|
|
||||||
<a href=#settimeout><tt>settimeout</tt></a>,
|
|
||||||
and <a href=#close><tt>close</tt></a> methods.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class=parameters>
|
<p class=parameters>
|
||||||
<tt>Address</tt> can be an IP address or a host name.
|
<tt>Address</tt> can be an IP address or a host name.
|
||||||
@ -103,10 +98,7 @@ and <a href=#close><tt>close</tt></a> methods.
|
|||||||
If <tt>address</tt>
|
If <tt>address</tt>
|
||||||
is '<tt>*</tt>', the system binds to all local interfaces
|
is '<tt>*</tt>', the system binds to all local interfaces
|
||||||
using the <tt>INADDR_ANY</tt> constant. If <tt>port</tt> is 0, the system automatically
|
using the <tt>INADDR_ANY</tt> constant. If <tt>port</tt> is 0, the system automatically
|
||||||
chooses an ephemeral port. The optional parameter <tt>backlog</tt>, which
|
chooses an ephemeral port.
|
||||||
defaults to 1, specifies the number of client connections that can
|
|
||||||
be queued waiting for service. If the queue is full and another client
|
|
||||||
attempts connection, the connection is refused.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
@ -115,8 +107,8 @@ method returns <b><tt>nil</tt></b> followed by an error message.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=note>
|
<p class=note>
|
||||||
Note: The function <tt>socket.bind</tt> is available and is a short
|
Note: The function <a href=#socket.bind><tt>socket.bind</tt></a>
|
||||||
for <a href=#socket.tcp><tt>socket.tcp</tt></a> followed by the <tt>bind</tt> method.
|
is available and is a shortcut for the creation server sockets.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- close ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- close ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
@ -150,7 +142,8 @@ master:<b>connect(</b>address, port<b>)</b>
|
|||||||
|
|
||||||
<p class=description>
|
<p class=description>
|
||||||
Attempts to connect a master object to a remote host, transforming it into a
|
Attempts to connect a master object to a remote host, transforming it into a
|
||||||
client object. Client objects support methods
|
client object.
|
||||||
|
Client objects support methods
|
||||||
<a href=#send><tt>send</tt></a>,
|
<a href=#send><tt>send</tt></a>,
|
||||||
<a href=#receive><tt>receive</tt></a>,
|
<a href=#receive><tt>receive</tt></a>,
|
||||||
<a href=#getsockname><tt>getsockname</tt></a>,
|
<a href=#getsockname><tt>getsockname</tt></a>,
|
||||||
@ -170,8 +163,15 @@ describing the error. In case of success, the method returns 1.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=note>
|
<p class=note>
|
||||||
Note: The function <tt>socket.connect</tt> is available and is a short
|
Note: The function <a href=#socket.connect><tt>socket.connect</tt></a>
|
||||||
for <a href=#socket.tcp><tt>socket.tcp</tt></a> followed by the <tt>connect</tt> method.
|
is available and is a shortcut for the creation of client sockets.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=note>
|
||||||
|
Note: Starting with LuaSocket 2.0,
|
||||||
|
the <a href=#settimeout><tt>settimeout</tt></a>
|
||||||
|
function affects the behavior of connect, causing it to return in case of
|
||||||
|
a timeout error.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- getpeername ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- getpeername ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
@ -210,12 +210,32 @@ The method returns a string with local IP address and a number with
|
|||||||
the port. In case of error, the method returns <b><tt>nil</tt></b>.
|
the port. In case of error, the method returns <b><tt>nil</tt></b>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=note>
|
<!-- listen ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
Note: Naturally, for a server object, the address and port returned are
|
|
||||||
those passed to the <a href=#bind>bind</a> method. If the port value
|
<p class=name id=listen>
|
||||||
passed to bind was 0, the OS assigned ephemeral port is returned. For
|
master:<b>listen(</b>backlog<b>)</b>
|
||||||
client objects, both the address and port are ephemeral and these are the
|
</p>
|
||||||
values returned.
|
|
||||||
|
<p class=description>
|
||||||
|
Specifies the socket is willing to receive connections, transforming the
|
||||||
|
object into a server object. Server objects support the
|
||||||
|
<a href=#accept><tt>accept</tt></a>,
|
||||||
|
<a href=#getsockname><tt>getsockname</tt></a>,
|
||||||
|
<a href=#setoption><tt>setoption</tt></a>,
|
||||||
|
<a href=#settimeout><tt>settimeout</tt></a>,
|
||||||
|
and <a href=#close><tt>close</tt></a> methods.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=parameters>
|
||||||
|
The parameter <tt>backlog</tt> specifies the number of client
|
||||||
|
connections that can
|
||||||
|
be queued waiting for service. If the queue is full and another client
|
||||||
|
attempts connection, the connection is refused.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=return>
|
||||||
|
In case of success, the method returns 1. In case of error, the
|
||||||
|
method returns <b><tt>nil</tt></b> followed by an error message.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- receive ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- receive ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
@ -242,8 +262,8 @@ closed. No end-of-line translation is performed;
|
|||||||
terminated by a LF character (ASCII 10), optionally preceded by a
|
terminated by a LF character (ASCII 10), optionally preceded by a
|
||||||
CR character (ASCII 13). The CR and LF characters are not included in
|
CR character (ASCII 13). The CR and LF characters are not included in
|
||||||
the returned line. This is the default pattern;
|
the returned line. This is the default pattern;
|
||||||
<li> <tt>number</tt>: causes the method to read <tt>number</tt> raw
|
<li> <tt>number</tt>: causes the method to read a specified <tt>number</tt>
|
||||||
bytes from the socket.
|
of bytes from the socket.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
@ -311,22 +331,30 @@ are sure you need it.
|
|||||||
depends on the option being set:
|
depends on the option being set:
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li> '<tt>tcp-nodelay</tt>': Setting this option to <tt>true</tt> disables the
|
|
||||||
Nagle's algorithm for the connection;
|
|
||||||
<li> '<tt>linger</tt>': Controls the action taken when unsent data are
|
|
||||||
queued on a socket and a close is performed. The value is a table with a
|
|
||||||
boolean entry '<tt>on</tt>' and a numeric entry for the time interval
|
|
||||||
'<tt>timeout</tt>' in seconds.
|
|
||||||
If the '<tt>on</tt>' field is set to <tt>true</tt>,
|
|
||||||
the system will block the process on the close attempt until it is able to
|
|
||||||
transmit the data or until '<tt>timeout</tt>' has passed. If '<tt>on</tt>'
|
|
||||||
is <tt>false</tt> and a close is issued, the system will process the close
|
|
||||||
in a manner that allows the process to continue as quickly as possible. I
|
|
||||||
do not advise you to set this to anything other than zero.
|
|
||||||
<li> '<tt>keepalive</tt>': Setting this option to <tt>true</tt> enables
|
<li> '<tt>keepalive</tt>': Setting this option to <tt>true</tt> enables
|
||||||
the periodic transmission of messages on a connected socket. Should the
|
the periodic transmission of messages on a connected socket. Should the
|
||||||
connected party fail to respond to these messages, the connection is
|
connected party fail to respond to these messages, the connection is
|
||||||
considered broken and processes using the socket are notified.
|
considered broken and processes using the socket are notified;
|
||||||
|
|
||||||
|
<li> '<tt>linger</tt>': Controls the action taken when unsent data are
|
||||||
|
queued on a socket and a close is performed. The value is a table with a
|
||||||
|
boolean entry '<tt>on</tt>' and a numeric entry for the time interval
|
||||||
|
'<tt>timeout</tt>' in seconds. If the '<tt>on</tt>' field is set to
|
||||||
|
<tt>true</tt>, the system will block the process on the close attempt until
|
||||||
|
it is able to transmit the data or until '<tt>timeout</tt>' has passed. If
|
||||||
|
'<tt>on</tt>' is <tt>false</tt> and a close is issued, the system will
|
||||||
|
process the close in a manner that allows the process to continue as
|
||||||
|
quickly as possible. I do not advise you to set this to anything other than
|
||||||
|
zero;
|
||||||
|
|
||||||
|
<li> '<tt>reuseaddr</tt>': Setting this option indicates that the rules
|
||||||
|
used in validating addresses supplied in a call to
|
||||||
|
<a href=#bind><tt>bind</tt></a> should allow reuse of local addresses;
|
||||||
|
|
||||||
|
<li> '<tt>tcp-nodelay</tt>': Setting this option to <tt>true</tt>
|
||||||
|
disables the Nagle's algorithm for the connection.
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p class=return>
|
<p class=return>
|
||||||
@ -382,7 +410,9 @@ indefinitely. Negative timeout values have the same effect.
|
|||||||
Note: although timeout values have millisecond precision in LuaSocket,
|
Note: although timeout values have millisecond precision in LuaSocket,
|
||||||
large blocks can cause I/O functions not to respect timeout values due
|
large blocks can cause I/O functions not to respect timeout values due
|
||||||
to the time the library takes to transfer blocks to and from the OS
|
to the time the library takes to transfer blocks to and from the OS
|
||||||
and to and from the Lua interpreter.
|
and to and from the Lua interpreter. Also, function that accept host names
|
||||||
|
and perform automatic name resolution might be blocked by the resolver for
|
||||||
|
longer than the specified timeout value.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class=note>
|
<p class=note>
|
||||||
@ -391,6 +421,30 @@ changed for sake of uniformity, since all other method names already
|
|||||||
contained verbs making their imperative nature obvious.
|
contained verbs making their imperative nature obvious.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<!-- shutdown +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<p class=name id=shutdown>
|
||||||
|
client:<b>shutdown(</b>mode<b>)</b><br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=description>
|
||||||
|
Shuts down part of a full duplex connection.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=parameters>
|
||||||
|
Mode tells which way of the connection should be shut down and can
|
||||||
|
take the value:
|
||||||
|
<ul>
|
||||||
|
<li>"<tt>both</tt>": disallow further sends and receives on the object.
|
||||||
|
This is the default mode;
|
||||||
|
<li>"<tt>send</tt>": disallow further sends on the object;
|
||||||
|
<li>"<tt>receive</tt>": disallow further receives on the object.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p class=return>
|
||||||
|
This function returns 1.
|
||||||
|
</p>
|
||||||
|
|
||||||
<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<div class=footer>
|
<div class=footer>
|
||||||
|
44
doc/url.html
44
doc/url.html
@ -241,6 +241,50 @@ returning a list with all the parsed segments, the function unescapes all
|
|||||||
of them.
|
of them.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<!-- escape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<p class=name id="escape">
|
||||||
|
socket.url.<b>escape(</b>content<b>)</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=description>
|
||||||
|
Applies the URL escaping content coding to a string
|
||||||
|
Each byte is encoded as a percent character followed
|
||||||
|
by the two byte hexadecimal representation of its integer
|
||||||
|
value.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=parameters>
|
||||||
|
<tt>Content</tt> is the string to be encoded.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=result>
|
||||||
|
The function returns the encoded string.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre class=example>
|
||||||
|
code = socket.url.escape("/#?;")
|
||||||
|
-- code = "%2f%23%3f%3b"
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<!-- unescape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
|
<p class=name id="unescape">
|
||||||
|
socket.url.<b>unescape(</b>content<b>)</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=description>
|
||||||
|
Removes the URL escaping content coding from a string.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=parameters>
|
||||||
|
<tt>Content</tt> is the string to be decoded.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class=return>
|
||||||
|
The function returns the decoded string.
|
||||||
|
</p>
|
||||||
|
|
||||||
<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||||
|
|
||||||
<div class=footer>
|
<div class=footer>
|
||||||
|
18
etc/qp.lua
Normal file
18
etc/qp.lua
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
local convert
|
||||||
|
arg = arg or {}
|
||||||
|
local mode = arg and arg[1] or "-et"
|
||||||
|
if mode == "-et" then
|
||||||
|
local canonic = socket.mime.canonic()
|
||||||
|
local qp = socket.mime.encode("quoted-printable")
|
||||||
|
local wrap = socket.mime.wrap("quoted-printable")
|
||||||
|
convert = socket.mime.chain(canonic, qp, wrap)
|
||||||
|
elseif mode == "-eb" then
|
||||||
|
local qp = socket.mime.encode("quoted-printable", "binary")
|
||||||
|
local wrap = socket.mime.wrap("quoted-printable")
|
||||||
|
convert = socket.mime.chain(qp, wrap)
|
||||||
|
else convert = socket.mime.decode("quoted-printable") end
|
||||||
|
while 1 do
|
||||||
|
local chunk = io.read(4096)
|
||||||
|
io.write(convert(chunk))
|
||||||
|
if not chunk then break end
|
||||||
|
end
|
43
samples/cddb.lua
Normal file
43
samples/cddb.lua
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
if not arg or not arg[1] or not arg[2] then
|
||||||
|
print("luasocket cddb.lua <category> <disc-id> [<server>]")
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local server = arg[3] or "http://freedb.freedb.org/~cddb/cddb.cgi"
|
||||||
|
|
||||||
|
function parse(body)
|
||||||
|
local lines = string.gfind(body, "(.-)\r\n")
|
||||||
|
local status = lines()
|
||||||
|
local _, _, code, message = string.find(status, "(%d%d%d) (.*)")
|
||||||
|
if tonumber(code) ~= 210 then
|
||||||
|
return nil, code, message
|
||||||
|
end
|
||||||
|
local data = {}
|
||||||
|
for l in lines do
|
||||||
|
local c = string.sub(l, 1, 1)
|
||||||
|
if c ~= '#' and c ~= '.' then
|
||||||
|
local _, _, key, value = string.find(l, "(.-)=(.*)")
|
||||||
|
value = string.gsub(value, "\\n", "\n")
|
||||||
|
value = string.gsub(value, "\\\\", "\\")
|
||||||
|
value = string.gsub(value, "\\t", "\t")
|
||||||
|
data[key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return data, code, message
|
||||||
|
end
|
||||||
|
|
||||||
|
local host = socket.dns.gethostname()
|
||||||
|
local query = "%s?cmd=cddb+read+%s+%s&hello=LuaSocket+%s+LuaSocket+2.0&proto=6"
|
||||||
|
local url = string.format(query, server, arg[1], arg[2], host)
|
||||||
|
local body, headers, code, error = socket.http.get(url)
|
||||||
|
|
||||||
|
if code == 200 then
|
||||||
|
local data, code, error = parse(body)
|
||||||
|
if not data then
|
||||||
|
print(error or code)
|
||||||
|
else
|
||||||
|
for i,v in data do
|
||||||
|
io.write(i, ': ', v, '\n')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else print(error) end
|
@ -37,9 +37,9 @@ error:
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes the module
|
* Initializes the module
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void aux_open(lua_State *L)
|
int aux_open(lua_State *L)
|
||||||
{
|
{
|
||||||
;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
@ -159,3 +159,13 @@ void *aux_getclassudata(lua_State *L, const char *classname, int objidx)
|
|||||||
return luaL_checkudata(L, objidx, classname);
|
return luaL_checkudata(L, objidx, classname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Accept "false" as nil
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
const char *aux_optlstring(lua_State *L, int n, const char *v, size_t *l)
|
||||||
|
{
|
||||||
|
if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) {
|
||||||
|
*l = 0;
|
||||||
|
return NULL;
|
||||||
|
} else return luaL_optlstring(L, n, v, l);
|
||||||
|
}
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
#define MAX(x, y) ((x) > (y) ? x : y)
|
#define MAX(x, y) ((x) > (y) ? x : y)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void aux_open(lua_State *L);
|
int aux_open(lua_State *L);
|
||||||
void aux_newclass(lua_State *L, const char *classname, luaL_reg *func);
|
void aux_newclass(lua_State *L, const char *classname, luaL_reg *func);
|
||||||
void aux_add2group(lua_State *L, const char *classname, const char *group);
|
void aux_add2group(lua_State *L, const char *classname, const char *group);
|
||||||
void aux_setclass(lua_State *L, const char *classname, int objidx);
|
void aux_setclass(lua_State *L, const char *classname, int objidx);
|
||||||
@ -49,5 +49,6 @@ void *aux_checkgroup(lua_State *L, const char *groupname, int objidx);
|
|||||||
void *aux_getclassudata(lua_State *L, const char *groupname, int objidx);
|
void *aux_getclassudata(lua_State *L, const char *groupname, int objidx);
|
||||||
void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx);
|
void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx);
|
||||||
int aux_checkboolean(lua_State *L, int objidx);
|
int aux_checkboolean(lua_State *L, int objidx);
|
||||||
|
const char *aux_optlstring(lua_State *L, int n, const char *v, size_t *l);
|
||||||
|
|
||||||
#endif /* AUX_H */
|
#endif /* AUX_H */
|
||||||
|
@ -26,9 +26,10 @@ static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent);
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes module
|
* Initializes module
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void buf_open(lua_State *L)
|
int buf_open(lua_State *L)
|
||||||
{
|
{
|
||||||
(void) L;
|
(void) L;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
|
@ -34,7 +34,7 @@ typedef struct t_buf_ {
|
|||||||
} t_buf;
|
} t_buf;
|
||||||
typedef t_buf *p_buf;
|
typedef t_buf *p_buf;
|
||||||
|
|
||||||
void buf_open(lua_State *L);
|
int buf_open(lua_State *L);
|
||||||
void buf_init(p_buf buf, p_io io, p_tm tm);
|
void buf_init(p_buf buf, p_io io, p_tm tm);
|
||||||
int buf_meth_send(lua_State *L, p_buf buf);
|
int buf_meth_send(lua_State *L, p_buf buf);
|
||||||
int buf_meth_receive(lua_State *L, p_buf buf);
|
int buf_meth_receive(lua_State *L, p_buf buf);
|
||||||
|
@ -649,3 +649,5 @@ function Public.get(url_or_request)
|
|||||||
local err = Public.get_cb(request)
|
local err = Public.get_cb(request)
|
||||||
return concat:getresult(), err
|
return concat:getresult(), err
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return ftp
|
||||||
|
@ -11,7 +11,7 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end
|
|||||||
local socket = _G[LUASOCKET_LIBNAME]
|
local socket = _G[LUASOCKET_LIBNAME]
|
||||||
if not socket then error('module requires LuaSocket') end
|
if not socket then error('module requires LuaSocket') end
|
||||||
-- create smtp namespace inside LuaSocket namespace
|
-- create smtp namespace inside LuaSocket namespace
|
||||||
local http = {}
|
local http = socket.http or {}
|
||||||
socket.http = http
|
socket.http = http
|
||||||
-- make all module globals fall into smtp namespace
|
-- make all module globals fall into smtp namespace
|
||||||
setmetatable(http, { __index = _G })
|
setmetatable(http, { __index = _G })
|
||||||
|
@ -35,17 +35,10 @@ static luaL_reg func[] = {
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes module
|
* Initializes module
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void inet_open(lua_State *L)
|
int inet_open(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_pushstring(L, LUASOCKET_LIBNAME);
|
lua_pushstring(L, LUASOCKET_LIBNAME);
|
||||||
lua_gettable(L, LUA_GLOBALSINDEX);
|
lua_gettable(L, LUA_GLOBALSINDEX);
|
||||||
if (lua_isnil(L, -1)) {
|
|
||||||
lua_pop(L, 1);
|
|
||||||
lua_newtable(L);
|
|
||||||
lua_pushstring(L, LUASOCKET_LIBNAME);
|
|
||||||
lua_pushvalue(L, -2);
|
|
||||||
lua_settable(L, LUA_GLOBALSINDEX);
|
|
||||||
}
|
|
||||||
lua_pushstring(L, "dns");
|
lua_pushstring(L, "dns");
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
luaL_openlib(L, NULL, func, 0);
|
luaL_openlib(L, NULL, func, 0);
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#define INET_ATON
|
#define INET_ATON
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void inet_open(lua_State *L);
|
int inet_open(lua_State *L);
|
||||||
|
|
||||||
const char *inet_trycreate(p_sock ps, int type);
|
const char *inet_trycreate(p_sock ps, int type);
|
||||||
const char *inet_tryconnect(p_sock ps, const char *address,
|
const char *inet_tryconnect(p_sock ps, const char *address,
|
||||||
|
@ -33,12 +33,14 @@
|
|||||||
#include "tcp.h"
|
#include "tcp.h"
|
||||||
#include "udp.h"
|
#include "udp.h"
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
|
#include "smtp.h"
|
||||||
#include "mime.h"
|
#include "mime.h"
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Declarations
|
* Declarations
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
static int base_open(lua_State *L);
|
static int base_open(lua_State *L);
|
||||||
|
static int mod_open(lua_State *L, const luaL_reg *mod);
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Setup basic stuff.
|
* Setup basic stuff.
|
||||||
@ -66,22 +68,9 @@ static int base_open(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
static int mod_open(lua_State *L, const luaL_reg *mod)
|
||||||
* Initializes all library modules.
|
|
||||||
\*-------------------------------------------------------------------------*/
|
|
||||||
LUASOCKET_API int luaopen_socket(lua_State *L)
|
|
||||||
{
|
{
|
||||||
if (!sock_open()) return 0;
|
for (; mod->name; mod++) mod->func(L);
|
||||||
/* initialize all modules */
|
|
||||||
base_open(L);
|
|
||||||
aux_open(L);
|
|
||||||
tm_open(L);
|
|
||||||
buf_open(L);
|
|
||||||
inet_open(L);
|
|
||||||
tcp_open(L);
|
|
||||||
udp_open(L);
|
|
||||||
select_open(L);
|
|
||||||
mime_open(L);
|
|
||||||
#ifdef LUASOCKET_COMPILED
|
#ifdef LUASOCKET_COMPILED
|
||||||
#include "auxiliar.lch"
|
#include "auxiliar.lch"
|
||||||
#include "concat.lch"
|
#include "concat.lch"
|
||||||
@ -101,5 +90,36 @@ LUASOCKET_API int luaopen_socket(lua_State *L)
|
|||||||
lua_dofile(L, "ftp.lua");
|
lua_dofile(L, "ftp.lua");
|
||||||
lua_dofile(L, "http.lua");
|
lua_dofile(L, "http.lua");
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Modules
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
static const luaL_reg mod[] = {
|
||||||
|
{"base", base_open},
|
||||||
|
{"aux", aux_open},
|
||||||
|
{"tm", tm_open},
|
||||||
|
{"buf", buf_open},
|
||||||
|
{"inet", inet_open},
|
||||||
|
{"tcp", tcp_open},
|
||||||
|
{"udp", udp_open},
|
||||||
|
{"select", select_open},
|
||||||
|
{"mime", mime_open},
|
||||||
|
{"smtp", smtp_open},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Initializes all library modules.
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
LUASOCKET_API int luaopen_socket(lua_State *L)
|
||||||
|
{
|
||||||
|
if (!sock_open()) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_pushstring(L, "unable to initialize library");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
mod_open(L, mod);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
136
src/mime.c
136
src/mime.c
@ -10,6 +10,7 @@
|
|||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
|
|
||||||
#include "luasocket.h"
|
#include "luasocket.h"
|
||||||
|
#include "auxiliar.h"
|
||||||
#include "mime.h"
|
#include "mime.h"
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
@ -45,18 +46,16 @@ static void qpquote(UC c, luaL_Buffer *buffer);
|
|||||||
static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
|
static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
|
||||||
static size_t qpencode(UC c, UC *input, size_t size,
|
static size_t qpencode(UC c, UC *input, size_t size,
|
||||||
const char *marker, luaL_Buffer *buffer);
|
const char *marker, luaL_Buffer *buffer);
|
||||||
|
static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer);
|
||||||
static const char *checklstring(lua_State *L, int n, size_t *l);
|
|
||||||
static const char *optlstring(lua_State *L, int n, const char *v, size_t *l);
|
|
||||||
|
|
||||||
/* code support functions */
|
/* code support functions */
|
||||||
static luaL_reg func[] = {
|
static luaL_reg func[] = {
|
||||||
|
{ "b64", mime_global_b64 },
|
||||||
{ "eol", mime_global_eol },
|
{ "eol", mime_global_eol },
|
||||||
{ "qp", mime_global_qp },
|
{ "qp", mime_global_qp },
|
||||||
{ "unqp", mime_global_unqp },
|
|
||||||
{ "qpwrp", mime_global_qpwrp },
|
{ "qpwrp", mime_global_qpwrp },
|
||||||
{ "b64", mime_global_b64 },
|
|
||||||
{ "unb64", mime_global_unb64 },
|
{ "unb64", mime_global_unb64 },
|
||||||
|
{ "unqp", mime_global_unqp },
|
||||||
{ "wrp", mime_global_wrp },
|
{ "wrp", mime_global_wrp },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
@ -82,17 +81,10 @@ static UC b64unbase[256];
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes module
|
* Initializes module
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void mime_open(lua_State *L)
|
int mime_open(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_pushstring(L, LUASOCKET_LIBNAME);
|
lua_pushstring(L, LUASOCKET_LIBNAME);
|
||||||
lua_gettable(L, LUA_GLOBALSINDEX);
|
lua_gettable(L, LUA_GLOBALSINDEX);
|
||||||
if (lua_isnil(L, -1)) {
|
|
||||||
lua_pop(L, 1);
|
|
||||||
lua_newtable(L);
|
|
||||||
lua_pushstring(L, LUASOCKET_LIBNAME);
|
|
||||||
lua_pushvalue(L, -2);
|
|
||||||
lua_settable(L, LUA_GLOBALSINDEX);
|
|
||||||
}
|
|
||||||
lua_pushstring(L, "mime");
|
lua_pushstring(L, "mime");
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
luaL_openlib(L, NULL, func, 0);
|
luaL_openlib(L, NULL, func, 0);
|
||||||
@ -101,25 +93,7 @@ void mime_open(lua_State *L)
|
|||||||
/* initialize lookup tables */
|
/* initialize lookup tables */
|
||||||
qpsetup(qpclass, qpunbase);
|
qpsetup(qpclass, qpunbase);
|
||||||
b64setup(b64unbase);
|
b64setup(b64unbase);
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
|
||||||
* Check if a string was provided. We accept false also.
|
|
||||||
\*-------------------------------------------------------------------------*/
|
|
||||||
static const char *checklstring(lua_State *L, int n, size_t *l)
|
|
||||||
{
|
|
||||||
if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) {
|
|
||||||
*l = 0;
|
|
||||||
return NULL;
|
|
||||||
} else return luaL_checklstring(L, n, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *optlstring(lua_State *L, int n, const char *v, size_t *l)
|
|
||||||
{
|
|
||||||
if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) {
|
|
||||||
*l = 0;
|
|
||||||
return NULL;
|
|
||||||
} else return luaL_optlstring(L, n, v, l);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
@ -127,31 +101,42 @@ static const char *optlstring(lua_State *L, int n, const char *v, size_t *l)
|
|||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Incrementaly breaks a string into lines
|
* Incrementaly breaks a string into lines
|
||||||
* A, n = wrp(l, B, length, marker)
|
* A, n = wrp(l, B, length)
|
||||||
* A is a copy of B, broken into lines of at most 'length' bytes.
|
* A is a copy of B, broken into lines of at most 'length' bytes.
|
||||||
* 'l' is how many bytes are left for the first line of B.
|
* 'l' is how many bytes are left for the first line of B.
|
||||||
* 'n' is the number of bytes left in the last line of A.
|
* 'n' is the number of bytes left in the last line of A.
|
||||||
* Marker is the end-of-line marker.
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static int mime_global_wrp(lua_State *L)
|
static int mime_global_wrp(lua_State *L)
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
int left = (int) luaL_checknumber(L, 1);
|
int left = (int) luaL_checknumber(L, 1);
|
||||||
const UC *input = (UC *) checklstring(L, 2, &size);
|
const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size);
|
||||||
const UC *last = input + size;
|
const UC *last = input + size;
|
||||||
int length = (int) luaL_optnumber(L, 3, 76);
|
int length = (int) luaL_optnumber(L, 3, 76);
|
||||||
const char *marker = luaL_optstring(L, 4, CRLF);
|
|
||||||
luaL_Buffer buffer;
|
luaL_Buffer buffer;
|
||||||
luaL_buffinit(L, &buffer);
|
luaL_buffinit(L, &buffer);
|
||||||
while (input < last) {
|
while (input < last) {
|
||||||
luaL_putchar(&buffer, *input++);
|
switch (*input) {
|
||||||
if (--left <= 0) {
|
case CR:
|
||||||
luaL_addstring(&buffer, marker);
|
break;
|
||||||
|
case LF:
|
||||||
|
luaL_addstring(&buffer, CRLF);
|
||||||
left = length;
|
left = length;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (left <= 0) {
|
||||||
|
left = length;
|
||||||
|
luaL_addstring(&buffer, CRLF);
|
||||||
}
|
}
|
||||||
|
luaL_putchar(&buffer, *input);
|
||||||
|
left--;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
input++;
|
||||||
|
}
|
||||||
|
/* if in last chunk and last line wasn't terminated, add a line-break */
|
||||||
if (!input && left < length) {
|
if (!input && left < length) {
|
||||||
luaL_addstring(&buffer, marker);
|
luaL_addstring(&buffer, CRLF);
|
||||||
left = length;
|
left = length;
|
||||||
}
|
}
|
||||||
luaL_pushresult(&buffer);
|
luaL_pushresult(&buffer);
|
||||||
@ -235,7 +220,6 @@ static size_t b64pad(const UC *input, size_t size,
|
|||||||
static size_t b64decode(UC c, UC *input, size_t size,
|
static size_t b64decode(UC c, UC *input, size_t size,
|
||||||
luaL_Buffer *buffer)
|
luaL_Buffer *buffer)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* ignore invalid characters */
|
/* ignore invalid characters */
|
||||||
if (b64unbase[c] > 64) return size;
|
if (b64unbase[c] > 64) return size;
|
||||||
input[size++] = c;
|
input[size++] = c;
|
||||||
@ -277,7 +261,7 @@ static int mime_global_b64(lua_State *L)
|
|||||||
luaL_buffinit(L, &buffer);
|
luaL_buffinit(L, &buffer);
|
||||||
while (input < last)
|
while (input < last)
|
||||||
asize = b64encode(*input++, atom, asize, &buffer);
|
asize = b64encode(*input++, atom, asize, &buffer);
|
||||||
input = (UC *) optlstring(L, 2, NULL, &isize);
|
input = (UC *) aux_optlstring(L, 2, NULL, &isize);
|
||||||
if (input) {
|
if (input) {
|
||||||
last = input + isize;
|
last = input + isize;
|
||||||
while (input < last)
|
while (input < last)
|
||||||
@ -305,12 +289,14 @@ static int mime_global_unb64(lua_State *L)
|
|||||||
luaL_buffinit(L, &buffer);
|
luaL_buffinit(L, &buffer);
|
||||||
while (input < last)
|
while (input < last)
|
||||||
asize = b64decode(*input++, atom, asize, &buffer);
|
asize = b64decode(*input++, atom, asize, &buffer);
|
||||||
input = (UC *) optlstring(L, 2, NULL, &isize);
|
input = (UC *) aux_optlstring(L, 2, NULL, &isize);
|
||||||
if (input) {
|
if (input) {
|
||||||
last = input + isize;
|
last = input + isize;
|
||||||
while (input < last)
|
while (input < last)
|
||||||
asize = b64decode(*input++, atom, asize, &buffer);
|
asize = b64decode(*input++, atom, asize, &buffer);
|
||||||
}
|
}
|
||||||
|
/* if !input we are done. if atom > 0, the remaning is invalid. we just
|
||||||
|
* return it undecoded. */
|
||||||
luaL_pushresult(&buffer);
|
luaL_pushresult(&buffer);
|
||||||
lua_pushlstring(L, (char *) atom, asize);
|
lua_pushlstring(L, (char *) atom, asize);
|
||||||
return 2;
|
return 2;
|
||||||
@ -416,7 +402,7 @@ static size_t qpencode(UC c, UC *input, size_t size,
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Deal with the final characters
|
* Deal with the final characters
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static void qppad(UC *input, size_t size, luaL_Buffer *buffer)
|
static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
@ -424,12 +410,13 @@ static void qppad(UC *input, size_t size, luaL_Buffer *buffer)
|
|||||||
else qpquote(input[i], buffer);
|
else qpquote(input[i], buffer);
|
||||||
}
|
}
|
||||||
luaL_addstring(buffer, EQCRLF);
|
luaL_addstring(buffer, EQCRLF);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Incrementally converts a string to quoted-printable
|
* Incrementally converts a string to quoted-printable
|
||||||
* A, B = qp(C, D, marker)
|
* A, B = qp(C, D, marker)
|
||||||
* Crlf is the text to be used to replace CRLF sequences found in A.
|
* Marker is the text to be used to replace CRLF sequences found in A.
|
||||||
* A is the encoded version of the largest prefix of C .. D that
|
* A is the encoded version of the largest prefix of C .. D that
|
||||||
* can be encoded without doubts.
|
* can be encoded without doubts.
|
||||||
* B has the remaining bytes of C .. D, *without* encoding.
|
* B has the remaining bytes of C .. D, *without* encoding.
|
||||||
@ -439,19 +426,20 @@ static int mime_global_qp(lua_State *L)
|
|||||||
|
|
||||||
size_t asize = 0, isize = 0;
|
size_t asize = 0, isize = 0;
|
||||||
UC atom[3];
|
UC atom[3];
|
||||||
const UC *input = (UC *) checklstring(L, 1, &isize);
|
const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize);
|
||||||
const UC *last = input + isize;
|
const UC *last = input + isize;
|
||||||
const char *marker = luaL_optstring(L, 3, CRLF);
|
const char *marker = luaL_optstring(L, 3, CRLF);
|
||||||
luaL_Buffer buffer;
|
luaL_Buffer buffer;
|
||||||
luaL_buffinit(L, &buffer);
|
luaL_buffinit(L, &buffer);
|
||||||
while (input < last)
|
while (input < last)
|
||||||
asize = qpencode(*input++, atom, asize, marker, &buffer);
|
asize = qpencode(*input++, atom, asize, marker, &buffer);
|
||||||
input = (UC *) optlstring(L, 2, NULL, &isize);
|
input = (UC *) aux_optlstring(L, 2, NULL, &isize);
|
||||||
if (input) {
|
if (input) {
|
||||||
last = input + isize;
|
last = input + isize;
|
||||||
while (input < last)
|
while (input < last)
|
||||||
asize = qpencode(*input++, atom, asize, marker, &buffer);
|
asize = qpencode(*input++, atom, asize, marker, &buffer);
|
||||||
} else qppad(atom, asize, &buffer);
|
} else
|
||||||
|
asize = qppad(atom, asize, &buffer);
|
||||||
luaL_pushresult(&buffer);
|
luaL_pushresult(&buffer);
|
||||||
lua_pushlstring(L, (char *) atom, asize);
|
lua_pushlstring(L, (char *) atom, asize);
|
||||||
return 2;
|
return 2;
|
||||||
@ -507,13 +495,13 @@ static int mime_global_unqp(lua_State *L)
|
|||||||
|
|
||||||
size_t asize = 0, isize = 0;
|
size_t asize = 0, isize = 0;
|
||||||
UC atom[3];
|
UC atom[3];
|
||||||
const UC *input = (UC *) checklstring(L, 1, &isize);
|
const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize);
|
||||||
const UC *last = input + isize;
|
const UC *last = input + isize;
|
||||||
luaL_Buffer buffer;
|
luaL_Buffer buffer;
|
||||||
luaL_buffinit(L, &buffer);
|
luaL_buffinit(L, &buffer);
|
||||||
while (input < last)
|
while (input < last)
|
||||||
asize = qpdecode(*input++, atom, asize, &buffer);
|
asize = qpdecode(*input++, atom, asize, &buffer);
|
||||||
input = (UC *) optlstring(L, 2, NULL, &isize);
|
input = (UC *) aux_optlstring(L, 2, NULL, &isize);
|
||||||
if (input) {
|
if (input) {
|
||||||
last = input + isize;
|
last = input + isize;
|
||||||
while (input < last)
|
while (input < last)
|
||||||
@ -537,38 +525,39 @@ static int mime_global_qpwrp(lua_State *L)
|
|||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
int left = (int) luaL_checknumber(L, 1);
|
int left = (int) luaL_checknumber(L, 1);
|
||||||
const UC *input = (UC *) checklstring(L, 2, &size);
|
const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size);
|
||||||
const UC *last = input + size;
|
const UC *last = input + size;
|
||||||
int length = (int) luaL_optnumber(L, 3, 76);
|
int length = (int) luaL_optnumber(L, 3, 76);
|
||||||
luaL_Buffer buffer;
|
luaL_Buffer buffer;
|
||||||
luaL_buffinit(L, &buffer);
|
luaL_buffinit(L, &buffer);
|
||||||
while (input < last) {
|
while (input < last) {
|
||||||
left--;
|
|
||||||
switch (*input) {
|
switch (*input) {
|
||||||
case '=':
|
|
||||||
/* if there's no room in this line for the quoted char,
|
|
||||||
* output a soft line break now */
|
|
||||||
if (left <= 3) {
|
|
||||||
luaL_addstring(&buffer, EQCRLF);
|
|
||||||
left = length;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* \r\n starts a new line */
|
|
||||||
case CR:
|
case CR:
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
left = length;
|
left = length;
|
||||||
|
luaL_addstring(&buffer, CRLF);
|
||||||
break;
|
break;
|
||||||
default:
|
case '=':
|
||||||
/* if in last column, output a soft line break */
|
if (left <= 3) {
|
||||||
if (left <= 1) {
|
|
||||||
luaL_addstring(&buffer, EQCRLF);
|
|
||||||
left = length;
|
left = length;
|
||||||
}
|
luaL_addstring(&buffer, EQCRLF);
|
||||||
}
|
}
|
||||||
luaL_putchar(&buffer, *input);
|
luaL_putchar(&buffer, *input);
|
||||||
|
left--;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (left <= 1) {
|
||||||
|
left = length;
|
||||||
|
luaL_addstring(&buffer, EQCRLF);
|
||||||
|
}
|
||||||
|
luaL_putchar(&buffer, *input);
|
||||||
|
left--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
input++;
|
input++;
|
||||||
}
|
}
|
||||||
|
/* if in last chunk and last line wasn't terminated, add a soft-break */
|
||||||
if (!input && left < length) {
|
if (!input && left < length) {
|
||||||
luaL_addstring(&buffer, EQCRLF);
|
luaL_addstring(&buffer, EQCRLF);
|
||||||
left = length;
|
left = length;
|
||||||
@ -579,10 +568,10 @@ static int mime_global_qpwrp(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Here is what we do: \n, \r and \f are considered candidates for line
|
* Here is what we do: \n, and \r are considered candidates for line
|
||||||
* break. We issue *one* new line marker if any of them is seen alone, or
|
* break. We issue *one* new line marker if any of them is seen alone, or
|
||||||
* followed by a different one. That is, \n\n, \r\r and \f\f will issue two
|
* followed by a different one. That is, \n\n and \r\r will issue two
|
||||||
* end of line markers each, but \r\n, \n\r, \r\f etc will only issue *one*
|
* end of line markers each, but \r\n, \n\r etc will only issue *one*
|
||||||
* marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as
|
* marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as
|
||||||
* probably other more obscure conventions.
|
* probably other more obscure conventions.
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
@ -616,21 +605,24 @@ static int mime_global_eol(lua_State *L)
|
|||||||
{
|
{
|
||||||
size_t asize = 0, isize = 0;
|
size_t asize = 0, isize = 0;
|
||||||
UC atom[2];
|
UC atom[2];
|
||||||
const UC *input = (UC *) checklstring(L, 1, &isize);
|
const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize);
|
||||||
const UC *last = input + isize;
|
const UC *last = input + isize;
|
||||||
const char *marker = luaL_optstring(L, 3, CRLF);
|
const char *marker = luaL_optstring(L, 3, CRLF);
|
||||||
luaL_Buffer buffer;
|
luaL_Buffer buffer;
|
||||||
luaL_buffinit(L, &buffer);
|
luaL_buffinit(L, &buffer);
|
||||||
while (input < last)
|
while (input < last)
|
||||||
asize = eolconvert(*input++, atom, asize, marker, &buffer);
|
asize = eolconvert(*input++, atom, asize, marker, &buffer);
|
||||||
input = (UC *) optlstring(L, 2, NULL, &isize);
|
input = (UC *) aux_optlstring(L, 2, NULL, &isize);
|
||||||
if (input) {
|
if (input) {
|
||||||
last = input + isize;
|
last = input + isize;
|
||||||
while (input < last)
|
while (input < last)
|
||||||
asize = eolconvert(*input++, atom, asize, marker, &buffer);
|
asize = eolconvert(*input++, atom, asize, marker, &buffer);
|
||||||
/* if there is something in atom, it's one character, and it
|
/* if there is something in atom, it's one character, and it
|
||||||
* is a candidate. so we output a new line */
|
* is a candidate. so we output a new line */
|
||||||
} else if (asize > 0) luaL_addstring(&buffer, marker);
|
} else if (asize > 0) {
|
||||||
|
luaL_addstring(&buffer, marker);
|
||||||
|
asize = 0;
|
||||||
|
}
|
||||||
luaL_pushresult(&buffer);
|
luaL_pushresult(&buffer);
|
||||||
lua_pushlstring(L, (char *) atom, asize);
|
lua_pushlstring(L, (char *) atom, asize);
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -12,6 +12,6 @@
|
|||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
|
||||||
void mime_open(lua_State *L);
|
int mime_open(lua_State *L);
|
||||||
|
|
||||||
#endif /* MIME_H */
|
#endif /* MIME_H */
|
||||||
|
83
src/mime.lua
83
src/mime.lua
@ -15,70 +15,57 @@ local et = {}
|
|||||||
local dt = {}
|
local dt = {}
|
||||||
local wt = {}
|
local wt = {}
|
||||||
|
|
||||||
-- creates a function that chooses an algorithm from a given table
|
-- creates a function that chooses a filter from a given table
|
||||||
local function choose(table)
|
local function choose(table)
|
||||||
return function(method, ...)
|
return function(filter, ...)
|
||||||
local f = table[method or "nil"]
|
local f = table[filter or "nil"]
|
||||||
if not f then error("unknown method (" .. tostring(method) .. ")", 3)
|
if not f then error("unknown filter (" .. tostring(filter) .. ")", 3)
|
||||||
else return f(unpack(arg)) end
|
else return f(unpack(arg)) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- creates a function that cicles a filter with a given initial
|
-- define the encoding filters
|
||||||
-- context and extra arguments
|
et['base64'] = function()
|
||||||
local function cicle(f, ctx, ...)
|
return socket.cicle(b64, "")
|
||||||
return function(chunk)
|
|
||||||
local ret
|
|
||||||
ret, ctx = f(ctx, chunk, unpack(arg))
|
|
||||||
return ret
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
et['quoted-printable'] = function(mode)
|
||||||
|
return socket.cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- define the decoding filters
|
||||||
|
dt['base64'] = function()
|
||||||
|
return socket.cicle(unb64, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
dt['quoted-printable'] = function()
|
||||||
|
return socket.cicle(unqp, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- define the line-wrap filters
|
||||||
|
wt['text'] = function(length)
|
||||||
|
length = length or 76
|
||||||
|
return socket.cicle(wrp, length, length)
|
||||||
|
end
|
||||||
|
wt['base64'] = wt['text']
|
||||||
|
|
||||||
|
wt['quoted-printable'] = function()
|
||||||
|
return socket.cicle(qpwrp, 76, 76)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- function that choose the encoding, decoding or wrap algorithm
|
-- function that choose the encoding, decoding or wrap algorithm
|
||||||
encode = choose(et)
|
encode = choose(et)
|
||||||
decode = choose(dt)
|
decode = choose(dt)
|
||||||
|
-- there is a default wrap filter
|
||||||
-- the wrap filter has default parameters
|
|
||||||
local cwt = choose(wt)
|
local cwt = choose(wt)
|
||||||
function wrap(...)
|
function wrap(...)
|
||||||
if not arg[1] or type(arg[1]) ~= "string" then
|
if type(arg[1]) ~= "string" then table.insert(arg, 1, "text") end
|
||||||
table.insert(arg, 1, "base64")
|
|
||||||
end
|
|
||||||
return cwt(unpack(arg))
|
return cwt(unpack(arg))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- define the encoding algorithms
|
-- define the end-of-line translation filter
|
||||||
et['base64'] = function()
|
|
||||||
return cicle(b64, "")
|
|
||||||
end
|
|
||||||
|
|
||||||
et['quoted-printable'] = function(mode)
|
|
||||||
return cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- define the decoding algorithms
|
|
||||||
dt['base64'] = function()
|
|
||||||
return cicle(unb64, "")
|
|
||||||
end
|
|
||||||
|
|
||||||
dt['quoted-printable'] = function()
|
|
||||||
return cicle(unqp, "")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- define the wrap algorithms
|
|
||||||
wt['base64'] = function(length, marker)
|
|
||||||
length = length or 76
|
|
||||||
return cicle(wrp, length, length, marker)
|
|
||||||
end
|
|
||||||
|
|
||||||
wt['quoted-printable'] = function(length)
|
|
||||||
length = length or 76
|
|
||||||
return cicle(qpwrp, length, length)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- define the end-of-line translation function
|
|
||||||
function canonic(marker)
|
function canonic(marker)
|
||||||
return cicle(eol, "", marker)
|
return socket.cicle(eol, "", marker)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- chains several filters together
|
-- chains several filters together
|
||||||
@ -104,4 +91,4 @@ function chain(...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return code
|
return mime
|
||||||
|
@ -42,7 +42,7 @@ static luaL_reg func[] = {
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes module
|
* Initializes module
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void select_open(lua_State *L)
|
int select_open(lua_State *L)
|
||||||
{
|
{
|
||||||
/* get select auxiliar lua function from lua code and register
|
/* get select auxiliar lua function from lua code and register
|
||||||
* pass it as an upvalue to global_select */
|
* pass it as an upvalue to global_select */
|
||||||
@ -54,6 +54,7 @@ void select_open(lua_State *L)
|
|||||||
luaL_openlib(L, LUASOCKET_LIBNAME, func, 1);
|
luaL_openlib(L, LUASOCKET_LIBNAME, func, 1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
aux_newclass(L, "select{fd_set}", set);
|
aux_newclass(L, "select{fd_set}", set);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
|
@ -15,6 +15,6 @@
|
|||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
|
|
||||||
void select_open(lua_State *L);
|
int select_open(lua_State *L);
|
||||||
|
|
||||||
#endif /* SELECT_H */
|
#endif /* SELECT_H */
|
||||||
|
@ -4,7 +4,7 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end
|
|||||||
local socket = _G[LUASOCKET_LIBNAME]
|
local socket = _G[LUASOCKET_LIBNAME]
|
||||||
if not socket then error('module requires LuaSocket') end
|
if not socket then error('module requires LuaSocket') end
|
||||||
-- create smtp namespace inside LuaSocket namespace
|
-- create smtp namespace inside LuaSocket namespace
|
||||||
local smtp = {}
|
local smtp = socket.smtp or {}
|
||||||
socket.smtp = smtp
|
socket.smtp = smtp
|
||||||
-- make all module globals fall into smtp namespace
|
-- make all module globals fall into smtp namespace
|
||||||
setmetatable(smtp, { __index = _G })
|
setmetatable(smtp, { __index = _G })
|
||||||
@ -18,6 +18,10 @@ DOMAIN = os.getenv("SERVER_NAME") or "localhost"
|
|||||||
-- default server used to send e-mails
|
-- default server used to send e-mails
|
||||||
SERVER = "localhost"
|
SERVER = "localhost"
|
||||||
|
|
||||||
|
function stuff()
|
||||||
|
return socket.cicle(dot, 2)
|
||||||
|
end
|
||||||
|
|
||||||
-- tries to get a pattern from the server and closes socket on error
|
-- tries to get a pattern from the server and closes socket on error
|
||||||
local function try_receiving(connection, pattern)
|
local function try_receiving(connection, pattern)
|
||||||
local data, message = connection:receive(pattern)
|
local data, message = connection:receive(pattern)
|
||||||
|
37
src/tcp.c
37
src/tcp.c
@ -39,25 +39,26 @@ static int meth_dirty(lua_State *L);
|
|||||||
|
|
||||||
/* tcp object methods */
|
/* tcp object methods */
|
||||||
static luaL_reg tcp[] = {
|
static luaL_reg tcp[] = {
|
||||||
{"connect", meth_connect},
|
{"__gc", meth_close},
|
||||||
{"send", meth_send},
|
|
||||||
{"receive", meth_receive},
|
|
||||||
{"bind", meth_bind},
|
|
||||||
{"listen", meth_listen},
|
|
||||||
{"accept", meth_accept},
|
{"accept", meth_accept},
|
||||||
{"setpeername", meth_connect},
|
{"bind", meth_bind},
|
||||||
{"setsockname", meth_bind},
|
{"close", meth_close},
|
||||||
|
{"connect", meth_connect},
|
||||||
|
{"dirty", meth_dirty},
|
||||||
|
{"getfd", meth_getfd},
|
||||||
{"getpeername", meth_getpeername},
|
{"getpeername", meth_getpeername},
|
||||||
{"getsockname", meth_getsockname},
|
{"getsockname", meth_getsockname},
|
||||||
{"settimeout", meth_settimeout},
|
{"listen", meth_listen},
|
||||||
{"close", meth_close},
|
{"receive", meth_receive},
|
||||||
{"shutdown", meth_shutdown},
|
{"send", meth_send},
|
||||||
{"setoption", meth_setoption},
|
|
||||||
{"__gc", meth_close},
|
|
||||||
{"getfd", meth_getfd},
|
|
||||||
{"setfd", meth_setfd},
|
{"setfd", meth_setfd},
|
||||||
{"dirty", meth_dirty},
|
{"setoption", meth_setoption},
|
||||||
|
{"setpeername", meth_connect},
|
||||||
|
{"setsockname", meth_bind},
|
||||||
|
{"settimeout", meth_settimeout},
|
||||||
|
{"shutdown", meth_shutdown},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* socket option handlers */
|
/* socket option handlers */
|
||||||
@ -78,7 +79,7 @@ static luaL_reg func[] = {
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes module
|
* Initializes module
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void tcp_open(lua_State *L)
|
int tcp_open(lua_State *L)
|
||||||
{
|
{
|
||||||
/* create classes */
|
/* create classes */
|
||||||
aux_newclass(L, "tcp{master}", tcp);
|
aux_newclass(L, "tcp{master}", tcp);
|
||||||
@ -96,6 +97,7 @@ void tcp_open(lua_State *L)
|
|||||||
/* define library functions */
|
/* define library functions */
|
||||||
luaL_openlib(L, LUASOCKET_LIBNAME, func, 0);
|
luaL_openlib(L, LUASOCKET_LIBNAME, func, 0);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
@ -250,7 +252,7 @@ static int meth_listen(lua_State *L)
|
|||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static int meth_shutdown(lua_State *L)
|
static int meth_shutdown(lua_State *L)
|
||||||
{
|
{
|
||||||
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
|
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client}", 1);
|
||||||
const char *how = luaL_optstring(L, 2, "both");
|
const char *how = luaL_optstring(L, 2, "both");
|
||||||
switch (how[0]) {
|
switch (how[0]) {
|
||||||
case 'b':
|
case 'b':
|
||||||
@ -266,7 +268,8 @@ static int meth_shutdown(lua_State *L)
|
|||||||
sock_shutdown(&tcp->sock, 0);
|
sock_shutdown(&tcp->sock, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
lua_pushnumber(L, 1);
|
||||||
|
return 1;
|
||||||
error:
|
error:
|
||||||
luaL_argerror(L, 2, "invalid shutdown method");
|
luaL_argerror(L, 2, "invalid shutdown method");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -31,6 +31,6 @@ typedef struct t_tcp_ {
|
|||||||
|
|
||||||
typedef t_tcp *p_tcp;
|
typedef t_tcp *p_tcp;
|
||||||
|
|
||||||
void tcp_open(lua_State *L);
|
int tcp_open(lua_State *L);
|
||||||
|
|
||||||
#endif /* TCP_H */
|
#endif /* TCP_H */
|
||||||
|
@ -141,10 +141,11 @@ int tm_gettime(void)
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes module
|
* Initializes module
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void tm_open(lua_State *L)
|
int tm_open(lua_State *L)
|
||||||
{
|
{
|
||||||
luaL_openlib(L, LUASOCKET_LIBNAME, func, 0);
|
luaL_openlib(L, LUASOCKET_LIBNAME, func, 0);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
|
@ -16,7 +16,7 @@ typedef struct t_tm_ {
|
|||||||
} t_tm;
|
} t_tm;
|
||||||
typedef t_tm *p_tm;
|
typedef t_tm *p_tm;
|
||||||
|
|
||||||
void tm_open(lua_State *L);
|
int tm_open(lua_State *L);
|
||||||
void tm_init(p_tm tm, int block, int total);
|
void tm_init(p_tm tm, int block, int total);
|
||||||
int tm_get(p_tm tm);
|
int tm_get(p_tm tm);
|
||||||
int tm_getretry(p_tm tm);
|
int tm_getretry(p_tm tm);
|
||||||
|
32
src/udp.c
32
src/udp.c
@ -30,7 +30,6 @@ static int meth_getpeername(lua_State *L);
|
|||||||
static int meth_setsockname(lua_State *L);
|
static int meth_setsockname(lua_State *L);
|
||||||
static int meth_setpeername(lua_State *L);
|
static int meth_setpeername(lua_State *L);
|
||||||
static int meth_close(lua_State *L);
|
static int meth_close(lua_State *L);
|
||||||
static int meth_shutdown(lua_State *L);
|
|
||||||
static int meth_setoption(lua_State *L);
|
static int meth_setoption(lua_State *L);
|
||||||
static int meth_settimeout(lua_State *L);
|
static int meth_settimeout(lua_State *L);
|
||||||
static int meth_getfd(lua_State *L);
|
static int meth_getfd(lua_State *L);
|
||||||
@ -49,7 +48,6 @@ static luaL_reg udp[] = {
|
|||||||
{"receivefrom", meth_receivefrom},
|
{"receivefrom", meth_receivefrom},
|
||||||
{"settimeout", meth_settimeout},
|
{"settimeout", meth_settimeout},
|
||||||
{"close", meth_close},
|
{"close", meth_close},
|
||||||
{"shutdown", meth_shutdown},
|
|
||||||
{"setoption", meth_setoption},
|
{"setoption", meth_setoption},
|
||||||
{"__gc", meth_close},
|
{"__gc", meth_close},
|
||||||
{"getfd", meth_getfd},
|
{"getfd", meth_getfd},
|
||||||
@ -79,7 +77,7 @@ static luaL_reg func[] = {
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes module
|
* Initializes module
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void udp_open(lua_State *L)
|
int udp_open(lua_State *L)
|
||||||
{
|
{
|
||||||
/* create classes */
|
/* create classes */
|
||||||
aux_newclass(L, "udp{connected}", udp);
|
aux_newclass(L, "udp{connected}", udp);
|
||||||
@ -92,6 +90,7 @@ void udp_open(lua_State *L)
|
|||||||
/* define library functions */
|
/* define library functions */
|
||||||
luaL_openlib(L, LUASOCKET_LIBNAME, func, 0);
|
luaL_openlib(L, LUASOCKET_LIBNAME, func, 0);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
@ -287,33 +286,6 @@ static int meth_close(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
|
||||||
* Shuts the connection down partially
|
|
||||||
\*-------------------------------------------------------------------------*/
|
|
||||||
static int meth_shutdown(lua_State *L)
|
|
||||||
{
|
|
||||||
p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1);
|
|
||||||
const char *how = luaL_optstring(L, 2, "both");
|
|
||||||
switch (how[0]) {
|
|
||||||
case 'b':
|
|
||||||
if (strcmp(how, "both")) goto error;
|
|
||||||
sock_shutdown(&udp->sock, 2);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
if (strcmp(how, "send")) goto error;
|
|
||||||
sock_shutdown(&udp->sock, 1);
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
if (strcmp(how, "receive")) goto error;
|
|
||||||
sock_shutdown(&udp->sock, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
error:
|
|
||||||
luaL_argerror(L, 2, "invalid shutdown method");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Turns a master object into a server object
|
* Turns a master object into a server object
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
|
@ -27,6 +27,6 @@ typedef struct t_udp_ {
|
|||||||
} t_udp;
|
} t_udp;
|
||||||
typedef t_udp *p_udp;
|
typedef t_udp *p_udp;
|
||||||
|
|
||||||
void udp_open(lua_State *L);
|
int udp_open(lua_State *L);
|
||||||
|
|
||||||
#endif /* UDP_H */
|
#endif /* UDP_H */
|
||||||
|
@ -12,7 +12,7 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end
|
|||||||
local socket = _G[LUASOCKET_LIBNAME]
|
local socket = _G[LUASOCKET_LIBNAME]
|
||||||
if not socket then error('module requires LuaSocket') end
|
if not socket then error('module requires LuaSocket') end
|
||||||
-- create smtp namespace inside LuaSocket namespace
|
-- create smtp namespace inside LuaSocket namespace
|
||||||
local url = {}
|
local url = socket.url or {}
|
||||||
socket.url = url
|
socket.url = url
|
||||||
-- make all module globals fall into smtp namespace
|
-- make all module globals fall into smtp namespace
|
||||||
setmetatable(url, { __index = _G })
|
setmetatable(url, { __index = _G })
|
||||||
|
@ -70,12 +70,10 @@ int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, int timeout)
|
|||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_create(p_sock ps, int domain, int type, int protocol)
|
const char *sock_create(p_sock ps, int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
int val = 1;
|
|
||||||
t_sock sock = socket(domain, type, protocol);
|
t_sock sock = socket(domain, type, protocol);
|
||||||
if (sock == SOCK_INVALID) return sock_createstrerror(errno);
|
if (sock == SOCK_INVALID) return sock_createstrerror(errno);
|
||||||
*ps = sock;
|
*ps = sock;
|
||||||
sock_setnonblocking(ps);
|
sock_setnonblocking(ps);
|
||||||
setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val));
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,13 +165,14 @@ const char *sock_accept(p_sock ps, p_sock pa, SA *addr,
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
int err;
|
int err;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
|
/* try to accept */
|
||||||
*pa = accept(sock, addr, addr_len);
|
*pa = accept(sock, addr, addr_len);
|
||||||
/* if result is valid, we are done */
|
/* if result is valid, we are done */
|
||||||
if (*pa != SOCK_INVALID) return NULL;
|
if (*pa != SOCK_INVALID) return NULL;
|
||||||
/* find out if we failed for a fatal reason */
|
/* find out if we failed for a fatal reason */
|
||||||
if (errno != EWOULDBLOCK && errno != ECONNABORTED)
|
if (errno != EWOULDBLOCK && errno != ECONNABORTED)
|
||||||
return sock_acceptstrerror(errno);
|
return sock_acceptstrerror(errno);
|
||||||
/* call select just to avoid busy-wait. */
|
/* call select to avoid busy-wait. */
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(sock, &fds);
|
FD_SET(sock, &fds);
|
||||||
do err = sock_select(sock+1, &fds, NULL, NULL, tm_getretry(tm));
|
do err = sock_select(sock+1, &fds, NULL, NULL, tm_getretry(tm));
|
||||||
|
@ -75,12 +75,10 @@ void sock_shutdown(p_sock ps, int how)
|
|||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_create(p_sock ps, int domain, int type, int protocol)
|
const char *sock_create(p_sock ps, int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
int val = 1;
|
|
||||||
t_sock sock = socket(domain, type, protocol);
|
t_sock sock = socket(domain, type, protocol);
|
||||||
if (sock == SOCK_INVALID)
|
if (sock == SOCK_INVALID)
|
||||||
return sock_createstrerror(WSAGetLastError());
|
return sock_createstrerror(WSAGetLastError());
|
||||||
*ps = sock;
|
*ps = sock;
|
||||||
setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val));
|
|
||||||
sock_setnonblocking(ps);
|
sock_setnonblocking(ps);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -112,8 +110,12 @@ const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm)
|
|||||||
/* if was in efds, we failed */
|
/* if was in efds, we failed */
|
||||||
if (FD_ISSET(sock, &efds)) {
|
if (FD_ISSET(sock, &efds)) {
|
||||||
int why, len = sizeof(why);
|
int why, len = sizeof(why);
|
||||||
|
/* give windows time to set the error (disgusting) */
|
||||||
|
Sleep(0);
|
||||||
/* find out why we failed */
|
/* find out why we failed */
|
||||||
getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&why, &len);
|
getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&why, &len);
|
||||||
|
/* we KNOW there was an error. if why is 0, we will return
|
||||||
|
* "unknown error", but it's not really our fault */
|
||||||
return sock_connectstrerror(why);
|
return sock_connectstrerror(why);
|
||||||
/* otherwise it must be in wfds, so we succeeded */
|
/* otherwise it must be in wfds, so we succeeded */
|
||||||
} else return NULL;
|
} else return NULL;
|
||||||
|
@ -181,6 +181,19 @@ local function compare_b64test()
|
|||||||
compare(b64test, db64test)
|
compare(b64test, db64test)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function identity_test()
|
||||||
|
local chain = socket.mime.chain(
|
||||||
|
socket.mime.encode("quoted-printable"),
|
||||||
|
socket.mime.encode("base64"),
|
||||||
|
socket.mime.decode("base64"),
|
||||||
|
socket.mime.decode("quoted-printable")
|
||||||
|
)
|
||||||
|
transform(b64test, eb64test, chain)
|
||||||
|
compare(b64test, eb64test)
|
||||||
|
os.remove(eb64test)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local function padcheck(original, encoded)
|
local function padcheck(original, encoded)
|
||||||
local e = (socket.mime.b64(original))
|
local e = (socket.mime.b64(original))
|
||||||
local d = (socket.mime.unb64(encoded))
|
local d = (socket.mime.unb64(encoded))
|
||||||
@ -233,4 +246,6 @@ compare_b64test()
|
|||||||
cleanup_b64test()
|
cleanup_b64test()
|
||||||
padding_b64test()
|
padding_b64test()
|
||||||
|
|
||||||
|
identity_test()
|
||||||
|
|
||||||
print(string.format("done in %.2fs", socket.time() - t))
|
print(string.format("done in %.2fs", socket.time() - t))
|
||||||
|
@ -3,18 +3,18 @@ port = port or "8080"
|
|||||||
|
|
||||||
function pass(...)
|
function pass(...)
|
||||||
local s = string.format(unpack(arg))
|
local s = string.format(unpack(arg))
|
||||||
io.write(s, "\n")
|
io.stderr:write(s, "\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
function fail(...)
|
function fail(...)
|
||||||
local s = string.format(unpack(arg))
|
local s = string.format(unpack(arg))
|
||||||
io.write("ERROR: ", s, "!\n")
|
io.stderr:write("ERROR: ", s, "!\n")
|
||||||
os.exit()
|
os.exit()
|
||||||
end
|
end
|
||||||
|
|
||||||
function warn(...)
|
function warn(...)
|
||||||
local s = string.format(unpack(arg))
|
local s = string.format(unpack(arg))
|
||||||
io.write("WARNING: ", s, "\n")
|
io.stderr:write("WARNING: ", s, "\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
pad = string.rep(" ", 8192)
|
pad = string.rep(" ", 8192)
|
||||||
@ -29,7 +29,7 @@ function remote(...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function test(test)
|
function test(test)
|
||||||
io.write("----------------------------------------------\n",
|
io.stderr:write("----------------------------------------------\n",
|
||||||
"testing: ", test, "\n",
|
"testing: ", test, "\n",
|
||||||
"----------------------------------------------\n")
|
"----------------------------------------------\n")
|
||||||
end
|
end
|
||||||
@ -72,14 +72,14 @@ if not socket.debug then
|
|||||||
fail("Please define LUASOCKET_DEBUG and recompile LuaSocket")
|
fail("Please define LUASOCKET_DEBUG and recompile LuaSocket")
|
||||||
end
|
end
|
||||||
|
|
||||||
io.write("----------------------------------------------\n",
|
io.stderr:write("----------------------------------------------\n",
|
||||||
"LuaSocket Test Procedures\n",
|
"LuaSocket Test Procedures\n",
|
||||||
"----------------------------------------------\n")
|
"----------------------------------------------\n")
|
||||||
|
|
||||||
start = socket.time()
|
start = socket.time()
|
||||||
|
|
||||||
function reconnect()
|
function reconnect()
|
||||||
io.write("attempting data connection... ")
|
io.stderr:write("attempting data connection... ")
|
||||||
if data then data:close() end
|
if data then data:close() end
|
||||||
remote [[
|
remote [[
|
||||||
if data then data:close() data = nil end
|
if data then data:close() data = nil end
|
||||||
@ -348,7 +348,7 @@ end
|
|||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
function accept_timeout()
|
function accept_timeout()
|
||||||
io.write("accept with timeout (if it hangs, it failed): ")
|
io.stderr:write("accept with timeout (if it hangs, it failed): ")
|
||||||
local s, e = socket.bind("*", 0, 0)
|
local s, e = socket.bind("*", 0, 0)
|
||||||
assert(s, e)
|
assert(s, e)
|
||||||
local t = socket.time()
|
local t = socket.time()
|
||||||
@ -364,7 +364,8 @@ end
|
|||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
function connect_timeout()
|
function connect_timeout()
|
||||||
io.write("connect with timeout (if it hangs, it failed): ")
|
io.stderr:write("connect with timeout (if it hangs, it failed): ")
|
||||||
|
local t = socket.time()
|
||||||
local c, e = socket.tcp()
|
local c, e = socket.tcp()
|
||||||
assert(c, e)
|
assert(c, e)
|
||||||
c:settimeout(0.1)
|
c:settimeout(0.1)
|
||||||
@ -380,16 +381,17 @@ end
|
|||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
function accept_errors()
|
function accept_errors()
|
||||||
io.write("not listening: ")
|
io.stderr:write("not listening: ")
|
||||||
local d, e = socket.bind("*", 0)
|
local d, e = socket.bind("*", 0)
|
||||||
assert(d, e);
|
assert(d, e);
|
||||||
local c, e = socket.tcp();
|
local c, e = socket.tcp();
|
||||||
assert(c, e);
|
assert(c, e);
|
||||||
d:setfd(c:getfd())
|
d:setfd(c:getfd())
|
||||||
|
d:settimeout(2)
|
||||||
local r, e = d:accept()
|
local r, e = d:accept()
|
||||||
assert(not r and e == "not listening", e)
|
assert(not r and e == "not listening", e)
|
||||||
print("ok")
|
print("ok")
|
||||||
io.write("not supported: ")
|
io.stderr:write("not supported: ")
|
||||||
local c, e = socket.udp()
|
local c, e = socket.udp()
|
||||||
assert(c, e);
|
assert(c, e);
|
||||||
d:setfd(c:getfd())
|
d:setfd(c:getfd())
|
||||||
@ -400,11 +402,11 @@ end
|
|||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
function connect_errors()
|
function connect_errors()
|
||||||
io.write("connection refused: ")
|
io.stderr:write("connection refused: ")
|
||||||
local c, e = socket.connect("localhost", 1);
|
local c, e = socket.connect("localhost", 1);
|
||||||
assert(not c and e == "connection refused", e)
|
assert(not c and e == "connection refused", e)
|
||||||
print("ok")
|
print("ok")
|
||||||
io.write("host not found: ")
|
io.stderr:write("host not found: ")
|
||||||
local c, e = socket.connect("not.exist.com", 1);
|
local c, e = socket.connect("not.exist.com", 1);
|
||||||
assert(not c and e == "host not found", e)
|
assert(not c and e == "host not found", e)
|
||||||
print("ok")
|
print("ok")
|
||||||
@ -534,7 +536,7 @@ test_raw(1)
|
|||||||
test("non-blocking transfer")
|
test("non-blocking transfer")
|
||||||
reconnect()
|
reconnect()
|
||||||
-- the value is not important, we only want
|
-- the value is not important, we only want
|
||||||
-- to test non-blockin I/O anyways
|
-- to test non-blocking I/O anyways
|
||||||
data:settimeout(200)
|
data:settimeout(200)
|
||||||
test_raw(1)
|
test_raw(1)
|
||||||
test_raw(17)
|
test_raw(17)
|
||||||
|
@ -35,8 +35,6 @@ local check_parse_path = function(path, expect)
|
|||||||
for i = 1, math.max(table.getn(parsed), table.getn(expect)) do
|
for i = 1, math.max(table.getn(parsed), table.getn(expect)) do
|
||||||
if parsed[i] ~= expect[i] then
|
if parsed[i] ~= expect[i] then
|
||||||
print(path)
|
print(path)
|
||||||
write("segment: ", i, " = '", Code.hexa(tostring(parsed[i])),
|
|
||||||
"' but expected '", Code.hexa(tostring(expect[i])), "'\n")
|
|
||||||
exit()
|
exit()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user