Saving before big changes to support IPv6.

This commit is contained in:
Diego Nehab 2011-05-25 20:57:22 +00:00
parent bce60be30f
commit 3a8ba90dfb
30 changed files with 948 additions and 850 deletions

13
FIX
View File

@ -1,15 +1,14 @@
http was preserving old host header during redirects
fix smtp.send hang on source error
add create field to FTP and SMTP and fix HTTP ugliness
clean timeout argument to open functions in SMTP, HTTP and FTP
eliminate globals from namespaces created by module().
url.absolute was not working when base_url was already parsed
http.request was redirecting even when the location header was empty
tcp{client}:shutdown() was checking for group instead of class.

40
NEW
View File

@ -2,19 +2,37 @@ What's New
This is just a bug-fix/update release.
* Fixed: manual links to home.html changed to index.html (Robert Hahn)
* Fixed: mime.unb64() returns empty string on results that start
with a null character (Robert Raschke)
* Fixed: HTTP now automatically redirecting on 303 and 307 (Jonathan Gray)
* Fixed: sleep(-1) could sleep forever wasting CPU. Now it
returns immediately (MPB);
* Fixed: manual sample of HTTP authentication now uses correct
"authorization" header (Alexandre Ittner);
* Fixed: failure on bind() was destroying the socket (Sam Roberts);
* Fixed: receive() returns immediatelly if prefix can satisfy
bytes requested (M Joonas Pihlaja);
* Fixed: multicast didn't work on Windows, or anywhere
else for that matter (Herbert Leuwer, Adrian Sietsma);
* Fixed: select() now reports an error when called with more
sockets than FD_SETSIZE (Lorenzo Leonini);
* Fixed: manual links to home.html changed to index.html (Robert Hahn);
* Fixed: mime.unb64() would return an empty string on results that started
with a null character (Robert Raschke);
* Fixed: HTTP now automatically redirects on 303 and 307 (Jonathan Gray);
* Fixed: calling sleep() with negative numbers could
block forever, wasting CPU. Now it returns immediately (MPB);
* Improved: FTP commands are now sent in upper case to
help buggy servers (Anders Eurenius)
help buggy servers (Anders Eurenius);
* Improved: known headers now sent in canonic
capitalization to help buggy servers (Joseph Stewart);
* Improved: Clarified tcp:receive() in the manual (MPB);
* Improved: Decent makefiles (LHF).
* Fixed: RFC links in documentation now point to IETF (Cosmin Apreutesei).
* Fixed: multicast didn't work on Windows (Herbert Leuwer, Adrian Sietsma)
* Fixed: select() reports an error when called with more
sockets than FD_SETSIZE (Lorenzo Leonini)
Yuri's bug?
Dahlberg
Sam Roberts
Thomas Harning Jr.
Sebastien Perin
remove getn in all files
ltn12.pump.all(
ltn12.source.file(io.open("original.png")),
ltn12.sink.file(io.open("copy.png", "wb"))
)

View File

@ -42,7 +42,7 @@
FTP (File Transfer Protocol) is a protocol used to transfer files
between hosts. The <tt>ftp</tt> namespace offers thorough support
to FTP, under a simple interface. The implementation conforms to
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc0959.txt">RFC 959</a>.
<a href="http://www.ietf.org/rfc/rfc959.txt">RFC 959</a>.
</p>
<p>
@ -70,8 +70,8 @@ local ftp = require("socket.ftp")
<p>
URLs MUST conform to
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc1738.txt">RFC
1738</a>, that is, an URL is a string in the form:
<a href="http://www.ietf.org/rfc/rfc1738.txt">RFC 1738</a>,
that is, an URL is a string in the form:
</p>
<blockquote>

View File

