From 911e8d7e7f63e6e90814e82955bfaf26328afb19 Mon Sep 17 00:00:00 2001
From: Diego Nehab
Date: Mon, 26 Jul 2004 05:17:37 +0000
Subject: [PATCH] Beta2 is out! Total timeout works on Windows.
---
NEW | 109 ++++++++++++----------------------------------
TODO | 8 ++--
doc/index.html | 7 +--
makefile.dist | 3 +-
src/buffer.c | 8 ++--
src/udp.h | 1 +
src/wsocket.c | 6 ++-
test/httptest.lua | 19 ++++----
test/testclnt.lua | 39 +++++++++--------
9 files changed, 77 insertions(+), 123 deletions(-)
diff --git a/NEW b/NEW
index 302974e..3d7a19a 100644
--- a/NEW
+++ b/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);
+<> Send doesn't support multiple arguments anymore;
+<> 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
+<> New timming functions sleep and gettime have
+ higher resolution and no wrap around problems;
+<> Bug fixes in the manual;
+<> Fixed bug of missing cast in getfd.
diff --git a/TODO b/TODO
index 23de9d7..cbc2edb 100644
--- a/TODO
+++ b/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?
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.
-- Fixed silly last minute bugs in HTTP/SMTP that prevented them from
-running;
+
- Fixed silly last-minute-change bug in HTTP/SMTP running;
- usocket.c/wsocket.c look nicer thanks to Mike;
-
- UDP has a reasonable maximum datagram size;
+
- 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);
- Send doesn't support multiple arguments anymore;
diff --git a/makefile.dist b/makefile.dist
index 56bba96..a0a9313 100644
--- a/makefile.dist
+++ b/makefile.dist
@@ -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)
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) {
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) {
diff --git a/src/udp.h b/src/udp.h
index f34c8ad..520573d 100644
--- a/src/udp.h
+++ b/src/udp.h
@@ -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_ {
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) {
/*-------------------------------------------------------------------------*\
* 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;
diff --git a/test/httptest.lua b/test/httptest.lua
index 31e8212..ce7a93b 100644
--- a/test/httptest.lua
+++ b/test/httptest.lua
@@ -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")
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
------------------------------------------------------------------------
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)