mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 12:28:21 +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
|
What's New
|
||||||
|
|
||||||
Everything is new! Many changes for 2.0 happened in the C layer,
|
Changes in the 2.0-beta2 were mostly bug-fixes.
|
||||||
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:
|
|
||||||
|
|
||||||
<> Major C code rewrite. Code is modular and extensible. Hopefully, other
|
<> Fixed silly last-minute-change bug in HTTP/SMTP running;
|
||||||
developers will be motivated to provide code for SSL, local domain
|
<> usocket.c/wsocket.c look nicer thanks to Mike;
|
||||||
sockets, file descriptors, pipes (on Unix) and named pipes etc;
|
<> Finally total timeout is reliable on Windows! (found a pretty
|
||||||
|
simple work around);
|
||||||
<> Everything that is exported by the library is exported inside
|
<> UDP has a reasonable maximum datagram size (8k);
|
||||||
namespaces. These should be obtained with calls to the
|
<> Receive accepts the prefix optional argument (good for
|
||||||
'require' function;
|
non-blocking);
|
||||||
|
<> <b>Send doesn't support multiple arguments anymore</b>;
|
||||||
<> Functions such as
|
<> Instead, send allows the selection of the substring
|
||||||
send/receive/timeout/close etc do not exist anymore as stand-alone
|
to be sent (good for non-blocking);
|
||||||
functions. They are now only available as methods of the appropriate
|
<> Fixed bug that caused select return tables not to be associative
|
||||||
objects;
|
on windows;
|
||||||
|
<> Should compiles with g++;
|
||||||
<> All functions return a non-nil value as first return value if successful.
|
<> New sample unix domain support;
|
||||||
All functions return 'nil' followed by error message
|
<> New sample LPD support;
|
||||||
in case of error. This made the library much easier to use;
|
<> Comprehensive error messages;
|
||||||
|
<> New getstats and setstats methods to help
|
||||||
<> Greatly reduced the number of times the C select is called
|
throttling;
|
||||||
during data transfers, by calling only on failure. This might
|
<> Listen defaults to 32 backlog;
|
||||||
improve a lot the maximum throughput;
|
<> SMTP/FTP/HTTP fail gracefully;
|
||||||
|
<> accept/connect/select interrupt safe
|
||||||
<> TCP has been changed to become more uniform. It's possible to first
|
<> Fixed bug that didn't set accepted sockets as non-blocking
|
||||||
create a TCP object,
|
<> <b>New timming functions sleep and gettime have
|
||||||
then connect or bind if needed, and finally use I/O functions.
|
higher resolution and no wrap around problems</b>;
|
||||||
'socket.connect' and 'socket.bind' functions are still
|
<> Bug fixes in the manual;
|
||||||
provided for simplicity;
|
<> Fixed bug of missing cast in getfd.
|
||||||
|
|
||||||
<> 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.
|
|
||||||
|
|
||||||
|
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?
|
use mike's "don't set to blocking before closing unless needed" patch?
|
||||||
take a look at DB's smtp patch
|
take a look at DB's smtp patch
|
||||||
|
|
||||||
@ -32,3 +29,6 @@ testar os options!
|
|||||||
*add getstats to the manual
|
*add getstats to the manual
|
||||||
*Fazer compilar com g++
|
*Fazer compilar com g++
|
||||||
*test associativity of socket.select
|
*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>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li> Fixed silly last minute bugs in HTTP/SMTP that prevented them from
|
<li> Fixed silly last-minute-change bug in HTTP/SMTP running;
|
||||||
running;
|
|
||||||
<li> <tt>usocket.c</tt>/<tt>wsocket.c</tt> look nicer thanks to Mike;
|
<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
|
<li> <tt>Receive</tt> accepts the prefix optional argument (good for
|
||||||
non-blocking);
|
non-blocking);
|
||||||
<li> <b><tt>Send</tt> doesn't support multiple arguments anymore</b>;
|
<li> <b><tt>Send</tt> doesn't support multiple arguments anymore</b>;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# Distribution makefile
|
# Distribution makefile
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
|
|
||||||
DIST = luasocket-2.0-beta
|
DIST = luasocket-2.0-beta2
|
||||||
|
|
||||||
LUA = \
|
LUA = \
|
||||||
ftp.lua \
|
ftp.lua \
|
||||||
@ -104,7 +104,6 @@ dist:
|
|||||||
mkdir -p $(DIST)/etc
|
mkdir -p $(DIST)/etc
|
||||||
mkdir -p $(DIST)/lua
|
mkdir -p $(DIST)/lua
|
||||||
mkdir -p $(DIST)/manual
|
mkdir -p $(DIST)/manual
|
||||||
cp -vf FIX $(DIST)
|
|
||||||
cp -vf TODO $(DIST)
|
cp -vf TODO $(DIST)
|
||||||
cp -vf $(CORE) $(DIST)
|
cp -vf $(CORE) $(DIST)
|
||||||
cp -vf README $(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);
|
const char *data = luaL_checklstring(L, 2, &size);
|
||||||
long start = (long) luaL_optnumber(L, 3, 1);
|
long start = (long) luaL_optnumber(L, 3, 1);
|
||||||
long end = (long) luaL_optnumber(L, 4, -1);
|
long end = (long) luaL_optnumber(L, 4, -1);
|
||||||
if (start < 0) start = size+start+1;
|
if (start < 0) start = (long) (size+start+1);
|
||||||
if (end < 0) end = size+end+1;
|
if (end < 0) end = (long) (size+end+1);
|
||||||
if (start < 1) start = 1;
|
if (start < 1) start = (long) 1;
|
||||||
if (end > (long) size) end = size;
|
if (end > (long) size) end = (long) size;
|
||||||
if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent);
|
if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent);
|
||||||
/* check if there was an error */
|
/* check if there was an error */
|
||||||
if (err != IO_DONE) {
|
if (err != IO_DONE) {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "timeout.h"
|
#include "timeout.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
|
/* can't be larger than wsocket.c MAXCHUNK!!! */
|
||||||
#define UDP_DATAGRAMSIZE 8192
|
#define UDP_DATAGRAMSIZE 8192
|
||||||
|
|
||||||
typedef struct t_udp_ {
|
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
|
* 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 sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm)
|
||||||
{
|
{
|
||||||
int err;
|
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;
|
*sent = 0;
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
/* try to send something */
|
/* 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 we sent something, we are done */
|
||||||
if (put > 0) {
|
if (put > 0) {
|
||||||
*sent = put;
|
*sent = put;
|
||||||
|
@ -115,6 +115,16 @@ ignore = {
|
|||||||
}
|
}
|
||||||
check_request(request, expect, 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: ")
|
io.write("testing post method: ")
|
||||||
-- wanted to test chunked post, but apache doesn't support it...
|
-- 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)
|
assert(r == nil and e == re)
|
||||||
print("ok")
|
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")
|
print("passed all tests")
|
||||||
os.remove("err")
|
os.remove("err")
|
||||||
|
@ -461,6 +461,7 @@ end
|
|||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
function test_nonblocking(size)
|
function test_nonblocking(size)
|
||||||
reconnect()
|
reconnect()
|
||||||
|
print("Testing " .. 2*size .. " bytes")
|
||||||
remote(string.format([[
|
remote(string.format([[
|
||||||
data:send(string.rep("a", %d))
|
data:send(string.rep("a", %d))
|
||||||
socket.sleep(0.5)
|
socket.sleep(0.5)
|
||||||
@ -471,7 +472,9 @@ remote(string.format([[
|
|||||||
local str
|
local str
|
||||||
data:settimeout(0)
|
data:settimeout(0)
|
||||||
while 1 do
|
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
|
if err ~= "timeout" then break end
|
||||||
end
|
end
|
||||||
assert(str == (string.rep("a", size) .. string.rep("b", size)))
|
assert(str == (string.rep("a", size) .. string.rep("b", size)))
|
||||||
@ -480,9 +483,7 @@ remote(string.format([[
|
|||||||
str = data:receive(%d)
|
str = data:receive(%d)
|
||||||
socket.sleep(0.5)
|
socket.sleep(0.5)
|
||||||
str = data:receive(%d, str)
|
str = data:receive(%d, str)
|
||||||
str = data:receive("*l", str)
|
|
||||||
data:send(str)
|
data:send(str)
|
||||||
data:send("\n")
|
|
||||||
]], size, size))
|
]], size, size))
|
||||||
data:settimeout(0)
|
data:settimeout(0)
|
||||||
local sofar = 1
|
local sofar = 1
|
||||||
@ -493,25 +494,12 @@ remote(string.format([[
|
|||||||
end
|
end
|
||||||
data:send("\n")
|
data:send("\n")
|
||||||
data:settimeout(-1)
|
data:settimeout(-1)
|
||||||
local back = data:receive()
|
local back = data:receive(2*size)
|
||||||
assert(back == str)
|
assert(back == str, "'" .. back .. "' vs '" .. str .. "'")
|
||||||
print("ok")
|
print("ok")
|
||||||
end
|
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("method registration")
|
||||||
test_methods(socket.tcp(), {
|
test_methods(socket.tcp(), {
|
||||||
@ -524,6 +512,7 @@ test_methods(socket.tcp(), {
|
|||||||
"getpeername",
|
"getpeername",
|
||||||
"getsockname",
|
"getsockname",
|
||||||
"getstats",
|
"getstats",
|
||||||
|
"setstats",
|
||||||
"listen",
|
"listen",
|
||||||
"receive",
|
"receive",
|
||||||
"send",
|
"send",
|
||||||
@ -628,6 +617,20 @@ test_raw(200)
|
|||||||
test_raw(17)
|
test_raw(17)
|
||||||
test_raw(1)
|
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("total timeout on send")
|
||||||
test_totaltimeoutsend(800091, 1, 3)
|
test_totaltimeoutsend(800091, 1, 3)
|
||||||
test_totaltimeoutsend(800091, 2, 3)
|
test_totaltimeoutsend(800091, 2, 3)
|
||||||
|
Loading…
Reference in New Issue
Block a user