Beta2 is out! Total timeout works on Windows.

master
Diego Nehab 2004-07-26 05:17:37 +00:00
parent d914007507
commit 911e8d7e7f
9 changed files with 77 additions and 123 deletions

109
NEW
View File

@ -1,86 +1,31 @@
What's New
Everything is new! Many changes for 2.0 happened in the C layer,
which has been almost completely rewritten. The code has been ported to
Lua 5.0 and greatly improved. There have also been some API changes
that made the interface simpler and more consistent. Here are some of
the changes that made it into version 2.0:
Changes in the 2.0-beta2 were mostly bug-fixes.
<> Major C code rewrite. Code is modular and extensible. Hopefully, other
developers will be motivated to provide code for SSL, local domain
sockets, file descriptors, pipes (on Unix) and named pipes etc;
<> Everything that is exported by the library is exported inside
namespaces. These should be obtained with calls to the
'require' function;
<> Functions such as
send/receive/timeout/close etc do not exist anymore as stand-alone
functions. They are now only available as methods of the appropriate
objects;
<> All functions return a non-nil value as first return value if successful.
All functions return 'nil' followed by error message
in case of error. This made the library much easier to use;
<> Greatly reduced the number of times the C select is called
during data transfers, by calling only on failure. This might
improve a lot the maximum throughput;
<> TCP has been changed to become more uniform. It's possible to first
create a TCP object,
then connect or bind if needed, and finally use I/O functions.
'socket.connect' and 'socket.bind' functions are still
provided for simplicity;
<> This allows for setting a timeout value before connecting;
<> And also allows binding to a local address before connecting;
<> New 'socket.dns.gethostname' function and 'shutdown'
method;
<> Better error messages and parameter checking;
<> Should be interrupt safe;
<> UDP connected sockets can break association with peer by calling
'setpeername' with address ''*'';
<> Sets returned by 'socket.select' are associative;
<> Select checks if sockets have buffered data and returns immediately;
<> 'socket.sleep' and 'socket.time' are now part of the
library and are supported. They used to be available only when
LUASOCKET_DEBUG was defined, but it turns out they might be useful for
applications;
<> 'socket.newtry' and 'socket.protect' provide a simple
interface to exceptions that proved very in the implementation of
high-level modules;
<> Socket options interface has been improved. TCP objects also
support socket options and many new options were added.
Lots of changes in the Lua modules, too!
<> Every module loads only the modules that it needs. There is no waste
of memory. LuaSocket core takes only 20k of memory;
<> New MIME and LTN12 modules make all other modules much more powerful;
<> Support for multipart messages in the SMTP module;
<> The old callback mechanism of FTP and HTTP has been replaced with LTN12
sources and sinks, with advantage;
<> Common implementation for low-level FTP and SMTP;
<> FTP, HTTP, and SMTP are implemented in multiple levels in such a way
that users will have no problems extending the functionality to satisfy
personal needs;
<> SMTP knows how to perform LOGIN and PLAIN authentication.
<> Fixed silly last-minute-change bug in HTTP/SMTP running;
<> usocket.c/wsocket.c look nicer thanks to Mike;
<> Finally total timeout is reliable on Windows! (found a pretty
simple work around);
<> UDP has a reasonable maximum datagram size (8k);
<> Receive accepts the prefix optional argument (good for
non-blocking);
<> <b>Send doesn't support multiple arguments anymore</b>;
<> Instead, send allows the selection of the substring
to be sent (good for non-blocking);
<> Fixed bug that caused select return tables not to be associative
on windows;
<> Should compiles with g++;
<> New sample unix domain support;
<> New sample LPD support;
<> Comprehensive error messages;
<> New getstats and setstats methods to help
throttling;
<> Listen defaults to 32 backlog;
<> SMTP/FTP/HTTP fail gracefully;
<> accept/connect/select interrupt safe
<> Fixed bug that didn't set accepted sockets as non-blocking
<> <b>New timming functions sleep and gettime have
higher resolution and no wrap around problems</b>;
<> Bug fixes in the manual;
<> Fixed bug of missing cast in getfd.

8
TODO
View File

@ -1,8 +1,5 @@
change sendraw to send by chunks
fix manual for send and receive
add thanks to mike
change sock:send to use indices just like string.sub?
use mike's "don't set to blocking before closing unless needed" patch?
take a look at DB's smtp patch
@ -32,3 +29,6 @@ testar os options!
*add getstats to the manual
*Fazer compilar com g++
*test associativity of socket.select
* fix manual for send and receive
* add thanks to mike
* change sock:send to use indices just like string.sub?

View File

@ -169,10 +169,11 @@ Changes in the 2.0-beta2 were mostly bug-fixes.
</p>
<ul>
<li> Fixed silly last minute bugs in HTTP/SMTP that prevented them from
running;
<li> Fixed silly last-minute-change bug in HTTP/SMTP running;
<li> <tt>usocket.c</tt>/<tt>wsocket.c</tt> look nicer thanks to Mike;
<li> UDP has a reasonable maximum datagram size;
<li> Finally total timeout is reliable on Windows! (found a pretty
simple work around);
<li> UDP has a reasonable maximum datagram size (8k);
<li> <tt>Receive</tt> accepts the prefix optional argument (good for
non-blocking);
<li> <b><tt>Send</tt> doesn't support multiple arguments anymore</b>;

View File