@ -45,8 +45,7 @@ namespace offers full support for the client side of the HTTP
protocol (i.e.,
the facilities that would be used by a web-browser implementation). The
implementation conforms to the HTTP/1.1 standard,
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2616.txt">RFC
2616</a>.
<a href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</a>.
</p>
<p>
@ -67,8 +66,7 @@ local http = require("socket.http")
<p>
URLs must conform to
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc1738.txt">RFC
1738</a>,
<a href="http://www.ietf.org/rfc/rfc1738.txt">RFC 1738</a>,
that is, an URL is a string in the form:
</p>
@ -199,8 +197,7 @@ it usually returns a message body (a web page informing the
URL was not found or some other useless page). To make sure the
operation was successful, check the returned status <tt>code</tt>. For
a list of the possible values and their meanings, refer to <a
href="http://www.cs.princeton.edu/~diego/rfc/rfc2616.txt">RFC
2616</a>.
href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</a>.
</p>
<p class=description>
@ -278,7 +275,7 @@ download and return status "401&nbsp;Authentication Required".
The HTTP/1.1 standard defines two authentication methods: the Basic
Authentication Scheme and the Digest Authentication Scheme, both
explained in detail in
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2068.txt">RFC 2068</a>.
<a href="http://www.ietf.org/rfc/rfc2068.txt">RFC 2068</a>.
</p>
<p class=note>The Basic Authentication Scheme sends
@ -304,7 +301,7 @@ b, c, h = http.request("http://fulano:silva@www.example.com/private/index.html")
-- the request directly.
r, c = http.request {
url = "http://www.example.com/private/index.html",
headers = { authentication = "Basic " .. (mime.b64("fulano:silva")) }
headers = { authorization = "Basic " .. (mime.b64("fulano:silva")) }
}
</pre>

View File

@ -138,18 +138,22 @@ all!
</p>
<ul>
<li> Fixed: manual sample of HTTP authentication now uses correct
"authorization" header (Alexandre Ittner);
<li> Fixed: receive() returns immediatelly if prefix can satisfy
bytes requested (M Joonas Pihlaja);
<li> Fixed: multicast didn't work on Windows, or anywhere
else for that matter (Herbert Leuwer, Adrian Sietsma)
else for that matter (Herbert Leuwer, Adrian Sietsma);
<li> Fixed: select() now reports an error when called with more
sockets than FD_SETSIZE (Lorenzo Leonini)
<li> Fixed: manual links to home.html changed to index.html (Robert Hahn)
sockets than FD_SETSIZE (Lorenzo Leonini);
<li> Fixed: manual links to home.html changed to index.html (Robert Hahn);
<li> Fixed: mime.unb64() would return an empty string on results that started
with a null character (Robert Raschke)
<li> Fixed: HTTP now automatically redirects on 303 and 307 (Jonathan Gray)
with a null character (Robert Raschke);
<li> Fixed: HTTP now automatically redirects on 303 and 307 (Jonathan Gray);
<li> Fixed: calling sleep() with negative numbers could
block forever, wasting CPU. Now it returns immediately (MPB);
<li> Improved: FTP commands are now sent in upper case to
help buggy servers (Anders Eurenius)
help buggy servers (Anders Eurenius);
<li> Improved: known headers now sent in canonic
capitalization to help buggy servers (Joseph Stewart);
<li> Improved: Clarified tcp:receive() in the manual (MPB);

View File

@ -44,11 +44,11 @@ content transfer encodings, such as Base64 and Quoted-Printable.
It also provides functions to break text into lines and change
the end-of-line convention.
MIME is described mainly in
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2045.txt">RFC 2045</a>,
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2046.txt">2046</a>,
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2047.txt">2047</a>,
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2047.txt">2048</a>, and
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2048.txt">2049</a>.
<a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>,
<a href="http://www.ietf.org/rfc/rfc2046.txt">2046</a>,
<a href="http://www.ietf.org/rfc/rfc2047.txt">2047</a>,
<a href="http://www.ietf.org/rfc/rfc2047.txt">2048</a>, and
<a href="http://www.ietf.org/rfc/rfc2048.txt">2049</a>.
</p>
<p>

View File

