diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2005-02-08 10:01:01 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2005-02-08 10:01:01 +0000 |
| commit | 8d4e240f6ae50d9b22ddc44f5e207018935da907 (patch) | |
| tree | d8ca9a51dc35534592f700e42740feac20242ede | |
| parent | 5d32848674b723521e87836eafa24f5ae8f80a89 (diff) | |
| download | luasocket-8d4e240f6ae50d9b22ddc44f5e207018935da907.tar.gz luasocket-8d4e240f6ae50d9b22ddc44f5e207018935da907.tar.bz2 luasocket-8d4e240f6ae50d9b22ddc44f5e207018935da907.zip | |
Forward server working on Mac OS X...
| -rw-r--r-- | FIX | 7 | ||||
| -rw-r--r-- | TODO | 40 | ||||
| -rw-r--r-- | doc/ftp.html | 12 | ||||
| -rw-r--r-- | doc/http.html | 8 | ||||
| -rw-r--r-- | doc/introduction.html | 10 | ||||
| -rw-r--r-- | doc/ltn12.html | 2 | ||||
| -rw-r--r-- | doc/smtp.html | 6 | ||||
| -rw-r--r-- | doc/socket.html | 9 | ||||
| -rw-r--r-- | doc/url.html | 6 | ||||
| -rw-r--r-- | src/buffer.c | 2 | ||||
| -rw-r--r-- | src/inet.c | 1 | ||||
| -rw-r--r-- | src/luasocket.c | 4 | ||||
| -rw-r--r-- | src/luasocket.h | 4 | ||||
| -rw-r--r-- | src/mime.c | 4 | ||||
| -rw-r--r-- | src/mime.h | 2 | ||||
| -rw-r--r-- | src/mime.lua | 3 | ||||
| -rw-r--r-- | src/socket.h | 4 | ||||
| -rw-r--r-- | src/socket.lua | 3 | ||||
| -rw-r--r-- | src/tcp.c | 22 | ||||
| -rw-r--r-- | src/unix.c | 27 | ||||
| -rw-r--r-- | src/unix.h | 2 | ||||
| -rw-r--r-- | src/usocket.c | 26 | ||||
| -rw-r--r-- | src/wsocket.c | 15 | ||||
| -rw-r--r-- | test/dicttest.lua | 2 | ||||
| -rw-r--r-- | test/httptest.lua | 2 | ||||
| -rw-r--r-- | test/testclnt.lua | 16 | ||||
| -rw-r--r-- | test/testsrvr.lua | 1 | ||||
| -rw-r--r-- | test/utestclnt.lua | 644 | ||||
| -rw-r--r-- | test/utestsrvr.lua | 17 |
29 files changed, 800 insertions, 101 deletions
| @@ -1,2 +1,9 @@ | |||
| 1 | tcp{client}:shutdown() was checking for group instead of class. | 1 | tcp{client}:shutdown() was checking for group instead of class. |
| 2 | tcp{client}:send() now returns i+sent-1... | 2 | tcp{client}:send() now returns i+sent-1... |
| 3 | get rid of a = socket.try() in the manual, except for protected cases. | ||
| 4 | replace it with assert. | ||
| 5 | get rid of "base." kludge | ||
| 6 | check all "require("http")" etc in the manual. | ||
| 7 | make sure sock_gethostname.* only return success if the hp is not null! | ||
| 8 | change 'l' prefix in C libraries to 'l-something'... | ||
| 9 | don't forget the declarations in luasocket.h and mime.h!!! | ||
| @@ -1,6 +1,7 @@ | |||
| 1 | get rid of a = socket.try() in the manual, except for protected cases. | ||
| 2 | replace it with assert. | ||
| 3 | 1 | ||
| 2 | BUG NO SET DO TINYIRC!!! SINISTRO. | ||
| 3 | talk about the non-blocking connect in the manual | ||
| 4 | test it on Windows!!! | ||
| 4 | 5 | ||
| 5 | think about a dispatcher. | 6 | think about a dispatcher. |
| 6 | - it creates a server and receives a function that will do the work on | 7 | - it creates a server and receives a function that will do the work on |
| @@ -13,17 +14,9 @@ functions for non-blocking so they can be used in the context of the | |||
| 13 | dispatcher! | 14 | dispatcher! |
| 14 | 15 | ||
| 15 | adjust manual for new sock:send returns. | 16 | adjust manual for new sock:send returns. |
| 16 | check all "require("http")" etc in the manual. | ||
| 17 | _VERSION, _DEBUG, etc. | 17 | _VERSION, _DEBUG, etc. |
| 18 | get rid of "base." kludge | ||
| 19 | make sure sock_gethostname.* only return success if the hp is not | ||
| 20 | null! | ||
| 21 | change 'l' prefix in C libraries to 'l-something'... | ||
| 22 | don't forget the declarations in luasocket.h and mime.h!!! | ||
| 23 | leave code for losers that don't have nanosleep | ||
| 24 | 18 | ||
| 25 | "foo.bar.baz" previously had to provide luaopen_foobarbaz() and now | 19 | leave code for losers that don't have nanosleep |
| 26 | should use luaopen_foo_bar_baz(). Change compat-5.1 and LuaSocket? | ||
| 27 | 20 | ||
| 28 | ftp.send/recv return bytes transfered? | 21 | ftp.send/recv return bytes transfered? |
| 29 | new scheme to choose family/protocol of object to create | 22 | new scheme to choose family/protocol of object to create |
| @@ -47,27 +40,4 @@ testar os options! | |||
| 47 | - proteger ou atomizar o conjunto (timedout, receive), (timedout, send) | 40 | - proteger ou atomizar o conjunto (timedout, receive), (timedout, send) |
| 48 | - inet_ntoa também é uma merda. | 41 | - inet_ntoa também é uma merda. |
| 49 | 42 | ||
| 50 | *eliminate globals from namespaces created by module(). | 43 | eliminate globals from namespaces created by module(). |
| 51 | *make sure standard libraries are "required" by modules before use. | ||
| 52 | *use wim's filter.chain or something better | ||
| 53 | *close wasn't returning 1 | ||
| 54 | *make sure errors not thrown by try() are not caught by protect() | ||
| 55 | *move wsocket.c:sock_send kludge to buffer.c:sendraw? | ||
| 56 | *bug on UDP sendto. | ||
| 57 | *fix PROXY in http.lua | ||
| 58 | *use new distribution scheme | ||
| 59 | *create the getstats method. | ||
| 60 | *fix local domain socket kludge of name size | ||
| 61 | *use TLS | ||
| 62 | *sort out the wrap around of gettime... | ||
| 63 | *use doubles all over | ||
| 64 | *sock_send, sock_recv & sock_select use p_tm instead of timeout | ||
| 65 | *make select interrupt safe (will be with tm stuff) | ||
| 66 | *use GetSystemTimeAsFileTime in windows (WinCE will suffer document) | ||
| 67 | *add getstats to the manual | ||
| 68 | *Fazer compilar com g++ | ||
| 69 | *test associativity of socket.select | ||
| 70 | * fix manual for send and receive | ||
| 71 | * add thanks to mike | ||
| 72 | * change sock:send to use indices just like string.sub? | ||
| 73 | * change sendraw to send by chunks | ||
diff --git a/doc/ftp.html b/doc/ftp.html index 454d417..7860c27 100644 --- a/doc/ftp.html +++ b/doc/ftp.html | |||
| @@ -65,7 +65,7 @@ To obtain the <tt>ftp</tt> namespace, run: | |||
| 65 | 65 | ||
| 66 | <pre class=example> | 66 | <pre class=example> |
| 67 | -- loads the FTP module and any libraries it requires | 67 | -- loads the FTP module and any libraries it requires |
| 68 | local ftp = require("ftp") | 68 | local ftp = require("socket.ftp") |
| 69 | </pre> | 69 | </pre> |
| 70 | 70 | ||
| 71 | <p> | 71 | <p> |
| @@ -150,7 +150,7 @@ error. | |||
| 150 | 150 | ||
| 151 | <pre class=example> | 151 | <pre class=example> |
| 152 | -- load the ftp support | 152 | -- load the ftp support |
| 153 | local ftp = require("ftp") | 153 | local ftp = require("socket.ftp") |
| 154 | 154 | ||
| 155 | -- Log as user "anonymous" on server "ftp.tecgraf.puc-rio.br", | 155 | -- Log as user "anonymous" on server "ftp.tecgraf.puc-rio.br", |
| 156 | -- and get file "lua.tar.gz" from directory "pub/lua" as binary. | 156 | -- and get file "lua.tar.gz" from directory "pub/lua" as binary. |
| @@ -159,9 +159,9 @@ f, e = ftp.get("ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz;type=i") | |||
| 159 | 159 | ||
| 160 | <pre class=example> | 160 | <pre class=example> |
| 161 | -- load needed modules | 161 | -- load needed modules |
| 162 | local ftp = require("ftp") | 162 | local ftp = require("socket.ftp") |
| 163 | local ltn12 = require("ltn12") | 163 | local ltn12 = require("ltn12") |
| 164 | local url = require("url") | 164 | local url = require("socket.url") |
| 165 | 165 | ||
| 166 | -- a function that returns a directory listing | 166 | -- a function that returns a directory listing |
| 167 | function nlst(u) | 167 | function nlst(u) |
| @@ -230,7 +230,7 @@ message describing the reason for failure. | |||
| 230 | 230 | ||
| 231 | <pre class=example> | 231 | <pre class=example> |
| 232 | -- load the ftp support | 232 | -- load the ftp support |
| 233 | local ftp = require("ftp") | 233 | local ftp = require("socket.ftp") |
| 234 | 234 | ||
| 235 | -- Log as user "fulano" on server "ftp.example.com", | 235 | -- Log as user "fulano" on server "ftp.example.com", |
| 236 | -- using password "silva", and store a file "README" with contents | 236 | -- using password "silva", and store a file "README" with contents |
| @@ -241,7 +241,7 @@ f, e = ftp.put("ftp://fulano:silva@ftp.example.com/README", | |||
| 241 | 241 | ||
| 242 | <pre class=example> | 242 | <pre class=example> |
| 243 | -- load the ftp support | 243 | -- load the ftp support |
| 244 | local ftp = require("ftp") | 244 | local ftp = require("socket.ftp") |
| 245 | local ltn12 = require("ltn12") | 245 | local ltn12 = require("ltn12") |
| 246 | 246 | ||
| 247 | -- Log as user "fulano" on server "ftp.example.com", | 247 | -- Log as user "fulano" on server "ftp.example.com", |
diff --git a/doc/http.html b/doc/http.html index 4cbbe95..af58571 100644 --- a/doc/http.html +++ b/doc/http.html | |||
| @@ -62,7 +62,7 @@ To obtain the <tt>http</tt> namespace, run: | |||
| 62 | 62 | ||
| 63 | <pre class=example> | 63 | <pre class=example> |
| 64 | -- loads the HTTP module and any libraries it requires | 64 | -- loads the HTTP module and any libraries it requires |
| 65 | local http = require("http") | 65 | local http = require("socket.http") |
| 66 | </pre> | 66 | </pre> |
| 67 | 67 | ||
| 68 | <p> | 68 | <p> |
| @@ -206,7 +206,7 @@ Here are a few examples with the simple interface: | |||
| 206 | 206 | ||
| 207 | <pre class=example> | 207 | <pre class=example> |
| 208 | -- load the http module | 208 | -- load the http module |
| 209 | http = require("http") | 209 | http = require("socket.http") |
| 210 | 210 | ||
| 211 | -- connect to server "www.tecgraf.puc-rio.br" and retrieves this manual | 211 | -- connect to server "www.tecgraf.puc-rio.br" and retrieves this manual |
| 212 | -- file from "/luasocket/http.html" | 212 | -- file from "/luasocket/http.html" |
| @@ -231,7 +231,7 @@ And here is an example using the generic interface: | |||
| 231 | 231 | ||
| 232 | <pre class=example> | 232 | <pre class=example> |
| 233 | -- load the http module | 233 | -- load the http module |
| 234 | http = require("http") | 234 | http = require("socket.http") |
| 235 | 235 | ||
| 236 | -- Requests information about a document, without downloading it. | 236 | -- Requests information about a document, without downloading it. |
| 237 | -- Useful, for example, if you want to display a download gauge and need | 237 | -- Useful, for example, if you want to display a download gauge and need |
| @@ -276,7 +276,7 @@ authentication is required. | |||
| 276 | 276 | ||
| 277 | <pre class=example> | 277 | <pre class=example> |
| 278 | -- load required modules | 278 | -- load required modules |
| 279 | http = require("http") | 279 | http = require("socket.http") |
| 280 | mime = require("mime") | 280 | mime = require("mime") |
| 281 | 281 | ||
| 282 | -- Connect to server "www.example.com" and tries to retrieve | 282 | -- Connect to server "www.example.com" and tries to retrieve |
diff --git a/doc/introduction.html b/doc/introduction.html index f8fe078..c88fa40 100644 --- a/doc/introduction.html +++ b/doc/introduction.html | |||
| @@ -182,7 +182,7 @@ program. | |||
| 182 | -- load namespace | 182 | -- load namespace |
| 183 | local socket = require("socket") | 183 | local socket = require("socket") |
| 184 | -- create a TCP socket and bind it to the local host, at any port | 184 | -- create a TCP socket and bind it to the local host, at any port |
| 185 | local server = socket.try(socket.bind("*", 0)) | 185 | local server = assert(socket.bind("*", 0)) |
| 186 | -- find out which port the OS chose for us | 186 | -- find out which port the OS chose for us |
| 187 | local ip, port = server:getsockname() | 187 | local ip, port = server:getsockname() |
| 188 | -- print a message informing what's up | 188 | -- print a message informing what's up |
| @@ -287,13 +287,13 @@ local host, port = "localhost", 13 | |||
| 287 | -- load namespace | 287 | -- load namespace |
| 288 | local socket = require("socket") | 288 | local socket = require("socket") |
| 289 | -- convert host name to ip address | 289 | -- convert host name to ip address |
| 290 | local ip = socket.try(socket.dns.toip(host)) | 290 | local ip = assert(socket.dns.toip(host)) |
| 291 | -- create a new UDP object | 291 | -- create a new UDP object |
| 292 | local udp = socket.try(socket.udp()) | 292 | local udp = assert(socket.udp()) |
| 293 | -- contact daytime host | 293 | -- contact daytime host |
| 294 | socket.try(udp:sendto("anything", ip, port)) | 294 | assert(udp:sendto("anything", ip, port)) |
| 295 | -- retrieve the answer and print results | 295 | -- retrieve the answer and print results |
| 296 | io.write(socket.try((udp:receive()))) | 296 | io.write(assert(udp:receive())) |
| 297 | </pre> | 297 | </pre> |
| 298 | </blockquote> | 298 | </blockquote> |
| 299 | 299 | ||
diff --git a/doc/ltn12.html b/doc/ltn12.html index 44fcbe4..c5a0f59 100644 --- a/doc/ltn12.html +++ b/doc/ltn12.html | |||
| @@ -271,7 +271,7 @@ The function returns the sink and the table used to store the chunks. | |||
| 271 | 271 | ||
| 272 | <pre class=example> | 272 | <pre class=example> |
| 273 | -- load needed modules | 273 | -- load needed modules |
| 274 | local http = require("http") | 274 | local http = require("socket.http") |
| 275 | local ltn12 = require("ltn12") | 275 | local ltn12 = require("ltn12") |
| 276 | 276 | ||
| 277 | -- a simplified http.get function | 277 | -- a simplified http.get function |
diff --git a/doc/smtp.html b/doc/smtp.html index 8feae3e..bd18bfa 100644 --- a/doc/smtp.html +++ b/doc/smtp.html | |||
| @@ -69,7 +69,7 @@ To obtain the <tt>smtp</tt> namespace, run: | |||
| 69 | 69 | ||
| 70 | <pre class=example> | 70 | <pre class=example> |
| 71 | -- loads the SMTP module and everything it requires | 71 | -- loads the SMTP module and everything it requires |
| 72 | local smtp = require("smtp") | 72 | local smtp = require("socket.smtp") |
| 73 | </pre> | 73 | </pre> |
| 74 | 74 | ||
| 75 | <p> | 75 | <p> |
| @@ -239,7 +239,7 @@ and | |||
| 239 | 239 | ||
| 240 | <pre class=example> | 240 | <pre class=example> |
| 241 | -- load the smtp support | 241 | -- load the smtp support |
| 242 | local smtp = require("smtp") | 242 | local smtp = require("socket.smtp") |
| 243 | 243 | ||
| 244 | -- Connects to server "localhost" and sends a message to users | 244 | -- Connects to server "localhost" and sends a message to users |
| 245 | -- "fulano@example.com", "beltrano@example.com", | 245 | -- "fulano@example.com", "beltrano@example.com", |
| @@ -329,7 +329,7 @@ as listed in the introduction. </p> | |||
| 329 | 329 | ||
| 330 | <pre class=example> | 330 | <pre class=example> |
| 331 | -- load the smtp support and its friends | 331 | -- load the smtp support and its friends |
| 332 | local smtp = require("smtp") | 332 | local smtp = require("socket.smtp") |
| 333 | local mime = require("mime") | 333 | local mime = require("mime") |
| 334 | local ltn12 = require("ltn12") | 334 | local ltn12 = require("ltn12") |
| 335 | 335 | ||
diff --git a/doc/socket.html b/doc/socket.html index f638fd9..18c71d1 100644 --- a/doc/socket.html +++ b/doc/socket.html | |||
| @@ -145,7 +145,10 @@ socket.<b>protect(</b>func<b>)</b> | |||
| 145 | </p> | 145 | </p> |
| 146 | 146 | ||
| 147 | <p class=description> | 147 | <p class=description> |
| 148 | Converts a function that throws exceptions into a safe function. | 148 | Converts a function that throws exceptions into a safe function. This |
| 149 | function only catches exceptions thrown by the <a href=#try><tt>try</tt></a> | ||
| 150 | and <a href=#newtry><tt>newtry</tt></a> functions. It does not catch normal | ||
| 151 | Lua errors. | ||
| 149 | </p> | 152 | </p> |
| 150 | 153 | ||
| 151 | <p class=parameters> | 154 | <p class=parameters> |
| @@ -346,7 +349,9 @@ socket.<b>try(</b>ret<sub>1</sub> [, ret<sub>2</sub> ... ret<sub>N</sub>]<b>)</b | |||
| 346 | </p> | 349 | </p> |
| 347 | 350 | ||
| 348 | <p class=description> | 351 | <p class=description> |
| 349 | Throws an exception in case of error. | 352 | Throws an exception in case of error. The exception can only be caught |
| 353 | by the <a href=#protect><tt>protect</tt></a> function. It does not explode | ||
| 354 | into an error message. | ||
| 350 | </p> | 355 | </p> |
| 351 | 356 | ||
| 352 | <p class=parameters> | 357 | <p class=parameters> |
diff --git a/doc/url.html b/doc/url.html index 56e1ef5..ac84d24 100644 --- a/doc/url.html +++ b/doc/url.html | |||
| @@ -52,7 +52,7 @@ To obtain the <tt>url</tt> namespace, run: | |||
| 52 | 52 | ||
| 53 | <pre class=example> | 53 | <pre class=example> |
| 54 | -- loads the URL module | 54 | -- loads the URL module |
| 55 | local url = require("url") | 55 | local url = require("socket.url") |
| 56 | </pre> | 56 | </pre> |
| 57 | 57 | ||
| 58 | <p> | 58 | <p> |
| @@ -193,7 +193,7 @@ The function returns the encoded string. | |||
| 193 | 193 | ||
| 194 | <pre class=example> | 194 | <pre class=example> |
| 195 | -- load url module | 195 | -- load url module |
| 196 | url = require("url") | 196 | url = require("socket.url") |
| 197 | 197 | ||
| 198 | code = url.escape("/#?;") | 198 | code = url.escape("/#?;") |
| 199 | -- code = "%2f%23%3f%3b" | 199 | -- code = "%2f%23%3f%3b" |
| @@ -239,7 +239,7 @@ parsed_url = {<br> | |||
| 239 | 239 | ||
| 240 | <pre class=example> | 240 | <pre class=example> |
| 241 | -- load url module | 241 | -- load url module |
| 242 | url = require("url") | 242 | url = require("socket.url") |
| 243 | 243 | ||
| 244 | parsed_url = url.parse("http://www.example.com/cgilua/index.lua?a=2#there") | 244 | parsed_url = url.parse("http://www.example.com/cgilua/index.lua?a=2#there") |
| 245 | -- parsed_url = { | 245 | -- parsed_url = { |
diff --git a/src/buffer.c b/src/buffer.c index 0ec7b4d..45cd0f2 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -123,7 +123,7 @@ int buf_meth_receive(lua_State *L, p_buf buf) { | |||
| 123 | else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b); | 123 | else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b); |
| 124 | else luaL_argcheck(L, 0, 2, "invalid receive pattern"); | 124 | else luaL_argcheck(L, 0, 2, "invalid receive pattern"); |
| 125 | /* get a fixed number of bytes */ | 125 | /* get a fixed number of bytes */ |
| 126 | } else err = recvraw(buf, (size_t) lua_tonumber(L, 2), &b); | 126 | } else err = recvraw(buf, (size_t) lua_tonumber(L, 2)-size, &b); |
| 127 | /* check if there was an error */ | 127 | /* check if there was an error */ |
| 128 | if (err != IO_DONE) { | 128 | if (err != IO_DONE) { |
| 129 | /* we can't push anyting in the stack before pushing the | 129 | /* we can't push anyting in the stack before pushing the |
| @@ -220,7 +220,6 @@ const char *inet_tryconnect(p_sock ps, const char *address, | |||
| 220 | } | 220 | } |
| 221 | } else remote.sin_family = AF_UNSPEC; | 221 | } else remote.sin_family = AF_UNSPEC; |
| 222 | err = sock_connect(ps, (SA *) &remote, sizeof(remote), tm); | 222 | err = sock_connect(ps, (SA *) &remote, sizeof(remote), tm); |
| 223 | if (err != IO_DONE) sock_destroy(ps); | ||
| 224 | return sock_strerror(err); | 223 | return sock_strerror(err); |
| 225 | } | 224 | } |
| 226 | 225 | ||
diff --git a/src/luasocket.c b/src/luasocket.c index 4b829f8..8f13dbc 100644 --- a/src/luasocket.c +++ b/src/luasocket.c | |||
| @@ -87,7 +87,7 @@ static int global_unload(lua_State *L) { | |||
| 87 | static int base_open(lua_State *L) { | 87 | static int base_open(lua_State *L) { |
| 88 | if (sock_open()) { | 88 | if (sock_open()) { |
| 89 | /* export functions (and leave namespace table on top of stack) */ | 89 | /* export functions (and leave namespace table on top of stack) */ |
| 90 | luaL_module(L, "socket", func, 0); | 90 | luaL_openlib(L, "socket", func, 0); |
| 91 | #ifdef LUASOCKET_DEBUG | 91 | #ifdef LUASOCKET_DEBUG |
| 92 | lua_pushstring(L, "DEBUG"); | 92 | lua_pushstring(L, "DEBUG"); |
| 93 | lua_pushboolean(L, 1); | 93 | lua_pushboolean(L, 1); |
| @@ -108,7 +108,7 @@ static int base_open(lua_State *L) { | |||
| 108 | /*-------------------------------------------------------------------------*\ | 108 | /*-------------------------------------------------------------------------*\ |
| 109 | * Initializes all library modules. | 109 | * Initializes all library modules. |
| 110 | \*-------------------------------------------------------------------------*/ | 110 | \*-------------------------------------------------------------------------*/ |
| 111 | LUASOCKET_API int luaopen_lsocket(lua_State *L) { | 111 | LUASOCKET_API int luaopen_csocket(lua_State *L) { |
| 112 | int i; | 112 | int i; |
| 113 | base_open(L); | 113 | base_open(L); |
| 114 | for (i = 0; mod[i].name; i++) mod[i].func(L); | 114 | for (i = 0; mod[i].name; i++) mod[i].func(L); |
diff --git a/src/luasocket.h b/src/luasocket.h index db54a18..768e335 100644 --- a/src/luasocket.h +++ b/src/luasocket.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | /*-------------------------------------------------------------------------*\ | 13 | /*-------------------------------------------------------------------------*\ |
| 14 | * Current luasocket version | 14 | * Current luasocket version |
| 15 | \*-------------------------------------------------------------------------*/ | 15 | \*-------------------------------------------------------------------------*/ |
| 16 | #define LUASOCKET_VERSION "LuaSocket 2.0 (beta3)" | 16 | #define LUASOCKET_VERSION "LuaSocket 2.0" |
| 17 | #define LUASOCKET_COPYRIGHT "Copyright (C) 2004-2005 Diego Nehab" | 17 | #define LUASOCKET_COPYRIGHT "Copyright (C) 2004-2005 Diego Nehab" |
| 18 | #define LUASOCKET_AUTHORS "Diego Nehab" | 18 | #define LUASOCKET_AUTHORS "Diego Nehab" |
| 19 | 19 | ||
| @@ -27,6 +27,6 @@ | |||
| 27 | /*-------------------------------------------------------------------------*\ | 27 | /*-------------------------------------------------------------------------*\ |
| 28 | * Initializes the library. | 28 | * Initializes the library. |
| 29 | \*-------------------------------------------------------------------------*/ | 29 | \*-------------------------------------------------------------------------*/ |
| 30 | LUASOCKET_API int luaopen_socket(lua_State *L); | 30 | LUASOCKET_API int luaopen_csocket(lua_State *L); |
| 31 | 31 | ||
| 32 | #endif /* LUASOCKET_H */ | 32 | #endif /* LUASOCKET_H */ |
| @@ -78,9 +78,9 @@ static UC b64unbase[256]; | |||
| 78 | /*-------------------------------------------------------------------------*\ | 78 | /*-------------------------------------------------------------------------*\ |
| 79 | * Initializes module | 79 | * Initializes module |
| 80 | \*-------------------------------------------------------------------------*/ | 80 | \*-------------------------------------------------------------------------*/ |
| 81 | MIME_API int luaopen_lmime(lua_State *L) | 81 | MIME_API int luaopen_cmime(lua_State *L) |
| 82 | { | 82 | { |
| 83 | luaL_module(L, "mime", func, 0); | 83 | luaL_openlib(L, "mime", func, 0); |
| 84 | /* initialize lookup tables */ | 84 | /* initialize lookup tables */ |
| 85 | qpsetup(qpclass, qpunbase); | 85 | qpsetup(qpclass, qpunbase); |
| 86 | b64setup(b64unbase); | 86 | b64setup(b64unbase); |
| @@ -19,6 +19,6 @@ | |||
| 19 | #define MIME_API extern | 19 | #define MIME_API extern |
| 20 | #endif | 20 | #endif |
| 21 | 21 | ||
| 22 | MIME_API int luaopen_mime(lua_State *L); | 22 | MIME_API int luaopen_cmime(lua_State *L); |
| 23 | 23 | ||
| 24 | #endif /* MIME_H */ | 24 | #endif /* MIME_H */ |
diff --git a/src/mime.lua b/src/mime.lua index 4d5bdba..6492a96 100644 --- a/src/mime.lua +++ b/src/mime.lua | |||
| @@ -8,9 +8,10 @@ | |||
| 8 | ----------------------------------------------------------------------------- | 8 | ----------------------------------------------------------------------------- |
| 9 | -- Declare module and import dependencies | 9 | -- Declare module and import dependencies |
| 10 | ----------------------------------------------------------------------------- | 10 | ----------------------------------------------------------------------------- |
| 11 | package.loaded.base = _G | ||
| 11 | local base = require("base") | 12 | local base = require("base") |
| 12 | local ltn12 = require("ltn12") | 13 | local ltn12 = require("ltn12") |
| 13 | local mime = require("lmime") | 14 | local mime = require("cmime") |
| 14 | module("mime") | 15 | module("mime") |
| 15 | 16 | ||
| 16 | -- encode, decode and wrap algorithm tables | 17 | -- encode, decode and wrap algorithm tables |
diff --git a/src/socket.h b/src/socket.h index 368c2b6..639229d 100644 --- a/src/socket.h +++ b/src/socket.h | |||
| @@ -45,11 +45,15 @@ int sock_sendto(p_sock ps, const char *data, size_t count, | |||
| 45 | size_t *sent, SA *addr, socklen_t addr_len, p_tm tm); | 45 | size_t *sent, SA *addr, socklen_t addr_len, p_tm tm); |
| 46 | int sock_recvfrom(p_sock ps, char *data, size_t count, | 46 | int sock_recvfrom(p_sock ps, char *data, size_t count, |
| 47 | size_t *got, SA *addr, socklen_t *addr_len, p_tm tm); | 47 | size_t *got, SA *addr, socklen_t *addr_len, p_tm tm); |
| 48 | |||
| 48 | void sock_setnonblocking(p_sock ps); | 49 | void sock_setnonblocking(p_sock ps); |
| 49 | void sock_setblocking(p_sock ps); | 50 | void sock_setblocking(p_sock ps); |
| 51 | |||
| 52 | int sock_waitfd(int fd, int sw, p_tm tm); | ||
| 50 | int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_tm tm); | 53 | int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_tm tm); |
| 51 | 54 | ||
| 52 | int sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm); | 55 | int sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm); |
| 56 | int sock_connected(p_sock ps, p_tm tm); | ||
| 53 | int sock_create(p_sock ps, int domain, int type, int protocol); | 57 | int sock_create(p_sock ps, int domain, int type, int protocol); |
| 54 | int sock_bind(p_sock ps, SA *addr, socklen_t addr_len); | 58 | int sock_bind(p_sock ps, SA *addr, socklen_t addr_len); |
| 55 | int sock_listen(p_sock ps, int backlog); | 59 | int sock_listen(p_sock ps, int backlog); |
diff --git a/src/socket.lua b/src/socket.lua index 1c82750..f3563e7 100644 --- a/src/socket.lua +++ b/src/socket.lua | |||
| @@ -7,10 +7,11 @@ | |||
| 7 | ----------------------------------------------------------------------------- | 7 | ----------------------------------------------------------------------------- |
| 8 | -- Declare module and import dependencies | 8 | -- Declare module and import dependencies |
| 9 | ----------------------------------------------------------------------------- | 9 | ----------------------------------------------------------------------------- |
| 10 | package.loaded.base = _G | ||
| 10 | local base = require("base") | 11 | local base = require("base") |
| 11 | local string = require("string") | 12 | local string = require("string") |
| 12 | local math = require("math") | 13 | local math = require("math") |
| 13 | local socket = require("lsocket") | 14 | local socket = require("csocket") |
| 14 | module("socket") | 15 | module("socket") |
| 15 | 16 | ||
| 16 | ----------------------------------------------------------------------------- | 17 | ----------------------------------------------------------------------------- |
| @@ -20,6 +20,7 @@ | |||
| 20 | \*=========================================================================*/ | 20 | \*=========================================================================*/ |
| 21 | static int global_create(lua_State *L); | 21 | static int global_create(lua_State *L); |
| 22 | static int meth_connect(lua_State *L); | 22 | static int meth_connect(lua_State *L); |
| 23 | static int meth_connected(lua_State *L); | ||
| 23 | static int meth_listen(lua_State *L); | 24 | static int meth_listen(lua_State *L); |
| 24 | static int meth_bind(lua_State *L); | 25 | static int meth_bind(lua_State *L); |
| 25 | static int meth_send(lua_State *L); | 26 | static int meth_send(lua_State *L); |
| @@ -45,6 +46,7 @@ static luaL_reg tcp[] = { | |||
| 45 | {"bind", meth_bind}, | 46 | {"bind", meth_bind}, |
| 46 | {"close", meth_close}, | 47 | {"close", meth_close}, |
| 47 | {"connect", meth_connect}, | 48 | {"connect", meth_connect}, |
| 49 | {"connected", meth_connected}, | ||
| 48 | {"dirty", meth_dirty}, | 50 | {"dirty", meth_dirty}, |
| 49 | {"getfd", meth_getfd}, | 51 | {"getfd", meth_getfd}, |
| 50 | {"getpeername", meth_getpeername}, | 52 | {"getpeername", meth_getpeername}, |
| @@ -113,12 +115,12 @@ static int meth_receive(lua_State *L) { | |||
| 113 | } | 115 | } |
| 114 | 116 | ||
| 115 | static int meth_getstats(lua_State *L) { | 117 | static int meth_getstats(lua_State *L) { |
| 116 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | 118 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); |
| 117 | return buf_meth_getstats(L, &tcp->buf); | 119 | return buf_meth_getstats(L, &tcp->buf); |
| 118 | } | 120 | } |
| 119 | 121 | ||
| 120 | static int meth_setstats(lua_State *L) { | 122 | static int meth_setstats(lua_State *L) { |
| 121 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | 123 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); |
| 122 | return buf_meth_setstats(L, &tcp->buf); | 124 | return buf_meth_setstats(L, &tcp->buf); |
| 123 | } | 125 | } |
| 124 | 126 | ||
| @@ -224,6 +226,22 @@ static int meth_connect(lua_State *L) | |||
| 224 | return 1; | 226 | return 1; |
| 225 | } | 227 | } |
| 226 | 228 | ||
| 229 | static int meth_connected(lua_State *L) | ||
| 230 | { | ||
| 231 | static t_tm tm = {-1, -1}; | ||
| 232 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | ||
| 233 | int err = sock_connected(&tcp->sock, &tm); | ||
| 234 | if (err != IO_DONE) { | ||
| 235 | lua_pushnil(L); | ||
| 236 | lua_pushstring(L, sock_strerror(err)); | ||
| 237 | return 2; | ||
| 238 | } | ||
| 239 | /* turn master object into a client object */ | ||
| 240 | aux_setclass(L, "tcp{client}", 1); | ||
| 241 | lua_pushnumber(L, 1); | ||
| 242 | return 1; | ||
| 243 | } | ||
| 244 | |||
| 227 | /*-------------------------------------------------------------------------*\ | 245 | /*-------------------------------------------------------------------------*\ |
| 228 | * Closes socket used by object | 246 | * Closes socket used by object |
| 229 | \*-------------------------------------------------------------------------*/ | 247 | \*-------------------------------------------------------------------------*/ |
| @@ -32,6 +32,8 @@ static int meth_settimeout(lua_State *L); | |||
| 32 | static int meth_getfd(lua_State *L); | 32 | static int meth_getfd(lua_State *L); |
| 33 | static int meth_setfd(lua_State *L); | 33 | static int meth_setfd(lua_State *L); |
| 34 | static int meth_dirty(lua_State *L); | 34 | static int meth_dirty(lua_State *L); |
| 35 | static int meth_getstats(lua_State *L); | ||
| 36 | static int meth_setstats(lua_State *L); | ||
| 35 | 37 | ||
| 36 | static const char *unix_tryconnect(p_unix un, const char *path); | 38 | static const char *unix_tryconnect(p_unix un, const char *path); |
| 37 | static const char *unix_trybind(p_unix un, const char *path); | 39 | static const char *unix_trybind(p_unix un, const char *path); |
| @@ -46,6 +48,8 @@ static luaL_reg un[] = { | |||
| 46 | {"connect", meth_connect}, | 48 | {"connect", meth_connect}, |
| 47 | {"dirty", meth_dirty}, | 49 | {"dirty", meth_dirty}, |
| 48 | {"getfd", meth_getfd}, | 50 | {"getfd", meth_getfd}, |
| 51 | {"getstats", meth_getstats}, | ||
| 52 | {"setstats", meth_setstats}, | ||
| 49 | {"listen", meth_listen}, | 53 | {"listen", meth_listen}, |
| 50 | {"receive", meth_receive}, | 54 | {"receive", meth_receive}, |
| 51 | {"send", meth_send}, | 55 | {"send", meth_send}, |
| @@ -75,7 +79,7 @@ static luaL_reg func[] = { | |||
| 75 | /*-------------------------------------------------------------------------*\ | 79 | /*-------------------------------------------------------------------------*\ |
| 76 | * Initializes module | 80 | * Initializes module |
| 77 | \*-------------------------------------------------------------------------*/ | 81 | \*-------------------------------------------------------------------------*/ |
| 78 | int unix_open(lua_State *L) { | 82 | int luaopen_socketunix(lua_State *L) { |
| 79 | /* create classes */ | 83 | /* create classes */ |
| 80 | aux_newclass(L, "unix{master}", un); | 84 | aux_newclass(L, "unix{master}", un); |
| 81 | aux_newclass(L, "unix{client}", un); | 85 | aux_newclass(L, "unix{client}", un); |
| @@ -84,11 +88,9 @@ int unix_open(lua_State *L) { | |||
| 84 | aux_add2group(L, "unix{master}", "unix{any}"); | 88 | aux_add2group(L, "unix{master}", "unix{any}"); |
| 85 | aux_add2group(L, "unix{client}", "unix{any}"); | 89 | aux_add2group(L, "unix{client}", "unix{any}"); |
| 86 | aux_add2group(L, "unix{server}", "unix{any}"); | 90 | aux_add2group(L, "unix{server}", "unix{any}"); |
| 87 | aux_add2group(L, "unix{client}", "unix{client,server}"); | ||
| 88 | aux_add2group(L, "unix{server}", "unix{client,server}"); | ||
| 89 | /* define library functions */ | 91 | /* define library functions */ |
| 90 | luaL_openlib(L, NULL, func, 0); | 92 | luaL_openlib(L, "socket", func, 0); |
| 91 | return 0; | 93 | return 1; |
| 92 | } | 94 | } |
| 93 | 95 | ||
| 94 | /*=========================================================================*\ | 96 | /*=========================================================================*\ |
| @@ -107,6 +109,16 @@ static int meth_receive(lua_State *L) { | |||
| 107 | return buf_meth_receive(L, &un->buf); | 109 | return buf_meth_receive(L, &un->buf); |
| 108 | } | 110 | } |
| 109 | 111 | ||
| 112 | static int meth_getstats(lua_State *L) { | ||
| 113 | p_unix un = (p_unix) aux_checkclass(L, "unix{client}", 1); | ||
| 114 | return buf_meth_getstats(L, &un->buf); | ||
| 115 | } | ||
| 116 | |||
| 117 | static int meth_setstats(lua_State *L) { | ||
| 118 | p_unix un = (p_unix) aux_checkclass(L, "unix{client}", 1); | ||
| 119 | return buf_meth_setstats(L, &un->buf); | ||
| 120 | } | ||
| 121 | |||
| 110 | /*-------------------------------------------------------------------------*\ | 122 | /*-------------------------------------------------------------------------*\ |
| 111 | * Just call option handler | 123 | * Just call option handler |
| 112 | \*-------------------------------------------------------------------------*/ | 124 | \*-------------------------------------------------------------------------*/ |
| @@ -250,7 +262,8 @@ static int meth_close(lua_State *L) | |||
| 250 | { | 262 | { |
| 251 | p_unix un = (p_unix) aux_checkgroup(L, "unix{any}", 1); | 263 | p_unix un = (p_unix) aux_checkgroup(L, "unix{any}", 1); |
| 252 | sock_destroy(&un->sock); | 264 | sock_destroy(&un->sock); |
| 253 | return 0; | 265 | lua_pushnumber(L, 1); |
| 266 | return 1; | ||
| 254 | } | 267 | } |
| 255 | 268 | ||
| 256 | /*-------------------------------------------------------------------------*\ | 269 | /*-------------------------------------------------------------------------*\ |
| @@ -277,7 +290,7 @@ static int meth_listen(lua_State *L) | |||
| 277 | \*-------------------------------------------------------------------------*/ | 290 | \*-------------------------------------------------------------------------*/ |
| 278 | static int meth_shutdown(lua_State *L) | 291 | static int meth_shutdown(lua_State *L) |
| 279 | { | 292 | { |
| 280 | p_unix un = (p_unix) aux_checkgroup(L, "unix{client}", 1); | 293 | p_unix un = (p_unix) aux_checkclass(L, "unix{client}", 1); |
| 281 | const char *how = luaL_optstring(L, 2, "both"); | 294 | const char *how = luaL_optstring(L, 2, "both"); |
| 282 | switch (how[0]) { | 295 | switch (how[0]) { |
| 283 | case 'b': | 296 | case 'b': |
| @@ -23,6 +23,6 @@ typedef struct t_unix_ { | |||
| 23 | } t_unix; | 23 | } t_unix; |
| 24 | typedef t_unix *p_unix; | 24 | typedef t_unix *p_unix; |
| 25 | 25 | ||
| 26 | int unix_open(lua_State *L); | 26 | int luaopen_socketunix(lua_State *L); |
| 27 | 27 | ||
| 28 | #endif /* UNIX_H */ | 28 | #endif /* UNIX_H */ |
diff --git a/src/usocket.c b/src/usocket.c index c1ab725..3428a0c 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #define WAITFD_R POLLIN | 22 | #define WAITFD_R POLLIN |
| 23 | #define WAITFD_W POLLOUT | 23 | #define WAITFD_W POLLOUT |
| 24 | #define WAITFD_C (POLLIN|POLLOUT) | 24 | #define WAITFD_C (POLLIN|POLLOUT) |
| 25 | static int sock_waitfd(int fd, int sw, p_tm tm) { | 25 | int sock_waitfd(int fd, int sw, p_tm tm) { |
| 26 | int ret; | 26 | int ret; |
| 27 | struct pollfd pfd; | 27 | struct pollfd pfd; |
| 28 | pfd.fd = fd; | 28 | pfd.fd = fd; |
| @@ -44,7 +44,7 @@ static int sock_waitfd(int fd, int sw, p_tm tm) { | |||
| 44 | #define WAITFD_W 2 | 44 | #define WAITFD_W 2 |
| 45 | #define WAITFD_C (WAITFD_R|WAITFD_W) | 45 | #define WAITFD_C (WAITFD_R|WAITFD_W) |
| 46 | 46 | ||
| 47 | static int sock_waitfd(int fd, int sw, p_tm tm) { | 47 | int sock_waitfd(int fd, int sw, p_tm tm) { |
| 48 | int ret; | 48 | int ret; |
| 49 | fd_set rfds, wfds, *rp, *wp; | 49 | fd_set rfds, wfds, *rp, *wp; |
| 50 | struct timeval tv, *tp; | 50 | struct timeval tv, *tp; |
| @@ -166,12 +166,20 @@ int sock_connect(p_sock ps, SA *addr, socklen_t len, p_tm tm) { | |||
| 166 | while ((err = errno) == EINTR); | 166 | while ((err = errno) == EINTR); |
| 167 | /* if connection failed immediately, return error code */ | 167 | /* if connection failed immediately, return error code */ |
| 168 | if (err != EINPROGRESS && err != EAGAIN) return err; | 168 | if (err != EINPROGRESS && err != EAGAIN) return err; |
| 169 | /* zero timeout case optimization */ | ||
| 170 | if (tm_iszero(tm)) return IO_TIMEOUT; | ||
| 169 | /* wait until we have the result of the connection attempt or timeout */ | 171 | /* wait until we have the result of the connection attempt or timeout */ |
| 170 | if ((err = sock_waitfd(*ps, WAITFD_C, tm)) == IO_CLOSED) { | 172 | return sock_connected(ps, tm); |
| 171 | /* finaly find out if we succeeded connecting */ | 173 | } |
| 174 | |||
| 175 | /*-------------------------------------------------------------------------*\ | ||
| 176 | * Checks if socket is connected, or return reason for failure | ||
| 177 | \*-------------------------------------------------------------------------*/ | ||
| 178 | int sock_connected(p_sock ps, p_tm tm) { | ||
| 179 | int err; | ||
| 180 | if ((err = sock_waitfd(*ps, WAITFD_C, tm) == IO_CLOSED)) { | ||
| 172 | if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE; | 181 | if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE; |
| 173 | else return errno; | 182 | else return errno; |
| 174 | /* timed out or some weirder error */ | ||
| 175 | } else return err; | 183 | } else return err; |
| 176 | } | 184 | } |
| 177 | 185 | ||
| @@ -321,13 +329,17 @@ void sock_setnonblocking(p_sock ps) { | |||
| 321 | int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { | 329 | int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { |
| 322 | *hp = gethostbyaddr(addr, len, AF_INET); | 330 | *hp = gethostbyaddr(addr, len, AF_INET); |
| 323 | if (*hp) return IO_DONE; | 331 | if (*hp) return IO_DONE; |
| 324 | else return h_errno; | 332 | else if (h_errno) return h_errno; |
| 333 | else if (errno) return errno; | ||
| 334 | else return IO_UNKNOWN; | ||
| 325 | } | 335 | } |
| 326 | 336 | ||
| 327 | int sock_gethostbyname(const char *addr, struct hostent **hp) { | 337 | int sock_gethostbyname(const char *addr, struct hostent **hp) { |
| 328 | *hp = gethostbyname(addr); | 338 | *hp = gethostbyname(addr); |
| 329 | if (*hp) return IO_DONE; | 339 | if (*hp) return IO_DONE; |
| 330 | else return h_errno; | 340 | else if (h_errno) return h_errno; |
| 341 | else if (errno) return errno; | ||
| 342 | else return IO_UNKNOWN; | ||
| 331 | } | 343 | } |
| 332 | 344 | ||
| 333 | /*-------------------------------------------------------------------------*\ | 345 | /*-------------------------------------------------------------------------*\ |
diff --git a/src/wsocket.c b/src/wsocket.c index 69fac4d..c0686cd 100644 --- a/src/wsocket.c +++ b/src/wsocket.c | |||
| @@ -45,7 +45,7 @@ int sock_close(void) { | |||
| 45 | #define WAITFD_E 4 | 45 | #define WAITFD_E 4 |
| 46 | #define WAITFD_C (WAITFD_E|WAITFD_W) | 46 | #define WAITFD_C (WAITFD_E|WAITFD_W) |
| 47 | 47 | ||
| 48 | static int sock_waitfd(t_sock fd, int sw, p_tm tm) { | 48 | int sock_waitfd(t_sock fd, int sw, p_tm tm) { |
| 49 | int ret; | 49 | int ret; |
| 50 | fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL; | 50 | fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL; |
| 51 | struct timeval tv, *tp = NULL; | 51 | struct timeval tv, *tp = NULL; |
| @@ -118,7 +118,17 @@ int sock_connect(p_sock ps, SA *addr, socklen_t len, p_tm tm) { | |||
| 118 | /* make sure the system is trying to connect */ | 118 | /* make sure the system is trying to connect */ |
| 119 | err = WSAGetLastError(); | 119 | err = WSAGetLastError(); |
| 120 | if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err; | 120 | if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err; |
| 121 | /* zero timeout case optimization */ | ||
| 122 | if (tm_iszero(tm)) return IO_TIMEOUT; | ||
| 121 | /* we wait until something happens */ | 123 | /* we wait until something happens */ |
| 124 | return sock_connected(ps, tm); | ||
| 125 | } | ||
| 126 | |||
| 127 | /*-------------------------------------------------------------------------*\ | ||
| 128 | * Check if socket is connected | ||
| 129 | \*-------------------------------------------------------------------------*/ | ||
| 130 | int sock_connected(p_sock ps) { | ||
| 131 | int err; | ||
| 122 | if ((err = sock_waitfd(*ps, WAITFD_C, tm)) == IO_CLOSED) { | 132 | if ((err = sock_waitfd(*ps, WAITFD_C, tm)) == IO_CLOSED) { |
| 123 | int len = sizeof(err); | 133 | int len = sizeof(err); |
| 124 | /* give windows time to set the error (yes, disgusting) */ | 134 | /* give windows time to set the error (yes, disgusting) */ |
| @@ -126,9 +136,8 @@ int sock_connect(p_sock ps, SA *addr, socklen_t len, p_tm tm) { | |||
| 126 | /* find out why we failed */ | 136 | /* find out why we failed */ |
| 127 | getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); | 137 | getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); |
| 128 | /* we KNOW there was an error. if why is 0, we will return | 138 | /* we KNOW there was an error. if why is 0, we will return |
| 129 | * "unknown error", but it's not really our fault */ | 139 | * "unknown error", but it's not really our fault */ |
| 130 | return err > 0? err: IO_UNKNOWN; | 140 | return err > 0? err: IO_UNKNOWN; |
| 131 | /* here we deal with the case in which it worked, timedout or weird errors */ | ||
| 132 | } else return err; | 141 | } else return err; |
| 133 | } | 142 | } |
| 134 | 143 | ||
diff --git a/test/dicttest.lua b/test/dicttest.lua index a37ec8d..7ac7811 100644 --- a/test/dicttest.lua +++ b/test/dicttest.lua | |||
| @@ -1,3 +1,3 @@ | |||
| 1 | local dict = require"socket.dict" | 1 | local dict = require"socket.dict" |
| 2 | 2 | ||
| 3 | for i,v in dict.get("dict://dell-diego/d:banana") do print(v) end | 3 | for i,v in dict.get("dict://localhost/d:teste") do print(v) end |
diff --git a/test/httptest.lua b/test/httptest.lua index 8862ceb..2335fcb 100644 --- a/test/httptest.lua +++ b/test/httptest.lua | |||
| @@ -23,7 +23,7 @@ http.TIMEOUT = 10 | |||
| 23 | local t = socket.gettime() | 23 | local t = socket.gettime() |
| 24 | 24 | ||
| 25 | host = host or "diego.student.princeton.edu" | 25 | host = host or "diego.student.princeton.edu" |
| 26 | proxy = proxy or "http://dell-diego:3128" | 26 | proxy = proxy or "http://localhost:3128" |
| 27 | prefix = prefix or "/luasocket-test" | 27 | prefix = prefix or "/luasocket-test" |
| 28 | cgiprefix = cgiprefix or "/luasocket-test-cgi" | 28 | cgiprefix = cgiprefix or "/luasocket-test-cgi" |
| 29 | index_file = "test/index.html" | 29 | index_file = "test/index.html" |
diff --git a/test/testclnt.lua b/test/testclnt.lua index c2c782c..e3f2b94 100644 --- a/test/testclnt.lua +++ b/test/testclnt.lua | |||
| @@ -465,16 +465,14 @@ print("Testing " .. 2*size .. " bytes") | |||
| 465 | remote(string.format([[ | 465 | remote(string.format([[ |
| 466 | data:send(string.rep("a", %d)) | 466 | data:send(string.rep("a", %d)) |
| 467 | socket.sleep(0.5) | 467 | socket.sleep(0.5) |
| 468 | data:send(string.rep("b", %d)) | 468 | data:send(string.rep("b", %d) .. "\n") |
| 469 | ]], size, size)) | 469 | ]], size, size)) |
| 470 | local err = "timeout" | 470 | local err = "timeout" |
| 471 | local part = "" | 471 | local part = "" |
| 472 | local str | 472 | local str |
| 473 | data:settimeout(0) | 473 | data:settimeout(0) |
| 474 | while 1 do | 474 | while 1 do |
| 475 | local needed = 2*size - string.len(part) | 475 | str, err, part = data:receive("*l", part) |
| 476 | assert(needed > 0, "weird") | ||
| 477 | str, err, part = data:receive(needed, part) | ||
| 478 | if err ~= "timeout" then break end | 476 | if err ~= "timeout" then break end |
| 479 | end | 477 | end |
| 480 | assert(str == (string.rep("a", size) .. string.rep("b", size))) | 478 | assert(str == (string.rep("a", size) .. string.rep("b", size))) |
| @@ -482,15 +480,14 @@ remote(string.format([[ | |||
| 482 | remote(string.format([[ | 480 | remote(string.format([[ |
| 483 | str = data:receive(%d) | 481 | str = data:receive(%d) |
| 484 | socket.sleep(0.5) | 482 | socket.sleep(0.5) |
| 485 | str = data:receive(%d, str) | 483 | str = data:receive(2*%d, str) |
| 486 | data:send(str) | 484 | data:send(str) |
| 487 | ]], size, size)) | 485 | ]], size, size)) |
| 488 | data:settimeout(0) | 486 | data:settimeout(0) |
| 489 | local sofar = 1 | 487 | local start = 0 |
| 490 | while 1 do | 488 | while 1 do |
| 491 | _, err, part = data:send(str, sofar) | 489 | ret, err, start = data:send(str, start+1) |
| 492 | if err ~= "timeout" then break end | 490 | if err ~= "timeout" then break end |
| 493 | sofar = sofar + part | ||
| 494 | end | 491 | end |
| 495 | data:send("\n") | 492 | data:send("\n") |
| 496 | data:settimeout(-1) | 493 | data:settimeout(-1) |
| @@ -501,6 +498,7 @@ end | |||
| 501 | 498 | ||
| 502 | ------------------------------------------------------------------------ | 499 | ------------------------------------------------------------------------ |
| 503 | 500 | ||
| 501 | |||
| 504 | test("method registration") | 502 | test("method registration") |
| 505 | test_methods(socket.tcp(), { | 503 | test_methods(socket.tcp(), { |
| 506 | "accept", | 504 | "accept", |
| @@ -622,7 +620,7 @@ test_nonblocking(17) | |||
| 622 | test_nonblocking(200) | 620 | test_nonblocking(200) |
| 623 | test_nonblocking(4091) | 621 | test_nonblocking(4091) |
| 624 | test_nonblocking(80199) | 622 | test_nonblocking(80199) |
| 625 | test_nonblocking(8000000) | 623 | test_nonblocking(800000) |
| 626 | test_nonblocking(80199) | 624 | test_nonblocking(80199) |
| 627 | test_nonblocking(4091) | 625 | test_nonblocking(4091) |
| 628 | test_nonblocking(200) | 626 | test_nonblocking(200) |
diff --git a/test/testsrvr.lua b/test/testsrvr.lua index 2408e83..f1972c2 100644 --- a/test/testsrvr.lua +++ b/test/testsrvr.lua | |||
| @@ -9,6 +9,7 @@ while 1 do | |||
| 9 | while 1 do | 9 | while 1 do |
| 10 | command = assert(control:receive()); | 10 | command = assert(control:receive()); |
| 11 | assert(control:send(ack)); | 11 | assert(control:send(ack)); |
| 12 | print(command); | ||
| 12 | (loadstring(command))(); | 13 | (loadstring(command))(); |
| 13 | end | 14 | end |
| 14 | end | 15 | end |
diff --git a/test/utestclnt.lua b/test/utestclnt.lua new file mode 100644 index 0000000..f002c6e --- /dev/null +++ b/test/utestclnt.lua | |||
| @@ -0,0 +1,644 @@ | |||
| 1 | require"socket" | ||
| 2 | local socket = require"socket.unix" | ||
| 3 | |||
| 4 | host = "luasocket" | ||
| 5 | |||
| 6 | function pass(...) | ||
| 7 | local s = string.format(unpack(arg)) | ||
| 8 | io.stderr:write(s, "\n") | ||
| 9 | end | ||
| 10 | |||
| 11 | function fail(...) | ||
| 12 | local s = string.format(unpack(arg)) | ||
| 13 | io.stderr:write("ERROR: ", s, "!\n") | ||
| 14 | socket.sleep(3) | ||
| 15 | os.exit() | ||
| 16 | end | ||
| 17 | |||
| 18 | function warn(...) | ||
| 19 | local s = string.format(unpack(arg)) | ||
| 20 | io.stderr:write("WARNING: ", s, "\n") | ||
| 21 | end | ||
| 22 | |||
| 23 | function remote(...) | ||
| 24 | local s = string.format(unpack(arg)) | ||
| 25 | s = string.gsub(s, "\n", ";") | ||
| 26 | s = string.gsub(s, "%s+", " ") | ||
| 27 | s = string.gsub(s, "^%s*", "") | ||
| 28 | control:send(s .. "\n") | ||
| 29 | control:receive() | ||
| 30 | end | ||
| 31 | |||
| 32 | function test(test) | ||
| 33 | io.stderr:write("----------------------------------------------\n", | ||
| 34 | "testing: ", test, "\n", | ||
| 35 | "----------------------------------------------\n") | ||
| 36 | end | ||
| 37 | |||
| 38 | function uconnect(path) | ||
| 39 | local u = assert(socket.unix()) | ||
| 40 | assert(u:connect(path)) | ||
| 41 | return u | ||
| 42 | end | ||
| 43 | |||
| 44 | function ubind(path) | ||
| 45 | local u = assert(socket.unix()) | ||
| 46 | assert(u:bind(path)) | ||
| 47 | assert(u:listen(5)) | ||
| 48 | return u | ||
| 49 | end | ||
| 50 | |||
| 51 | function check_timeout(tm, sl, elapsed, err, opp, mode, alldone) | ||
| 52 | if tm < sl then | ||
| 53 | if opp == "send" then | ||
| 54 | if not err then warn("must be buffered") | ||
| 55 | elseif err == "timeout" then pass("proper timeout") | ||
| 56 | else fail("unexpected error '%s'", err) end | ||
| 57 | else | ||
| 58 | if err ~= "timeout" then fail("should have timed out") | ||
| 59 | else pass("proper timeout") end | ||
| 60 | end | ||
| 61 | else | ||
| 62 | if mode == "total" then | ||
| 63 | if elapsed > tm then | ||
| 64 | if err ~= "timeout" then fail("should have timed out") | ||
| 65 | else pass("proper timeout") end | ||
| 66 | elseif elapsed < tm then | ||
| 67 | if err then fail(err) | ||
| 68 | else pass("ok") end | ||
| 69 | else | ||
| 70 | if alldone then | ||
| 71 | if err then fail("unexpected error '%s'", err) | ||
| 72 | else pass("ok") end | ||
| 73 | else | ||
| 74 | if err ~= "timeout" then fail(err) | ||
| 75 | else pass("proper timeoutk") end | ||
| 76 | end | ||
| 77 | end | ||
| 78 | else | ||
| 79 | if err then fail(err) | ||
| 80 | else pass("ok") end | ||
| 81 | end | ||
| 82 | end | ||
| 83 | end | ||
| 84 | |||
| 85 | if not socket.DEBUG then | ||
| 86 | fail("Please define LUASOCKET_DEBUG and recompile LuaSocket") | ||
| 87 | end | ||
| 88 | |||
| 89 | io.stderr:write("----------------------------------------------\n", | ||
| 90 | "LuaSocket Test Procedures\n", | ||
| 91 | "----------------------------------------------\n") | ||
| 92 | |||
| 93 | start = socket.gettime() | ||
| 94 | |||
| 95 | function reconnect() | ||
| 96 | io.stderr:write("attempting data connection... ") | ||
| 97 | if data then data:close() end | ||
| 98 | remote [[ | ||
| 99 | i = i or 1 | ||
| 100 | if data then data:close() data = nil end | ||
| 101 | print("accepting") | ||
| 102 | data = server:accept() | ||
| 103 | i = i + 1 | ||
| 104 | print("done " .. i) | ||
| 105 | ]] | ||
| 106 | data, err = uconnect(host, port) | ||
| 107 | if not data then fail(err) | ||
| 108 | else pass("connected!") end | ||
| 109 | end | ||
| 110 | |||
| 111 | pass("attempting control connection...") | ||
| 112 | control, err = uconnect(host, port) | ||
| 113 | if err then fail(err) | ||
| 114 | else pass("connected!") end | ||
| 115 | |||
| 116 | ------------------------------------------------------------------------ | ||
| 117 | function test_methods(sock, methods) | ||
| 118 | for _, v in methods do | ||
| 119 | if type(sock[v]) ~= "function" then | ||
| 120 | fail(sock.class .. " method '" .. v .. "' not registered") | ||
| 121 | end | ||
| 122 | end | ||
| 123 | pass(sock.class .. " methods are ok") | ||
| 124 | end | ||
| 125 | |||
| 126 | ------------------------------------------------------------------------ | ||
| 127 | function test_mixed(len) | ||
| 128 | reconnect() | ||
| 129 | local inter = math.ceil(len/4) | ||
| 130 | local p1 = "unix " .. string.rep("x", inter) .. "line\n" | ||
| 131 | local p2 = "dos " .. string.rep("y", inter) .. "line\r\n" | ||
| 132 | local p3 = "raw " .. string.rep("z", inter) .. "bytes" | ||
| 133 | local p4 = "end" .. string.rep("w", inter) .. "bytes" | ||
| 134 | local bp1, bp2, bp3, bp4 | ||
| 135 | remote (string.format("str = data:receive(%d)", | ||
| 136 | string.len(p1)+string.len(p2)+string.len(p3)+string.len(p4))) | ||
| 137 | sent, err = data:send(p1..p2..p3..p4) | ||
| 138 | if err then fail(err) end | ||
| 139 | remote "data:send(str); data:close()" | ||
| 140 | bp1, err = data:receive() | ||
| 141 | if err then fail(err) end | ||
| 142 | bp2, err = data:receive() | ||
| 143 | if err then fail(err) end | ||
| 144 | bp3, err = data:receive(string.len(p3)) | ||
| 145 | if err then fail(err) end | ||
| 146 | bp4, err = data:receive("*a") | ||
| 147 | if err then fail(err) end | ||
| 148 | if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 and bp4 == p4 then | ||
| 149 | pass("patterns match") | ||
| 150 | else fail("patterns don't match") end | ||
| 151 | end | ||
| 152 | |||
| 153 | ------------------------------------------------------------------------ | ||
| 154 | function test_asciiline(len) | ||
| 155 | reconnect() | ||
| 156 | local str, str10, back, err | ||
| 157 | str = string.rep("x", math.mod(len, 10)) | ||
| 158 | str10 = string.rep("aZb.c#dAe?", math.floor(len/10)) | ||
| 159 | str = str .. str10 | ||
| 160 | remote "str = data:receive()" | ||
| 161 | sent, err = data:send(str.."\n") | ||
| 162 | if err then fail(err) end | ||
| 163 | remote "data:send(str ..'\\n')" | ||
| 164 | back, err = data:receive() | ||
| 165 | if err then fail(err) end | ||
| 166 | if back == str then pass("lines match") | ||
| 167 | else fail("lines don't match") end | ||
| 168 | end | ||
| 169 | |||
| 170 | ------------------------------------------------------------------------ | ||
| 171 | function test_rawline(len) | ||
| 172 | reconnect() | ||
| 173 | local str, str10, back, err | ||
| 174 | str = string.rep(string.char(47), math.mod(len, 10)) | ||
| 175 | str10 = string.rep(string.char(120,21,77,4,5,0,7,36,44,100), | ||
| 176 | math.floor(len/10)) | ||
| 177 | str = str .. str10 | ||
| 178 | remote "str = data:receive()" | ||
| 179 | sent, err = data:send(str.."\n") | ||
| 180 | if err then fail(err) end | ||
| 181 | remote "data:send(str..'\\n')" | ||
| 182 | back, err = data:receive() | ||
| 183 | if err then fail(err) end | ||
| 184 | if back == str then pass("lines match") | ||
| 185 | else fail("lines don't match") end | ||
| 186 | end | ||
| 187 | |||
| 188 | ------------------------------------------------------------------------ | ||
| 189 | function test_raw(len) | ||
| 190 | reconnect() | ||
| 191 | local half = math.floor(len/2) | ||
| 192 | local s1, s2, back, err | ||
| 193 | s1 = string.rep("x", half) | ||
| 194 | s2 = string.rep("y", len-half) | ||
| 195 | remote (string.format("str = data:receive(%d)", len)) | ||
| 196 | sent, err = data:send(s1) | ||
| 197 | if err then fail(err) end | ||
| 198 | sent, err = data:send(s2) | ||
| 199 | if err then fail(err) end | ||
| 200 | remote "data:send(str)" | ||
| 201 | back, err = data:receive(len) | ||
| 202 | if err then fail(err) end | ||
| 203 | if back == s1..s2 then pass("blocks match") | ||
| 204 | else fail("blocks don't match") end | ||
| 205 | end | ||
| 206 | |||
| 207 | ------------------------------------------------------------------------ | ||
| 208 | function test_totaltimeoutreceive(len, tm, sl) | ||
| 209 | reconnect() | ||
| 210 | local str, err, partial | ||
| 211 | pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl) | ||
| 212 | remote (string.format ([[ | ||
| 213 | data:settimeout(%d) | ||
| 214 | str = string.rep('a', %d) | ||
| 215 | data:send(str) | ||
| 216 | print('server: sleeping for %ds') | ||
| 217 | socket.sleep(%d) | ||
| 218 | print('server: woke up') | ||
| 219 | data:send(str) | ||
| 220 | ]], 2*tm, len, sl, sl)) | ||
| 221 | data:settimeout(tm, "total") | ||
| 222 | local t = socket.gettime() | ||
| 223 | str, err, partial, elapsed = data:receive(2*len) | ||
| 224 | check_timeout(tm, sl, elapsed, err, "receive", "total", | ||
| 225 | string.len(str or partial) == 2*len) | ||
| 226 | end | ||
| 227 | |||
| 228 | ------------------------------------------------------------------------ | ||
| 229 | function test_totaltimeoutsend(len, tm, sl) | ||
| 230 | reconnect() | ||
| 231 | local str, err, total | ||
| 232 | pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl) | ||
| 233 | remote (string.format ([[ | ||
| 234 | data:settimeout(%d) | ||
| 235 | str = data:receive(%d) | ||
| 236 | print('server: sleeping for %ds') | ||
| 237 | socket.sleep(%d) | ||
| 238 | print('server: woke up') | ||
| 239 | str = data:receive(%d) | ||
| 240 | ]], 2*tm, len, sl, sl, len)) | ||
| 241 | data:settimeout(tm, "total") | ||
| 242 | str = string.rep("a", 2*len) | ||
| 243 | total, err, partial, elapsed = data:send(str) | ||
| 244 | check_timeout(tm, sl, elapsed, err, "send", "total", | ||
| 245 | total == 2*len) | ||
| 246 | end | ||
| 247 | |||
| 248 | ------------------------------------------------------------------------ | ||
| 249 | function test_blockingtimeoutreceive(len, tm, sl) | ||
| 250 | reconnect() | ||
| 251 | local str, err, partial | ||
| 252 | pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) | ||
| 253 | remote (string.format ([[ | ||
| 254 | data:settimeout(%d) | ||
| 255 | str = string.rep('a', %d) | ||
| 256 | data:send(str) | ||
| 257 | print('server: sleeping for %ds') | ||
| 258 | socket.sleep(%d) | ||
| 259 | print('server: woke up') | ||
| 260 | data:send(str) | ||
| 261 | ]], 2*tm, len, sl, sl)) | ||
| 262 | data:settimeout(tm) | ||
| 263 | str, err, partial, elapsed = data:receive(2*len) | ||
| 264 | check_timeout(tm, sl, elapsed, err, "receive", "blocking", | ||
| 265 | string.len(str or partial) == 2*len) | ||
| 266 | end | ||
| 267 | |||
| 268 | ------------------------------------------------------------------------ | ||
| 269 | function test_blockingtimeoutsend(len, tm, sl) | ||
| 270 | reconnect() | ||
| 271 | local str, err, total | ||
| 272 | pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) | ||
| 273 | remote (string.format ([[ | ||
| 274 | data:settimeout(%d) | ||
| 275 | str = data:receive(%d) | ||
| 276 | print('server: sleeping for %ds') | ||
| 277 | socket.sleep(%d) | ||
| 278 | print('server: woke up') | ||
| 279 | str = data:receive(%d) | ||
| 280 | ]], 2*tm, len, sl, sl, len)) | ||
| 281 | data:settimeout(tm) | ||
| 282 | str = string.rep("a", 2*len) | ||
| 283 | total, err, partial, elapsed = data:send(str) | ||
| 284 | check_timeout(tm, sl, elapsed, err, "send", "blocking", | ||
| 285 | total == 2*len) | ||
| 286 | end | ||
| 287 | |||
| 288 | ------------------------------------------------------------------------ | ||
| 289 | function empty_connect() | ||
| 290 | reconnect() | ||
| 291 | if data then data:close() data = nil end | ||
| 292 | remote [[ | ||
| 293 | if data then data:close() data = nil end | ||
| 294 | data = server:accept() | ||
| 295 | ]] | ||
| 296 | data, err = socket.connect("", port) | ||
| 297 | if not data then | ||
| 298 | pass("ok") | ||
| 299 | data = socket.connect(host, port) | ||
| 300 | else | ||
| 301 | pass("gethostbyname returns localhost on empty string...") | ||
| 302 | end | ||
| 303 | end | ||
| 304 | |||
| 305 | ------------------------------------------------------------------------ | ||
| 306 | function isclosed(c) | ||
| 307 | return c:getfd() == -1 or c:getfd() == (2^32-1) | ||
| 308 | end | ||
| 309 | |||
| 310 | function active_close() | ||
| 311 | reconnect() | ||
| 312 | if isclosed(data) then fail("should not be closed") end | ||
| 313 | data:close() | ||
| 314 | if not isclosed(data) then fail("should be closed") end | ||
| 315 | data = nil | ||
| 316 | local udp = socket.udp() | ||
| 317 | if isclosed(udp) then fail("should not be closed") end | ||
| 318 | udp:close() | ||
| 319 | if not isclosed(udp) then fail("should be closed") end | ||
| 320 | pass("ok") | ||
| 321 | end | ||
| 322 | |||
| 323 | ------------------------------------------------------------------------ | ||
| 324 | function test_closed() | ||
| 325 | local back, partial, err | ||
| 326 | local str = 'little string' | ||
| 327 | reconnect() | ||
| 328 | pass("trying read detection") | ||
| 329 | remote (string.format ([[ | ||
| 330 | data:send('%s') | ||
| 331 | data:close() | ||
| 332 | data = nil | ||
| 333 | ]], str)) | ||
| 334 | -- try to get a line | ||
| 335 | back, err, partial = data:receive() | ||
| 336 | if not err then fail("should have gotten 'closed'.") | ||
| 337 | elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.") | ||
| 338 | elseif str ~= partial then fail("didn't receive partial result.") | ||
| 339 | else pass("graceful 'closed' received") end | ||
| 340 | reconnect() | ||
| 341 | pass("trying write detection") | ||
| 342 | remote [[ | ||
| 343 | data:close() | ||
| 344 | data = nil | ||
| 345 | ]] | ||
| 346 | total, err, partial = data:send(string.rep("ugauga", 100000)) | ||
| 347 | if not err then | ||
| 348 | pass("failed: output buffer is at least %d bytes long!", total) | ||
| 349 | elseif err ~= "closed" then | ||
| 350 | fail("got '"..err.."' instead of 'closed'.") | ||
| 351 | else | ||
| 352 | pass("graceful 'closed' received after %d bytes were sent", partial) | ||
| 353 | end | ||
| 354 | end | ||
| 355 | |||
| 356 | ------------------------------------------------------------------------ | ||
| 357 | function test_selectbugs() | ||
| 358 | local r, s, e = socket.select(nil, nil, 0.1) | ||
| 359 | assert(type(r) == "table" and type(s) == "table" and | ||
| 360 | (e == "timeout" or e == "error")) | ||
| 361 | pass("both nil: ok") | ||
| 362 | local udp = socket.udp() | ||
| 363 | udp:close() | ||
| 364 | r, s, e = socket.select({ udp }, { udp }, 0.1) | ||
| 365 | assert(type(r) == "table" and type(s) == "table" and | ||
| 366 | (e == "timeout" or e == "error")) | ||
| 367 | pass("closed sockets: ok") | ||
| 368 | e = pcall(socket.select, "wrong", 1, 0.1) | ||
| 369 | assert(e == false) | ||
| 370 | e = pcall(socket.select, {}, 1, 0.1) | ||
| 371 | assert(e == false) | ||
| 372 | pass("invalid input: ok") | ||
| 373 | end | ||
| 374 | |||
| 375 | ------------------------------------------------------------------------ | ||
| 376 | function accept_timeout() | ||
| 377 | io.stderr:write("accept with timeout (if it hangs, it failed): ") | ||
| 378 | local s, e = socket.bind("*", 0, 0) | ||
| 379 | assert(s, e) | ||
| 380 | local t = socket.gettime() | ||
| 381 | s:settimeout(1) | ||
| 382 | local c, e = s:accept() | ||
| 383 | assert(not c, "should not accept") | ||
| 384 | assert(e == "timeout", string.format("wrong error message (%s)", e)) | ||
| 385 | t = socket.gettime() - t | ||
| 386 | assert(t < 2, string.format("took to long to give up (%gs)", t)) | ||
| 387 | s:close() | ||
| 388 | pass("good") | ||
| 389 | end | ||
| 390 | |||
| 391 | ------------------------------------------------------------------------ | ||
| 392 | function connect_timeout() | ||
| 393 | io.stderr:write("connect with timeout (if it hangs, it failed!): ") | ||
| 394 | local t = socket.gettime() | ||
| 395 | local c, e = socket.tcp() | ||
| 396 | assert(c, e) | ||
| 397 | c:settimeout(0.1) | ||
| 398 | local t = socket.gettime() | ||
| 399 | local r, e = c:connect("127.0.0.2", 80) | ||
| 400 | assert(not r, "should not connect") | ||
| 401 | assert(socket.gettime() - t < 2, "took too long to give up.") | ||
| 402 | c:close() | ||
| 403 | print("ok") | ||
| 404 | end | ||
| 405 | |||
| 406 | ------------------------------------------------------------------------ | ||
| 407 | function accept_errors() | ||
| 408 | io.stderr:write("not listening: ") | ||
| 409 | local d, e = socket.bind("*", 0) | ||
| 410 | assert(d, e); | ||
| 411 | local c, e = socket.tcp(); | ||
| 412 | assert(c, e); | ||
| 413 | d:setfd(c:getfd()) | ||
| 414 | d:settimeout(2) | ||
| 415 | local r, e = d:accept() | ||
| 416 | assert(not r and e) | ||
| 417 | print("ok: ", e) | ||
| 418 | io.stderr:write("not supported: ") | ||
| 419 | local c, e = socket.udp() | ||
| 420 | assert(c, e); | ||
| 421 | d:setfd(c:getfd()) | ||
| 422 | local r, e = d:accept() | ||
| 423 | assert(not r and e) | ||
| 424 | print("ok: ", e) | ||
| 425 | end | ||
| 426 | |||
| 427 | ------------------------------------------------------------------------ | ||
| 428 | function connect_errors() | ||
| 429 | io.stderr:write("connection refused: ") | ||
| 430 | local c, e = socket.connect("localhost", 1); | ||
| 431 | assert(not c and e) | ||
| 432 | print("ok: ", e) | ||
| 433 | io.stderr:write("host not found: ") | ||
| 434 | local c, e = socket.connect("host.is.invalid", 1); | ||
| 435 | assert(not c and e, e) | ||
| 436 | print("ok: ", e) | ||
| 437 | end | ||
| 438 | |||
| 439 | ------------------------------------------------------------------------ | ||
| 440 | function rebind_test() | ||
| 441 | local c = socket.bind("localhost", 0) | ||
| 442 | local i, p = c:getsockname() | ||
| 443 | local s, e = socket.tcp() | ||
| 444 | assert(s, e) | ||
| 445 | s:setoption("reuseaddr", false) | ||
| 446 | r, e = s:bind("localhost", p) | ||
| 447 | assert(not r, "managed to rebind!") | ||
| 448 | assert(e) | ||
| 449 | print("ok: ", e) | ||
| 450 | end | ||
| 451 | |||
| 452 | ------------------------------------------------------------------------ | ||
| 453 | function getstats_test() | ||
| 454 | reconnect() | ||
| 455 | local t = 0 | ||
| 456 | for i = 1, 25 do | ||
| 457 | local c = math.random(1, 100) | ||
| 458 | remote (string.format ([[ | ||
| 459 | str = data:receive(%d) | ||
| 460 | data:send(str) | ||
| 461 | ]], c)) | ||
| 462 | data:send(string.rep("a", c)) | ||
| 463 | data:receive(c) | ||
| 464 | t = t + c | ||
| 465 | local r, s, a = data:getstats() | ||
| 466 | assert(r == t, "received count failed" .. tostring(r) | ||
| 467 | .. "/" .. tostring(t)) | ||
| 468 | assert(s == t, "sent count failed" .. tostring(s) | ||
| 469 | .. "/" .. tostring(t)) | ||
| 470 | end | ||
| 471 | print("ok") | ||
| 472 | end | ||
| 473 | |||
| 474 | |||
| 475 | ------------------------------------------------------------------------ | ||
| 476 | function test_nonblocking(size) | ||
| 477 | reconnect() | ||
| 478 | print("Testing " .. 2*size .. " bytes") | ||
| 479 | remote(string.format([[ | ||
| 480 | data:send(string.rep("a", %d)) | ||
| 481 | socket.sleep(0.5) | ||
| 482 | data:send(string.rep("b", %d) .. "\n") | ||
| 483 | ]], size, size)) | ||
| 484 | local err = "timeout" | ||
| 485 | local part = "" | ||
| 486 | local str | ||
| 487 | data:settimeout(0) | ||
| 488 | while 1 do | ||
| 489 | str, err, part = data:receive("*l", part) | ||
| 490 | if err ~= "timeout" then break end | ||
| 491 | end | ||
| 492 | assert(str == (string.rep("a", size) .. string.rep("b", size))) | ||
| 493 | reconnect() | ||
| 494 | remote(string.format([[ | ||
| 495 | str = data:receive(%d) | ||
| 496 | socket.sleep(0.5) | ||
| 497 | str = data:receive(%d, str) | ||
| 498 | data:send(str) | ||
| 499 | ]], size, size)) | ||
| 500 | data:settimeout(0) | ||
| 501 | local start = 0 | ||
| 502 | while 1 do | ||
| 503 | ret, err, start = data:send(str, start+1) | ||
| 504 | if err ~= "timeout" then break end | ||
| 505 | end | ||
| 506 | data:send("\n") | ||
| 507 | data:settimeout(-1) | ||
| 508 | local back = data:receive(2*size) | ||
| 509 | assert(back == str, "'" .. back .. "' vs '" .. str .. "'") | ||
| 510 | print("ok") | ||
| 511 | end | ||
| 512 | |||
| 513 | ------------------------------------------------------------------------ | ||
| 514 | |||
| 515 | test("method registration") | ||
| 516 | test_methods(socket.unix(), { | ||
| 517 | "accept", | ||
| 518 | "bind", | ||
| 519 | "close", | ||
| 520 | "connect", | ||
| 521 | "dirty", | ||
| 522 | "getfd", | ||
| 523 | "getstats", | ||
| 524 | "setstats", | ||
| 525 | "listen", | ||
| 526 | "receive", | ||
| 527 | "send", | ||
| 528 | "setfd", | ||
| 529 | "setoption", | ||
| 530 | "setpeername", | ||
| 531 | "setsockname", | ||
| 532 | "settimeout", | ||
| 533 | "shutdown", | ||
| 534 | }) | ||
| 535 | |||
| 536 | test("connect function") | ||
| 537 | --connect_timeout() | ||
| 538 | --empty_connect() | ||
| 539 | --connect_errors() | ||
| 540 | |||
| 541 | --test("rebinding: ") | ||
| 542 | --rebind_test() | ||
| 543 | |||
| 544 | test("active close: ") | ||
| 545 | active_close() | ||
| 546 | |||
| 547 | test("closed connection detection: ") | ||
| 548 | test_closed() | ||
| 549 | |||
| 550 | test("accept function: ") | ||
| 551 | accept_timeout() | ||
| 552 | accept_errors() | ||
| 553 | |||
| 554 | test("getstats test") | ||
| 555 | getstats_test() | ||
| 556 | |||
| 557 | test("character line") | ||
| 558 | test_asciiline(1) | ||
| 559 | test_asciiline(17) | ||
| 560 | test_asciiline(200) | ||
| 561 | test_asciiline(4091) | ||
| 562 | test_asciiline(80199) | ||
| 563 | test_asciiline(8000000) | ||
| 564 | test_asciiline(80199) | ||
| 565 | test_asciiline(4091) | ||
| 566 | test_asciiline(200) | ||
| 567 | test_asciiline(17) | ||
| 568 | test_asciiline(1) | ||
| 569 | |||
| 570 | test("mixed patterns") | ||
| 571 | test_mixed(1) | ||
| 572 | test_mixed(17) | ||
| 573 | test_mixed(200) | ||
| 574 | test_mixed(4091) | ||
| 575 | test_mixed(801990) | ||
| 576 | test_mixed(4091) | ||
| 577 | test_mixed(200) | ||
| 578 | test_mixed(17) | ||
| 579 | test_mixed(1) | ||
| 580 | |||
| 581 | test("binary line") | ||
| 582 | test_rawline(1) | ||
| 583 | test_rawline(17) | ||
| 584 | test_rawline(200) | ||
| 585 | test_rawline(4091) | ||
| 586 | test_rawline(80199) | ||
| 587 | test_rawline(8000000) | ||
| 588 | test_rawline(80199) | ||
| 589 | test_rawline(4091) | ||
| 590 | test_rawline(200) | ||
| 591 | test_rawline(17) | ||
| 592 | test_rawline(1) | ||
| 593 | |||
| 594 | test("raw transfer") | ||
| 595 | test_raw(1) | ||
| 596 | test_raw(17) | ||
| 597 | test_raw(200) | ||
| 598 | test_raw(4091) | ||
| 599 | test_raw(80199) | ||
| 600 | test_raw(8000000) | ||
| 601 | test_raw(80199) | ||
| 602 | test_raw(4091) | ||
| 603 | test_raw(200) | ||
| 604 | test_raw(17) | ||
| 605 | test_raw(1) | ||
| 606 | |||
| 607 | test("non-blocking transfer") | ||
| 608 | test_nonblocking(1) | ||
| 609 | test_nonblocking(17) | ||
| 610 | test_nonblocking(200) | ||
| 611 | test_nonblocking(4091) | ||
| 612 | test_nonblocking(80199) | ||
| 613 | test_nonblocking(8000000) | ||
| 614 | test_nonblocking(80199) | ||
| 615 | test_nonblocking(4091) | ||
| 616 | test_nonblocking(200) | ||
| 617 | test_nonblocking(17) | ||
| 618 | test_nonblocking(1) | ||
| 619 | |||
| 620 | test("total timeout on send") | ||
| 621 | test_totaltimeoutsend(800091, 1, 3) | ||
| 622 | test_totaltimeoutsend(800091, 2, 3) | ||
| 623 | test_totaltimeoutsend(800091, 5, 2) | ||
| 624 | test_totaltimeoutsend(800091, 3, 1) | ||
| 625 | |||
| 626 | test("total timeout on receive") | ||
| 627 | test_totaltimeoutreceive(800091, 1, 3) | ||
| 628 | test_totaltimeoutreceive(800091, 2, 3) | ||
| 629 | test_totaltimeoutreceive(800091, 3, 2) | ||
| 630 | test_totaltimeoutreceive(800091, 3, 1) | ||
| 631 | |||
| 632 | test("blocking timeout on send") | ||
| 633 | test_blockingtimeoutsend(800091, 1, 3) | ||
| 634 | test_blockingtimeoutsend(800091, 2, 3) | ||
| 635 | test_blockingtimeoutsend(800091, 3, 2) | ||
| 636 | test_blockingtimeoutsend(800091, 3, 1) | ||
| 637 | |||
| 638 | test("blocking timeout on receive") | ||
| 639 | test_blockingtimeoutreceive(800091, 1, 3) | ||
| 640 | test_blockingtimeoutreceive(800091, 2, 3) | ||
| 641 | test_blockingtimeoutreceive(800091, 3, 2) | ||
| 642 | test_blockingtimeoutreceive(800091, 3, 1) | ||
| 643 | |||
| 644 | test(string.format("done in %.2fs", socket.gettime() - start)) | ||
diff --git a/test/utestsrvr.lua b/test/utestsrvr.lua new file mode 100644 index 0000000..f7be196 --- /dev/null +++ b/test/utestsrvr.lua | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | require("socket"); | ||
| 2 | os.remove("/tmp/luasocket") | ||
| 3 | socket = require("socket.unix"); | ||
| 4 | host = "luasocket"; | ||
| 5 | server = socket.unix() | ||
| 6 | print(server:bind(host)) | ||
| 7 | print(server:listen(5)) | ||
| 8 | ack = "\n"; | ||
| 9 | while 1 do | ||
| 10 | print("server: waiting for client connection..."); | ||
| 11 | control = assert(server:accept()); | ||
| 12 | while 1 do | ||
| 13 | command = assert(control:receive()); | ||
| 14 | assert(control:send(ack)); | ||
| 15 | (loadstring(command))(); | ||
| 16 | end | ||
| 17 | end | ||
