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 |