@ -48,14 +48,13 @@ control (if you bother to read the code).
</p>
<p>The implementation conforms to the Simple Mail Transfer Protocol,
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2821.txt">RFC 2821</a>.
<a href="http://www.ietf.org/rfc/rfc2821.txt">RFC 2821</a>.
Another RFC of interest is <a
href="http://www.cs.princeton.edu/~diego/rfc/rfc2822.txt">RFC 2822</a>,
href="http://www.ietf.org/rfc/rfc2822.txt">RFC 2822</a>,
which governs the Internet Message Format.
Multipart messages (those that contain attachments) are part
of the MIME standard, but described mainly
in <a href="http://www.cs.princeton.edu/~diego/rfc/rfc2046.txt">RFC
2046</a>
in <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a>
<p> In the description below, good understanding of <a
href="http://lua-users.org/wiki/FiltersSourcesAndSinks"> LTN012, Filters
@ -196,7 +195,7 @@ part of the message and will not be sent to anyone.
</p>
<p class=note>
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2822.txt">RFC 2822</a>
<a href="http://www.ietf.org/rfc/rfc2822.txt">RFC 2822</a>
has two <em>important and short</em> sections, "3.6.3. Destination address
fields" and "5. Security considerations", explaining the proper
use of these headers. Here is a summary of what it says:
@ -236,9 +235,9 @@ exactly what you <em>don't</em> want to happen!
<p class=note>
I hope this clarifies the issue. Otherwise, please refer to
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2821.txt">RFC 2821</a>
<a href="http://www.ietf.org/rfc/rfc2821.txt">RFC 2821</a>
and
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2822.txt">RFC 2822</a>.
<a href="http://www.ietf.org/rfc/rfc2822.txt">RFC 2822</a>.
</p>
<pre class=example>

View File

@ -42,8 +42,7 @@
The <tt>url</tt> namespace provides functions to parse, protect,
and build URLs, as well as functions to compose absolute URLs
from base and relative URLs, according to
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2396.txt">RFC
2396</a>.
<a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>.
</p>
<p>
@ -91,7 +90,7 @@ The function returns a string with the absolute URL.
<p class=note>
Note: The rules that
govern the composition are fairly complex, and are described in detail in
<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2396.txt">RFC 2396</a>.
<a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>.
The example bellow should give an idea of what the rules are.
</p>

View File

@ -1,21 +1,13 @@
PLAT= none
PLATS= macosx linux
PLAT?= macosx
PLATS= macosx linux win32
#------
# Hopefully no need to change anything below this line
#
all: $(PLAT)
none:
@echo "Please run"
@echo " make PLATFORM"
@echo "where PLATFORM is one of these:"
@echo " $(PLATS)"
$(PLATS) install local clean:
cd src; $(MAKE) $@
dummy:
$(PLATS) none install local clean:
@cd src; $(MAKE) $@
test: dummy
lua test/hello.lua

View File

