mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 04:28:20 +01:00
Beta2 is out! Total timeout works on Windows.
This commit is contained in:
parent
d914007507
commit
911e8d7e7f
109
NEW
109
NEW
@ -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
8
TODO
@ -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?
|
||||
|
@ -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>;
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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_ {
|
||||
|
@ -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;
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user