diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-02-04 14:29:11 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-02-04 14:29:11 +0000 |
commit | 0b2542d1a61fc5425ff65ab3dbf7ba7de174763f (patch) | |
tree | 8a6188e11db0c9ef6891c31e8a1bebca050b23b2 | |
parent | f67864f86c7d703325e86b14d0ba33992c52891b (diff) | |
download | luasocket-0b2542d1a61fc5425ff65ab3dbf7ba7de174763f.tar.gz luasocket-0b2542d1a61fc5425ff65ab3dbf7ba7de174763f.tar.bz2 luasocket-0b2542d1a61fc5425ff65ab3dbf7ba7de174763f.zip |
Worked on the manual.
Implemented stuffing (needs test)
Added cddb and qp examples.
-rw-r--r-- | TODO | 62 | ||||
-rw-r--r-- | doc/callback.html | 158 | ||||
-rw-r--r-- | doc/dns.html | 19 | ||||
-rw-r--r-- | doc/http.html | 2 | ||||
-rw-r--r-- | doc/index.html | 18 | ||||
-rw-r--r-- | doc/reference.html | 8 | ||||
-rw-r--r-- | doc/tcp.html | 148 | ||||
-rw-r--r-- | doc/url.html | 44 | ||||
-rw-r--r-- | etc/qp.lua | 18 | ||||
-rw-r--r-- | samples/cddb.lua | 43 | ||||
-rw-r--r-- | src/auxiliar.c | 14 | ||||
-rw-r--r-- | src/auxiliar.h | 3 | ||||
-rw-r--r-- | src/buffer.c | 3 | ||||
-rw-r--r-- | src/buffer.h | 2 | ||||
-rw-r--r-- | src/ftp.lua | 2 | ||||
-rw-r--r-- | src/http.lua | 2 | ||||
-rw-r--r-- | src/inet.c | 9 | ||||
-rw-r--r-- | src/inet.h | 2 | ||||
-rw-r--r-- | src/luasocket.c | 50 | ||||
-rw-r--r-- | src/mime.c | 138 | ||||
-rw-r--r-- | src/mime.h | 2 | ||||
-rw-r--r-- | src/mime.lua | 71 | ||||
-rw-r--r-- | src/select.c | 3 | ||||
-rw-r--r-- | src/select.h | 2 | ||||
-rw-r--r-- | src/smtp.lua | 6 | ||||
-rw-r--r-- | src/tcp.c | 33 | ||||
-rw-r--r-- | src/tcp.h | 2 | ||||
-rw-r--r-- | src/timeout.c | 3 | ||||
-rw-r--r-- | src/timeout.h | 2 | ||||
-rw-r--r-- | src/udp.c | 32 | ||||
-rw-r--r-- | src/udp.h | 2 | ||||
-rw-r--r-- | src/url.lua | 2 | ||||
-rw-r--r-- | src/usocket.c | 5 | ||||
-rw-r--r-- | src/wsocket.c | 6 | ||||
-rw-r--r-- | test/mimetest.lua | 15 | ||||
-rw-r--r-- | test/testclnt.lua | 28 | ||||
-rw-r--r-- | test/urltest.lua | 2 |
37 files changed, 639 insertions, 322 deletions
@@ -1,7 +1,36 @@ | |||
1 | * should be interrupt-safe | ||
2 | * notice the change in callback conventions | ||
3 | * new mime module replacing old code module (faster, more functionality) | ||
4 | * new socket options (many) | ||
5 | * only allocate in case of success | ||
6 | * optimize for success (only call select if fails) | ||
7 | * add proxy support to http | ||
8 | * add gethostname | ||
9 | * local connect | ||
10 | * connect with timeout | ||
11 | * change code to mime | ||
12 | * change stay to redirect | ||
13 | * add shutdown | ||
14 | * change send/recv to avoid using select | ||
15 | * O location do "redirect" pode ser relativo ao servidor atual (não pode, | ||
16 | mas os servidores fazem merda...) | ||
17 | * Ajeitar para Lua 5.0 | ||
18 | * Padronizar os retornos de funccao | ||
19 | * Separar as classes em arquivos | ||
20 | * Retorno de sendto em datagram sockets pode ser refused | ||
21 | |||
22 | |||
23 | check garbage collection in test*.lua | ||
24 | pop3??? | ||
25 | |||
26 | add socket.TIMEOUT to be default timeout? | ||
27 | |||
1 | manual | 28 | manual |
29 | add socket.connect and socket.bind to the manual | ||
30 | say what a nil callback does for http | ||
2 | check all occurences of it's | 31 | check all occurences of it's |
3 | add shutdown | 32 | - add shutdown |
4 | add gethostname | 33 | - add gethostname |
5 | the need of a content-length header in the post method... | 34 | the need of a content-length header in the post method... |
6 | notice the change in callback conventions | 35 | notice the change in callback conventions |
7 | the callback.lua module and the new mime module. | 36 | the callback.lua module and the new mime module. |
@@ -9,11 +38,11 @@ manual | |||
9 | add timeout and proxy to request table | 38 | add timeout and proxy to request table |
10 | change stay to redirect | 39 | change stay to redirect |
11 | socket.time and socket.sleep | 40 | socket.time and socket.sleep |
12 | connect with timeout | 41 | - connect with timeout |
13 | local connect | 42 | local connect |
14 | add thanks to 'carlos cassino' and 'david burgess' | 43 | add thanks to 'carlos cassino' and 'david burgess' |
15 | add new ip- options and reuseaddr option | 44 | add new ip- options and reuseaddr option |
16 | add listen to manual | 45 | - add listen to manual |
17 | bind method doesn't do listen anymore | 46 | bind method doesn't do listen anymore |
18 | bind doesn't turn an object into a server object: listen does. | 47 | bind doesn't turn an object into a server object: listen does. |
19 | 48 | ||
@@ -23,6 +52,9 @@ tests | |||
23 | checar garbage collection | 52 | checar garbage collection |
24 | check for interrupts | 53 | check for interrupts |
25 | 54 | ||
55 | wrp can't break lines in the middle of a line break. | ||
56 | call select before accept, not after, dumbass! | ||
57 | get rid of setnonblocking/setblocking in the bind function | ||
26 | close has to block... | 58 | close has to block... |
27 | fmt is not a good name | 59 | fmt is not a good name |
28 | change wrap() to accept a number and default to "character" | 60 | change wrap() to accept a number and default to "character" |
@@ -76,30 +108,10 @@ Ajeitar o protocolo da luaopen_socket()... sei lá qual é. | |||
76 | 108 | ||
77 | - adicionar exemplos de expansão: pipe, local, named pipe | 109 | - adicionar exemplos de expansão: pipe, local, named pipe |
78 | 110 | ||
79 | * should be interrupt-safe | ||
80 | * notice the change in callback conventions | ||
81 | * new mime module replacing old code module (faster, more functionality) | ||
82 | * new socket options (many) | ||
83 | * only allocate in case of success | ||
84 | * optimize for success (only call select if fails) | ||
85 | * add proxy support to http | ||
86 | * add gethostname | ||
87 | * local connect | ||
88 | * connect with timeout | ||
89 | * change code to mime | ||
90 | * change stay to redirect | ||
91 | * add shutdown | ||
92 | * change send/recv to avoid using select | ||
93 | * O location do "redirect" pode ser relativo ao servidor atual (não pode, | ||
94 | mas os servidores fazem merda...) | ||
95 | * Ajeitar para Lua 5.0 | ||
96 | * Padronizar os retornos de funccao | ||
97 | * Separar as classes em arquivos | ||
98 | * Retorno de sendto em datagram sockets pode ser refused | ||
99 | 111 | ||
100 | - Fazer compilar com g++ | 112 | - Fazer compilar com g++ |
101 | - Thread-safe | 113 | - Thread-safe |
102 | - proteger gethostby*.* com um mutex GLOBAL! | 114 | - proteger get*by*.* com um mutex GLOBAL! |
103 | - proteger ou atomizar o conjunto (timedout, receive), (timedout, send) | 115 | - proteger ou atomizar o conjunto (timedout, receive), (timedout, send) |
104 | - inet_ntoa também é uma merda. | 116 | - inet_ntoa também é uma merda. |
105 | - SSL | 117 | - SSL |
diff --git a/doc/callback.html b/doc/callback.html index 94af8ff..98b4476 100644 --- a/doc/callback.html +++ b/doc/callback.html | |||
@@ -31,16 +31,16 @@ | |||
31 | <hr> | 31 | <hr> |
32 | </div> | 32 | </div> |
33 | 33 | ||
34 | <!-- stream ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 34 | <!-- stream ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
35 | 35 | ||
36 | <h2 id=stream>Streaming with Callbacks</h2> | 36 | <h2 id=stream>Callbacks</h2> |
37 | 37 | ||
38 | <p> | 38 | <p> |
39 | HTTP, FTP, and SMTP transfers sometimes involve large amounts of | 39 | HTTP, FTP, and SMTP transfers sometimes involve large amounts of |
40 | information. Sometimes an application needs to generate outgoing data | 40 | information. Sometimes an application needs to generate outgoing data |
41 | in real time, or needs to process incoming information as it is being | 41 | in real time, or needs to process incoming information as it is being |
42 | received. To address these problems, LuaSocket allows HTTP and SMTP message | 42 | received. To address these problems, LuaSocket allows HTTP and SMTP message |
43 | bodies and FTP file contents to be received or sent through the | 43 | bodies and FTP file contents to be streamed through the |
44 | callback mechanism outlined below. | 44 | callback mechanism outlined below. |
45 | </p> | 45 | </p> |
46 | 46 | ||
@@ -52,7 +52,7 @@ chunks of data, as the data becomes available. Conversely, the <em>send | |||
52 | callback</em> mechanism can be used when the application wants to incrementally provide LuaSocket with the data to be sent. | 52 | callback</em> mechanism can be used when the application wants to incrementally provide LuaSocket with the data to be sent. |
53 | </p> | 53 | </p> |
54 | 54 | ||
55 | <!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 55 | <!-- receive +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
56 | 56 | ||
57 | <p class=name id=receive> | 57 | <p class=name id=receive> |
58 | <b>receive_cb(</b>chunk, err<b>)</b> | 58 | <b>receive_cb(</b>chunk, err<b>)</b> |
@@ -60,7 +60,7 @@ callback</em> mechanism can be used when the application wants to incrementally | |||
60 | 60 | ||
61 | <p class=description> | 61 | <p class=description> |
62 | A receive callback will be repeatedly called by | 62 | A receive callback will be repeatedly called by |
63 | LuaSocket wheneve new data is available. Each time it is called, the | 63 | LuaSocket whenever new data is available. Each time it is called, the |
64 | callback receives successive chunks of downloaded data. | 64 | callback receives successive chunks of downloaded data. |
65 | </p> | 65 | </p> |
66 | 66 | ||
@@ -113,10 +113,129 @@ Together, these two modules provide a powerful interface to send and | |||
113 | receive information. | 113 | receive information. |
114 | </p> | 114 | </p> |
115 | 115 | ||
116 | <!-- done +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
117 | |||
118 | <p class=name id=done> | ||
119 | socket.callback.<b>done()</b> | ||
120 | </p> | ||
121 | |||
122 | <p class=description> | ||
123 | This function creates and returns a callback that successfully terminates | ||
124 | the transmission. | ||
125 | </p> | ||
126 | |||
127 | <!-- fail +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
128 | |||
129 | <p class=name id=fail> | ||
130 | socket.callback.<b>fail(</b>message<b>)</b> | ||
131 | </p> | ||
132 | |||
133 | <p class=description> | ||
134 | This function creates and returns a callback that aborts the | ||
135 | transmission with a given error <tt>message</tt>. | ||
136 | </p> | ||
137 | |||
138 | <!-- receive.concat +++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
139 | |||
140 | <p class=name id=receive.concat> | ||
141 | socket.callback.<b>receive.concat(</b>cat<b>)</b> | ||
142 | </p> | ||
143 | |||
144 | <p class=description> | ||
145 | This function creates a receive callback that stores whatever it receives | ||
146 | into a concat object. When done, the application can get the contents | ||
147 | received as a single string, directly from the concat object. | ||
148 | </p> | ||
149 | |||
150 | <p class=parameters> | ||
151 | <tt>Cat</tt> is the target concat object, or <b><tt>nil</tt></b>. | ||
152 | If <tt>cat</tt> is <b><tt>nil</tt></b>, the function creates its own | ||
153 | concat object. | ||
154 | </p> | ||
155 | |||
156 | <p class=return> | ||
157 | The function returns a receive callback for the file, and the concat object | ||
158 | that will be used to store the received contents. | ||
159 | </p> | ||
160 | |||
161 | <!-- receive.file +++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
162 | |||
163 | <p class=name id=receive.file> | ||
164 | socket.callback.<b>receive.file(</b>file, io_err<b>)</b> | ||
165 | </p> | ||
166 | |||
167 | <p class=description> | ||
168 | This function creates a receive callback that stores whatever it receives | ||
169 | into a file. When done, the callback closes the file. | ||
170 | </p> | ||
171 | |||
172 | <p class=parameters> | ||
173 | <tt>File</tt> is a file handle opened for writing. If <tt>file</tt> is | ||
174 | <b><tt>nil</tt></b>, <tt>io_err</tt> can contain an error message. In this | ||
175 | case, the function returns a callback that just aborts | ||
176 | transmission with the error message. | ||
177 | </p> | ||
178 | |||
179 | <p class=return> | ||
180 | The function returns a receive callback for the file. | ||
181 | </p> | ||
182 | |||
183 | <p class=note> | ||
184 | Note: This function is designed so that it directly accepts the return | ||
185 | values of Lua's IO <tt>io.open</tt> library function. | ||
186 | </p> | ||
187 | |||
188 | <!-- receive.chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
189 | |||
190 | <p class=name id=receive.chain> | ||
191 | socket.callback.<b>receive.chain(</b>filter, receive_cb<b>)</b> | ||
192 | </p> | ||
193 | |||
194 | <p class=description> | ||
195 | This function creates a receive callback that passes all received data | ||
196 | through a filter, before handing it to a given receive callback. | ||
197 | </p> | ||
198 | |||
199 | <p class=parameters> | ||
200 | <tt>Cat</tt> is the target concat object, or <b><tt>nil</tt></b>. | ||
201 | If <tt>cat</tt> is <b><tt>nil</tt></b>, the function creates its own | ||
202 | concat object. | ||
203 | </p> | ||
204 | |||
205 | <p class=return> | ||
206 | The function returns a receive callback for the file, and the concat object | ||
207 | that will be used to store the received contents. | ||
208 | </p> | ||
209 | |||
210 | <p class=note> | ||
211 | Note: Several filters are defined in the <a href=mime.html>MIME</a> | ||
212 | module. Below is an example that creates a receive callback that | ||
213 | creates a string from the received contents, after decoding the | ||
214 | Quoted-Printable transfer content encoding. | ||
215 | </p> | ||
216 | |||
217 | <pre class=example> | ||
218 | string_cb, concat = socket.callback.receive.concat() | ||
219 | receive_cb = socket.callback.receive.chain( | ||
220 | socket.mime.decode("quoted-printable"), | ||
221 | string_cb | ||
222 | ) | ||
223 | </pre> | ||
224 | |||
225 | <p class=note> | ||
226 | The call to <tt>callback.chain</tt> creates a chained | ||
227 | receive callback that decodes data using the | ||
228 | <tt><a href=mime.html#decode>mime.decode</a></tt> | ||
229 | Quoted-Printable MIME filter and | ||
230 | hands the decoded data to a concat receive callback. | ||
231 | The concatenated decoded data can be retrieved later | ||
232 | from the associated concat object. | ||
233 | </p> | ||
234 | |||
116 | <!-- send.file ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 235 | <!-- send.file ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
117 | 236 | ||
118 | <p class=name id=send.file> | 237 | <p class=name id=send.file> |
119 | <b>send.file</b>(file, io_err<b>)</b> | 238 | socket.callback.<b>send.file(</b>file, io_err<b>)</b> |
120 | </p> | 239 | </p> |
121 | 240 | ||
122 | <p class=description> | 241 | <p class=description> |
@@ -126,25 +245,25 @@ When done, the callback closes the file. | |||
126 | </p> | 245 | </p> |
127 | 246 | ||
128 | <p class=parameters> | 247 | <p class=parameters> |
129 | <tt>File</tt> is a file opened for reading. If <tt>file</tt> is | 248 | <tt>File</tt> is a file handle opened for reading. If <tt>file</tt> is |
130 | <b><tt>nil</tt></b>, <tt>io_err</tt> can contain an error message. In this | 249 | <b><tt>nil</tt></b>, <tt>io_err</tt> can contain an error message. In this |
131 | case, the function returns a callback that just aborts | 250 | case, the function returns a callback that just aborts |
132 | transmission with the error message. | 251 | transmission with the error message. |
133 | </p> | 252 | </p> |
134 | 253 | ||
135 | <p class=return> | 254 | <p class=return> |
136 | Returns a send callback for the file. | 255 | The function returns a send callback for the file. |
137 | </p> | 256 | </p> |
138 | 257 | ||
139 | <p class=note> | 258 | <p class=note> |
140 | Note: This function is designed so that it directly accepts the return | 259 | Note: This function is designed so that it directly accepts the return |
141 | values of the <tt>io.open</tt> function. | 260 | values of Lua's IO <tt>io.open</tt> library function. |
142 | </p> | 261 | </p> |
143 | 262 | ||
144 | <!-- send.string ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 263 | <!-- send.string ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
145 | 264 | ||
146 | <p class=name id=send.string> | 265 | <p class=name id=send.string> |
147 | <b>send.string(</b>str, err<b>)</b> | 266 | socket.callback.<b>send.string(</b>str, err<b>)</b> |
148 | </p> | 267 | </p> |
149 | 268 | ||
150 | <p class=description> | 269 | <p class=description> |
@@ -154,26 +273,17 @@ the contents of a string. | |||
154 | 273 | ||
155 | <p class=parameters> | 274 | <p class=parameters> |
156 | <tt>Str</tt> is the string to be sent. | 275 | <tt>Str</tt> is the string to be sent. |
157 | <!-- | ||
158 | If <tt>str</tt> is | ||
159 | <b><tt>nil</tt></b>, <tt>err</tt> can optionally contain an error message. | ||
160 | --> | ||
161 | </p> | 276 | </p> |
162 | 277 | ||
163 | <p class=return> | 278 | <p class=return> |
164 | Returns a send callback for the string, or <b><tt>nil</tt></b> if the string is | 279 | It returns a send callback for the string, |
165 | <b><tt>nil</tt></b>. | 280 | or <b><tt>nil</tt></b> if <tt>str</tt> is <b><tt>nil</tt></b>. |
166 | </p> | ||
167 | |||
168 | <p class=note> | ||
169 | Note: A <tt>nil</tt></b> | ||
170 | send callback is equivalent to a callback that returns the empty string. | ||
171 | </p> | 281 | </p> |
172 | 282 | ||
173 | <!-- send.chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 283 | <!-- send.chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
174 | 284 | ||
175 | <p class=name id=send.chain> | 285 | <p class=name id=send.chain> |
176 | <b>send.chain(</b>send_cb, filter<b>)</b> | 286 | socket.callback.<b>send.chain(</b>send_cb, filter<b>)</b> |
177 | </p> | 287 | </p> |
178 | 288 | ||
179 | <p class=description> | 289 | <p class=description> |
@@ -207,9 +317,9 @@ send_cb = socket.callback.send.chain( | |||
207 | </pre> | 317 | </pre> |
208 | 318 | ||
209 | <p class=note> | 319 | <p class=note> |
210 | The call to <a href=mime.html#chain><tt>socket.mime.chain</tt></a> | 320 | The call to <a href=mime.html#chain><tt>mime.chain</tt></a> |
211 | creates a chained filter that encodes it's input and then breaks it | 321 | creates a chained filter that encodes it's input and then breaks it |
212 | into lines. The call to <tt>socket.callback.chain</tt> creates a chained | 322 | into lines. The call to <tt>callback.chain</tt> creates a chained |
213 | send callback that reads the file from disk and passes it through the | 323 | send callback that reads the file from disk and passes it through the |
214 | filter before sending it. | 324 | filter before sending it. |
215 | </p> | 325 | </p> |
diff --git a/doc/dns.html b/doc/dns.html index 17cee45..71a9719 100644 --- a/doc/dns.html +++ b/doc/dns.html | |||
@@ -36,8 +36,7 @@ | |||
36 | <h2 id=dns>DNS</h2> | 36 | <h2 id=dns>DNS</h2> |
37 | 37 | ||
38 | <p> | 38 | <p> |
39 | The following functions can be used to convert between host names and IP | 39 | Name resolution function return <em>all</em> information returned by the |
40 | addresses. Both functions return <em>all</em> information returned by the | ||
41 | resolver in a table of the form: | 40 | resolver in a table of the form: |
42 | </p> | 41 | </p> |
43 | 42 | ||
@@ -53,6 +52,21 @@ resolved = {<br> | |||
53 | Note that the <tt>alias</tt> list can be empty. | 52 | Note that the <tt>alias</tt> list can be empty. |
54 | </p> | 53 | </p> |
55 | 54 | ||
55 | <!-- gethostname ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
56 | |||
57 | <p class=name id=gethostname> | ||
58 | socket.dns.<b>gethostname()</b> | ||
59 | </p> | ||
60 | |||
61 | <p class=description> | ||
62 | Returns the standard host name for the machine. | ||
63 | </p> | ||
64 | |||
65 | <p class=return> | ||
66 | The function returns a string with the host name. | ||
67 | </p> | ||
68 | |||
69 | |||
56 | <!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 70 | <!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
57 | 71 | ||
58 | <p class=name id=tohostname> | 72 | <p class=name id=tohostname> |
@@ -74,7 +88,6 @@ the resolver. In case of error, the function returns <b><tt>nil</tt></b> | |||
74 | followed by an error message. | 88 | followed by an error message. |
75 | </p> | 89 | </p> |
76 | 90 | ||
77 | |||
78 | <!-- toip +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 91 | <!-- toip +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
79 | 92 | ||
80 | <p class=name id=toip> | 93 | <p class=name id=toip> |
diff --git a/doc/http.html b/doc/http.html index f977ea9..f82f515 100644 --- a/doc/http.html +++ b/doc/http.html | |||
@@ -49,7 +49,7 @@ implementation conforms to the HTTP/1.1 standard, | |||
49 | The module exports functions that provide HTTP functionality in different | 49 | The module exports functions that provide HTTP functionality in different |
50 | levels of abstraction, from a simple <a | 50 | levels of abstraction, from a simple <a |
51 | href="#get"><tt>get</tt></a>, to the generic, stream oriented | 51 | href="#get"><tt>get</tt></a>, to the generic, stream oriented |
52 | <a href="#request_cb"> <tt>request_cb</tt></a>. | 52 | <a href="#request_cb"><tt>request_cb</tt></a>. |
53 | </p> | 53 | </p> |
54 | 54 | ||
55 | <p> | 55 | <p> |
diff --git a/doc/index.html b/doc/index.html index 620f385..a2c2d59 100644 --- a/doc/index.html +++ b/doc/index.html | |||
@@ -40,7 +40,8 @@ LuaSocket is a <a href="http://www.lua.org">Lua</a> extension library | |||
40 | that is composed by two parts: a C layer that provides support for the TCP | 40 | that is composed by two parts: a C layer that provides support for the TCP |
41 | and UDP transport layers, and a set of Lua modules that add support for | 41 | and UDP transport layers, and a set of Lua modules that add support for |
42 | the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and | 42 | the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and |
43 | downloading files) protocols. | 43 | downloading files) protocols and other functionality commonly needed by |
44 | applications that deal with the Internet. | ||
44 | </p> | 45 | </p> |
45 | 46 | ||
46 | <p> | 47 | <p> |
@@ -106,10 +107,25 @@ This binary has been compiled with the <tt>LUASOCKET_DEBUG</tt> | |||
106 | option, and should be able to run the automatic test procedures. | 107 | option, and should be able to run the automatic test procedures. |
107 | </p> | 108 | </p> |
108 | 109 | ||
110 | <!-- thanks +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
111 | |||
112 | <h2 id=thanks>Special thanks</h2> | ||
113 | |||
114 | <p> | ||
115 | Throughout LuaSocket its history, many people gave sugestions that helped | ||
116 | improve it. For that, I thank the Lua comunity. | ||
117 | Special thanks go to | ||
118 | David Burgess, who has pushed the library to a new level of quality and | ||
119 | from whom I have learned a lot stuff that doesn't show up in RFCs. | ||
120 | Special thanks also to Carlos Cassino, who played a big part in the | ||
121 | extensible design seen in the C core of LuaSocket 2.0. | ||
122 | </p> | ||
123 | |||
109 | <!-- whatsnew +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 124 | <!-- whatsnew +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
110 | 125 | ||
111 | <h2 id=new>What's New</h2> | 126 | <h2 id=new>What's New</h2> |
112 | 127 | ||
128 | |||
113 | <p> | 129 | <p> |
114 | Most of the changes for 2.0 happened in the C layer, which | 130 | Most of the changes for 2.0 happened in the C layer, which |
115 | has been almost completely rewritten. The code has been ported to Lua 5.0 | 131 | has been almost completely rewritten. The code has been ported to Lua 5.0 |
diff --git a/doc/reference.html b/doc/reference.html index 0bfd378..e6efb6e 100644 --- a/doc/reference.html +++ b/doc/reference.html | |||
@@ -40,6 +40,10 @@ | |||
40 | <blockquote> | 40 | <blockquote> |
41 | <a href="callback.html">Callbacks (socket.callback)</a> | 41 | <a href="callback.html">Callbacks (socket.callback)</a> |
42 | <blockquote> | 42 | <blockquote> |
43 | <a href="callback.html#done">done</a>, | ||
44 | <a href="callback.html#fail">fail</a>. | ||
45 | </blockquote> | ||
46 | <blockquote> | ||
43 | <a href="callback.html#send">send</a>: | 47 | <a href="callback.html#send">send</a>: |
44 | <a href="callback.html#send.chain">chain</a>, | 48 | <a href="callback.html#send.chain">chain</a>, |
45 | <a href="callback.html#send.file">file</a>, | 49 | <a href="callback.html#send.file">file</a>, |
@@ -121,7 +125,7 @@ | |||
121 | <blockquote> | 125 | <blockquote> |
122 | <a href="mime.html">MIME (socket.mime) </a> | 126 | <a href="mime.html">MIME (socket.mime) </a> |
123 | <blockquote> | 127 | <blockquote> |
124 | <a href="mime.html#filters">filters</a>: | 128 | <a href="mime.html#high">high-level</a>: |
125 | <a href="mime.html#decode">canonic</a>, | 129 | <a href="mime.html#decode">canonic</a>, |
126 | <a href="mime.html#chain">chain</a>, | 130 | <a href="mime.html#chain">chain</a>, |
127 | <a href="mime.html#decode">decode</a>, | 131 | <a href="mime.html#decode">decode</a>, |
@@ -129,7 +133,7 @@ | |||
129 | <a href="mime.html#wrap">wrap</a>. | 133 | <a href="mime.html#wrap">wrap</a>. |
130 | </blockquote> | 134 | </blockquote> |
131 | <blockquote> | 135 | <blockquote> |
132 | <a href="mime.html#low-level">low-level</a>: | 136 | <a href="mime.html#low">low-level</a>: |
133 | <a href="mime.html#b64">b64</a>, | 137 | <a href="mime.html#b64">b64</a>, |
134 | <a href="mime.html#unb64">unb64</a>, | 138 | <a href="mime.html#unb64">unb64</a>, |
135 | <a href="mime.html#eol">eol</a>, | 139 | <a href="mime.html#eol">eol</a>, |
diff --git a/doc/tcp.html b/doc/tcp.html index eb4cdfa..34d6c6e 100644 --- a/doc/tcp.html +++ b/doc/tcp.html | |||
@@ -44,10 +44,11 @@ socket.<b>tcp()</b> | |||
44 | <p class=description> | 44 | <p class=description> |
45 | Creates and returns a TCP master object. A master object can | 45 | Creates and returns a TCP master object. A master object can |
46 | be transformed into a server object with the method | 46 | be transformed into a server object with the method |
47 | <a href=#bind><tt>bind</tt></a> or into a client object with the method | 47 | <a href=#listen><tt>listen</tt></a> (after a call to <a |
48 | <a href=#connect><tt>connect</tt></a>. The only other method | 48 | href=#bind><tt>bind</tt></a>) or into a client object with |
49 | supported by a master object is the <a href=#close><tt>close</tt></a> | 49 | the method <a href=#connect><tt>connect</tt></a>. The only other |
50 | method.</p> | 50 | method supported by a master object is the |
51 | <a href=#close><tt>close</tt></a> method.</p> | ||
51 | 52 | ||
52 | <p class=return> | 53 | <p class=return> |
53 | In case of success, a new master object is returned. In case of error, | 54 | 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. | |||
67 | 68 | ||
68 | <p class=return> | 69 | <p class=return> |
69 | If a connection is successfully initiated, a client object is returned. | 70 | If a connection is successfully initiated, a client object is returned. |
70 | If a timeout condition is met, the method returns <b><tt>nil</tt></b> followed | 71 | If a timeout condition is met, the method returns <b><tt>nil</tt></b> |
71 | by the error string '<tt>timeout</tt>'. | 72 | followed by the error string '<tt>timeout</tt>'. Other errors are |
73 | reported by <b><tt>nil</tt></b> followed by a message describing the error. | ||
72 | </p> | 74 | </p> |
73 | 75 | ||
74 | <p class=note> | 76 | <p class=note> |
@@ -77,25 +79,18 @@ with a server object in | |||
77 | the <tt>receive</tt> parameter before a call to <tt>accept</tt> does | 79 | the <tt>receive</tt> parameter before a call to <tt>accept</tt> does |
78 | <em>not</em> guarantee <tt>accept</tt> will return immediately. Use the <a | 80 | <em>not</em> guarantee <tt>accept</tt> will return immediately. Use the <a |
79 | href=#settimeout><tt>settimeout</tt></a> method or <tt>accept</tt> | 81 | href=#settimeout><tt>settimeout</tt></a> method or <tt>accept</tt> |
80 | might block until <em>another</em> client shows up. | 82 | might block until <em>another</em> client shows up. |
81 | </p> | 83 | </p> |
82 | 84 | ||
83 | <!-- bind +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 85 | <!-- bind +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
84 | 86 | ||
85 | <p class=name id=bind> | 87 | <p class=name id=bind> |
86 | master:<b>bind(</b>address, port [, backlog]<b>)</b> | 88 | master:<b>bind(</b>address, port<b>)</b> |
87 | </p> | 89 | </p> |
88 | 90 | ||
89 | <p class=description> | 91 | <p class=description> |
90 | Binds a master object to <tt>address</tt> and <tt>port</tt> on the | 92 | Binds a master object to <tt>address</tt> and <tt>port</tt> on the |
91 | local host, transforming it into a server object. Server | 93 | local host. |
92 | objects support the | ||
93 | <a href=#accept><tt>accept</tt></a>, | ||
94 | <a href=#getsockname><tt>getsockname</tt></a>, | ||
95 | <a href=#setoption><tt>setoption</tt></a>, | ||
96 | <a href=#settimeout><tt>settimeout</tt></a>, | ||
97 | and <a href=#close><tt>close</tt></a> methods. | ||
98 | </p> | ||
99 | 94 | ||
100 | <p class=parameters> | 95 | <p class=parameters> |
101 | <tt>Address</tt> can be an IP address or a host name. | 96 | <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. | |||
103 | If <tt>address</tt> | 98 | If <tt>address</tt> |
104 | is '<tt>*</tt>', the system binds to all local interfaces | 99 | is '<tt>*</tt>', the system binds to all local interfaces |
105 | using the <tt>INADDR_ANY</tt> constant. If <tt>port</tt> is 0, the system automatically | 100 | using the <tt>INADDR_ANY</tt> constant. If <tt>port</tt> is 0, the system automatically |
106 | chooses an ephemeral port. The optional parameter <tt>backlog</tt>, which | 101 | chooses an ephemeral port. |
107 | defaults to 1, specifies the number of client connections that can | ||
108 | be queued waiting for service. If the queue is full and another client | ||
109 | attempts connection, the connection is refused. | ||
110 | </p> | 102 | </p> |
111 | 103 | ||
112 | <p class=return> | 104 | <p class=return> |
@@ -115,8 +107,8 @@ method returns <b><tt>nil</tt></b> followed by an error message. | |||
115 | </p> | 107 | </p> |
116 | 108 | ||
117 | <p class=note> | 109 | <p class=note> |
118 | Note: The function <tt>socket.bind</tt> is available and is a short | 110 | Note: The function <a href=#socket.bind><tt>socket.bind</tt></a> |
119 | for <a href=#socket.tcp><tt>socket.tcp</tt></a> followed by the <tt>bind</tt> method. | 111 | is available and is a shortcut for the creation server sockets. |
120 | </p> | 112 | </p> |
121 | 113 | ||
122 | <!-- close ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 114 | <!-- close ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
@@ -150,7 +142,8 @@ master:<b>connect(</b>address, port<b>)</b> | |||
150 | 142 | ||
151 | <p class=description> | 143 | <p class=description> |
152 | Attempts to connect a master object to a remote host, transforming it into a | 144 | Attempts to connect a master object to a remote host, transforming it into a |
153 | client object. Client objects support methods | 145 | client object. |
146 | Client objects support methods | ||
154 | <a href=#send><tt>send</tt></a>, | 147 | <a href=#send><tt>send</tt></a>, |
155 | <a href=#receive><tt>receive</tt></a>, | 148 | <a href=#receive><tt>receive</tt></a>, |
156 | <a href=#getsockname><tt>getsockname</tt></a>, | 149 | <a href=#getsockname><tt>getsockname</tt></a>, |
@@ -170,8 +163,15 @@ describing the error. In case of success, the method returns 1. | |||
170 | </p> | 163 | </p> |
171 | 164 | ||
172 | <p class=note> | 165 | <p class=note> |
173 | Note: The function <tt>socket.connect</tt> is available and is a short | 166 | Note: The function <a href=#socket.connect><tt>socket.connect</tt></a> |
174 | for <a href=#socket.tcp><tt>socket.tcp</tt></a> followed by the <tt>connect</tt> method. | 167 | is available and is a shortcut for the creation of client sockets. |
168 | </p> | ||
169 | |||
170 | <p class=note> | ||
171 | Note: Starting with LuaSocket 2.0, | ||
172 | the <a href=#settimeout><tt>settimeout</tt></a> | ||
173 | function affects the behavior of connect, causing it to return in case of | ||
174 | a timeout error. | ||
175 | </p> | 175 | </p> |
176 | 176 | ||
177 | <!-- getpeername ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 177 | <!-- getpeername ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
@@ -210,12 +210,32 @@ The method returns a string with local IP address and a number with | |||
210 | the port. In case of error, the method returns <b><tt>nil</tt></b>. | 210 | the port. In case of error, the method returns <b><tt>nil</tt></b>. |
211 | </p> | 211 | </p> |
212 | 212 | ||
213 | <p class=note> | 213 | <!-- listen ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
214 | Note: Naturally, for a server object, the address and port returned are | 214 | |
215 | those passed to the <a href=#bind>bind</a> method. If the port value | 215 | <p class=name id=listen> |
216 | passed to bind was 0, the OS assigned ephemeral port is returned. For | 216 | master:<b>listen(</b>backlog<b>)</b> |
217 | client objects, both the address and port are ephemeral and these are the | 217 | </p> |
218 | values returned. | 218 | |
219 | <p class=description> | ||
220 | Specifies the socket is willing to receive connections, transforming the | ||
221 | object into a server object. Server objects support the | ||
222 | <a href=#accept><tt>accept</tt></a>, | ||
223 | <a href=#getsockname><tt>getsockname</tt></a>, | ||
224 | <a href=#setoption><tt>setoption</tt></a>, | ||
225 | <a href=#settimeout><tt>settimeout</tt></a>, | ||
226 | and <a href=#close><tt>close</tt></a> methods. | ||
227 | </p> | ||
228 | |||
229 | <p class=parameters> | ||
230 | The parameter <tt>backlog</tt> specifies the number of client | ||
231 | connections that can | ||
232 | be queued waiting for service. If the queue is full and another client | ||
233 | attempts connection, the connection is refused. | ||
234 | </p> | ||
235 | |||
236 | <p class=return> | ||
237 | In case of success, the method returns 1. In case of error, the | ||
238 | method returns <b><tt>nil</tt></b> followed by an error message. | ||
219 | </p> | 239 | </p> |
220 | 240 | ||
221 | <!-- receive ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 241 | <!-- receive ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
@@ -242,8 +262,8 @@ closed. No end-of-line translation is performed; | |||
242 | terminated by a LF character (ASCII 10), optionally preceded by a | 262 | terminated by a LF character (ASCII 10), optionally preceded by a |
243 | CR character (ASCII 13). The CR and LF characters are not included in | 263 | CR character (ASCII 13). The CR and LF characters are not included in |
244 | the returned line. This is the default pattern; | 264 | the returned line. This is the default pattern; |
245 | <li> <tt>number</tt>: causes the method to read <tt>number</tt> raw | 265 | <li> <tt>number</tt>: causes the method to read a specified <tt>number</tt> |
246 | bytes from the socket. | 266 | of bytes from the socket. |
247 | </ul> | 267 | </ul> |
248 | 268 | ||
249 | <p class=return> | 269 | <p class=return> |
@@ -311,22 +331,30 @@ are sure you need it. | |||
311 | depends on the option being set: | 331 | depends on the option being set: |
312 | 332 | ||
313 | <ul> | 333 | <ul> |
314 | <li> '<tt>tcp-nodelay</tt>': Setting this option to <tt>true</tt> disables the | 334 | |
315 | Nagle's algorithm for the connection; | 335 | <li> '<tt>keepalive</tt>': Setting this option to <tt>true</tt> enables |
336 | the periodic transmission of messages on a connected socket. Should the | ||
337 | connected party fail to respond to these messages, the connection is | ||
338 | considered broken and processes using the socket are notified; | ||
339 | |||
316 | <li> '<tt>linger</tt>': Controls the action taken when unsent data are | 340 | <li> '<tt>linger</tt>': Controls the action taken when unsent data are |
317 | queued on a socket and a close is performed. The value is a table with a | 341 | queued on a socket and a close is performed. The value is a table with a |
318 | boolean entry '<tt>on</tt>' and a numeric entry for the time interval | 342 | boolean entry '<tt>on</tt>' and a numeric entry for the time interval |
319 | '<tt>timeout</tt>' in seconds. | 343 | '<tt>timeout</tt>' in seconds. If the '<tt>on</tt>' field is set to |
320 | If the '<tt>on</tt>' field is set to <tt>true</tt>, | 344 | <tt>true</tt>, the system will block the process on the close attempt until |
321 | the system will block the process on the close attempt until it is able to | 345 | it is able to transmit the data or until '<tt>timeout</tt>' has passed. If |
322 | transmit the data or until '<tt>timeout</tt>' has passed. If '<tt>on</tt>' | 346 | '<tt>on</tt>' is <tt>false</tt> and a close is issued, the system will |
323 | is <tt>false</tt> and a close is issued, the system will process the close | 347 | process the close in a manner that allows the process to continue as |
324 | in a manner that allows the process to continue as quickly as possible. I | 348 | quickly as possible. I do not advise you to set this to anything other than |
325 | do not advise you to set this to anything other than zero. | 349 | zero; |
326 | <li> '<tt>keepalive</tt>': Setting this option to <tt>true</tt> enables | 350 | |
327 | the periodic transmission of messages on a connected socket. Should the | 351 | <li> '<tt>reuseaddr</tt>': Setting this option indicates that the rules |
328 | connected party fail to respond to these messages, the connection is | 352 | used in validating addresses supplied in a call to |
329 | considered broken and processes using the socket are notified. | 353 | <a href=#bind><tt>bind</tt></a> should allow reuse of local addresses; |
354 | |||
355 | <li> '<tt>tcp-nodelay</tt>': Setting this option to <tt>true</tt> | ||
356 | disables the Nagle's algorithm for the connection. | ||
357 | |||
330 | </ul> | 358 | </ul> |
331 | 359 | ||
332 | <p class=return> | 360 | <p class=return> |
@@ -382,7 +410,9 @@ indefinitely. Negative timeout values have the same effect. | |||
382 | Note: although timeout values have millisecond precision in LuaSocket, | 410 | Note: although timeout values have millisecond precision in LuaSocket, |
383 | large blocks can cause I/O functions not to respect timeout values due | 411 | large blocks can cause I/O functions not to respect timeout values due |
384 | to the time the library takes to transfer blocks to and from the OS | 412 | to the time the library takes to transfer blocks to and from the OS |
385 | and to and from the Lua interpreter. | 413 | and to and from the Lua interpreter. Also, function that accept host names |
414 | and perform automatic name resolution might be blocked by the resolver for | ||
415 | longer than the specified timeout value. | ||
386 | </p> | 416 | </p> |
387 | 417 | ||
388 | <p class=note> | 418 | <p class=note> |
@@ -391,6 +421,30 @@ changed for sake of uniformity, since all other method names already | |||
391 | contained verbs making their imperative nature obvious. | 421 | contained verbs making their imperative nature obvious. |
392 | </p> | 422 | </p> |
393 | 423 | ||
424 | <!-- shutdown +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
425 | |||
426 | <p class=name id=shutdown> | ||
427 | client:<b>shutdown(</b>mode<b>)</b><br> | ||
428 | </p> | ||
429 | |||
430 | <p class=description> | ||
431 | Shuts down part of a full duplex connection. | ||
432 | </p> | ||
433 | |||
434 | <p class=parameters> | ||
435 | Mode tells which way of the connection should be shut down and can | ||
436 | take the value: | ||
437 | <ul> | ||
438 | <li>"<tt>both</tt>": disallow further sends and receives on the object. | ||
439 | This is the default mode; | ||
440 | <li>"<tt>send</tt>": disallow further sends on the object; | ||
441 | <li>"<tt>receive</tt>": disallow further receives on the object. | ||
442 | </ul> | ||
443 | |||
444 | <p class=return> | ||
445 | This function returns 1. | ||
446 | </p> | ||
447 | |||
394 | <!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 448 | <!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
395 | 449 | ||
396 | <div class=footer> | 450 | <div class=footer> |
diff --git a/doc/url.html b/doc/url.html index 0eafafa..f3a7cb7 100644 --- a/doc/url.html +++ b/doc/url.html | |||
@@ -241,6 +241,50 @@ returning a list with all the parsed segments, the function unescapes all | |||
241 | of them. | 241 | of them. |
242 | </p> | 242 | </p> |
243 | 243 | ||
244 | <!-- escape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
245 | |||
246 | <p class=name id="escape"> | ||
247 | socket.url.<b>escape(</b>content<b>)</b> | ||
248 | </p> | ||
249 | |||
250 | <p class=description> | ||
251 | Applies the URL escaping content coding to a string | ||
252 | Each byte is encoded as a percent character followed | ||
253 | by the two byte hexadecimal representation of its integer | ||
254 | value. | ||
255 | </p> | ||
256 | |||
257 | <p class=parameters> | ||
258 | <tt>Content</tt> is the string to be encoded. | ||
259 | </p> | ||
260 | |||
261 | <p class=result> | ||
262 | The function returns the encoded string. | ||
263 | </p> | ||
264 | |||
265 | <pre class=example> | ||
266 | code = socket.url.escape("/#?;") | ||
267 | -- code = "%2f%23%3f%3b" | ||
268 | </pre> | ||
269 | |||
270 | <!-- unescape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
271 | |||
272 | <p class=name id="unescape"> | ||
273 | socket.url.<b>unescape(</b>content<b>)</b> | ||
274 | </p> | ||
275 | |||
276 | <p class=description> | ||
277 | Removes the URL escaping content coding from a string. | ||
278 | </p> | ||
279 | |||
280 | <p class=parameters> | ||
281 | <tt>Content</tt> is the string to be decoded. | ||
282 | </p> | ||
283 | |||
284 | <p class=return> | ||
285 | The function returns the decoded string. | ||
286 | </p> | ||
287 | |||
244 | <!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 288 | <!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
245 | 289 | ||
246 | <div class=footer> | 290 | <div class=footer> |
diff --git a/etc/qp.lua b/etc/qp.lua new file mode 100644 index 0000000..23c834a --- /dev/null +++ b/etc/qp.lua | |||
@@ -0,0 +1,18 @@ | |||
1 | local convert | ||
2 | arg = arg or {} | ||
3 | local mode = arg and arg[1] or "-et" | ||
4 | if mode == "-et" then | ||
5 | local canonic = socket.mime.canonic() | ||
6 | local qp = socket.mime.encode("quoted-printable") | ||
7 | local wrap = socket.mime.wrap("quoted-printable") | ||
8 | convert = socket.mime.chain(canonic, qp, wrap) | ||
9 | elseif mode == "-eb" then | ||
10 | local qp = socket.mime.encode("quoted-printable", "binary") | ||
11 | local wrap = socket.mime.wrap("quoted-printable") | ||
12 | convert = socket.mime.chain(qp, wrap) | ||
13 | else convert = socket.mime.decode("quoted-printable") end | ||
14 | while 1 do | ||
15 | local chunk = io.read(4096) | ||
16 | io.write(convert(chunk)) | ||
17 | if not chunk then break end | ||
18 | end | ||
diff --git a/samples/cddb.lua b/samples/cddb.lua new file mode 100644 index 0000000..6ade3c0 --- /dev/null +++ b/samples/cddb.lua | |||
@@ -0,0 +1,43 @@ | |||
1 | if not arg or not arg[1] or not arg[2] then | ||
2 | print("luasocket cddb.lua <category> <disc-id> [<server>]") | ||
3 | os.exit(1) | ||
4 | end | ||
5 | |||
6 | local server = arg[3] or "http://freedb.freedb.org/~cddb/cddb.cgi" | ||
7 | |||
8 | function parse(body) | ||
9 | local lines = string.gfind(body, "(.-)\r\n") | ||
10 | local status = lines() | ||
11 | local _, _, code, message = string.find(status, "(%d%d%d) (.*)") | ||
12 | if tonumber(code) ~= 210 then | ||
13 | return nil, code, message | ||
14 | end | ||
15 | local data = {} | ||
16 | for l in lines do | ||
17 | local c = string.sub(l, 1, 1) | ||
18 | if c ~= '#' and c ~= '.' then | ||
19 | local _, _, key, value = string.find(l, "(.-)=(.*)") | ||
20 | value = string.gsub(value, "\\n", "\n") | ||
21 | value = string.gsub(value, "\\\\", "\\") | ||
22 | value = string.gsub(value, "\\t", "\t") | ||
23 | data[key] = value | ||
24 | end | ||
25 | end | ||
26 | return data, code, message | ||
27 | end | ||
28 | |||
29 | local host = socket.dns.gethostname() | ||
30 | local query = "%s?cmd=cddb+read+%s+%s&hello=LuaSocket+%s+LuaSocket+2.0&proto=6" | ||
31 | local url = string.format(query, server, arg[1], arg[2], host) | ||
32 | local body, headers, code, error = socket.http.get(url) | ||
33 | |||
34 | if code == 200 then | ||
35 | local data, code, error = parse(body) | ||
36 | if not data then | ||
37 | print(error or code) | ||
38 | else | ||
39 | for i,v in data do | ||
40 | io.write(i, ': ', v, '\n') | ||
41 | end | ||
42 | end | ||
43 | else print(error) end | ||
diff --git a/src/auxiliar.c b/src/auxiliar.c index 9a249b6..812d7fc 100644 --- a/src/auxiliar.c +++ b/src/auxiliar.c | |||
@@ -37,9 +37,9 @@ error: | |||
37 | /*-------------------------------------------------------------------------*\ | 37 | /*-------------------------------------------------------------------------*\ |
38 | * Initializes the module | 38 | * Initializes the module |
39 | \*-------------------------------------------------------------------------*/ | 39 | \*-------------------------------------------------------------------------*/ |
40 | void aux_open(lua_State *L) | 40 | int aux_open(lua_State *L) |
41 | { | 41 | { |
42 | ; | 42 | return 0; |
43 | } | 43 | } |
44 | 44 | ||
45 | /*-------------------------------------------------------------------------*\ | 45 | /*-------------------------------------------------------------------------*\ |
@@ -159,3 +159,13 @@ void *aux_getclassudata(lua_State *L, const char *classname, int objidx) | |||
159 | return luaL_checkudata(L, objidx, classname); | 159 | return luaL_checkudata(L, objidx, classname); |
160 | } | 160 | } |
161 | 161 | ||
162 | /*-------------------------------------------------------------------------*\ | ||
163 | * Accept "false" as nil | ||
164 | \*-------------------------------------------------------------------------*/ | ||
165 | const char *aux_optlstring(lua_State *L, int n, const char *v, size_t *l) | ||
166 | { | ||
167 | if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { | ||
168 | *l = 0; | ||
169 | return NULL; | ||
170 | } else return luaL_optlstring(L, n, v, l); | ||
171 | } | ||
diff --git a/src/auxiliar.h b/src/auxiliar.h index b98eb9c..ac62ecd 100644 --- a/src/auxiliar.h +++ b/src/auxiliar.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #define MAX(x, y) ((x) > (y) ? x : y) | 40 | #define MAX(x, y) ((x) > (y) ? x : y) |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | void aux_open(lua_State *L); | 43 | int aux_open(lua_State *L); |
44 | void aux_newclass(lua_State *L, const char *classname, luaL_reg *func); | 44 | void aux_newclass(lua_State *L, const char *classname, luaL_reg *func); |
45 | void aux_add2group(lua_State *L, const char *classname, const char *group); | 45 | void aux_add2group(lua_State *L, const char *classname, const char *group); |
46 | void aux_setclass(lua_State *L, const char *classname, int objidx); | 46 | 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); | |||
49 | void *aux_getclassudata(lua_State *L, const char *groupname, int objidx); | 49 | void *aux_getclassudata(lua_State *L, const char *groupname, int objidx); |
50 | void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx); | 50 | void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx); |
51 | int aux_checkboolean(lua_State *L, int objidx); | 51 | int aux_checkboolean(lua_State *L, int objidx); |
52 | const char *aux_optlstring(lua_State *L, int n, const char *v, size_t *l); | ||
52 | 53 | ||
53 | #endif /* AUX_H */ | 54 | #endif /* AUX_H */ |
diff --git a/src/buffer.c b/src/buffer.c index e6d4ce8..d9ba779 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
@@ -26,9 +26,10 @@ static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent); | |||
26 | /*-------------------------------------------------------------------------*\ | 26 | /*-------------------------------------------------------------------------*\ |
27 | * Initializes module | 27 | * Initializes module |
28 | \*-------------------------------------------------------------------------*/ | 28 | \*-------------------------------------------------------------------------*/ |
29 | void buf_open(lua_State *L) | 29 | int buf_open(lua_State *L) |
30 | { | 30 | { |
31 | (void) L; | 31 | (void) L; |
32 | return 0; | ||
32 | } | 33 | } |
33 | 34 | ||
34 | /*-------------------------------------------------------------------------*\ | 35 | /*-------------------------------------------------------------------------*\ |
diff --git a/src/buffer.h b/src/buffer.h index 12b90a0..4b7563f 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
@@ -34,7 +34,7 @@ typedef struct t_buf_ { | |||
34 | } t_buf; | 34 | } t_buf; |
35 | typedef t_buf *p_buf; | 35 | typedef t_buf *p_buf; |
36 | 36 | ||
37 | void buf_open(lua_State *L); | 37 | int buf_open(lua_State *L); |
38 | void buf_init(p_buf buf, p_io io, p_tm tm); | 38 | void buf_init(p_buf buf, p_io io, p_tm tm); |
39 | int buf_meth_send(lua_State *L, p_buf buf); | 39 | int buf_meth_send(lua_State *L, p_buf buf); |
40 | int buf_meth_receive(lua_State *L, p_buf buf); | 40 | int buf_meth_receive(lua_State *L, p_buf buf); |
diff --git a/src/ftp.lua b/src/ftp.lua index bfc4ece..e596416 100644 --- a/src/ftp.lua +++ b/src/ftp.lua | |||
@@ -649,3 +649,5 @@ function Public.get(url_or_request) | |||
649 | local err = Public.get_cb(request) | 649 | local err = Public.get_cb(request) |
650 | return concat:getresult(), err | 650 | return concat:getresult(), err |
651 | end | 651 | end |
652 | |||
653 | return ftp | ||
diff --git a/src/http.lua b/src/http.lua index 4d6e426..74c29ba 100644 --- a/src/http.lua +++ b/src/http.lua | |||
@@ -11,7 +11,7 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end | |||
11 | local socket = _G[LUASOCKET_LIBNAME] | 11 | local socket = _G[LUASOCKET_LIBNAME] |
12 | if not socket then error('module requires LuaSocket') end | 12 | if not socket then error('module requires LuaSocket') end |
13 | -- create smtp namespace inside LuaSocket namespace | 13 | -- create smtp namespace inside LuaSocket namespace |
14 | local http = {} | 14 | local http = socket.http or {} |
15 | socket.http = http | 15 | socket.http = http |
16 | -- make all module globals fall into smtp namespace | 16 | -- make all module globals fall into smtp namespace |
17 | setmetatable(http, { __index = _G }) | 17 | setmetatable(http, { __index = _G }) |
@@ -35,17 +35,10 @@ static luaL_reg func[] = { | |||
35 | /*-------------------------------------------------------------------------*\ | 35 | /*-------------------------------------------------------------------------*\ |
36 | * Initializes module | 36 | * Initializes module |
37 | \*-------------------------------------------------------------------------*/ | 37 | \*-------------------------------------------------------------------------*/ |
38 | void inet_open(lua_State *L) | 38 | int inet_open(lua_State *L) |
39 | { | 39 | { |
40 | lua_pushstring(L, LUASOCKET_LIBNAME); | 40 | lua_pushstring(L, LUASOCKET_LIBNAME); |
41 | lua_gettable(L, LUA_GLOBALSINDEX); | 41 | lua_gettable(L, LUA_GLOBALSINDEX); |
42 | if (lua_isnil(L, -1)) { | ||
43 | lua_pop(L, 1); | ||
44 | lua_newtable(L); | ||
45 | lua_pushstring(L, LUASOCKET_LIBNAME); | ||
46 | lua_pushvalue(L, -2); | ||
47 | lua_settable(L, LUA_GLOBALSINDEX); | ||
48 | } | ||
49 | lua_pushstring(L, "dns"); | 42 | lua_pushstring(L, "dns"); |
50 | lua_newtable(L); | 43 | lua_newtable(L); |
51 | luaL_openlib(L, NULL, func, 0); | 44 | luaL_openlib(L, NULL, func, 0); |
@@ -24,7 +24,7 @@ | |||
24 | #define INET_ATON | 24 | #define INET_ATON |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | void inet_open(lua_State *L); | 27 | int inet_open(lua_State *L); |
28 | 28 | ||
29 | const char *inet_trycreate(p_sock ps, int type); | 29 | const char *inet_trycreate(p_sock ps, int type); |
30 | const char *inet_tryconnect(p_sock ps, const char *address, | 30 | const char *inet_tryconnect(p_sock ps, const char *address, |
diff --git a/src/luasocket.c b/src/luasocket.c index bfe71c2..e99fcdf 100644 --- a/src/luasocket.c +++ b/src/luasocket.c | |||
@@ -33,12 +33,14 @@ | |||
33 | #include "tcp.h" | 33 | #include "tcp.h" |
34 | #include "udp.h" | 34 | #include "udp.h" |
35 | #include "select.h" | 35 | #include "select.h" |
36 | #include "smtp.h" | ||
36 | #include "mime.h" | 37 | #include "mime.h" |
37 | 38 | ||
38 | /*=========================================================================*\ | 39 | /*=========================================================================*\ |
39 | * Declarations | 40 | * Declarations |
40 | \*=========================================================================*/ | 41 | \*=========================================================================*/ |
41 | static int base_open(lua_State *L); | 42 | static int base_open(lua_State *L); |
43 | static int mod_open(lua_State *L, const luaL_reg *mod); | ||
42 | 44 | ||
43 | /*-------------------------------------------------------------------------*\ | 45 | /*-------------------------------------------------------------------------*\ |
44 | * Setup basic stuff. | 46 | * Setup basic stuff. |
@@ -66,22 +68,9 @@ static int base_open(lua_State *L) | |||
66 | return 0; | 68 | return 0; |
67 | } | 69 | } |
68 | 70 | ||
69 | /*-------------------------------------------------------------------------*\ | 71 | static int mod_open(lua_State *L, const luaL_reg *mod) |
70 | * Initializes all library modules. | ||
71 | \*-------------------------------------------------------------------------*/ | ||
72 | LUASOCKET_API int luaopen_socket(lua_State *L) | ||
73 | { | 72 | { |
74 | if (!sock_open()) return 0; | 73 | for (; mod->name; mod++) mod->func(L); |
75 | /* initialize all modules */ | ||
76 | base_open(L); | ||
77 | aux_open(L); | ||
78 | tm_open(L); | ||
79 | buf_open(L); | ||
80 | inet_open(L); | ||
81 | tcp_open(L); | ||
82 | udp_open(L); | ||
83 | select_open(L); | ||
84 | mime_open(L); | ||
85 | #ifdef LUASOCKET_COMPILED | 74 | #ifdef LUASOCKET_COMPILED |
86 | #include "auxiliar.lch" | 75 | #include "auxiliar.lch" |
87 | #include "concat.lch" | 76 | #include "concat.lch" |
@@ -101,5 +90,36 @@ LUASOCKET_API int luaopen_socket(lua_State *L) | |||
101 | lua_dofile(L, "ftp.lua"); | 90 | lua_dofile(L, "ftp.lua"); |
102 | lua_dofile(L, "http.lua"); | 91 | lua_dofile(L, "http.lua"); |
103 | #endif | 92 | #endif |
93 | return 0; | ||
94 | } | ||
95 | |||
96 | /*-------------------------------------------------------------------------*\ | ||
97 | * Modules | ||
98 | \*-------------------------------------------------------------------------*/ | ||
99 | static const luaL_reg mod[] = { | ||
100 | {"base", base_open}, | ||
101 | {"aux", aux_open}, | ||
102 | {"tm", tm_open}, | ||
103 | {"buf", buf_open}, | ||
104 | {"inet", inet_open}, | ||
105 | {"tcp", tcp_open}, | ||
106 | {"udp", udp_open}, | ||
107 | {"select", select_open}, | ||
108 | {"mime", mime_open}, | ||
109 | {"smtp", smtp_open}, | ||
110 | {NULL, NULL} | ||
111 | }; | ||
112 | |||
113 | /*-------------------------------------------------------------------------*\ | ||
114 | * Initializes all library modules. | ||
115 | \*-------------------------------------------------------------------------*/ | ||
116 | LUASOCKET_API int luaopen_socket(lua_State *L) | ||
117 | { | ||
118 | if (!sock_open()) { | ||
119 | lua_pushnil(L); | ||
120 | lua_pushstring(L, "unable to initialize library"); | ||
121 | return 2; | ||
122 | } | ||
123 | mod_open(L, mod); | ||
104 | return 1; | 124 | return 1; |
105 | } | 125 | } |
@@ -10,6 +10,7 @@ | |||
10 | #include <lauxlib.h> | 10 | #include <lauxlib.h> |
11 | 11 | ||
12 | #include "luasocket.h" | 12 | #include "luasocket.h" |
13 | #include "auxiliar.h" | ||
13 | #include "mime.h" | 14 | #include "mime.h" |
14 | 15 | ||
15 | /*=========================================================================*\ | 16 | /*=========================================================================*\ |
@@ -45,18 +46,16 @@ static void qpquote(UC c, luaL_Buffer *buffer); | |||
45 | static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); | 46 | static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); |
46 | static size_t qpencode(UC c, UC *input, size_t size, | 47 | static size_t qpencode(UC c, UC *input, size_t size, |
47 | const char *marker, luaL_Buffer *buffer); | 48 | const char *marker, luaL_Buffer *buffer); |
48 | 49 | static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer); | |
49 | static const char *checklstring(lua_State *L, int n, size_t *l); | ||
50 | static const char *optlstring(lua_State *L, int n, const char *v, size_t *l); | ||
51 | 50 | ||
52 | /* code support functions */ | 51 | /* code support functions */ |
53 | static luaL_reg func[] = { | 52 | static luaL_reg func[] = { |
53 | { "b64", mime_global_b64 }, | ||
54 | { "eol", mime_global_eol }, | 54 | { "eol", mime_global_eol }, |
55 | { "qp", mime_global_qp }, | 55 | { "qp", mime_global_qp }, |
56 | { "unqp", mime_global_unqp }, | ||
57 | { "qpwrp", mime_global_qpwrp }, | 56 | { "qpwrp", mime_global_qpwrp }, |
58 | { "b64", mime_global_b64 }, | ||
59 | { "unb64", mime_global_unb64 }, | 57 | { "unb64", mime_global_unb64 }, |
58 | { "unqp", mime_global_unqp }, | ||
60 | { "wrp", mime_global_wrp }, | 59 | { "wrp", mime_global_wrp }, |
61 | { NULL, NULL } | 60 | { NULL, NULL } |
62 | }; | 61 | }; |
@@ -82,17 +81,10 @@ static UC b64unbase[256]; | |||
82 | /*-------------------------------------------------------------------------*\ | 81 | /*-------------------------------------------------------------------------*\ |
83 | * Initializes module | 82 | * Initializes module |
84 | \*-------------------------------------------------------------------------*/ | 83 | \*-------------------------------------------------------------------------*/ |
85 | void mime_open(lua_State *L) | 84 | int mime_open(lua_State *L) |
86 | { | 85 | { |
87 | lua_pushstring(L, LUASOCKET_LIBNAME); | 86 | lua_pushstring(L, LUASOCKET_LIBNAME); |
88 | lua_gettable(L, LUA_GLOBALSINDEX); | 87 | lua_gettable(L, LUA_GLOBALSINDEX); |
89 | if (lua_isnil(L, -1)) { | ||
90 | lua_pop(L, 1); | ||
91 | lua_newtable(L); | ||
92 | lua_pushstring(L, LUASOCKET_LIBNAME); | ||
93 | lua_pushvalue(L, -2); | ||
94 | lua_settable(L, LUA_GLOBALSINDEX); | ||
95 | } | ||
96 | lua_pushstring(L, "mime"); | 88 | lua_pushstring(L, "mime"); |
97 | lua_newtable(L); | 89 | lua_newtable(L); |
98 | luaL_openlib(L, NULL, func, 0); | 90 | luaL_openlib(L, NULL, func, 0); |
@@ -101,25 +93,7 @@ void mime_open(lua_State *L) | |||
101 | /* initialize lookup tables */ | 93 | /* initialize lookup tables */ |
102 | qpsetup(qpclass, qpunbase); | 94 | qpsetup(qpclass, qpunbase); |
103 | b64setup(b64unbase); | 95 | b64setup(b64unbase); |
104 | } | 96 | return 0; |
105 | |||
106 | /*-------------------------------------------------------------------------*\ | ||
107 | * Check if a string was provided. We accept false also. | ||
108 | \*-------------------------------------------------------------------------*/ | ||
109 | static const char *checklstring(lua_State *L, int n, size_t *l) | ||
110 | { | ||
111 | if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { | ||
112 | *l = 0; | ||
113 | return NULL; | ||
114 | } else return luaL_checklstring(L, n, l); | ||
115 | } | ||
116 | |||
117 | static const char *optlstring(lua_State *L, int n, const char *v, size_t *l) | ||
118 | { | ||
119 | if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { | ||
120 | *l = 0; | ||
121 | return NULL; | ||
122 | } else return luaL_optlstring(L, n, v, l); | ||
123 | } | 97 | } |
124 | 98 | ||
125 | /*=========================================================================*\ | 99 | /*=========================================================================*\ |
@@ -127,31 +101,42 @@ static const char *optlstring(lua_State *L, int n, const char *v, size_t *l) | |||
127 | \*=========================================================================*/ | 101 | \*=========================================================================*/ |
128 | /*-------------------------------------------------------------------------*\ | 102 | /*-------------------------------------------------------------------------*\ |
129 | * Incrementaly breaks a string into lines | 103 | * Incrementaly breaks a string into lines |
130 | * A, n = wrp(l, B, length, marker) | 104 | * A, n = wrp(l, B, length) |
131 | * A is a copy of B, broken into lines of at most 'length' bytes. | 105 | * A is a copy of B, broken into lines of at most 'length' bytes. |
132 | * 'l' is how many bytes are left for the first line of B. | 106 | * 'l' is how many bytes are left for the first line of B. |
133 | * 'n' is the number of bytes left in the last line of A. | 107 | * 'n' is the number of bytes left in the last line of A. |
134 | * Marker is the end-of-line marker. | ||
135 | \*-------------------------------------------------------------------------*/ | 108 | \*-------------------------------------------------------------------------*/ |
136 | static int mime_global_wrp(lua_State *L) | 109 | static int mime_global_wrp(lua_State *L) |
137 | { | 110 | { |
138 | size_t size = 0; | 111 | size_t size = 0; |
139 | int left = (int) luaL_checknumber(L, 1); | 112 | int left = (int) luaL_checknumber(L, 1); |
140 | const UC *input = (UC *) checklstring(L, 2, &size); | 113 | const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size); |
141 | const UC *last = input + size; | 114 | const UC *last = input + size; |
142 | int length = (int) luaL_optnumber(L, 3, 76); | 115 | int length = (int) luaL_optnumber(L, 3, 76); |
143 | const char *marker = luaL_optstring(L, 4, CRLF); | ||
144 | luaL_Buffer buffer; | 116 | luaL_Buffer buffer; |
145 | luaL_buffinit(L, &buffer); | 117 | luaL_buffinit(L, &buffer); |
146 | while (input < last) { | 118 | while (input < last) { |
147 | luaL_putchar(&buffer, *input++); | 119 | switch (*input) { |
148 | if (--left <= 0) { | 120 | case CR: |
149 | luaL_addstring(&buffer, marker); | 121 | break; |
150 | left = length; | 122 | case LF: |
123 | luaL_addstring(&buffer, CRLF); | ||
124 | left = length; | ||
125 | break; | ||
126 | default: | ||
127 | if (left <= 0) { | ||
128 | left = length; | ||
129 | luaL_addstring(&buffer, CRLF); | ||
130 | } | ||
131 | luaL_putchar(&buffer, *input); | ||
132 | left--; | ||
133 | break; | ||
151 | } | 134 | } |
135 | input++; | ||
152 | } | 136 | } |
137 | /* if in last chunk and last line wasn't terminated, add a line-break */ | ||
153 | if (!input && left < length) { | 138 | if (!input && left < length) { |
154 | luaL_addstring(&buffer, marker); | 139 | luaL_addstring(&buffer, CRLF); |
155 | left = length; | 140 | left = length; |
156 | } | 141 | } |
157 | luaL_pushresult(&buffer); | 142 | luaL_pushresult(&buffer); |
@@ -235,7 +220,6 @@ static size_t b64pad(const UC *input, size_t size, | |||
235 | static size_t b64decode(UC c, UC *input, size_t size, | 220 | static size_t b64decode(UC c, UC *input, size_t size, |
236 | luaL_Buffer *buffer) | 221 | luaL_Buffer *buffer) |
237 | { | 222 | { |
238 | |||
239 | /* ignore invalid characters */ | 223 | /* ignore invalid characters */ |
240 | if (b64unbase[c] > 64) return size; | 224 | if (b64unbase[c] > 64) return size; |
241 | input[size++] = c; | 225 | input[size++] = c; |
@@ -277,7 +261,7 @@ static int mime_global_b64(lua_State *L) | |||
277 | luaL_buffinit(L, &buffer); | 261 | luaL_buffinit(L, &buffer); |
278 | while (input < last) | 262 | while (input < last) |
279 | asize = b64encode(*input++, atom, asize, &buffer); | 263 | asize = b64encode(*input++, atom, asize, &buffer); |
280 | input = (UC *) optlstring(L, 2, NULL, &isize); | 264 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
281 | if (input) { | 265 | if (input) { |
282 | last = input + isize; | 266 | last = input + isize; |
283 | while (input < last) | 267 | while (input < last) |
@@ -305,12 +289,14 @@ static int mime_global_unb64(lua_State *L) | |||
305 | luaL_buffinit(L, &buffer); | 289 | luaL_buffinit(L, &buffer); |
306 | while (input < last) | 290 | while (input < last) |
307 | asize = b64decode(*input++, atom, asize, &buffer); | 291 | asize = b64decode(*input++, atom, asize, &buffer); |
308 | input = (UC *) optlstring(L, 2, NULL, &isize); | 292 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
309 | if (input) { | 293 | if (input) { |
310 | last = input + isize; | 294 | last = input + isize; |
311 | while (input < last) | 295 | while (input < last) |
312 | asize = b64decode(*input++, atom, asize, &buffer); | 296 | asize = b64decode(*input++, atom, asize, &buffer); |
313 | } | 297 | } |
298 | /* if !input we are done. if atom > 0, the remaning is invalid. we just | ||
299 | * return it undecoded. */ | ||
314 | luaL_pushresult(&buffer); | 300 | luaL_pushresult(&buffer); |
315 | lua_pushlstring(L, (char *) atom, asize); | 301 | lua_pushlstring(L, (char *) atom, asize); |
316 | return 2; | 302 | return 2; |
@@ -416,7 +402,7 @@ static size_t qpencode(UC c, UC *input, size_t size, | |||
416 | /*-------------------------------------------------------------------------*\ | 402 | /*-------------------------------------------------------------------------*\ |
417 | * Deal with the final characters | 403 | * Deal with the final characters |
418 | \*-------------------------------------------------------------------------*/ | 404 | \*-------------------------------------------------------------------------*/ |
419 | static void qppad(UC *input, size_t size, luaL_Buffer *buffer) | 405 | static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) |
420 | { | 406 | { |
421 | size_t i; | 407 | size_t i; |
422 | for (i = 0; i < size; i++) { | 408 | for (i = 0; i < size; i++) { |
@@ -424,12 +410,13 @@ static void qppad(UC *input, size_t size, luaL_Buffer *buffer) | |||
424 | else qpquote(input[i], buffer); | 410 | else qpquote(input[i], buffer); |
425 | } | 411 | } |
426 | luaL_addstring(buffer, EQCRLF); | 412 | luaL_addstring(buffer, EQCRLF); |
413 | return 0; | ||
427 | } | 414 | } |
428 | 415 | ||
429 | /*-------------------------------------------------------------------------*\ | 416 | /*-------------------------------------------------------------------------*\ |
430 | * Incrementally converts a string to quoted-printable | 417 | * Incrementally converts a string to quoted-printable |
431 | * A, B = qp(C, D, marker) | 418 | * A, B = qp(C, D, marker) |
432 | * Crlf is the text to be used to replace CRLF sequences found in A. | 419 | * Marker is the text to be used to replace CRLF sequences found in A. |
433 | * A is the encoded version of the largest prefix of C .. D that | 420 | * A is the encoded version of the largest prefix of C .. D that |
434 | * can be encoded without doubts. | 421 | * can be encoded without doubts. |
435 | * B has the remaining bytes of C .. D, *without* encoding. | 422 | * B has the remaining bytes of C .. D, *without* encoding. |
@@ -439,19 +426,20 @@ static int mime_global_qp(lua_State *L) | |||
439 | 426 | ||
440 | size_t asize = 0, isize = 0; | 427 | size_t asize = 0, isize = 0; |
441 | UC atom[3]; | 428 | UC atom[3]; |
442 | const UC *input = (UC *) checklstring(L, 1, &isize); | 429 | const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); |
443 | const UC *last = input + isize; | 430 | const UC *last = input + isize; |
444 | const char *marker = luaL_optstring(L, 3, CRLF); | 431 | const char *marker = luaL_optstring(L, 3, CRLF); |
445 | luaL_Buffer buffer; | 432 | luaL_Buffer buffer; |
446 | luaL_buffinit(L, &buffer); | 433 | luaL_buffinit(L, &buffer); |
447 | while (input < last) | 434 | while (input < last) |
448 | asize = qpencode(*input++, atom, asize, marker, &buffer); | 435 | asize = qpencode(*input++, atom, asize, marker, &buffer); |
449 | input = (UC *) optlstring(L, 2, NULL, &isize); | 436 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
450 | if (input) { | 437 | if (input) { |
451 | last = input + isize; | 438 | last = input + isize; |
452 | while (input < last) | 439 | while (input < last) |
453 | asize = qpencode(*input++, atom, asize, marker, &buffer); | 440 | asize = qpencode(*input++, atom, asize, marker, &buffer); |
454 | } else qppad(atom, asize, &buffer); | 441 | } else |
442 | asize = qppad(atom, asize, &buffer); | ||
455 | luaL_pushresult(&buffer); | 443 | luaL_pushresult(&buffer); |
456 | lua_pushlstring(L, (char *) atom, asize); | 444 | lua_pushlstring(L, (char *) atom, asize); |
457 | return 2; | 445 | return 2; |
@@ -507,13 +495,13 @@ static int mime_global_unqp(lua_State *L) | |||
507 | 495 | ||
508 | size_t asize = 0, isize = 0; | 496 | size_t asize = 0, isize = 0; |
509 | UC atom[3]; | 497 | UC atom[3]; |
510 | const UC *input = (UC *) checklstring(L, 1, &isize); | 498 | const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); |
511 | const UC *last = input + isize; | 499 | const UC *last = input + isize; |
512 | luaL_Buffer buffer; | 500 | luaL_Buffer buffer; |
513 | luaL_buffinit(L, &buffer); | 501 | luaL_buffinit(L, &buffer); |
514 | while (input < last) | 502 | while (input < last) |
515 | asize = qpdecode(*input++, atom, asize, &buffer); | 503 | asize = qpdecode(*input++, atom, asize, &buffer); |
516 | input = (UC *) optlstring(L, 2, NULL, &isize); | 504 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
517 | if (input) { | 505 | if (input) { |
518 | last = input + isize; | 506 | last = input + isize; |
519 | while (input < last) | 507 | while (input < last) |
@@ -537,38 +525,39 @@ static int mime_global_qpwrp(lua_State *L) | |||
537 | { | 525 | { |
538 | size_t size = 0; | 526 | size_t size = 0; |
539 | int left = (int) luaL_checknumber(L, 1); | 527 | int left = (int) luaL_checknumber(L, 1); |
540 | const UC *input = (UC *) checklstring(L, 2, &size); | 528 | const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size); |
541 | const UC *last = input + size; | 529 | const UC *last = input + size; |
542 | int length = (int) luaL_optnumber(L, 3, 76); | 530 | int length = (int) luaL_optnumber(L, 3, 76); |
543 | luaL_Buffer buffer; | 531 | luaL_Buffer buffer; |
544 | luaL_buffinit(L, &buffer); | 532 | luaL_buffinit(L, &buffer); |
545 | while (input < last) { | 533 | while (input < last) { |
546 | left--; | ||
547 | switch (*input) { | 534 | switch (*input) { |
548 | case '=': | 535 | case CR: |
549 | /* if there's no room in this line for the quoted char, | ||
550 | * output a soft line break now */ | ||
551 | if (left <= 3) { | ||
552 | luaL_addstring(&buffer, EQCRLF); | ||
553 | left = length; | ||
554 | } | ||
555 | break; | ||
556 | /* \r\n starts a new line */ | ||
557 | case CR: | ||
558 | break; | 536 | break; |
559 | case LF: | 537 | case LF: |
560 | left = length; | 538 | left = length; |
539 | luaL_addstring(&buffer, CRLF); | ||
561 | break; | 540 | break; |
562 | default: | 541 | case '=': |
563 | /* if in last column, output a soft line break */ | 542 | if (left <= 3) { |
564 | if (left <= 1) { | 543 | left = length; |
565 | luaL_addstring(&buffer, EQCRLF); | 544 | luaL_addstring(&buffer, EQCRLF); |
545 | } | ||
546 | luaL_putchar(&buffer, *input); | ||
547 | left--; | ||
548 | break; | ||
549 | default: | ||
550 | if (left <= 1) { | ||
566 | left = length; | 551 | left = length; |
552 | luaL_addstring(&buffer, EQCRLF); | ||
567 | } | 553 | } |
554 | luaL_putchar(&buffer, *input); | ||
555 | left--; | ||
556 | break; | ||
568 | } | 557 | } |
569 | luaL_putchar(&buffer, *input); | ||
570 | input++; | 558 | input++; |
571 | } | 559 | } |
560 | /* if in last chunk and last line wasn't terminated, add a soft-break */ | ||
572 | if (!input && left < length) { | 561 | if (!input && left < length) { |
573 | luaL_addstring(&buffer, EQCRLF); | 562 | luaL_addstring(&buffer, EQCRLF); |
574 | left = length; | 563 | left = length; |
@@ -579,10 +568,10 @@ static int mime_global_qpwrp(lua_State *L) | |||
579 | } | 568 | } |
580 | 569 | ||
581 | /*-------------------------------------------------------------------------*\ | 570 | /*-------------------------------------------------------------------------*\ |
582 | * Here is what we do: \n, \r and \f are considered candidates for line | 571 | * Here is what we do: \n, and \r are considered candidates for line |
583 | * break. We issue *one* new line marker if any of them is seen alone, or | 572 | * break. We issue *one* new line marker if any of them is seen alone, or |
584 | * followed by a different one. That is, \n\n, \r\r and \f\f will issue two | 573 | * followed by a different one. That is, \n\n and \r\r will issue two |
585 | * end of line markers each, but \r\n, \n\r, \r\f etc will only issue *one* | 574 | * end of line markers each, but \r\n, \n\r etc will only issue *one* |
586 | * marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as | 575 | * marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as |
587 | * probably other more obscure conventions. | 576 | * probably other more obscure conventions. |
588 | \*-------------------------------------------------------------------------*/ | 577 | \*-------------------------------------------------------------------------*/ |
@@ -616,21 +605,24 @@ static int mime_global_eol(lua_State *L) | |||
616 | { | 605 | { |
617 | size_t asize = 0, isize = 0; | 606 | size_t asize = 0, isize = 0; |
618 | UC atom[2]; | 607 | UC atom[2]; |
619 | const UC *input = (UC *) checklstring(L, 1, &isize); | 608 | const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); |
620 | const UC *last = input + isize; | 609 | const UC *last = input + isize; |
621 | const char *marker = luaL_optstring(L, 3, CRLF); | 610 | const char *marker = luaL_optstring(L, 3, CRLF); |
622 | luaL_Buffer buffer; | 611 | luaL_Buffer buffer; |
623 | luaL_buffinit(L, &buffer); | 612 | luaL_buffinit(L, &buffer); |
624 | while (input < last) | 613 | while (input < last) |
625 | asize = eolconvert(*input++, atom, asize, marker, &buffer); | 614 | asize = eolconvert(*input++, atom, asize, marker, &buffer); |
626 | input = (UC *) optlstring(L, 2, NULL, &isize); | 615 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
627 | if (input) { | 616 | if (input) { |
628 | last = input + isize; | 617 | last = input + isize; |
629 | while (input < last) | 618 | while (input < last) |
630 | asize = eolconvert(*input++, atom, asize, marker, &buffer); | 619 | asize = eolconvert(*input++, atom, asize, marker, &buffer); |
631 | /* if there is something in atom, it's one character, and it | 620 | /* if there is something in atom, it's one character, and it |
632 | * is a candidate. so we output a new line */ | 621 | * is a candidate. so we output a new line */ |
633 | } else if (asize > 0) luaL_addstring(&buffer, marker); | 622 | } else if (asize > 0) { |
623 | luaL_addstring(&buffer, marker); | ||
624 | asize = 0; | ||
625 | } | ||
634 | luaL_pushresult(&buffer); | 626 | luaL_pushresult(&buffer); |
635 | lua_pushlstring(L, (char *) atom, asize); | 627 | lua_pushlstring(L, (char *) atom, asize); |
636 | return 2; | 628 | return 2; |
@@ -12,6 +12,6 @@ | |||
12 | \*=========================================================================*/ | 12 | \*=========================================================================*/ |
13 | #include <lua.h> | 13 | #include <lua.h> |
14 | 14 | ||
15 | void mime_open(lua_State *L); | 15 | int mime_open(lua_State *L); |
16 | 16 | ||
17 | #endif /* MIME_H */ | 17 | #endif /* MIME_H */ |
diff --git a/src/mime.lua b/src/mime.lua index 30c6b38..369567f 100644 --- a/src/mime.lua +++ b/src/mime.lua | |||
@@ -15,70 +15,57 @@ local et = {} | |||
15 | local dt = {} | 15 | local dt = {} |
16 | local wt = {} | 16 | local wt = {} |
17 | 17 | ||
18 | -- creates a function that chooses an algorithm from a given table | 18 | -- creates a function that chooses a filter from a given table |
19 | local function choose(table) | 19 | local function choose(table) |
20 | return function(method, ...) | 20 | return function(filter, ...) |
21 | local f = table[method or "nil"] | 21 | local f = table[filter or "nil"] |
22 | if not f then error("unknown method (" .. tostring(method) .. ")", 3) | 22 | if not f then error("unknown filter (" .. tostring(filter) .. ")", 3) |
23 | else return f(unpack(arg)) end | 23 | else return f(unpack(arg)) end |
24 | end | 24 | end |
25 | end | 25 | end |
26 | 26 | ||
27 | -- creates a function that cicles a filter with a given initial | 27 | -- define the encoding filters |
28 | -- context and extra arguments | ||
29 | local function cicle(f, ctx, ...) | ||
30 | return function(chunk) | ||
31 | local ret | ||
32 | ret, ctx = f(ctx, chunk, unpack(arg)) | ||
33 | return ret | ||
34 | end | ||
35 | end | ||
36 | |||
37 | -- function that choose the encoding, decoding or wrap algorithm | ||
38 | encode = choose(et) | ||
39 | decode = choose(dt) | ||
40 | |||
41 | -- the wrap filter has default parameters | ||
42 | local cwt = choose(wt) | ||
43 | function wrap(...) | ||
44 | if not arg[1] or type(arg[1]) ~= "string" then | ||
45 | table.insert(arg, 1, "base64") | ||
46 | end | ||
47 | return cwt(unpack(arg)) | ||
48 | end | ||
49 | |||
50 | -- define the encoding algorithms | ||
51 | et['base64'] = function() | 28 | et['base64'] = function() |
52 | return cicle(b64, "") | 29 | return socket.cicle(b64, "") |
53 | end | 30 | end |
54 | 31 | ||
55 | et['quoted-printable'] = function(mode) | 32 | et['quoted-printable'] = function(mode) |
56 | return cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10") | 33 | return socket.cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10") |
57 | end | 34 | end |
58 | 35 | ||
59 | -- define the decoding algorithms | 36 | -- define the decoding filters |
60 | dt['base64'] = function() | 37 | dt['base64'] = function() |
61 | return cicle(unb64, "") | 38 | return socket.cicle(unb64, "") |
62 | end | 39 | end |
63 | 40 | ||
64 | dt['quoted-printable'] = function() | 41 | dt['quoted-printable'] = function() |
65 | return cicle(unqp, "") | 42 | return socket.cicle(unqp, "") |
66 | end | 43 | end |
67 | 44 | ||
68 | -- define the wrap algorithms | 45 | -- define the line-wrap filters |
69 | wt['base64'] = function(length, marker) | 46 | wt['text'] = function(length) |
70 | length = length or 76 | 47 | length = length or 76 |
71 | return cicle(wrp, length, length, marker) | 48 | return socket.cicle(wrp, length, length) |
72 | end | 49 | end |
50 | wt['base64'] = wt['text'] | ||
73 | 51 | ||
74 | wt['quoted-printable'] = function(length) | 52 | wt['quoted-printable'] = function() |
75 | length = length or 76 | 53 | return socket.cicle(qpwrp, 76, 76) |
76 | return cicle(qpwrp, length, length) | 54 | end |
55 | |||
56 | -- function that choose the encoding, decoding or wrap algorithm | ||
57 | encode = choose(et) | ||
58 | decode = choose(dt) | ||
59 | -- there is a default wrap filter | ||
60 | local cwt = choose(wt) | ||
61 | function wrap(...) | ||
62 | if type(arg[1]) ~= "string" then table.insert(arg, 1, "text") end | ||
63 | return cwt(unpack(arg)) | ||
77 | end | 64 | end |
78 | 65 | ||
79 | -- define the end-of-line translation function | 66 | -- define the end-of-line translation filter |
80 | function canonic(marker) | 67 | function canonic(marker) |
81 | return cicle(eol, "", marker) | 68 | return socket.cicle(eol, "", marker) |
82 | end | 69 | end |
83 | 70 | ||
84 | -- chains several filters together | 71 | -- chains several filters together |
@@ -104,4 +91,4 @@ function chain(...) | |||
104 | end | 91 | end |
105 | end | 92 | end |
106 | 93 | ||
107 | return code | 94 | return mime |
diff --git a/src/select.c b/src/select.c index 9769667..8590b96 100644 --- a/src/select.c +++ b/src/select.c | |||
@@ -42,7 +42,7 @@ static luaL_reg func[] = { | |||
42 | /*-------------------------------------------------------------------------*\ | 42 | /*-------------------------------------------------------------------------*\ |
43 | * Initializes module | 43 | * Initializes module |
44 | \*-------------------------------------------------------------------------*/ | 44 | \*-------------------------------------------------------------------------*/ |
45 | void select_open(lua_State *L) | 45 | int select_open(lua_State *L) |
46 | { | 46 | { |
47 | /* get select auxiliar lua function from lua code and register | 47 | /* get select auxiliar lua function from lua code and register |
48 | * pass it as an upvalue to global_select */ | 48 | * pass it as an upvalue to global_select */ |
@@ -54,6 +54,7 @@ void select_open(lua_State *L) | |||
54 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 1); | 54 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 1); |
55 | lua_pop(L, 1); | 55 | lua_pop(L, 1); |
56 | aux_newclass(L, "select{fd_set}", set); | 56 | aux_newclass(L, "select{fd_set}", set); |
57 | return 0; | ||
57 | } | 58 | } |
58 | 59 | ||
59 | /*=========================================================================*\ | 60 | /*=========================================================================*\ |
diff --git a/src/select.h b/src/select.h index 0e1eeb4..de10ea4 100644 --- a/src/select.h +++ b/src/select.h | |||
@@ -15,6 +15,6 @@ | |||
15 | * RCS ID: $Id$ | 15 | * RCS ID: $Id$ |
16 | \*=========================================================================*/ | 16 | \*=========================================================================*/ |
17 | 17 | ||
18 | void select_open(lua_State *L); | 18 | int select_open(lua_State *L); |
19 | 19 | ||
20 | #endif /* SELECT_H */ | 20 | #endif /* SELECT_H */ |
diff --git a/src/smtp.lua b/src/smtp.lua index 25d7f74..8b65e44 100644 --- a/src/smtp.lua +++ b/src/smtp.lua | |||
@@ -4,7 +4,7 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end | |||
4 | local socket = _G[LUASOCKET_LIBNAME] | 4 | local socket = _G[LUASOCKET_LIBNAME] |
5 | if not socket then error('module requires LuaSocket') end | 5 | if not socket then error('module requires LuaSocket') end |
6 | -- create smtp namespace inside LuaSocket namespace | 6 | -- create smtp namespace inside LuaSocket namespace |
7 | local smtp = {} | 7 | local smtp = socket.smtp or {} |
8 | socket.smtp = smtp | 8 | socket.smtp = smtp |
9 | -- make all module globals fall into smtp namespace | 9 | -- make all module globals fall into smtp namespace |
10 | setmetatable(smtp, { __index = _G }) | 10 | setmetatable(smtp, { __index = _G }) |
@@ -18,6 +18,10 @@ DOMAIN = os.getenv("SERVER_NAME") or "localhost" | |||
18 | -- default server used to send e-mails | 18 | -- default server used to send e-mails |
19 | SERVER = "localhost" | 19 | SERVER = "localhost" |
20 | 20 | ||
21 | function stuff() | ||
22 | return socket.cicle(dot, 2) | ||
23 | end | ||
24 | |||
21 | -- tries to get a pattern from the server and closes socket on error | 25 | -- tries to get a pattern from the server and closes socket on error |
22 | local function try_receiving(connection, pattern) | 26 | local function try_receiving(connection, pattern) |
23 | local data, message = connection:receive(pattern) | 27 | local data, message = connection:receive(pattern) |
@@ -39,25 +39,26 @@ static int meth_dirty(lua_State *L); | |||
39 | 39 | ||
40 | /* tcp object methods */ | 40 | /* tcp object methods */ |
41 | static luaL_reg tcp[] = { | 41 | static luaL_reg tcp[] = { |
42 | {"connect", meth_connect}, | 42 | {"__gc", meth_close}, |
43 | {"send", meth_send}, | 43 | {"accept", meth_accept}, |
44 | {"receive", meth_receive}, | ||
45 | {"bind", meth_bind}, | 44 | {"bind", meth_bind}, |
45 | {"close", meth_close}, | ||
46 | {"connect", meth_connect}, | ||
47 | {"dirty", meth_dirty}, | ||
48 | {"getfd", meth_getfd}, | ||
49 | {"getpeername", meth_getpeername}, | ||
50 | {"getsockname", meth_getsockname}, | ||
46 | {"listen", meth_listen}, | 51 | {"listen", meth_listen}, |
47 | {"accept", meth_accept}, | 52 | {"receive", meth_receive}, |
53 | {"send", meth_send}, | ||
54 | {"setfd", meth_setfd}, | ||
55 | {"setoption", meth_setoption}, | ||
48 | {"setpeername", meth_connect}, | 56 | {"setpeername", meth_connect}, |
49 | {"setsockname", meth_bind}, | 57 | {"setsockname", meth_bind}, |
50 | {"getpeername", meth_getpeername}, | ||
51 | {"getsockname", meth_getsockname}, | ||
52 | {"settimeout", meth_settimeout}, | 58 | {"settimeout", meth_settimeout}, |
53 | {"close", meth_close}, | ||
54 | {"shutdown", meth_shutdown}, | 59 | {"shutdown", meth_shutdown}, |
55 | {"setoption", meth_setoption}, | ||
56 | {"__gc", meth_close}, | ||
57 | {"getfd", meth_getfd}, | ||
58 | {"setfd", meth_setfd}, | ||
59 | {"dirty", meth_dirty}, | ||
60 | {NULL, NULL} | 60 | {NULL, NULL} |
61 | |||
61 | }; | 62 | }; |
62 | 63 | ||
63 | /* socket option handlers */ | 64 | /* socket option handlers */ |
@@ -78,7 +79,7 @@ static luaL_reg func[] = { | |||
78 | /*-------------------------------------------------------------------------*\ | 79 | /*-------------------------------------------------------------------------*\ |
79 | * Initializes module | 80 | * Initializes module |
80 | \*-------------------------------------------------------------------------*/ | 81 | \*-------------------------------------------------------------------------*/ |
81 | void tcp_open(lua_State *L) | 82 | int tcp_open(lua_State *L) |
82 | { | 83 | { |
83 | /* create classes */ | 84 | /* create classes */ |
84 | aux_newclass(L, "tcp{master}", tcp); | 85 | aux_newclass(L, "tcp{master}", tcp); |
@@ -96,6 +97,7 @@ void tcp_open(lua_State *L) | |||
96 | /* define library functions */ | 97 | /* define library functions */ |
97 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 98 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
98 | lua_pop(L, 1); | 99 | lua_pop(L, 1); |
100 | return 0; | ||
99 | } | 101 | } |
100 | 102 | ||
101 | /*=========================================================================*\ | 103 | /*=========================================================================*\ |
@@ -250,7 +252,7 @@ static int meth_listen(lua_State *L) | |||
250 | \*-------------------------------------------------------------------------*/ | 252 | \*-------------------------------------------------------------------------*/ |
251 | static int meth_shutdown(lua_State *L) | 253 | static int meth_shutdown(lua_State *L) |
252 | { | 254 | { |
253 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | 255 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client}", 1); |
254 | const char *how = luaL_optstring(L, 2, "both"); | 256 | const char *how = luaL_optstring(L, 2, "both"); |
255 | switch (how[0]) { | 257 | switch (how[0]) { |
256 | case 'b': | 258 | case 'b': |
@@ -266,7 +268,8 @@ static int meth_shutdown(lua_State *L) | |||
266 | sock_shutdown(&tcp->sock, 0); | 268 | sock_shutdown(&tcp->sock, 0); |
267 | break; | 269 | break; |
268 | } | 270 | } |
269 | return 0; | 271 | lua_pushnumber(L, 1); |
272 | return 1; | ||
270 | error: | 273 | error: |
271 | luaL_argerror(L, 2, "invalid shutdown method"); | 274 | luaL_argerror(L, 2, "invalid shutdown method"); |
272 | return 0; | 275 | return 0; |
@@ -31,6 +31,6 @@ typedef struct t_tcp_ { | |||
31 | 31 | ||
32 | typedef t_tcp *p_tcp; | 32 | typedef t_tcp *p_tcp; |
33 | 33 | ||
34 | void tcp_open(lua_State *L); | 34 | int tcp_open(lua_State *L); |
35 | 35 | ||
36 | #endif /* TCP_H */ | 36 | #endif /* TCP_H */ |
diff --git a/src/timeout.c b/src/timeout.c index 83bffc9..73a1146 100644 --- a/src/timeout.c +++ b/src/timeout.c | |||
@@ -141,10 +141,11 @@ int tm_gettime(void) | |||
141 | /*-------------------------------------------------------------------------*\ | 141 | /*-------------------------------------------------------------------------*\ |
142 | * Initializes module | 142 | * Initializes module |
143 | \*-------------------------------------------------------------------------*/ | 143 | \*-------------------------------------------------------------------------*/ |
144 | void tm_open(lua_State *L) | 144 | int tm_open(lua_State *L) |
145 | { | 145 | { |
146 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 146 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
147 | lua_pop(L, 1); | 147 | lua_pop(L, 1); |
148 | return 0; | ||
148 | } | 149 | } |
149 | 150 | ||
150 | /*-------------------------------------------------------------------------*\ | 151 | /*-------------------------------------------------------------------------*\ |
diff --git a/src/timeout.h b/src/timeout.h index 6584a8e..6b105c3 100644 --- a/src/timeout.h +++ b/src/timeout.h | |||
@@ -16,7 +16,7 @@ typedef struct t_tm_ { | |||
16 | } t_tm; | 16 | } t_tm; |
17 | typedef t_tm *p_tm; | 17 | typedef t_tm *p_tm; |
18 | 18 | ||
19 | void tm_open(lua_State *L); | 19 | int tm_open(lua_State *L); |
20 | void tm_init(p_tm tm, int block, int total); | 20 | void tm_init(p_tm tm, int block, int total); |
21 | int tm_get(p_tm tm); | 21 | int tm_get(p_tm tm); |
22 | int tm_getretry(p_tm tm); | 22 | int tm_getretry(p_tm tm); |
@@ -30,7 +30,6 @@ static int meth_getpeername(lua_State *L); | |||
30 | static int meth_setsockname(lua_State *L); | 30 | static int meth_setsockname(lua_State *L); |
31 | static int meth_setpeername(lua_State *L); | 31 | static int meth_setpeername(lua_State *L); |
32 | static int meth_close(lua_State *L); | 32 | static int meth_close(lua_State *L); |
33 | static int meth_shutdown(lua_State *L); | ||
34 | static int meth_setoption(lua_State *L); | 33 | static int meth_setoption(lua_State *L); |
35 | static int meth_settimeout(lua_State *L); | 34 | static int meth_settimeout(lua_State *L); |
36 | static int meth_getfd(lua_State *L); | 35 | static int meth_getfd(lua_State *L); |
@@ -49,7 +48,6 @@ static luaL_reg udp[] = { | |||
49 | {"receivefrom", meth_receivefrom}, | 48 | {"receivefrom", meth_receivefrom}, |
50 | {"settimeout", meth_settimeout}, | 49 | {"settimeout", meth_settimeout}, |
51 | {"close", meth_close}, | 50 | {"close", meth_close}, |
52 | {"shutdown", meth_shutdown}, | ||
53 | {"setoption", meth_setoption}, | 51 | {"setoption", meth_setoption}, |
54 | {"__gc", meth_close}, | 52 | {"__gc", meth_close}, |
55 | {"getfd", meth_getfd}, | 53 | {"getfd", meth_getfd}, |
@@ -79,7 +77,7 @@ static luaL_reg func[] = { | |||
79 | /*-------------------------------------------------------------------------*\ | 77 | /*-------------------------------------------------------------------------*\ |
80 | * Initializes module | 78 | * Initializes module |
81 | \*-------------------------------------------------------------------------*/ | 79 | \*-------------------------------------------------------------------------*/ |
82 | void udp_open(lua_State *L) | 80 | int udp_open(lua_State *L) |
83 | { | 81 | { |
84 | /* create classes */ | 82 | /* create classes */ |
85 | aux_newclass(L, "udp{connected}", udp); | 83 | aux_newclass(L, "udp{connected}", udp); |
@@ -92,6 +90,7 @@ void udp_open(lua_State *L) | |||
92 | /* define library functions */ | 90 | /* define library functions */ |
93 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 91 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
94 | lua_pop(L, 1); | 92 | lua_pop(L, 1); |
93 | return 0; | ||
95 | } | 94 | } |
96 | 95 | ||
97 | /*=========================================================================*\ | 96 | /*=========================================================================*\ |
@@ -288,33 +287,6 @@ static int meth_close(lua_State *L) | |||
288 | } | 287 | } |
289 | 288 | ||
290 | /*-------------------------------------------------------------------------*\ | 289 | /*-------------------------------------------------------------------------*\ |
291 | * Shuts the connection down partially | ||
292 | \*-------------------------------------------------------------------------*/ | ||
293 | static int meth_shutdown(lua_State *L) | ||
294 | { | ||
295 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | ||
296 | const char *how = luaL_optstring(L, 2, "both"); | ||
297 | switch (how[0]) { | ||
298 | case 'b': | ||
299 | if (strcmp(how, "both")) goto error; | ||
300 | sock_shutdown(&udp->sock, 2); | ||
301 | break; | ||
302 | case 's': | ||
303 | if (strcmp(how, "send")) goto error; | ||
304 | sock_shutdown(&udp->sock, 1); | ||
305 | break; | ||
306 | case 'r': | ||
307 | if (strcmp(how, "receive")) goto error; | ||
308 | sock_shutdown(&udp->sock, 0); | ||
309 | break; | ||
310 | } | ||
311 | return 0; | ||
312 | error: | ||
313 | luaL_argerror(L, 2, "invalid shutdown method"); | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | /*-------------------------------------------------------------------------*\ | ||
318 | * Turns a master object into a server object | 290 | * Turns a master object into a server object |
319 | \*-------------------------------------------------------------------------*/ | 291 | \*-------------------------------------------------------------------------*/ |
320 | static int meth_setsockname(lua_State *L) | 292 | static int meth_setsockname(lua_State *L) |
@@ -27,6 +27,6 @@ typedef struct t_udp_ { | |||
27 | } t_udp; | 27 | } t_udp; |
28 | typedef t_udp *p_udp; | 28 | typedef t_udp *p_udp; |
29 | 29 | ||
30 | void udp_open(lua_State *L); | 30 | int udp_open(lua_State *L); |
31 | 31 | ||
32 | #endif /* UDP_H */ | 32 | #endif /* UDP_H */ |
diff --git a/src/url.lua b/src/url.lua index ab3a922..de0474b 100644 --- a/src/url.lua +++ b/src/url.lua | |||
@@ -12,7 +12,7 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end | |||
12 | local socket = _G[LUASOCKET_LIBNAME] | 12 | local socket = _G[LUASOCKET_LIBNAME] |
13 | if not socket then error('module requires LuaSocket') end | 13 | if not socket then error('module requires LuaSocket') end |
14 | -- create smtp namespace inside LuaSocket namespace | 14 | -- create smtp namespace inside LuaSocket namespace |
15 | local url = {} | 15 | local url = socket.url or {} |
16 | socket.url = url | 16 | socket.url = url |
17 | -- make all module globals fall into smtp namespace | 17 | -- make all module globals fall into smtp namespace |
18 | setmetatable(url, { __index = _G }) | 18 | setmetatable(url, { __index = _G }) |
diff --git a/src/usocket.c b/src/usocket.c index bece354..eb1a49a 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -70,12 +70,10 @@ int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, int timeout) | |||
70 | \*-------------------------------------------------------------------------*/ | 70 | \*-------------------------------------------------------------------------*/ |
71 | const char *sock_create(p_sock ps, int domain, int type, int protocol) | 71 | const char *sock_create(p_sock ps, int domain, int type, int protocol) |
72 | { | 72 | { |
73 | int val = 1; | ||
74 | t_sock sock = socket(domain, type, protocol); | 73 | t_sock sock = socket(domain, type, protocol); |
75 | if (sock == SOCK_INVALID) return sock_createstrerror(errno); | 74 | if (sock == SOCK_INVALID) return sock_createstrerror(errno); |
76 | *ps = sock; | 75 | *ps = sock; |
77 | sock_setnonblocking(ps); | 76 | sock_setnonblocking(ps); |
78 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); | ||
79 | return NULL; | 77 | return NULL; |
80 | } | 78 | } |
81 | 79 | ||
@@ -167,13 +165,14 @@ const char *sock_accept(p_sock ps, p_sock pa, SA *addr, | |||
167 | for (;;) { | 165 | for (;;) { |
168 | int err; | 166 | int err; |
169 | fd_set fds; | 167 | fd_set fds; |
168 | /* try to accept */ | ||
170 | *pa = accept(sock, addr, addr_len); | 169 | *pa = accept(sock, addr, addr_len); |
171 | /* if result is valid, we are done */ | 170 | /* if result is valid, we are done */ |
172 | if (*pa != SOCK_INVALID) return NULL; | 171 | if (*pa != SOCK_INVALID) return NULL; |
173 | /* find out if we failed for a fatal reason */ | 172 | /* find out if we failed for a fatal reason */ |
174 | if (errno != EWOULDBLOCK && errno != ECONNABORTED) | 173 | if (errno != EWOULDBLOCK && errno != ECONNABORTED) |
175 | return sock_acceptstrerror(errno); | 174 | return sock_acceptstrerror(errno); |
176 | /* call select just to avoid busy-wait. */ | 175 | /* call select to avoid busy-wait. */ |
177 | FD_ZERO(&fds); | 176 | FD_ZERO(&fds); |
178 | FD_SET(sock, &fds); | 177 | FD_SET(sock, &fds); |
179 | do err = sock_select(sock+1, &fds, NULL, NULL, tm_getretry(tm)); | 178 | do err = sock_select(sock+1, &fds, NULL, NULL, tm_getretry(tm)); |
diff --git a/src/wsocket.c b/src/wsocket.c index f33e154..fcd2fff 100644 --- a/src/wsocket.c +++ b/src/wsocket.c | |||
@@ -75,12 +75,10 @@ void sock_shutdown(p_sock ps, int how) | |||
75 | \*-------------------------------------------------------------------------*/ | 75 | \*-------------------------------------------------------------------------*/ |
76 | const char *sock_create(p_sock ps, int domain, int type, int protocol) | 76 | const char *sock_create(p_sock ps, int domain, int type, int protocol) |
77 | { | 77 | { |
78 | int val = 1; | ||
79 | t_sock sock = socket(domain, type, protocol); | 78 | t_sock sock = socket(domain, type, protocol); |
80 | if (sock == SOCK_INVALID) | 79 | if (sock == SOCK_INVALID) |
81 | return sock_createstrerror(WSAGetLastError()); | 80 | return sock_createstrerror(WSAGetLastError()); |
82 | *ps = sock; | 81 | *ps = sock; |
83 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); | ||
84 | sock_setnonblocking(ps); | 82 | sock_setnonblocking(ps); |
85 | return NULL; | 83 | return NULL; |
86 | } | 84 | } |
@@ -112,8 +110,12 @@ const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm) | |||
112 | /* if was in efds, we failed */ | 110 | /* if was in efds, we failed */ |
113 | if (FD_ISSET(sock, &efds)) { | 111 | if (FD_ISSET(sock, &efds)) { |
114 | int why, len = sizeof(why); | 112 | int why, len = sizeof(why); |
113 | /* give windows time to set the error (disgusting) */ | ||
114 | Sleep(0); | ||
115 | /* find out why we failed */ | 115 | /* find out why we failed */ |
116 | getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&why, &len); | 116 | getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&why, &len); |
117 | /* we KNOW there was an error. if why is 0, we will return | ||
118 | * "unknown error", but it's not really our fault */ | ||
117 | return sock_connectstrerror(why); | 119 | return sock_connectstrerror(why); |
118 | /* otherwise it must be in wfds, so we succeeded */ | 120 | /* otherwise it must be in wfds, so we succeeded */ |
119 | } else return NULL; | 121 | } else return NULL; |
diff --git a/test/mimetest.lua b/test/mimetest.lua index 81814de..5a461fa 100644 --- a/test/mimetest.lua +++ b/test/mimetest.lua | |||
@@ -181,6 +181,19 @@ local function compare_b64test() | |||
181 | compare(b64test, db64test) | 181 | compare(b64test, db64test) |
182 | end | 182 | end |
183 | 183 | ||
184 | local function identity_test() | ||
185 | local chain = socket.mime.chain( | ||
186 | socket.mime.encode("quoted-printable"), | ||
187 | socket.mime.encode("base64"), | ||
188 | socket.mime.decode("base64"), | ||
189 | socket.mime.decode("quoted-printable") | ||
190 | ) | ||
191 | transform(b64test, eb64test, chain) | ||
192 | compare(b64test, eb64test) | ||
193 | os.remove(eb64test) | ||
194 | end | ||
195 | |||
196 | |||
184 | local function padcheck(original, encoded) | 197 | local function padcheck(original, encoded) |
185 | local e = (socket.mime.b64(original)) | 198 | local e = (socket.mime.b64(original)) |
186 | local d = (socket.mime.unb64(encoded)) | 199 | local d = (socket.mime.unb64(encoded)) |
@@ -233,4 +246,6 @@ compare_b64test() | |||
233 | cleanup_b64test() | 246 | cleanup_b64test() |
234 | padding_b64test() | 247 | padding_b64test() |
235 | 248 | ||
249 | identity_test() | ||
250 | |||
236 | print(string.format("done in %.2fs", socket.time() - t)) | 251 | print(string.format("done in %.2fs", socket.time() - t)) |
diff --git a/test/testclnt.lua b/test/testclnt.lua index 348439a..1b64abd 100644 --- a/test/testclnt.lua +++ b/test/testclnt.lua | |||
@@ -3,18 +3,18 @@ port = port or "8080" | |||
3 | 3 | ||
4 | function pass(...) | 4 | function pass(...) |
5 | local s = string.format(unpack(arg)) | 5 | local s = string.format(unpack(arg)) |
6 | io.write(s, "\n") | 6 | io.stderr:write(s, "\n") |
7 | end | 7 | end |
8 | 8 | ||
9 | function fail(...) | 9 | function fail(...) |
10 | local s = string.format(unpack(arg)) | 10 | local s = string.format(unpack(arg)) |
11 | io.write("ERROR: ", s, "!\n") | 11 | io.stderr:write("ERROR: ", s, "!\n") |
12 | os.exit() | 12 | os.exit() |
13 | end | 13 | end |
14 | 14 | ||
15 | function warn(...) | 15 | function warn(...) |
16 | local s = string.format(unpack(arg)) | 16 | local s = string.format(unpack(arg)) |
17 | io.write("WARNING: ", s, "\n") | 17 | io.stderr:write("WARNING: ", s, "\n") |
18 | end | 18 | end |
19 | 19 | ||
20 | pad = string.rep(" ", 8192) | 20 | pad = string.rep(" ", 8192) |
@@ -29,7 +29,7 @@ function remote(...) | |||
29 | end | 29 | end |
30 | 30 | ||
31 | function test(test) | 31 | function test(test) |
32 | io.write("----------------------------------------------\n", | 32 | io.stderr:write("----------------------------------------------\n", |
33 | "testing: ", test, "\n", | 33 | "testing: ", test, "\n", |
34 | "----------------------------------------------\n") | 34 | "----------------------------------------------\n") |
35 | end | 35 | end |
@@ -72,14 +72,14 @@ if not socket.debug then | |||
72 | fail("Please define LUASOCKET_DEBUG and recompile LuaSocket") | 72 | fail("Please define LUASOCKET_DEBUG and recompile LuaSocket") |
73 | end | 73 | end |
74 | 74 | ||
75 | io.write("----------------------------------------------\n", | 75 | io.stderr:write("----------------------------------------------\n", |
76 | "LuaSocket Test Procedures\n", | 76 | "LuaSocket Test Procedures\n", |
77 | "----------------------------------------------\n") | 77 | "----------------------------------------------\n") |
78 | 78 | ||
79 | start = socket.time() | 79 | start = socket.time() |
80 | 80 | ||
81 | function reconnect() | 81 | function reconnect() |
82 | io.write("attempting data connection... ") | 82 | io.stderr:write("attempting data connection... ") |
83 | if data then data:close() end | 83 | if data then data:close() end |
84 | remote [[ | 84 | remote [[ |
85 | if data then data:close() data = nil end | 85 | if data then data:close() data = nil end |
@@ -348,7 +348,7 @@ end | |||
348 | 348 | ||
349 | ------------------------------------------------------------------------ | 349 | ------------------------------------------------------------------------ |
350 | function accept_timeout() | 350 | function accept_timeout() |
351 | io.write("accept with timeout (if it hangs, it failed): ") | 351 | io.stderr:write("accept with timeout (if it hangs, it failed): ") |
352 | local s, e = socket.bind("*", 0, 0) | 352 | local s, e = socket.bind("*", 0, 0) |
353 | assert(s, e) | 353 | assert(s, e) |
354 | local t = socket.time() | 354 | local t = socket.time() |
@@ -364,7 +364,8 @@ end | |||
364 | 364 | ||
365 | ------------------------------------------------------------------------ | 365 | ------------------------------------------------------------------------ |
366 | function connect_timeout() | 366 | function connect_timeout() |
367 | io.write("connect with timeout (if it hangs, it failed): ") | 367 | io.stderr:write("connect with timeout (if it hangs, it failed): ") |
368 | local t = socket.time() | ||
368 | local c, e = socket.tcp() | 369 | local c, e = socket.tcp() |
369 | assert(c, e) | 370 | assert(c, e) |
370 | c:settimeout(0.1) | 371 | c:settimeout(0.1) |
@@ -380,16 +381,17 @@ end | |||
380 | 381 | ||
381 | ------------------------------------------------------------------------ | 382 | ------------------------------------------------------------------------ |
382 | function accept_errors() | 383 | function accept_errors() |
383 | io.write("not listening: ") | 384 | io.stderr:write("not listening: ") |
384 | local d, e = socket.bind("*", 0) | 385 | local d, e = socket.bind("*", 0) |
385 | assert(d, e); | 386 | assert(d, e); |
386 | local c, e = socket.tcp(); | 387 | local c, e = socket.tcp(); |
387 | assert(c, e); | 388 | assert(c, e); |
388 | d:setfd(c:getfd()) | 389 | d:setfd(c:getfd()) |
390 | d:settimeout(2) | ||
389 | local r, e = d:accept() | 391 | local r, e = d:accept() |
390 | assert(not r and e == "not listening", e) | 392 | assert(not r and e == "not listening", e) |
391 | print("ok") | 393 | print("ok") |
392 | io.write("not supported: ") | 394 | io.stderr:write("not supported: ") |
393 | local c, e = socket.udp() | 395 | local c, e = socket.udp() |
394 | assert(c, e); | 396 | assert(c, e); |
395 | d:setfd(c:getfd()) | 397 | d:setfd(c:getfd()) |
@@ -400,11 +402,11 @@ end | |||
400 | 402 | ||
401 | ------------------------------------------------------------------------ | 403 | ------------------------------------------------------------------------ |
402 | function connect_errors() | 404 | function connect_errors() |
403 | io.write("connection refused: ") | 405 | io.stderr:write("connection refused: ") |
404 | local c, e = socket.connect("localhost", 1); | 406 | local c, e = socket.connect("localhost", 1); |
405 | assert(not c and e == "connection refused", e) | 407 | assert(not c and e == "connection refused", e) |
406 | print("ok") | 408 | print("ok") |
407 | io.write("host not found: ") | 409 | io.stderr:write("host not found: ") |
408 | local c, e = socket.connect("not.exist.com", 1); | 410 | local c, e = socket.connect("not.exist.com", 1); |
409 | assert(not c and e == "host not found", e) | 411 | assert(not c and e == "host not found", e) |
410 | print("ok") | 412 | print("ok") |
@@ -534,7 +536,7 @@ test_raw(1) | |||
534 | test("non-blocking transfer") | 536 | test("non-blocking transfer") |
535 | reconnect() | 537 | reconnect() |
536 | -- the value is not important, we only want | 538 | -- the value is not important, we only want |
537 | -- to test non-blockin I/O anyways | 539 | -- to test non-blocking I/O anyways |
538 | data:settimeout(200) | 540 | data:settimeout(200) |
539 | test_raw(1) | 541 | test_raw(1) |
540 | test_raw(17) | 542 | test_raw(17) |
diff --git a/test/urltest.lua b/test/urltest.lua index 7b1f0c0..990a3e5 100644 --- a/test/urltest.lua +++ b/test/urltest.lua | |||
@@ -35,8 +35,6 @@ local check_parse_path = function(path, expect) | |||
35 | for i = 1, math.max(table.getn(parsed), table.getn(expect)) do | 35 | for i = 1, math.max(table.getn(parsed), table.getn(expect)) do |
36 | if parsed[i] ~= expect[i] then | 36 | if parsed[i] ~= expect[i] then |
37 | print(path) | 37 | print(path) |
38 | write("segment: ", i, " = '", Code.hexa(tostring(parsed[i])), | ||
39 | "' but expected '", Code.hexa(tostring(expect[i])), "'\n") | ||
40 | exit() | 38 | exit() |
41 | end | 39 | end |
42 | end | 40 | end |