@ -124,7 +124,13 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) {
else luaL_argcheck(L, 0, 2, "invalid receive pattern");
/* get a fixed number of bytes (minus what was already partially
* received) */
} else err = recvraw(buf, (size_t) lua_tonumber(L, 2)-size, &b);
} else {
double n = lua_tonumber(L, 2);
size_t wanted = (size_t) n;
luaL_argcheck(L, n >= 0, 2, "invalid receive pattern");
if (size == 0 || wanted > size)
err = recvraw(buf, wanted-size, &b);
}
/* check if there was an error */
if (err != IO_DONE) {
/* we can't push anyting in the stack before pushing the

View File

@ -248,7 +248,6 @@ const char *inet_trybind(p_socket ps, const char *address, unsigned short port)
memcpy(&local.sin_addr, *addr, sizeof(struct in_addr));
}
err = socket_bind(ps, (SA *) &local, sizeof(local));
if (err != IO_DONE) socket_destroy(ps);
return socket_strerror(err);
}

View File

@ -1,8 +1,13 @@
PLAT = none
PLAT?=macosx
INSTALL_DATA=cp
INSTALL_EXEC=cp
INSTALL_TOP=/opt/local
LUAINC= $(LUAINC_$(PLAT))
LUAINC_macosx=/opt/local/include
LUAINC_linux=/usr/include/lua5.1
LUAINC_win32="../../lua-5.1.3/src"
LUALIB_win32="../../lua-5.1.3"
#------
# Install directories
@ -15,40 +20,76 @@ INSTALL_MIME_SHARE=$(INSTALL_TOP_SHARE)/mime
INSTALL_MIME_LIB=$(INSTALL_TOP_LIB)/mime
#------
# Output file names
# Supported platforms
#
EXT=so
SOCKET_V=2.0.3
MIME_V=1.0.3
SOCKET_SO=socket.$(EXT).$(SOCKET_V)
MIME_SO=mime.$(EXT).$(MIME_V)
UNIX_SO=unix.$(EXT)
PLATS= macosx linux win32
#------
# Compiler and linker settings
# for Mac OS X
LUAINC_macosx= -I/opt/local/include
SO_macosx=so
O_macosx=o
CC_macosx=gcc
DEF_macosx= -DLUASOCKET_DEBUG -DUNIX_HAS_SUN_LEN \
-DLUASOCKET_API='__attribute__((visibility("default")))' \
-DMIME_API='__attribute__((visibility("default")))'
CFLAGS_macosx= $(LUAINC) $(COMPAT) $(DEF) -pedantic -Wall -O2 -fno-common \
CFLAGS_macosx= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \
-fvisibility=hidden
LDFLAGS_macosx= -bundle -undefined dynamic_lookup
LDFLAGS_macosx= -bundle -undefined dynamic_lookup -o
LD_macosx= export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc
SOCKET_macosx=usocket.o
#------
# Compiler and linker settings
# for Linux
LUAINC_linux= -I/usr/local/include/lua5.1
SO_linux=so
O_linux=o
CC_linux=gcc
DEF_linux=-DLUASOCKET_DEBUG \
-DLUASOCKET_API='__attribute__((visibility("default")))' \
-DMIME_API='__attribute__((visibility("default")))'
CFLAGS_linux= $(LUAINC) $(DEF) -pedantic -Wall -O2 -fpic \
CFLAGS_linux= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fpic \
-fvisibility=hidden
LDFLAGS_linux=-O -shared -fpic
LDFLAGS_linux=-O -shared -fpic -o
LD_linux=gcc
SOCKET_linux=usocket.o
#------
# Compiler and linker settings
# for Win32
SO_win32=dll
O_win32=obj
CC_win32=cl
DEF_win32= /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" \
/D "LUASOCKET_API=__declspec(dllexport)" /D "LUASOCKET_DEBUG" \
/D "_CRT_SECURE_NO_WARNINGS" /D "_WINDLL"
CFLAGS_win32=/I$(LUAINC) $(DEF) /O2 /Ot /MD /W3 /nologo
LDFLAGS_win32= /nologo /link /NOLOGO /DLL /INCREMENTAL:NO \
/LIBPATH:$(LUALIB) \
/MANIFEST \
/MANIFESTFILE:"intermediate.manifest" \
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" \
/SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /DYNAMICBASE:NO \
/MACHINE:X86 ws2_32.lib lua5.1.lib /OUT:
LD_win32=cl
SOCKET_win32=wsocket.obj
.SUFFIXES: .obj
.c.obj:
$(CC) $(CFLAGS) /Fo"$@" /c $<
#------
# Output file names
#
SO=$(SO_$(PLAT))
O=$(O_$(PLAT))
SOCKET_V=2.0.3
MIME_V=1.0.3
SOCKET_SO=socket.$(SO).$(SOCKET_V)
MIME_SO=mime.$(SO).$(MIME_V)
UNIX_SO=unix.$(SO)
SOCKET=$(SOCKET_$(PLAT))
#------
# Settings selected for platform
@ -58,46 +99,48 @@ DEF=$(DEF_$(PLAT))
CFLAGS=$(CFLAGS_$(PLAT))
LDFLAGS=$(LDFLAGS_$(PLAT))
LD=$(LD_$(PLAT))
LUAINC= $(LUAINC_$(PLAT))
LUALIB= $(LUALIB_$(PLAT))
#------
# Modules belonging to socket-core
#
SOCKET_OBJS= \
luasocket.o \
timeout.o \
buffer.o \
io.o \
auxiliar.o \
options.o \
inet.o \
usocket.o \
except.o \
select.o \
tcp.o \
udp.o
luasocket.$(O) \
timeout.$(O) \
buffer.$(O) \
io.$(O) \
auxiliar.$(O) \
options.$(O) \
inet.$(O) \
$(SOCKET) \
except.$(O) \
select.$(O) \
tcp.$(O) \
udp.$(O)
#------
# Modules belonging mime-core
#
MIME_OBJS= \
mime.o
mime.$(O)
#------
# Modules belonging unix (local domain sockets)
#
UNIX_OBJS:=\
buffer.o \
auxiliar.o \
options.o \
timeout.o \
io.o \
usocket.o \
unix.o
UNIX_OBJS=\
buffer.$(O) \
auxiliar.$(O) \
options.$(O) \
timeout.$(O) \
io.$(O) \
usocket.$(O) \
unix.$(O)
#------
# Files to install
#
TO_SOCKET_SHARE:= \
TO_SOCKET_SHARE= \
http.lua \
url.lua \
tp.lua \
@ -105,33 +148,41 @@ TO_SOCKET_SHARE:= \
headers.lua \
smtp.lua
TO_TOP_SHARE:= \
TO_TOP_SHARE= \
ltn12.lua \
socket.lua \
mime.lua
#------
# Targets
#
default: $(PLAT)
macosx:
$(MAKE) all PLAT=macosx
win32:
$(MAKE) all PLAT=win32
linux:
$(MAKE) all PLAT=linux
none:
@echo "Please choose a platform:"
@echo "Please run"
@echo " make PLATFORM"
@echo "where PLATFORM is one of these:"
@echo " $(PLATS)"
all: $(SOCKET_SO) $(MIME_SO)
$(SOCKET_SO): $(SOCKET_OBJS)
$(LD) $(LDFLAGS) -o $@ $(SOCKET_OBJS)
$(LD) $(SOCKET_OBJS) $(LDFLAGS)$@
$(MIME_SO): $(MIME_OBJS)
$(LD) $(LDFLAGS) -o $@ $(MIME_OBJS)
$(LD) $(MIME_OBJS) $(LDFLAGS)$@
$(UNIX_SO): $(UNIX_OBJS)
$(LD) $(LDFLAGS) -o $@ $(UNIX_OBJS)
$(LD) $(UNIX_OBJS) $(LDFLAGS)$@
install:
mkdir -p $(INSTALL_TOP_SHARE)
@ -139,9 +190,9 @@ install:
mkdir -p $(INSTALL_SOCKET_SHARE)
$(INSTALL_DATA) $(TO_SOCKET_SHARE) $(INSTALL_SOCKET_SHARE)
mkdir -p $(INSTALL_SOCKET_LIB)
$(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_LIB)/core.$(EXT)
$(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_LIB)/core.$(SO)
mkdir -p $(INSTALL_MIME_LIB)
$(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_LIB)/core.$(EXT)
$(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_LIB)/core.$(SO)
local:
$(MAKE) install INSTALL_TOP_LIB=.. INSTALL_TOP_SHARE=..
@ -155,24 +206,24 @@ clean:
#------
# List of dependencies
#
auxiliar.o: auxiliar.c auxiliar.h
buffer.o: buffer.c buffer.h io.h timeout.h
except.o: except.c except.h
inet.o: inet.c inet.h socket.h io.h timeout.h usocket.h
io.o: io.c io.h timeout.h
luasocket.o: luasocket.c luasocket.h auxiliar.h except.h \
auxiliar.$(O): auxiliar.c auxiliar.h
buffer.$(O): buffer.c buffer.h io.h timeout.h
except.$(O): except.c except.h
inet.$(O): inet.c inet.h socket.h io.h timeout.h usocket.h
io.$(O): io.c io.h timeout.h
luasocket.$(O): luasocket.c luasocket.h auxiliar.h except.h \
timeout.h buffer.h io.h inet.h socket.h usocket.h tcp.h \
udp.h select.h
mime.o: mime.c mime.h
options.o: options.c auxiliar.h options.h socket.h io.h \
mime.$(O): mime.c mime.h
options.$(O): options.c auxiliar.h options.h socket.h io.h \
timeout.h usocket.h inet.h
select.o: select.c socket.h io.h timeout.h usocket.h select.h
tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h usocket.h \
select.$(O): select.c socket.h io.h timeout.h usocket.h select.h
tcp.$(O): tcp.c auxiliar.h socket.h io.h timeout.h usocket.h \
inet.h options.h tcp.h buffer.h
timeout.o: timeout.c auxiliar.h timeout.h
udp.o: udp.c auxiliar.h socket.h io.h timeout.h usocket.h \
timeout.$(O): timeout.c auxiliar.h timeout.h
udp.$(O): udp.c auxiliar.h socket.h io.h timeout.h usocket.h \
inet.h options.h udp.h
unix.o: unix.c auxiliar.h socket.h io.h timeout.h usocket.h \
unix.$(O): unix.c auxiliar.h socket.h io.h timeout.h usocket.h \
options.h unix.h buffer.h
usocket.o: usocket.c socket.h io.h timeout.h usocket.h
wsocket.o: wsocket.c socket.h io.h timeout.h usocket.h
usocket.$(O): usocket.c socket.h io.h timeout.h usocket.h
wsocket.$(O): wsocket.c socket.h io.h timeout.h usocket.h

View File

@ -195,7 +195,13 @@ function build(parsed)
end
if userinfo then authority = userinfo .. "@" .. authority end
end
if authority then url = "//" .. authority .. url end
if authority then
if string.sub(url, 1, 1) == "/" then
url = "//" .. authority .. url
else
url = "//" .. authority .. "/" .. url
end
end
if parsed.scheme then url = parsed.scheme .. ":" .. url end
if parsed.fragment then url = url .. "#" .. parsed.fragment end
-- url = string.gsub(url, "%s", "")
@ -211,8 +217,8 @@ end
-- corresponding absolute url
-----------------------------------------------------------------------------
function absolute(base_url, relative_url)
local base_parsed = base_url
if base.type(base_url) == "table" then
base_parsed = base_url
base_url = build(base_parsed)
else
base_parsed = parse(base_url)

View File

@ -3,15 +3,20 @@ local socket = require"socket"
host = host or "localhost"
port = port or "8383"
function pass(...)
function printf(...)
local s = string.format(unpack(arg))
io.stderr:write(s, "\n")
io.stderr:write(s)
end
function pass(...)
printf(...)
io.stderr:write("\n")
end
function fail(...)
local s = string.format(unpack(arg))
io.stderr:write("ERROR: ", s, "!\n")
socket.sleep(3)
io.stderr:write("ERROR: ")
printf(...)
io.stderr:write("!\n")
os.exit()
end
@ -80,7 +85,6 @@ io.stderr:write("----------------------------------------------\n",
start = socket.gettime()
function reconnect()
io.stderr:write("attempting data connection... ")
if data then data:close() end
remote [[
if data then data:close() data = nil end
@ -88,12 +92,11 @@ function reconnect()
data:setoption("tcp-nodelay", true)
]]
data, err = socket.connect(host, port)
if not data then fail(err)
else pass("connected!") end
if not data then fail(err) end
data:setoption("tcp-nodelay", true)
end
pass("attempting control connection...")
printf("attempting control connection...")
control, err = socket.connect(host, port)
if err then fail(err)
else pass("connected!") end
@ -112,6 +115,7 @@ end
------------------------------------------------------------------------
function test_mixed(len)
reconnect()
io.stderr:write("length " .. len .. ": ")
local inter = math.ceil(len/4)
local p1 = "unix " .. string.rep("x", inter) .. "line\n"
local p2 = "dos " .. string.rep("y", inter) .. "line\r\n"
@ -139,6 +143,7 @@ end
------------------------------------------------------------------------
function test_asciiline(len)
reconnect()
io.stderr:write("length " .. len .. ": ")
local str, str10, back, err
str = string.rep("x", math.mod(len, 10))
str10 = string.rep("aZb.c#dAe?", math.floor(len/10))
@ -156,6 +161,7 @@ end
------------------------------------------------------------------------
function test_rawline(len)
reconnect()
io.stderr:write("length " .. len .. ": ")
local str, str10, back, err
str = string.rep(string.char(47), math.mod(len, 10))
str10 = string.rep(string.char(120,21,77,4,5,0,7,36,44,100),
@ -174,6 +180,7 @@ end
------------------------------------------------------------------------
function test_raw(len)
reconnect()
io.stderr:write("length " .. len .. ": ")
local half = math.floor(len/2)
local s1, s2, back, err
s1 = string.rep("x", half)
@ -194,7 +201,7 @@ end
function test_totaltimeoutreceive(len, tm, sl)
reconnect()
local str, err, partial
pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl)
printf("%d bytes, %ds total timeout, %ds pause: ", len, tm, sl)
remote (string.format ([[
data:settimeout(%d)
str = string.rep('a', %d)
@ -215,7 +222,7 @@ end
function test_totaltimeoutsend(len, tm, sl)
reconnect()
local str, err, total
pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl)
printf("%d bytes, %ds total timeout, %ds pause: ", len, tm, sl)
remote (string.format ([[
data:settimeout(%d)
str = data:receive(%d)
@ -235,7 +242,7 @@ end
function test_blockingtimeoutreceive(len, tm, sl)
reconnect()
local str, err, partial
pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
printf("%d bytes, %ds blocking timeout, %ds pause: ", len, tm, sl)
remote (string.format ([[
data:settimeout(%d)
str = string.rep('a', %d)
@ -255,7 +262,7 @@ end
function test_blockingtimeoutsend(len, tm, sl)
reconnect()
local str, err, total
pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
printf("%d bytes, %ds blocking timeout, %ds pause: ", len, tm, sl)
remote (string.format ([[
data:settimeout(%d)
str = data:receive(%d)
@ -273,6 +280,7 @@ end
------------------------------------------------------------------------
function empty_connect()
printf("empty connect: ")
reconnect()
if data then data:close() data = nil end
remote [[
@ -311,7 +319,7 @@ function test_closed()
local back, partial, err
local str = 'little string'
reconnect()
pass("trying read detection")
printf("trying read detection: ")
remote (string.format ([[
data:send('%s')
data:close()
@ -324,7 +332,7 @@ function test_closed()
elseif str ~= partial then fail("didn't receive partial result.")
else pass("graceful 'closed' received") end
reconnect()
pass("trying write detection")
printf("trying write detection: ")
remote [[
data:close()
data = nil
@ -342,7 +350,6 @@ end
------------------------------------------------------------------------
function test_selectbugs()
local r, s, e = socket.select(nil, nil, 0.1)
print(r, s, e)
assert(type(r) == "table" and type(s) == "table" and
(e == "timeout" or e == "error"))
pass("both nil: ok")
@ -374,7 +381,7 @@ end
------------------------------------------------------------------------
function accept_timeout()
io.stderr:write("accept with timeout (if it hangs, it failed): ")
printf("accept with timeout (if it hangs, it failed): ")
local s, e = socket.bind("*", 0, 0)
assert(s, e)
local t = socket.gettime()
@ -390,23 +397,22 @@ end
------------------------------------------------------------------------
function connect_timeout()
io.stderr:write("connect with timeout (if it hangs, it failed!): ")
printf("connect with timeout (if it hangs, it failed!): ")
local t = socket.gettime()
local c, e = socket.tcp()
assert(c, e)
c:settimeout(0.1)
local t = socket.gettime()
local r, e = c:connect("10.0.0.1", 81)
print(r, e)
assert(not r, "should not connect")
assert(socket.gettime() - t < 2, "took too long to give up.")
c:close()
print("ok")
pass("ok")
end
------------------------------------------------------------------------
function accept_errors()
io.stderr:write("not listening: ")
printf("not listening: ")
local d, e = socket.bind("*", 0)
assert(d, e);
local c, e = socket.tcp();
@ -415,26 +421,26 @@ function accept_errors()
d:settimeout(2)
local r, e = d:accept()
assert(not r and e)
print("ok: ", e)
io.stderr:write("not supported: ")
pass("ok")
printf("not supported: ")
local c, e = socket.udp()
assert(c, e);
d:setfd(c:getfd())
local r, e = d:accept()
assert(not r and e)
print("ok: ", e)
pass("ok")
end
------------------------------------------------------------------------
function connect_errors()
io.stderr:write("connection refused: ")
printf("connection refused: ")
local c, e = socket.connect("localhost", 1);
assert(not c and e)
print("ok: ", e)
io.stderr:write("host not found: ")
pass("ok")
printf("host not found: ")
local c, e = socket.connect("host.is.invalid", 1);
assert(not c and e, e)
print("ok: ", e)
pass("ok")
end
------------------------------------------------------------------------
@ -447,7 +453,7 @@ function rebind_test()
r, e = s:bind("localhost", p)
assert(not r, "managed to rebind!")
assert(e)
print("ok: ", e)
pass("ok")
end
------------------------------------------------------------------------
@ -469,14 +475,14 @@ function getstats_test()
assert(s == t, "sent count failed" .. tostring(s)
.. "/" .. tostring(t))
end
print("ok")
pass("ok")
end
------------------------------------------------------------------------
function test_nonblocking(size)
reconnect()
print("Testing " .. 2*size .. " bytes")
printf("testing " .. 2*size .. " bytes: ")
remote(string.format([[
data:send(string.rep("a", %d))
socket.sleep(0.5)
@ -508,7 +514,7 @@ remote(string.format([[
data:settimeout(-1)
local back = data:receive(2*size)
assert(back == str, "'" .. back .. "' vs '" .. str .. "'")
print("ok")
pass("ok")
end
------------------------------------------------------------------------
@ -516,7 +522,7 @@ function test_readafterclose()
local back, partial, err
local str = 'little string'
reconnect()
pass("trying repeated '*a' pattern")
printf("trying repeated '*a' pattern")
remote (string.format ([[
data:send('%s')
data:close()
@ -526,9 +532,9 @@ function test_readafterclose()
assert(back == str, "unexpected data read")
back, err, partial = data:receive("*a")
assert(back == nil and err == "closed", "should have returned 'closed'")
print("ok")
pass("ok")
reconnect()
pass("trying active close before '*a'")
printf("trying active close before '*a'")
remote (string.format ([[
data:close()
data = nil
@ -536,9 +542,9 @@ function test_readafterclose()
data:close()
back, err, partial = data:receive("*a")
assert(back == nil and err == "closed", "should have returned 'closed'")
print("ok")
pass("ok")
reconnect()
pass("trying active close before '*l'")
printf("trying active close before '*l'")
remote (string.format ([[
data:close()
data = nil
@ -546,9 +552,9 @@ function test_readafterclose()
data:close()
back, err, partial = data:receive()
assert(back == nil and err == "closed", "should have returned 'closed'")
print("ok")
pass("ok")
reconnect()
pass("trying active close before raw 1")
printf("trying active close before raw 1")
remote (string.format ([[
data:close()
data = nil
@ -556,9 +562,9 @@ function test_readafterclose()
data:close()
back, err, partial = data:receive(1)
assert(back == nil and err == "closed", "should have returned 'closed'")
print("ok")
pass("ok")
reconnect()
pass("trying active close before raw 0")
printf("trying active close before raw 0")
remote (string.format ([[
data:close()
data = nil
@ -566,7 +572,7 @@ function test_readafterclose()
data:close()
back, err, partial = data:receive(0)
assert(back == nil and err == "closed", "should have returned 'closed'")
print("ok")
pass("ok")
end
------------------------------------------------------------------------
@ -581,13 +587,29 @@ function test_writeafterclose()
while not err do
sent, err, errsent, time = data:send(str)
end
print(sent, err, errsent, time)
print("ok")
assert(err == "closed", "should have returned 'closed'")
pass("ok")
end
------------------------------------------------------------------------
--test_writeafterclose()
function test_partialrecv()
local str = 'little string'
reconnect()
remote([[
data:send("7890")
]])
data:settimeout(1)
back, err = data:receive(10, "123456")
assert(back == "1234567890", "failed on exact mixed length")
back, err = data:receive(8, "87654321")
assert(back == "87654321", "failed on exact length")
back, err = data:receive(4, "87654321")
assert(back == "87654321", "failed on smaller length")
pass("ok")
end
------------------------------------------------------------------------
test("method registration")
test_methods(socket.tcp(), {
"accept",
@ -629,12 +651,18 @@ test_methods(socket.udp(), {
"settimeout"
})
test("partial receive")
test_partialrecv()
test("select function")
test_selectbugs()
test("testing read after close")
test("read after close")
test_readafterclose()
test("write after close")
test_writeafterclose()
test("connect function")
connect_timeout()
empty_connect()