diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-07-26 05:17:37 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-07-26 05:17:37 +0000 |
| commit | 911e8d7e7f63e6e90814e82955bfaf26328afb19 (patch) | |
| tree | 575a916f4616a0f865bff9928faa9be67a8c867e | |
| parent | d914007507a6a4ad3489cca19652af403fef7074 (diff) | |
| download | luasocket-911e8d7e7f63e6e90814e82955bfaf26328afb19.tar.gz luasocket-911e8d7e7f63e6e90814e82955bfaf26328afb19.tar.bz2 luasocket-911e8d7e7f63e6e90814e82955bfaf26328afb19.zip | |
Beta2 is out! Total timeout works on Windows.
| -rw-r--r-- | NEW | 111 | ||||
| -rw-r--r-- | TODO | 8 | ||||
| -rw-r--r-- | doc/index.html | 7 | ||||
| -rw-r--r-- | makefile.dist | 3 | ||||
| -rw-r--r-- | src/buffer.c | 8 | ||||
| -rw-r--r-- | src/udp.h | 1 | ||||
| -rw-r--r-- | src/wsocket.c | 6 | ||||
| -rw-r--r-- | test/httptest.lua | 19 | ||||
| -rw-r--r-- | test/testclnt.lua | 39 |
9 files changed, 78 insertions, 124 deletions
| @@ -1,86 +1,31 @@ | |||
| 1 | What's New | 1 | What's New |
| 2 | 2 | ||
| 3 | Everything is new! Many changes for 2.0 happened in the C layer, | 3 | Changes in the 2.0-beta2 were mostly bug-fixes. |
| 4 | which has been almost completely rewritten. The code has been ported to | 4 | |
| 5 | Lua 5.0 and greatly improved. There have also been some API changes | 5 | <> Fixed silly last-minute-change bug in HTTP/SMTP running; |
| 6 | that made the interface simpler and more consistent. Here are some of | 6 | <> usocket.c/wsocket.c look nicer thanks to Mike; |
| 7 | the changes that made it into version 2.0: | 7 | <> Finally total timeout is reliable on Windows! (found a pretty |
| 8 | 8 | simple work around); | |
| 9 | <> Major C code rewrite. Code is modular and extensible. Hopefully, other | 9 | <> UDP has a reasonable maximum datagram size (8k); |
| 10 | developers will be motivated to provide code for SSL, local domain | 10 | <> Receive accepts the prefix optional argument (good for |
| 11 | sockets, file descriptors, pipes (on Unix) and named pipes etc; | 11 | non-blocking); |
| 12 | 12 | <> <b>Send doesn't support multiple arguments anymore</b>; | |
| 13 | <> Everything that is exported by the library is exported inside | 13 | <> Instead, send allows the selection of the substring |
| 14 | namespaces. These should be obtained with calls to the | 14 | to be sent (good for non-blocking); |
| 15 | 'require' function; | 15 | <> Fixed bug that caused select return tables not to be associative |
| 16 | 16 | on windows; | |
| 17 | <> Functions such as | 17 | <> Should compiles with g++; |
| 18 | send/receive/timeout/close etc do not exist anymore as stand-alone | 18 | <> New sample unix domain support; |
| 19 | functions. They are now only available as methods of the appropriate | 19 | <> New sample LPD support; |
| 20 | objects; | 20 | <> Comprehensive error messages; |
| 21 | 21 | <> New getstats and setstats methods to help | |
| 22 | <> All functions return a non-nil value as first return value if successful. | 22 | throttling; |
| 23 | All functions return 'nil' followed by error message | 23 | <> Listen defaults to 32 backlog; |
| 24 | in case of error. This made the library much easier to use; | 24 | <> SMTP/FTP/HTTP fail gracefully; |
| 25 | 25 | <> accept/connect/select interrupt safe | |
| 26 | <> Greatly reduced the number of times the C select is called | 26 | <> Fixed bug that didn't set accepted sockets as non-blocking |
| 27 | during data transfers, by calling only on failure. This might | 27 | <> <b>New timming functions sleep and gettime have |
| 28 | improve a lot the maximum throughput; | 28 | higher resolution and no wrap around problems</b>; |
| 29 | 29 | <> Bug fixes in the manual; | |
| 30 | <> TCP has been changed to become more uniform. It's possible to first | 30 | <> Fixed bug of missing cast in getfd. |
| 31 | create a TCP object, | ||
| 32 | then connect or bind if needed, and finally use I/O functions. | ||
| 33 | 'socket.connect' and 'socket.bind' functions are still | ||
| 34 | provided for simplicity; | ||
| 35 | |||
| 36 | <> This allows for setting a timeout value before connecting; | ||
| 37 | |||
| 38 | <> And also allows binding to a local address before connecting; | ||
| 39 | |||
| 40 | <> New 'socket.dns.gethostname' function and 'shutdown' | ||
| 41 | method; | ||
| 42 | |||
| 43 | <> Better error messages and parameter checking; | ||
| 44 | |||
| 45 | <> Should be interrupt safe; | ||
| 46 | |||
| 47 | <> UDP connected sockets can break association with peer by calling | ||
| 48 | 'setpeername' with address ''*''; | ||
| 49 | |||
| 50 | <> Sets returned by 'socket.select' are associative; | ||
| 51 | |||
| 52 | <> Select checks if sockets have buffered data and returns immediately; | ||
| 53 | |||
| 54 | <> 'socket.sleep' and 'socket.time' are now part of the | ||
| 55 | library and are supported. They used to be available only when | ||
| 56 | LUASOCKET_DEBUG was defined, but it turns out they might be useful for | ||
| 57 | applications; | ||
| 58 | |||
| 59 | <> 'socket.newtry' and 'socket.protect' provide a simple | ||
| 60 | interface to exceptions that proved very in the implementation of | ||
| 61 | high-level modules; | ||
| 62 | |||
| 63 | <> Socket options interface has been improved. TCP objects also | ||
| 64 | support socket options and many new options were added. | ||
| 65 | |||
| 66 | |||
| 67 | Lots of changes in the Lua modules, too! | ||
| 68 | |||
| 69 | <> Every module loads only the modules that it needs. There is no waste | ||
| 70 | of memory. LuaSocket core takes only 20k of memory; | ||
| 71 | |||
| 72 | <> New MIME and LTN12 modules make all other modules much more powerful; | ||
| 73 | |||
| 74 | <> Support for multipart messages in the SMTP module; | ||
| 75 | |||
| 76 | <> The old callback mechanism of FTP and HTTP has been replaced with LTN12 | ||
| 77 | sources and sinks, with advantage; | ||
| 78 | |||
| 79 | <> Common implementation for low-level FTP and SMTP; | ||
| 80 | |||
| 81 | <> FTP, HTTP, and SMTP are implemented in multiple levels in such a way | ||
| 82 | that users will have no problems extending the functionality to satisfy | ||
| 83 | personal needs; | ||
| 84 | |||
| 85 | <> SMTP knows how to perform LOGIN and PLAIN authentication. | ||
| 86 | 31 | ||
| @@ -1,8 +1,5 @@ | |||
| 1 | change sendraw to send by chunks | ||
| 1 | 2 | ||
| 2 | fix manual for send and receive | ||
| 3 | add thanks to mike | ||
| 4 | |||
| 5 | change sock:send to use indices just like string.sub? | ||
| 6 | use mike's "don't set to blocking before closing unless needed" patch? | 3 | use mike's "don't set to blocking before closing unless needed" patch? |
| 7 | take a look at DB's smtp patch | 4 | take a look at DB's smtp patch |
| 8 | 5 | ||
| @@ -32,3 +29,6 @@ testar os options! | |||
| 32 | *add getstats to the manual | 29 | *add getstats to the manual |
| 33 | *Fazer compilar com g++ | 30 | *Fazer compilar com g++ |
| 34 | *test associativity of socket.select | 31 | *test associativity of socket.select |
| 32 | * fix manual for send and receive | ||
| 33 | * add thanks to mike | ||
| 34 | * change sock:send to use indices just like string.sub? | ||
diff --git a/doc/index.html b/doc/index.html index 8eaa37a..ada3b61 100644 --- a/doc/index.html +++ b/doc/index.html | |||
| @@ -169,10 +169,11 @@ Changes in the 2.0-beta2 were mostly bug-fixes. | |||
| 169 | </p> | 169 | </p> |
| 170 | 170 | ||
| 171 | <ul> | 171 | <ul> |
| 172 | <li> Fixed silly last minute bugs in HTTP/SMTP that prevented them from | 172 | <li> Fixed silly last-minute-change bug in HTTP/SMTP running; |
| 173 | running; | ||
| 174 | <li> <tt>usocket.c</tt>/<tt>wsocket.c</tt> look nicer thanks to Mike; | 173 | <li> <tt>usocket.c</tt>/<tt>wsocket.c</tt> look nicer thanks to Mike; |
| 175 | <li> UDP has a reasonable maximum datagram size; | 174 | <li> Finally total timeout is reliable on Windows! (found a pretty |
| 175 | simple work around); | ||
| 176 | <li> UDP has a reasonable maximum datagram size (8k); | ||
| 176 | <li> <tt>Receive</tt> accepts the prefix optional argument (good for | 177 | <li> <tt>Receive</tt> accepts the prefix optional argument (good for |
| 177 | non-blocking); | 178 | non-blocking); |
| 178 | <li> <b><tt>Send</tt> doesn't support multiple arguments anymore</b>; | 179 | <li> <b><tt>Send</tt> doesn't support multiple arguments anymore</b>; |
diff --git a/makefile.dist b/makefile.dist index 56bba96..a0a9313 100644 --- a/makefile.dist +++ b/makefile.dist | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Distribution makefile | 2 | # Distribution makefile |
| 3 | #-------------------------------------------------------------------------- | 3 | #-------------------------------------------------------------------------- |
| 4 | 4 | ||
| 5 | DIST = luasocket-2.0-beta | 5 | DIST = luasocket-2.0-beta2 |
| 6 | 6 | ||
| 7 | LUA = \ | 7 | LUA = \ |
| 8 | ftp.lua \ | 8 | ftp.lua \ |
| @@ -104,7 +104,6 @@ dist: | |||
| 104 | mkdir -p $(DIST)/etc | 104 | mkdir -p $(DIST)/etc |
| 105 | mkdir -p $(DIST)/lua | 105 | mkdir -p $(DIST)/lua |
| 106 | mkdir -p $(DIST)/manual | 106 | mkdir -p $(DIST)/manual |
| 107 | cp -vf FIX $(DIST) | ||
| 108 | cp -vf TODO $(DIST) | 107 | cp -vf TODO $(DIST) |
| 109 | cp -vf $(CORE) $(DIST) | 108 | cp -vf $(CORE) $(DIST) |
| 110 | cp -vf README $(DIST) | 109 | cp -vf README $(DIST) |
diff --git a/src/buffer.c b/src/buffer.c index a696158..dbd5d2c 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -81,10 +81,10 @@ int buf_meth_send(lua_State *L, p_buf buf) { | |||
| 81 | const char *data = luaL_checklstring(L, 2, &size); | 81 | const char *data = luaL_checklstring(L, 2, &size); |
| 82 | long start = (long) luaL_optnumber(L, 3, 1); | 82 | long start = (long) luaL_optnumber(L, 3, 1); |
| 83 | long end = (long) luaL_optnumber(L, 4, -1); | 83 | long end = (long) luaL_optnumber(L, 4, -1); |
| 84 | if (start < 0) start = size+start+1; | 84 | if (start < 0) start = (long) (size+start+1); |
| 85 | if (end < 0) end = size+end+1; | 85 | if (end < 0) end = (long) (size+end+1); |
| 86 | if (start < 1) start = 1; | 86 | if (start < 1) start = (long) 1; |
| 87 | if (end > (long) size) end = size; | 87 | if (end > (long) size) end = (long) size; |
| 88 | if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent); | 88 | if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent); |
| 89 | /* check if there was an error */ | 89 | /* check if there was an error */ |
| 90 | if (err != IO_DONE) { | 90 | if (err != IO_DONE) { |
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "timeout.h" | 19 | #include "timeout.h" |
| 20 | #include "socket.h" | 20 | #include "socket.h" |
| 21 | 21 | ||
| 22 | /* can't be larger than wsocket.c MAXCHUNK!!! */ | ||
| 22 | #define UDP_DATAGRAMSIZE 8192 | 23 | #define UDP_DATAGRAMSIZE 8192 |
| 23 | 24 | ||
| 24 | typedef struct t_udp_ { | 25 | typedef struct t_udp_ { |
diff --git a/src/wsocket.c b/src/wsocket.c index 1f1e99d..1b169ed 100644 --- a/src/wsocket.c +++ b/src/wsocket.c | |||
| @@ -181,6 +181,8 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *len, p_tm tm) { | |||
| 181 | /*-------------------------------------------------------------------------*\ | 181 | /*-------------------------------------------------------------------------*\ |
| 182 | * Send with timeout | 182 | * Send with timeout |
| 183 | \*-------------------------------------------------------------------------*/ | 183 | \*-------------------------------------------------------------------------*/ |
| 184 | /* has to be larger than UDP_DATAGRAMSIZE !!!*/ | ||
| 185 | #define MAXCHUNK (64*1024) | ||
| 184 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) | 186 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) |
| 185 | { | 187 | { |
| 186 | int err; | 188 | int err; |
| @@ -190,7 +192,9 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) | |||
| 190 | *sent = 0; | 192 | *sent = 0; |
| 191 | for ( ;; ) { | 193 | for ( ;; ) { |
| 192 | /* try to send something */ | 194 | /* try to send something */ |
| 193 | int put = send(*ps, data, (int) count, 0); | 195 | /* on windows, if you try to send 10MB, the OS will buffer EVERYTHING |
| 196 | * this can take an awful lot of time and we will end up blocked. */ | ||
| 197 | int put = send(*ps, data, (count < MAXCHUNK)? (int)count: MAXCHUNK, 0); | ||
| 194 | /* if we sent something, we are done */ | 198 | /* if we sent something, we are done */ |
| 195 | if (put > 0) { | 199 | if (put > 0) { |
| 196 | *sent = put; | 200 | *sent = put; |
diff --git a/test/httptest.lua b/test/httptest.lua index 31e8212..ce7a93b 100644 --- a/test/httptest.lua +++ b/test/httptest.lua | |||
| @@ -116,6 +116,16 @@ ignore = { | |||
| 116 | check_request(request, expect, ignore) | 116 | check_request(request, expect, ignore) |
| 117 | 117 | ||
| 118 | ------------------------------------------------------------------------ | 118 | ------------------------------------------------------------------------ |
| 119 | io.write("testing invalid url: ") | ||
| 120 | local c, e = socket.connect("", 80) | ||
| 121 | local r, re = http.request{url = host .. prefix} | ||
| 122 | assert(r == nil and e == re) | ||
| 123 | r, re = http.request(host .. prefix) | ||
| 124 | assert(r == nil and e == re, tostring(r) ..", " .. tostring(re) .. | ||
| 125 | " vs " .. tostring(e)) | ||
| 126 | print("ok") | ||
| 127 | |||
| 128 | ------------------------------------------------------------------------ | ||
| 119 | io.write("testing post method: ") | 129 | io.write("testing post method: ") |
| 120 | -- wanted to test chunked post, but apache doesn't support it... | 130 | -- wanted to test chunked post, but apache doesn't support it... |
| 121 | request = { | 131 | request = { |
| @@ -407,15 +417,6 @@ assert(r == nil and e == re) | |||
| 407 | print("ok") | 417 | print("ok") |
| 408 | 418 | ||
| 409 | ------------------------------------------------------------------------ | 419 | ------------------------------------------------------------------------ |
| 410 | io.write("testing invalid url: ") | ||
| 411 | local c, e = socket.connect("", 80) | ||
| 412 | local r, re = http.request{url = host .. prefix} | ||
| 413 | assert(r == nil and e == re) | ||
| 414 | r, re = http.request(host .. prefix) | ||
| 415 | assert(r == nil and e == re) | ||
| 416 | print("ok") | ||
| 417 | |||
| 418 | ------------------------------------------------------------------------ | ||
| 419 | print("passed all tests") | 420 | print("passed all tests") |
| 420 | os.remove("err") | 421 | os.remove("err") |
| 421 | 422 | ||
diff --git a/test/testclnt.lua b/test/testclnt.lua index 356350a..f838533 100644 --- a/test/testclnt.lua +++ b/test/testclnt.lua | |||
| @@ -461,6 +461,7 @@ end | |||
| 461 | ------------------------------------------------------------------------ | 461 | ------------------------------------------------------------------------ |
| 462 | function test_nonblocking(size) | 462 | function test_nonblocking(size) |
| 463 | reconnect() | 463 | reconnect() |
| 464 | print("Testing " .. 2*size .. " bytes") | ||
| 464 | remote(string.format([[ | 465 | remote(string.format([[ |
| 465 | data:send(string.rep("a", %d)) | 466 | data:send(string.rep("a", %d)) |
| 466 | socket.sleep(0.5) | 467 | socket.sleep(0.5) |
| @@ -471,7 +472,9 @@ remote(string.format([[ | |||
| 471 | local str | 472 | local str |
| 472 | data:settimeout(0) | 473 | data:settimeout(0) |
| 473 | while 1 do | 474 | while 1 do |
| 474 | str, err, part = data:receive(2*size - string.len(part), part) | 475 | local needed = 2*size - string.len(part) |
| 476 | assert(needed > 0, "weird") | ||
| 477 | str, err, part = data:receive(needed, part) | ||
| 475 | if err ~= "timeout" then break end | 478 | if err ~= "timeout" then break end |
| 476 | end | 479 | end |
| 477 | assert(str == (string.rep("a", size) .. string.rep("b", size))) | 480 | assert(str == (string.rep("a", size) .. string.rep("b", size))) |
| @@ -480,9 +483,7 @@ remote(string.format([[ | |||
| 480 | str = data:receive(%d) | 483 | str = data:receive(%d) |
| 481 | socket.sleep(0.5) | 484 | socket.sleep(0.5) |
| 482 | str = data:receive(%d, str) | 485 | str = data:receive(%d, str) |
| 483 | str = data:receive("*l", str) | ||
| 484 | data:send(str) | 486 | data:send(str) |
| 485 | data:send("\n") | ||
| 486 | ]], size, size)) | 487 | ]], size, size)) |
| 487 | data:settimeout(0) | 488 | data:settimeout(0) |
| 488 | local sofar = 1 | 489 | local sofar = 1 |
| @@ -493,25 +494,12 @@ remote(string.format([[ | |||
| 493 | end | 494 | end |
| 494 | data:send("\n") | 495 | data:send("\n") |
| 495 | data:settimeout(-1) | 496 | data:settimeout(-1) |
| 496 | local back = data:receive() | 497 | local back = data:receive(2*size) |
| 497 | assert(back == str) | 498 | assert(back == str, "'" .. back .. "' vs '" .. str .. "'") |
| 498 | print("ok") | 499 | print("ok") |
| 499 | end | 500 | end |
| 500 | 501 | ||
| 501 | |||
| 502 | ------------------------------------------------------------------------ | 502 | ------------------------------------------------------------------------ |
| 503 | test("non-blocking transfer") | ||
| 504 | test_nonblocking(1) | ||
| 505 | test_nonblocking(17) | ||
| 506 | test_nonblocking(200) | ||
| 507 | test_nonblocking(4091) | ||
| 508 | test_nonblocking(80199) | ||
| 509 | test_nonblocking(8000000) | ||
| 510 | test_nonblocking(80199) | ||
| 511 | test_nonblocking(4091) | ||
| 512 | test_nonblocking(200) | ||
| 513 | test_nonblocking(17) | ||
| 514 | test_nonblocking(1) | ||
| 515 | 503 | ||
| 516 | test("method registration") | 504 | test("method registration") |
| 517 | test_methods(socket.tcp(), { | 505 | test_methods(socket.tcp(), { |
| @@ -524,6 +512,7 @@ test_methods(socket.tcp(), { | |||
| 524 | "getpeername", | 512 | "getpeername", |
| 525 | "getsockname", | 513 | "getsockname", |
| 526 | "getstats", | 514 | "getstats", |
| 515 | "setstats", | ||
| 527 | "listen", | 516 | "listen", |
| 528 | "receive", | 517 | "receive", |
| 529 | "send", | 518 | "send", |
| @@ -628,6 +617,20 @@ test_raw(200) | |||
| 628 | test_raw(17) | 617 | test_raw(17) |
| 629 | test_raw(1) | 618 | test_raw(1) |
| 630 | 619 | ||
| 620 | test("non-blocking transfer") | ||
| 621 | test_nonblocking(1) | ||
| 622 | test_nonblocking(17) | ||
| 623 | test_nonblocking(200) | ||
| 624 | test_nonblocking(4091) | ||
| 625 | test_nonblocking(80199) | ||
| 626 | test_nonblocking(8000000) | ||
| 627 | test_nonblocking(80199) | ||
| 628 | test_nonblocking(4091) | ||
| 629 | test_nonblocking(200) | ||
| 630 | test_nonblocking(17) | ||
| 631 | test_nonblocking(1) | ||
| 632 | |||
| 633 | |||
| 631 | test("total timeout on send") | 634 | test("total timeout on send") |
| 632 | test_totaltimeoutsend(800091, 1, 3) | 635 | test_totaltimeoutsend(800091, 1, 3) |
| 633 | test_totaltimeoutsend(800091, 2, 3) | 636 | test_totaltimeoutsend(800091, 2, 3) |