@ -2,7 +2,7 @@
# Distribution makefile
#--------------------------------------------------------------------------
DIST = luasocket-2.0-beta
DIST = luasocket-2.0-beta2
LUA = \
ftp.lua \
@ -104,7 +104,6 @@ dist:
mkdir -p $(DIST)/etc
mkdir -p $(DIST)/lua
mkdir -p $(DIST)/manual
cp -vf FIX $(DIST)
cp -vf TODO $(DIST)
cp -vf $(CORE) $(DIST)
cp -vf README $(DIST)

View File

@ -81,10 +81,10 @@ int buf_meth_send(lua_State *L, p_buf buf) {
const char *data = luaL_checklstring(L, 2, &size);
long start = (long) luaL_optnumber(L, 3, 1);
long end = (long) luaL_optnumber(L, 4, -1);
if (start < 0) start = size+start+1;
if (end < 0) end = size+end+1;
if (start < 1) start = 1;
if (end > (long) size) end = size;
if (start < 0) start = (long) (size+start+1);
if (end < 0) end = (long) (size+end+1);
if (start < 1) start = (long) 1;
if (end > (long) size) end = (long) size;
if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent);
/* check if there was an error */
if (err != IO_DONE) {

View File

@ -19,6 +19,7 @@
#include "timeout.h"
#include "socket.h"
/* can't be larger than wsocket.c MAXCHUNK!!! */
#define UDP_DATAGRAMSIZE 8192
typedef struct t_udp_ {

View File

@ -181,6 +181,8 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *len, p_tm tm) {
/*-------------------------------------------------------------------------*\
* Send with timeout
\*-------------------------------------------------------------------------*/
/* has to be larger than UDP_DATAGRAMSIZE !!!*/
#define MAXCHUNK (64*1024)
int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm)
{
int err;
@ -190,7 +192,9 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm)
*sent = 0;
for ( ;; ) {
/* try to send something */
int put = send(*ps, data, (int) count, 0);
/* on windows, if you try to send 10MB, the OS will buffer EVERYTHING
* this can take an awful lot of time and we will end up blocked. */
int put = send(*ps, data, (count < MAXCHUNK)? (int)count: MAXCHUNK, 0);
/* if we sent something, we are done */
if (put > 0) {
*sent = put;

View File

@ -115,6 +115,16 @@ ignore = {
}
check_request(request, expect, ignore)
------------------------------------------------------------------------
io.write("testing invalid url: ")
local c, e = socket.connect("", 80)
local r, re = http.request{url = host .. prefix}
assert(r == nil and e == re)
r, re = http.request(host .. prefix)
assert(r == nil and e == re, tostring(r) ..", " .. tostring(re) ..
" vs " .. tostring(e))
print("ok")
------------------------------------------------------------------------
io.write("testing post method: ")
-- wanted to test chunked post, but apache doesn't support it...
@ -406,15 +416,6 @@ r, re = http.request("http://wronghost/does/not/exist")
assert(r == nil and e == re)
print("ok")
------------------------------------------------------------------------
io.write("testing invalid url: ")
local c, e = socket.connect("", 80)
local r, re = http.request{url = host .. prefix}
assert(r == nil and e == re)
r, re = http.request(host .. prefix)
assert(r == nil and e == re)
print("ok")
------------------------------------------------------------------------
print("passed all tests")
os.remove("err")

View File

@ -461,6 +461,7 @@ end
------------------------------------------------------------------------
function test_nonblocking(size)
reconnect()
print("Testing " .. 2*size .. " bytes")
remote(string.format([[
data:send(string.rep("a", %d))
socket.sleep(0.5)
@ -471,7 +472,9 @@ remote(string.format([[
local str
data:settimeout(0)
while 1 do
str, err, part = data:receive(2*size - string.len(part), part)
local needed = 2*size - string.len(part)
assert(needed > 0, "weird")
str, err, part = data:receive(needed, part)
if err ~= "timeout" then break end
end
assert(str == (string.rep("a", size) .. string.rep("b", size)))
@ -480,9 +483,7 @@ remote(string.format([[
str = data:receive(%d)
socket.sleep(0.5)
str = data:receive(%d, str)
str = data:receive("*l", str)
data:send(str)
data:send("\n")
]], size, size))
data:settimeout(0)
local sofar = 1
@ -493,25 +494,12 @@ remote(string.format([[
end
data:send("\n")
data:settimeout(-1)
local back = data:receive()
assert(back == str)
local back = data:receive(2*size)
assert(back == str, "'" .. back .. "' vs '" .. str .. "'")
print("ok")
end
------------------------------------------------------------------------
test("non-blocking transfer")
test_nonblocking(1)
test_nonblocking(17)
test_nonblocking(200)
test_nonblocking(4091)
test_nonblocking(80199)
test_nonblocking(8000000)
test_nonblocking(80199)
test_nonblocking(4091)
test_nonblocking(200)
test_nonblocking(17)
test_nonblocking(1)
test("method registration")
test_methods(socket.tcp(), {
@ -524,6 +512,7 @@ test_methods(socket.tcp(), {
"getpeername",
"getsockname",
"getstats",
"setstats",
"listen",
"receive",
"send",
@ -628,6 +617,20 @@ test_raw(200)
test_raw(17)
test_raw(1)
test("non-blocking transfer")
test_nonblocking(1)
test_nonblocking(17)
test_nonblocking(200)
test_nonblocking(4091)
test_nonblocking(80199)
test_nonblocking(8000000)
test_nonblocking(80199)
test_nonblocking(4091)
test_nonblocking(200)
test_nonblocking(17)
test_nonblocking(1)
test("total timeout on send")
test_totaltimeoutsend(800091, 1, 3)
test_totaltimeoutsend(800091, 2, 3)