diff --git a/doc/reference.css b/doc/reference.css index b1dd25d..04e38cf 100644 --- a/doc/reference.css +++ b/doc/reference.css @@ -2,6 +2,7 @@ body { margin-left: 1em; margin-right: 1em; font-family: "Verdana", sans-serif; + background: #ffffff; } tt { diff --git a/etc/dispatch.lua b/etc/dispatch.lua index cab7f59..2485415 100644 --- a/etc/dispatch.lua +++ b/etc/dispatch.lua @@ -5,6 +5,7 @@ ----------------------------------------------------------------------------- local base = _G local table = require("table") +local string = require("string") local socket = require("socket") local coroutine = require("coroutine") module("dispatch") @@ -43,26 +44,32 @@ end ----------------------------------------------------------------------------- -- Mega hack. Don't try to do this at home. ----------------------------------------------------------------------------- --- we can't yield across calls to protect, so we rewrite it with coxpcall +-- we can't yield across calls to protect on Lua 5.1, so we rewrite it with +-- coroutines -- make sure you don't require any module that uses socket.protect before -- loading our hack -function socket.protect(f) - return function(...) - local co = coroutine.create(f) - while true do - local results = {coroutine.resume(co, ...)} - local status = table.remove(results, 1) - if not status then - if base.type(results[1]) == 'table' then - return nil, results[1][1] - else base.error(results[1]) end - end - if coroutine.status(co) == "suspended" then - arg = {coroutine.yield(base.unpack(results))} +if string.sub(base._VERSION, -3) == "5.1" then + local function _protect(co, status, ...) + if not status then + local msg = ... + if base.type(msg) == 'table' then + return nil, msg[1] else - return base.unpack(results) + base.error(msg, 0) end end + if coroutine.status(co) == "suspended" then + return _protect(co, coroutine.resume(co, coroutine.yield(...))) + else + return ... + end + end + + function socket.protect(f) + return function(...) + local co = coroutine.create(f) + return _protect(co, coroutine.resume(co, ...)) + end end end diff --git a/makefile b/makefile index 04cd894..e34f5a9 100644 --- a/makefile +++ b/makefile @@ -5,12 +5,12 @@ # Targets: # install install system independent support # install-unix also install unix-only support -# install-both install for both lua5.1 and lua5.2 -# install-both-unix also install unix-only +# install-both install for lua51 lua52 lua53 +# install-both-unix also install unix-only # print print the build settings PLAT?= linux -PLATS= macosx linux win32 mingw +PLATS= macosx linux win32 mingw freebsd all: $(PLAT) @@ -24,20 +24,26 @@ test: lua test/hello.lua install-both: - $(MAKE) clean + $(MAKE) clean @cd src; $(MAKE) $(PLAT) LUAV=5.1 @cd src; $(MAKE) install LUAV=5.1 - $(MAKE) clean + $(MAKE) clean @cd src; $(MAKE) $(PLAT) LUAV=5.2 @cd src; $(MAKE) install LUAV=5.2 + $(MAKE) clean + @cd src; $(MAKE) $(PLAT) LUAV=5.3 + @cd src; $(MAKE) install LUAV=5.3 install-both-unix: - $(MAKE) clean + $(MAKE) clean @cd src; $(MAKE) $(PLAT) LUAV=5.1 @cd src; $(MAKE) install-unix LUAV=5.1 - $(MAKE) clean + $(MAKE) clean @cd src; $(MAKE) $(PLAT) LUAV=5.2 @cd src; $(MAKE) install-unix LUAV=5.2 + $(MAKE) clean + @cd src; $(MAKE) $(PLAT) LUAV=5.3 + @cd src; $(MAKE) install-unix LUAV=5.3 .PHONY: test diff --git a/src/buffer.c b/src/buffer.c index 4ef4e8e..423d804 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -78,9 +78,7 @@ int buffer_meth_send(lua_State *L, p_buffer 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); -#ifdef LUASOCKET_DEBUG - p_timeout tm = timeout_markstart(buf->tm); -#endif + timeout_markstart(buf->tm); if (start < 0) start = (long) (size+start+1); if (end < 0) end = (long) (size+end+1); if (start < 1) start = (long) 1; @@ -98,7 +96,7 @@ int buffer_meth_send(lua_State *L, p_buffer buf) { } #ifdef LUASOCKET_DEBUG /* push time elapsed during operation as the last return value */ - lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); + lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm)); #endif return lua_gettop(L) - top; } @@ -111,9 +109,7 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) { luaL_Buffer b; size_t size; const char *part = luaL_optlstring(L, 3, "", &size); -#ifdef LUASOCKET_DEBUG - p_timeout tm = timeout_markstart(buf->tm); -#endif + timeout_markstart(buf->tm); /* initialize buffer with optional extra prefix * (useful for concatenating previous partial results) */ luaL_buffinit(L, &b); @@ -149,7 +145,7 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) { } #ifdef LUASOCKET_DEBUG /* push time elapsed during operation as the last return value */ - lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); + lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm)); #endif return lua_gettop(L) - top; } diff --git a/src/except.c b/src/except.c index 002e701..4faa208 100644 --- a/src/except.c +++ b/src/except.c @@ -9,6 +9,15 @@ #include "except.h" +#if LUA_VERSION_NUM < 502 +#define lua_pcallk(L, na, nr, err, ctx, cont) \ + ((void)ctx,(void)cont,lua_pcall(L, na, nr, err)) +#endif + +#if LUA_VERSION_NUM < 503 +typedef int lua_KContext; +#endif + /*=========================================================================*\ * Internal function prototypes. \*=========================================================================*/ @@ -73,14 +82,30 @@ static int unwrap(lua_State *L) { } else return 0; } +static int protected_finish(lua_State *L, int status, lua_KContext ctx) { + (void)ctx; + if (status != 0 && status != LUA_YIELD) { + if (unwrap(L)) return 2; + else return lua_error(L); + } else return lua_gettop(L); +} + +#if LUA_VERSION_NUM == 502 +static int protected_cont(lua_State *L) { + int ctx = 0; + int status = lua_getctx(L, &ctx); + return protected_finish(L, status, ctx); +} +#else +#define protected_cont protected_finish +#endif + static int protected_(lua_State *L) { + int status; lua_pushvalue(L, lua_upvalueindex(1)); lua_insert(L, 1); - if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) { - if (unwrap(L)) return 2; - else lua_error(L); - return 0; - } else return lua_gettop(L); + status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, protected_cont); + return protected_finish(L, status, 0); } static int global_protect(lua_State *L) { diff --git a/src/ftp.lua b/src/ftp.lua index ea1145b..917cd89 100644 --- a/src/ftp.lua +++ b/src/ftp.lua @@ -268,7 +268,7 @@ _M.command = socket.protect(function(cmdt) cmdt = override(cmdt) socket.try(cmdt.host, "missing hostname") socket.try(cmdt.command, "missing command") - local f = open(cmdt.host, cmdt.port, cmdt.create) + local f = _M.open(cmdt.host, cmdt.port, cmdt.create) f:greet() f:login(cmdt.user, cmdt.password) f.try(f.tp:command(cmdt.command, cmdt.argument)) diff --git a/src/http.lua b/src/http.lua index ac4b2d6..d5457f6 100644 --- a/src/http.lua +++ b/src/http.lua @@ -22,7 +22,7 @@ local _M = socket.http -- Program constants ----------------------------------------------------------------------------- -- connection timeout in seconds -TIMEOUT = 60 +_M.TIMEOUT = 60 -- default port for document retrieval _M.PORT = 80 -- user agent field sent in request @@ -186,7 +186,7 @@ end local function adjusturi(reqt) local u = reqt -- if there is a proxy, we need the full url. otherwise, just a part. - if not reqt.proxy and not PROXY then + if not reqt.proxy and not _M.PROXY then u = { path = socket.try(reqt.path, "invalid path 'nil'"), params = reqt.params, @@ -198,7 +198,7 @@ local function adjusturi(reqt) end local function adjustproxy(reqt) - local proxy = reqt.proxy or PROXY + local proxy = reqt.proxy or _M.PROXY if proxy then proxy = url.parse(proxy) return proxy.host, proxy.port or 3128 @@ -209,9 +209,10 @@ end local function adjustheaders(reqt) -- default headers + local host = string.gsub(reqt.authority, "^.-@", "") local lower = { ["user-agent"] = _M.USERAGENT, - ["host"] = reqt.host, + ["host"] = host, ["connection"] = "close, TE", ["te"] = "trailers" } @@ -351,4 +352,4 @@ _M.request = socket.protect(function(reqt, body) else return trequest(reqt) end end) -return _M \ No newline at end of file +return _M diff --git a/src/inet.c b/src/inet.c index 1a411f6..48e654b 100644 --- a/src/inet.c +++ b/src/inet.c @@ -183,6 +183,7 @@ static int inet_global_getaddrinfo(lua_State *L) ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen, hbuf, (socklen_t) sizeof(hbuf), NULL, 0, NI_NUMERICHOST); if (ret){ + freeaddrinfo(resolved); lua_pushnil(L); lua_pushstring(L, socket_gaistrerror(ret)); return 2; diff --git a/src/ltn12.lua b/src/ltn12.lua index 5b10f56..1014de2 100644 --- a/src/ltn12.lua +++ b/src/ltn12.lua @@ -139,7 +139,9 @@ function source.rewind(src) end end -function source.chain(src, f) +-- chains a source with one or several filter(s) +function source.chain(src, f, ...) + if ... then f=filter.chain(f, ...) end base.assert(src and f) local last_in, last_out = "", "" local state = "feeding" @@ -254,8 +256,13 @@ function sink.error(err) end end --- chains a sink with a filter -function sink.chain(f, snk) +-- chains a sink with one or several filter(s) +function sink.chain(f, snk, ...) + if ... then + local args = { f, snk, ... } + snk = table.remove(args, #args) + f = filter.chain(unpack(args)) + end base.assert(f and snk) return function(chunk, err) if chunk ~= "" then diff --git a/src/luasocket.c b/src/luasocket.c index e6ee747..c4eeab3 100644 --- a/src/luasocket.c +++ b/src/luasocket.c @@ -18,7 +18,6 @@ #include "lua.h" #include "lauxlib.h" - /*=========================================================================*\ * LuaSocket includes \*=========================================================================*/ @@ -64,7 +63,7 @@ static luaL_Reg func[] = { * Skip a few arguments \*-------------------------------------------------------------------------*/ static int global_skip(lua_State *L) { - int amount = luaL_checkint(L, 1); + int amount = luaL_checkinteger(L, 1); int ret = lua_gettop(L) - amount - 1; return ret >= 0 ? ret : 0; } @@ -78,14 +77,6 @@ static int global_unload(lua_State *L) { return 0; } -#if LUA_VERSION_NUM > 501 -int luaL_typerror (lua_State *L, int narg, const char *tname) { - const char *msg = lua_pushfstring(L, "%s expected, got %s", - tname, luaL_typename(L, narg)); - return luaL_argerror(L, narg, msg); -} -#endif - /*-------------------------------------------------------------------------*\ * Setup basic stuff. \*-------------------------------------------------------------------------*/ diff --git a/src/makefile b/src/makefile index c24e61b..7f118a7 100644 --- a/src/makefile +++ b/src/makefile @@ -20,6 +20,12 @@ PLAT?=linux # lua version to build against LUAV?=5.1 +# MYCFLAGS: to be set by user if needed +MYCFLAGS= + +# MYLDFLAGS: to be set by user if needed +MYLDFLAGS= + # DEBUG: NODEBUG DEBUG # debug mode causes luasocket to collect and returns timing information useful # for testing and debugging luasocket itself @@ -40,7 +46,6 @@ LUAPREFIX_macosx?=/opt/local CDIR_macosx?=lib/lua/$(LUAV) LDIR_macosx?=share/lua/$(LUAV) - # LUAINC_linux: # /usr/include/lua$(LUAV) # /usr/local/include @@ -52,8 +57,17 @@ LUAPREFIX_linux?=/usr/local CDIR_linux?=lib/lua/$(LUAV) LDIR_linux?=share/lua/$(LUAV) +# LUAINC_freebsd: +# /usr/local/include/lua$(LUAV) +# where lua headers are found for linux builds +LUAINC_freebsd_base?=/usr/local/include/ +LUAINC_freebsd?=$(LUAINC_freebsd_base)/lua$(LUAV) +LUAPREFIX_freebsd?=/usr/local/ +CDIR_freebsd?=lib/lua/$(LUAV) +LDIR_freebsd?=share/lua/$(LUAV) + # where lua headers are found for mingw builds -# LUAINC_mingw: +# LUAINC_mingw: # /opt/local/include LUAINC_mingw_base?=/usr/include LUAINC_mingw?=$(LUAINC_mingw_base)/lua/$(LUAV) @@ -133,7 +147,7 @@ DEF_macosx= -DLUASOCKET_$(DEBUG) -DUNIX_HAS_SUN_LEN -DLUA_$(COMPAT)_MODULE \ -DLUASOCKET_API='__attribute__((visibility("default")))' \ -DUNIX_API='__attribute__((visibility("default")))' \ -DMIME_API='__attribute__((visibility("default")))' -CFLAGS_macosx= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \ +CFLAGS_macosx= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \ -fvisibility=hidden LDFLAGS_macosx= -bundle -undefined dynamic_lookup -o LD_macosx= export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc @@ -149,7 +163,7 @@ DEF_linux=-DLUASOCKET_$(DEBUG) -DLUA_$(COMPAT)_MODULE \ -DLUASOCKET_API='__attribute__((visibility("default")))' \ -DUNIX_API='__attribute__((visibility("default")))' \ -DMIME_API='__attribute__((visibility("default")))' -CFLAGS_linux= -I$(LUAINC) $(DEF) -pedantic -Wall -Wshadow -Wextra \ +CFLAGS_linux= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \ -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden LDFLAGS_linux=-O -shared -fpic -o LD_linux=gcc @@ -157,6 +171,22 @@ SOCKET_linux=usocket.o #------ # Compiler and linker settings +# for FreeBSD +SO_freebsd=so +O_freebsd=o +CC_freebsd=gcc +DEF_freebsd=-DLUASOCKET_$(DEBUG) -DLUA_$(COMPAT)_MODULE \ + -DLUASOCKET_API='__attribute__((visibility("default")))' \ + -DUNIX_API='__attribute__((visibility("default")))' \ + -DMIME_API='__attribute__((visibility("default")))' +CFLAGS_freebsd= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \ + -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden +LDFLAGS_freebsd=-O -shared -fpic -o +LD_freebsd=gcc +SOCKET_freebsd=usocket.o + +#------ +# Compiler and linker settings # for MingW SO_mingw=dll O_mingw=o @@ -164,7 +194,7 @@ CC_mingw=gcc DEF_mingw= -DLUASOCKET_INET_PTON -DLUASOCKET_$(DEBUG) -DLUA_$(COMPAT)_MODULE \ -DWINVER=0x0501 -DLUASOCKET_API='__declspec(dllexport)' \ -DMIME_API='__declspec(dllexport)' -CFLAGS_mingw= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \ +CFLAGS_mingw= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \ -fvisibility=hidden LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lws2_32 -o LD_mingw=gcc @@ -195,7 +225,7 @@ SOCKET_win32=wsocket.obj .SUFFIXES: .obj .c.obj: - $(CC) $(CFLAGS) //Fo"$@" //c $< + $(CC) $(LUASOCKET_CFLAGS) //Fo"$@" //c $< #------ # Output file names @@ -215,8 +245,8 @@ SOCKET=$(SOCKET_$(PLAT)) # CC=$(CC_$(PLAT)) DEF=$(DEF_$(PLAT)) -CFLAGS=$(CFLAGS_$(PLAT)) -LDFLAGS=$(LDFLAGS_$(PLAT)) +CFLAGS=$(MYCFLAGS) $(CFLAGS_$(PLAT)) +LDFLAGS=$(MYLDFLAGS) $(LDFLAGS_$(PLAT)) LD=$(LD_$(PLAT)) LUAINC= $(LUAINC_$(PLAT)) LUALIB= $(LUALIB_$(PLAT)) @@ -259,7 +289,7 @@ UNIX_OBJS=\ #------ # Modules belonging to serial (device streams) # -SERIAL_OBJS:=\ +SERIAL_OBJS=\ buffer.$(O) \ auxiliar.$(O) \ options.$(O) \ @@ -289,6 +319,10 @@ TO_TOP_LDIR= \ # default: $(PLAT) + +freebsd: + $(MAKE) all-unix PLAT=freebsd + macosx: $(MAKE) all-unix PLAT=macosx diff --git a/src/mime.c b/src/mime.c index dd37dcf..d121e9e 100644 --- a/src/mime.c +++ b/src/mime.c @@ -41,7 +41,7 @@ static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer); static void qpsetup(UC *class, UC *unbase); static void qpquote(UC c, luaL_Buffer *buffer); static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); -static size_t qpencode(UC c, UC *input, size_t size, +static size_t qpencode(UC c, UC *input, size_t size, const char *marker, luaL_Buffer *buffer); static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer); @@ -103,15 +103,15 @@ MIME_API int luaopen_mime_core(lua_State *L) /*-------------------------------------------------------------------------*\ * Incrementaly breaks a string into lines. The string can have CRLF breaks. * A, n = wrp(l, B, length) -* A is a copy of B, broken into lines of at most 'length' bytes. -* 'l' is how many bytes are left for the first line of B. -* 'n' is the number of bytes left in the last line of A. +* A is a copy of B, broken into lines of at most 'length' bytes. +* 'l' is how many bytes are left for the first line of B. +* 'n' is the number of bytes left in the last line of A. \*-------------------------------------------------------------------------*/ static int mime_global_wrp(lua_State *L) { size_t size = 0; int left = (int) luaL_checknumber(L, 1); - const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); + const UC *input = (const UC *) luaL_optlstring(L, 2, NULL, &size); const UC *last = input + size; int length = (int) luaL_optnumber(L, 3, 76); luaL_Buffer buffer; @@ -123,7 +123,7 @@ static int mime_global_wrp(lua_State *L) else lua_pushnil(L); lua_pushnumber(L, length); return 2; - } + } luaL_buffinit(L, &buffer); while (input < last) { switch (*input) { @@ -150,9 +150,9 @@ static int mime_global_wrp(lua_State *L) } /*-------------------------------------------------------------------------*\ -* Fill base64 decode map. +* Fill base64 decode map. \*-------------------------------------------------------------------------*/ -static void b64setup(UC *unbase) +static void b64setup(UC *unbase) { int i; for (i = 0; i <= 255; i++) unbase[i] = (UC) 255; @@ -161,11 +161,11 @@ static void b64setup(UC *unbase) } /*-------------------------------------------------------------------------*\ -* Acumulates bytes in input buffer until 3 bytes are available. +* Acumulates bytes in input buffer until 3 bytes are available. * Translate the 3 bytes into Base64 form and append to buffer. * Returns new number of bytes in buffer. \*-------------------------------------------------------------------------*/ -static size_t b64encode(UC c, UC *input, size_t size, +static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { input[size++] = c; @@ -174,7 +174,7 @@ static size_t b64encode(UC c, UC *input, size_t size, unsigned long value = 0; value += input[0]; value <<= 8; value += input[1]; value <<= 8; - value += input[2]; + value += input[2]; code[3] = b64base[value & 0x3f]; value >>= 6; code[2] = b64base[value & 0x3f]; value >>= 6; code[1] = b64base[value & 0x3f]; value >>= 6; @@ -186,11 +186,11 @@ static size_t b64encode(UC c, UC *input, size_t size, } /*-------------------------------------------------------------------------*\ -* Encodes the Base64 last 1 or 2 bytes and adds padding '=' +* Encodes the Base64 last 1 or 2 bytes and adds padding '=' * Result, if any, is appended to buffer. * Returns 0. \*-------------------------------------------------------------------------*/ -static size_t b64pad(const UC *input, size_t size, +static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer) { unsigned long value = 0; @@ -203,7 +203,7 @@ static size_t b64pad(const UC *input, size_t size, luaL_addlstring(buffer, (char *) code, 4); break; case 2: - value = input[0]; value <<= 8; + value = input[0]; value <<= 8; value |= input[1]; value <<= 2; code[2] = b64base[value & 0x3f]; value >>= 6; code[1] = b64base[value & 0x3f]; value >>= 6; @@ -217,11 +217,11 @@ static size_t b64pad(const UC *input, size_t size, } /*-------------------------------------------------------------------------*\ -* Acumulates bytes in input buffer until 4 bytes are available. +* Acumulates bytes in input buffer until 4 bytes are available. * Translate the 4 bytes from Base64 form and append to buffer. * Returns new number of bytes in buffer. \*-------------------------------------------------------------------------*/ -static size_t b64decode(UC c, UC *input, size_t size, +static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { /* ignore invalid characters */ @@ -239,7 +239,7 @@ static size_t b64decode(UC c, UC *input, size_t size, decoded[1] = (UC) (value & 0xff); value >>= 8; decoded[0] = (UC) value; /* take care of paddding */ - valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3; + valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3; luaL_addlstring(buffer, (char *) decoded, valid); return 0; /* need more data */ @@ -251,7 +251,7 @@ static size_t b64decode(UC c, UC *input, size_t size, * A, B = b64(C, D) * A is the encoded version of the largest prefix of C .. D that is * divisible by 3. B has the remaining bytes of C .. D, *without* encoding. -* The easiest thing would be to concatenate the two strings and +* The easiest thing would be to concatenate the two strings and * encode the result, but we can't afford that or Lua would dupplicate * every chunk we received. \*-------------------------------------------------------------------------*/ @@ -259,7 +259,7 @@ static int mime_global_b64(lua_State *L) { UC atom[3]; size_t isize = 0, asize = 0; - const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; luaL_Buffer buffer; /* end-of-input blackhole */ @@ -272,9 +272,9 @@ static int mime_global_b64(lua_State *L) lua_settop(L, 2); /* process first part of the input */ luaL_buffinit(L, &buffer); - while (input < last) + while (input < last) asize = b64encode(*input++, atom, asize, &buffer); - input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + input = (const UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second part is nil, we are done */ if (!input) { size_t osize = 0; @@ -288,7 +288,7 @@ static int mime_global_b64(lua_State *L) } /* otherwise process the second part */ last = input + isize; - while (input < last) + while (input < last) asize = b64encode(*input++, atom, asize, &buffer); luaL_pushresult(&buffer); lua_pushlstring(L, (char *) atom, asize); @@ -305,7 +305,7 @@ static int mime_global_unb64(lua_State *L) { UC atom[4]; size_t isize = 0, asize = 0; - const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; luaL_Buffer buffer; /* end-of-input blackhole */ @@ -318,9 +318,9 @@ static int mime_global_unb64(lua_State *L) lua_settop(L, 2); /* process first part of the input */ luaL_buffinit(L, &buffer); - while (input < last) + while (input < last) asize = b64decode(*input++, atom, asize, &buffer); - input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + input = (const UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second is nil, we are done */ if (!input) { size_t osize = 0; @@ -333,7 +333,7 @@ static int mime_global_unb64(lua_State *L) } /* otherwise, process the rest of the input */ last = input + isize; - while (input < last) + while (input < last) asize = b64decode(*input++, atom, asize, &buffer); luaL_pushresult(&buffer); lua_pushlstring(L, (char *) atom, asize); @@ -349,7 +349,7 @@ static int mime_global_unb64(lua_State *L) * 9 and 32 can be plain, unless in the end of a line, where must be =XX * encoded lines must be no longer than 76 not counting CRLF * soft line-break are =CRLF -* To encode one byte, we need to see the next two. +* To encode one byte, we need to see the next two. * Worst case is when we see a space, and wonder if a CRLF is comming \*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*\ @@ -362,7 +362,7 @@ static void qpsetup(UC *cl, UC *unbase) for (i = 0; i < 256; i++) cl[i] = QP_QUOTED; for (i = 33; i <= 60; i++) cl[i] = QP_PLAIN; for (i = 62; i <= 126; i++) cl[i] = QP_PLAIN; - cl['\t'] = QP_IF_LAST; + cl['\t'] = QP_IF_LAST; cl[' '] = QP_IF_LAST; cl['\r'] = QP_CR; for (i = 0; i < 256; i++) unbase[i] = 255; @@ -388,9 +388,9 @@ static void qpquote(UC c, luaL_Buffer *buffer) /*-------------------------------------------------------------------------*\ * Accumulate characters until we are sure about how to deal with them. -* Once we are sure, output to the buffer, in the correct form. +* Once we are sure, output to the buffer, in the correct form. \*-------------------------------------------------------------------------*/ -static size_t qpencode(UC c, UC *input, size_t size, +static size_t qpencode(UC c, UC *input, size_t size, const char *marker, luaL_Buffer *buffer) { input[size++] = c; @@ -431,7 +431,7 @@ static size_t qpencode(UC c, UC *input, size_t size, } /*-------------------------------------------------------------------------*\ -* Deal with the final characters +* Deal with the final characters \*-------------------------------------------------------------------------*/ static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) { @@ -448,8 +448,8 @@ static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) * Incrementally converts a string to quoted-printable * A, B = qp(C, D, marker) * Marker is the text to be used to replace CRLF sequences found in A. -* A is the encoded version of the largest prefix of C .. D that -* can be encoded without doubts. +* A is the encoded version of the largest prefix of C .. D that +* can be encoded without doubts. * B has the remaining bytes of C .. D, *without* encoding. \*-------------------------------------------------------------------------*/ static int mime_global_qp(lua_State *L) @@ -457,7 +457,7 @@ static int mime_global_qp(lua_State *L) size_t asize = 0, isize = 0; UC atom[3]; - const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; const char *marker = luaL_optstring(L, 3, CRLF); luaL_Buffer buffer; @@ -473,7 +473,7 @@ static int mime_global_qp(lua_State *L) luaL_buffinit(L, &buffer); while (input < last) asize = qpencode(*input++, atom, asize, marker, &buffer); - input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + input = (const UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second part is nil, we are done */ if (!input) { asize = qppad(atom, asize, &buffer); @@ -493,7 +493,7 @@ static int mime_global_qp(lua_State *L) /*-------------------------------------------------------------------------*\ * Accumulate characters until we are sure about how to deal with them. -* Once we are sure, output the to the buffer, in the correct form. +* Once we are sure, output the to the buffer, in the correct form. \*-------------------------------------------------------------------------*/ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { int d; @@ -501,8 +501,8 @@ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { /* deal with all characters we can deal */ switch (input[0]) { /* if we have an escape character */ - case '=': - if (size < 3) return size; + case '=': + if (size < 3) return size; /* eliminate soft line break */ if (input[1] == '\r' && input[2] == '\n') return 0; /* decode quoted representation */ @@ -512,7 +512,7 @@ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { else luaL_addchar(buffer, (char) ((c << 4) + d)); return 0; case '\r': - if (size < 2) return size; + if (size < 2) return size; if (input[1] == '\n') luaL_addlstring(buffer, (char *)input, 2); return 0; default: @@ -525,15 +525,15 @@ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { /*-------------------------------------------------------------------------*\ * Incrementally decodes a string in quoted-printable * A, B = qp(C, D) -* A is the decoded version of the largest prefix of C .. D that -* can be decoded without doubts. +* A is the decoded version of the largest prefix of C .. D that +* can be decoded without doubts. * B has the remaining bytes of C .. D, *without* decoding. \*-------------------------------------------------------------------------*/ static int mime_global_unqp(lua_State *L) { size_t asize = 0, isize = 0; UC atom[3]; - const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; luaL_Buffer buffer; /* end-of-input blackhole */ @@ -548,14 +548,14 @@ static int mime_global_unqp(lua_State *L) luaL_buffinit(L, &buffer); while (input < last) asize = qpdecode(*input++, atom, asize, &buffer); - input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + input = (const UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second part is nil, we are done */ if (!input) { luaL_pushresult(&buffer); if (!(*lua_tostring(L, -1))) lua_pushnil(L); lua_pushnil(L); return 2; - } + } /* otherwise process rest of input */ last = input + isize; while (input < last) @@ -568,9 +568,9 @@ static int mime_global_unqp(lua_State *L) /*-------------------------------------------------------------------------*\ * Incrementally breaks a quoted-printed string into lines * A, n = qpwrp(l, B, length) -* A is a copy of B, broken into lines of at most 'length' bytes. -* 'l' is how many bytes are left for the first line of B. -* 'n' is the number of bytes left in the last line of A. +* A is a copy of B, broken into lines of at most 'length' bytes. +* 'l' is how many bytes are left for the first line of B. +* 'n' is the number of bytes left in the last line of A. * There are two complications: lines can't be broken in the middle * of an encoded =XX, and there might be line breaks already \*-------------------------------------------------------------------------*/ @@ -578,7 +578,7 @@ static int mime_global_qpwrp(lua_State *L) { size_t size = 0; int left = (int) luaL_checknumber(L, 1); - const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); + const UC *input = (const UC *) luaL_optlstring(L, 2, NULL, &size); const UC *last = input + size; int length = (int) luaL_optnumber(L, 3, 76); luaL_Buffer buffer; @@ -603,11 +603,11 @@ static int mime_global_qpwrp(lua_State *L) if (left <= 3) { left = length; luaL_addstring(&buffer, EQCRLF); - } + } luaL_addchar(&buffer, *input); left--; break; - default: + default: if (left <= 1) { left = length; luaL_addstring(&buffer, EQCRLF); @@ -635,7 +635,7 @@ static int mime_global_qpwrp(lua_State *L) * last is the previous character \*-------------------------------------------------------------------------*/ #define eolcandidate(c) (c == '\r' || c == '\n') -static int eolprocess(int c, int last, const char *marker, +static int eolprocess(int c, int last, const char *marker, luaL_Buffer *buffer) { if (eolcandidate(c)) { @@ -653,15 +653,15 @@ static int eolprocess(int c, int last, const char *marker, } /*-------------------------------------------------------------------------*\ -* Converts a string to uniform EOL convention. +* Converts a string to uniform EOL convention. * A, n = eol(o, B, marker) * A is the converted version of the largest prefix of B that can be -* converted unambiguously. 'o' is the context returned by the previous +* converted unambiguously. 'o' is the context returned by the previous * call. 'n' is the new context. \*-------------------------------------------------------------------------*/ static int mime_global_eol(lua_State *L) { - int ctx = luaL_checkint(L, 1); + int ctx = luaL_checkinteger(L, 1); size_t isize = 0; const char *input = luaL_optlstring(L, 2, NULL, &isize); const char *last = input + isize; @@ -683,18 +683,18 @@ static int mime_global_eol(lua_State *L) } /*-------------------------------------------------------------------------*\ -* Takes one byte and stuff it if needed. +* Takes one byte and stuff it if needed. \*-------------------------------------------------------------------------*/ static size_t dot(int c, size_t state, luaL_Buffer *buffer) { luaL_addchar(buffer, (char) c); switch (c) { - case '\r': + case '\r': return 1; - case '\n': - return (state == 1)? 2: 0; - case '.': - if (state == 2) + case '\n': + return (state == 1)? 2: 0; + case '.': + if (state == 2) luaL_addchar(buffer, '.'); default: return 0; @@ -719,7 +719,7 @@ static int mime_global_dot(lua_State *L) } /* process all input */ luaL_buffinit(L, &buffer); - while (input < last) + while (input < last) state = dot(*input++, state, &buffer); luaL_pushresult(&buffer); lua_pushnumber(L, (lua_Number) state); diff --git a/src/options.h b/src/options.h index 5657a06..b75db37 100644 --- a/src/options.h +++ b/src/options.h @@ -51,7 +51,8 @@ int opt_get_error(lua_State *L, p_socket ps); int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps); int opt_get_ip6_multicast_hops(lua_State *L, p_socket ps); int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps); -int opt_get_ip6_v6only(lua_State *L, p_socket ps); +int opt_get_ip6_v6only(lua_State *L, p_socket ps); +int opt_get_reuseport(lua_State *L, p_socket ps); /* invokes the appropriate option handler */ int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps); diff --git a/src/pierror.h b/src/pierror.h new file mode 100644 index 0000000..cb773ab --- /dev/null +++ b/src/pierror.h @@ -0,0 +1,28 @@ +#ifndef PIERROR_H +#define PIERROR_H +/*=========================================================================*\ +* Error messages +* Defines platform independent error messages +\*=========================================================================*/ + +#define PIE_HOST_NOT_FOUND "host not found" +#define PIE_ADDRINUSE "address already in use" +#define PIE_ISCONN "already connected" +#define PIE_ACCESS "permission denied" +#define PIE_CONNREFUSED "connection refused" +#define PIE_CONNABORTED "closed" +#define PIE_CONNRESET "closed" +#define PIE_TIMEDOUT "timeout" +#define PIE_AGAIN "temporary failure in name resolution" +#define PIE_BADFLAGS "invalid value for ai_flags" +#define PIE_BADHINTS "invalid value for hints" +#define PIE_FAIL "non-recoverable failure in name resolution" +#define PIE_FAMILY "ai_family not supported" +#define PIE_MEMORY "memory allocation failure" +#define PIE_NONAME "host or service not provided, or not known" +#define PIE_OVERFLOW "argument buffer overflow" +#define PIE_PROTOCOL "resolved protocol is unknown" +#define PIE_SERVICE "service not supported for socket type" +#define PIE_SOCKTYPE "ai_socktype not supported" + +#endif diff --git a/src/udp.c b/src/udp.c index a9f2393..12e320a 100644 --- a/src/udp.c +++ b/src/udp.c @@ -131,7 +131,7 @@ int udp_open(lua_State *L) /*=========================================================================*\ * Lua methods \*=========================================================================*/ -const char *udp_strerror(int err) { +static const char *udp_strerror(int err) { /* a 'closed' error on an unconnected means the target address was not * accepted by the transport layer */ if (err == IO_CLOSED) return "refused"; diff --git a/src/usocket.c b/src/usocket.c index 096ecd0..99e551b 100644 --- a/src/usocket.c +++ b/src/usocket.c @@ -4,12 +4,13 @@ * * The code is now interrupt-safe. * The penalty of calling select to avoid busy-wait is only paid when -* the I/O call fail in the first place. +* the I/O call fail in the first place. \*=========================================================================*/ -#include +#include #include #include "socket.h" +#include "pierror.h" /*-------------------------------------------------------------------------*\ * Wait for readable/writable/connected socket with timeout @@ -72,7 +73,7 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) { /*-------------------------------------------------------------------------*\ -* Initializes module +* Initializes module \*-------------------------------------------------------------------------*/ int socket_open(void) { /* instals a handler to ignore sigpipe or it will crash us */ @@ -81,7 +82,7 @@ int socket_open(void) { } /*-------------------------------------------------------------------------*\ -* Close module +* Close module \*-------------------------------------------------------------------------*/ int socket_close(void) { return 1; @@ -92,7 +93,6 @@ int socket_close(void) { \*-------------------------------------------------------------------------*/ void socket_destroy(p_socket ps) { if (*ps != SOCKET_INVALID) { - socket_setblocking(ps); close(*ps); *ps = SOCKET_INVALID; } @@ -101,7 +101,7 @@ void socket_destroy(p_socket ps) { /*-------------------------------------------------------------------------*\ * Select with timeout control \*-------------------------------------------------------------------------*/ -int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_timeout tm) { int ret; do { @@ -120,8 +120,8 @@ int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, \*-------------------------------------------------------------------------*/ int socket_create(p_socket ps, int domain, int type, int protocol) { *ps = socket(domain, type, protocol); - if (*ps != SOCKET_INVALID) return IO_DONE; - else return errno; + if (*ps != SOCKET_INVALID) return IO_DONE; + else return errno; } /*-------------------------------------------------------------------------*\ @@ -130,29 +130,25 @@ int socket_create(p_socket ps, int domain, int type, int protocol) { int socket_bind(p_socket ps, SA *addr, socklen_t len) { int err = IO_DONE; socket_setblocking(ps); - if (bind(*ps, addr, len) < 0) err = errno; + if (bind(*ps, addr, len) < 0) err = errno; socket_setnonblocking(ps); return err; } /*-------------------------------------------------------------------------*\ -* +* \*-------------------------------------------------------------------------*/ int socket_listen(p_socket ps, int backlog) { - int err = IO_DONE; - socket_setblocking(ps); - if (listen(*ps, backlog)) err = errno; - socket_setnonblocking(ps); + int err = IO_DONE; + if (listen(*ps, backlog)) err = errno; return err; } /*-------------------------------------------------------------------------*\ -* +* \*-------------------------------------------------------------------------*/ void socket_shutdown(p_socket ps, int how) { - socket_setblocking(ps); shutdown(*ps, how); - socket_setnonblocking(ps); } /*-------------------------------------------------------------------------*\ @@ -166,7 +162,7 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { do if (connect(*ps, addr, len) == 0) return IO_DONE; while ((err = errno) == EINTR); /* if connection failed immediately, return error code */ - if (err != EINPROGRESS && err != EAGAIN) return err; + if (err != EINPROGRESS && err != EAGAIN) return err; /* zero timeout case optimization */ if (timeout_iszero(tm)) return IO_TIMEOUT; /* wait until we have the result of the connection attempt or timeout */ @@ -181,7 +177,7 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { * Accept with timeout \*-------------------------------------------------------------------------*/ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) { - if (*ps == SOCKET_INVALID) return IO_CLOSED; + if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { int err; if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; @@ -197,7 +193,7 @@ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout /*-------------------------------------------------------------------------*\ * Send with timeout \*-------------------------------------------------------------------------*/ -int socket_send(p_socket ps, const char *data, size_t count, +int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm) { int err; @@ -229,14 +225,14 @@ int socket_send(p_socket ps, const char *data, size_t count, /*-------------------------------------------------------------------------*\ * Sendto with timeout \*-------------------------------------------------------------------------*/ -int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, +int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, SA *addr, socklen_t len, p_timeout tm) { int err; *sent = 0; if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { - long put = (long) sendto(*ps, data, count, 0, addr, len); + long put = (long) sendto(*ps, data, count, 0, addr, len); if (put >= 0) { *sent = put; return IO_DONE; @@ -266,8 +262,8 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm err = errno; if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; - if (err != EAGAIN) return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -275,7 +271,7 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm /*-------------------------------------------------------------------------*\ * Recvfrom with timeout \*-------------------------------------------------------------------------*/ -int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, +int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, SA *addr, socklen_t *len, p_timeout tm) { int err; *got = 0; @@ -289,8 +285,8 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, err = errno; if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; - if (err != EAGAIN) return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -303,7 +299,7 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, * with send/recv replaced with write/read. We can't just use write/read * in the socket version, because behaviour when size is zero is different. \*-------------------------------------------------------------------------*/ -int socket_write(p_socket ps, const char *data, size_t count, +int socket_write(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm) { int err; @@ -349,8 +345,8 @@ int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm err = errno; if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; - if (err != EAGAIN) return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -374,7 +370,7 @@ void socket_setnonblocking(p_socket ps) { } /*-------------------------------------------------------------------------*\ -* DNS helpers +* DNS helpers \*-------------------------------------------------------------------------*/ int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { *hp = gethostbyaddr(addr, len, AF_INET); @@ -399,7 +395,7 @@ int socket_gethostbyname(const char *addr, struct hostent **hp) { const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case HOST_NOT_FOUND: return "host not found"; + case HOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; default: return hstrerror(err); } } @@ -407,13 +403,13 @@ const char *socket_hoststrerror(int err) { const char *socket_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case EADDRINUSE: return "address already in use"; - case EISCONN: return "already connected"; - case EACCES: return "permission denied"; - case ECONNREFUSED: return "connection refused"; - case ECONNABORTED: return "closed"; - case ECONNRESET: return "closed"; - case ETIMEDOUT: return "timeout"; + case EADDRINUSE: return PIE_ADDRINUSE; + case EISCONN: return PIE_ISCONN; + case EACCES: return PIE_ACCESS; + case ECONNREFUSED: return PIE_CONNREFUSED; + case ECONNABORTED: return PIE_CONNABORTED; + case ECONNRESET: return PIE_CONNRESET; + case ETIMEDOUT: return PIE_TIMEDOUT; default: return strerror(err); } } @@ -421,28 +417,27 @@ const char *socket_strerror(int err) { const char *socket_ioerror(p_socket ps, int err) { (void) ps; return socket_strerror(err); -} +} const char *socket_gaistrerror(int err) { - if (err == 0) return NULL; + if (err == 0) return NULL; switch (err) { - case EAI_AGAIN: return "temporary failure in name resolution"; - case EAI_BADFLAGS: return "invalid value for ai_flags"; + case EAI_AGAIN: return PIE_AGAIN; + case EAI_BADFLAGS: return PIE_BADFLAGS; #ifdef EAI_BADHINTS - case EAI_BADHINTS: return "invalid value for hints"; + case EAI_BADHINTS: return PIE_BADHINTS; #endif - case EAI_FAIL: return "non-recoverable failure in name resolution"; - case EAI_FAMILY: return "ai_family not supported"; - case EAI_MEMORY: return "memory allocation failure"; - case EAI_NONAME: - return "host or service not provided, or not known"; - case EAI_OVERFLOW: return "argument buffer overflow"; + case EAI_FAIL: return PIE_FAIL; + case EAI_FAMILY: return PIE_FAMILY; + case EAI_MEMORY: return PIE_MEMORY; + case EAI_NONAME: return PIE_NONAME; + case EAI_OVERFLOW: return PIE_OVERFLOW; #ifdef EAI_PROTOCOL - case EAI_PROTOCOL: return "resolved protocol is unknown"; + case EAI_PROTOCOL: return PIE_PROTOCOL; #endif - case EAI_SERVICE: return "service not supported for socket type"; - case EAI_SOCKTYPE: return "ai_socktype not supported"; - case EAI_SYSTEM: return strerror(errno); + case EAI_SERVICE: return PIE_SERVICE; + case EAI_SOCKTYPE: return PIE_SOCKTYPE; + case EAI_SYSTEM: return strerror(errno); default: return gai_strerror(err); } } diff --git a/src/wsocket.c b/src/wsocket.c index b4a4384..10800e3 100644 --- a/src/wsocket.c +++ b/src/wsocket.c @@ -8,6 +8,7 @@ #include #include "socket.h" +#include "pierror.h" /* WinSock doesn't have a strerror... */ static const char *wstrerror(int err); @@ -330,7 +331,7 @@ int socket_gethostbyname(const char *addr, struct hostent **hp) { const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case WSAHOST_NOT_FOUND: return "host not found"; + case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; default: return wstrerror(err); } } @@ -338,13 +339,13 @@ const char *socket_hoststrerror(int err) { const char *socket_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case WSAEADDRINUSE: return "address already in use"; - case WSAECONNREFUSED: return "connection refused"; - case WSAEISCONN: return "already connected"; - case WSAEACCES: return "permission denied"; - case WSAECONNABORTED: return "closed"; - case WSAECONNRESET: return "closed"; - case WSAETIMEDOUT: return "timeout"; + case WSAEADDRINUSE: return PIE_ADDRINUSE; + case WSAECONNREFUSED : return PIE_CONNREFUSED; + case WSAEISCONN: return PIE_ISCONN; + case WSAEACCES: return PIE_ACCESS; + case WSAECONNABORTED: return PIE_CONNABORTED; + case WSAECONNRESET: return PIE_CONNRESET; + case WSAETIMEDOUT: return PIE_TIMEDOUT; default: return wstrerror(err); } } @@ -357,7 +358,7 @@ const char *socket_ioerror(p_socket ps, int err) { static const char *wstrerror(int err) { switch (err) { case WSAEINTR: return "Interrupted function call"; - case WSAEACCES: return "Permission denied"; + case WSAEACCES: return PIE_ACCESS; // "Permission denied"; case WSAEFAULT: return "Bad address"; case WSAEINVAL: return "Invalid argument"; case WSAEMFILE: return "Too many open files"; @@ -370,24 +371,23 @@ static const char *wstrerror(int err) { case WSAEPROTOTYPE: return "Protocol wrong type for socket"; case WSAENOPROTOOPT: return "Bad protocol option"; case WSAEPROTONOSUPPORT: return "Protocol not supported"; - case WSAESOCKTNOSUPPORT: return "Socket type not supported"; + case WSAESOCKTNOSUPPORT: return PIE_SOCKTYPE; // "Socket type not supported"; case WSAEOPNOTSUPP: return "Operation not supported"; case WSAEPFNOSUPPORT: return "Protocol family not supported"; - case WSAEAFNOSUPPORT: - return "Address family not supported by protocol family"; - case WSAEADDRINUSE: return "Address already in use"; + case WSAEAFNOSUPPORT: return PIE_FAMILY; // "Address family not supported by protocol family"; + case WSAEADDRINUSE: return PIE_ADDRINUSE; // "Address already in use"; case WSAEADDRNOTAVAIL: return "Cannot assign requested address"; case WSAENETDOWN: return "Network is down"; case WSAENETUNREACH: return "Network is unreachable"; case WSAENETRESET: return "Network dropped connection on reset"; case WSAECONNABORTED: return "Software caused connection abort"; - case WSAECONNRESET: return "Connection reset by peer"; + case WSAECONNRESET: return PIE_CONNRESET; // "Connection reset by peer"; case WSAENOBUFS: return "No buffer space available"; - case WSAEISCONN: return "Socket is already connected"; + case WSAEISCONN: return PIE_ISCONN; // "Socket is already connected"; case WSAENOTCONN: return "Socket is not connected"; case WSAESHUTDOWN: return "Cannot send after socket shutdown"; - case WSAETIMEDOUT: return "Connection timed out"; - case WSAECONNREFUSED: return "Connection refused"; + case WSAETIMEDOUT: return PIE_TIMEDOUT; // "Connection timed out"; + case WSAECONNREFUSED: return PIE_CONNREFUSED; // "Connection refused"; case WSAEHOSTDOWN: return "Host is down"; case WSAEHOSTUNREACH: return "No route to host"; case WSAEPROCLIM: return "Too many processes"; @@ -396,9 +396,9 @@ static const char *wstrerror(int err) { case WSANOTINITIALISED: return "Successful WSAStartup not yet performed"; case WSAEDISCON: return "Graceful shutdown in progress"; - case WSAHOST_NOT_FOUND: return "Host not found"; + case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; // "Host not found"; case WSATRY_AGAIN: return "Nonauthoritative host not found"; - case WSANO_RECOVERY: return "Nonrecoverable name lookup error"; + case WSANO_RECOVERY: return PIE_FAIL; // "Nonrecoverable name lookup error"; case WSANO_DATA: return "Valid name, no data record of requested type"; default: return "Unknown error"; } @@ -407,24 +407,23 @@ static const char *wstrerror(int err) { const char *socket_gaistrerror(int err) { if (err == 0) return NULL; switch (err) { - case EAI_AGAIN: return "temporary failure in name resolution"; - case EAI_BADFLAGS: return "invalid value for ai_flags"; + case EAI_AGAIN: return PIE_AGAIN; + case EAI_BADFLAGS: return PIE_BADFLAGS; #ifdef EAI_BADHINTS - case EAI_BADHINTS: return "invalid value for hints"; + case EAI_BADHINTS: return PIE_BADHINTS; #endif - case EAI_FAIL: return "non-recoverable failure in name resolution"; - case EAI_FAMILY: return "ai_family not supported"; - case EAI_MEMORY: return "memory allocation failure"; - case EAI_NONAME: - return "host or service not provided, or not known"; + case EAI_FAIL: return PIE_FAIL; + case EAI_FAMILY: return PIE_FAMILY; + case EAI_MEMORY: return PIE_MEMORY; + case EAI_NONAME: return PIE_NONAME; #ifdef EAI_OVERFLOW - case EAI_OVERFLOW: return "argument buffer overflow"; + case EAI_OVERFLOW: return PIE_OVERFLOW; #endif #ifdef EAI_PROTOCOL - case EAI_PROTOCOL: return "resolved protocol is unknown"; + case EAI_PROTOCOL: return PIE_PROTOCOL; #endif - case EAI_SERVICE: return "service not supported for socket type"; - case EAI_SOCKTYPE: return "ai_socktype not supported"; + case EAI_SERVICE: return PIE_SERVICE; + case EAI_SOCKTYPE: return PIE_SOCKTYPE; #ifdef EAI_SYSTEM case EAI_SYSTEM: return strerror(errno); #endif diff --git a/test/auth/.htaccess b/test/auth/.htaccess new file mode 100644 index 0000000..bb2794a --- /dev/null +++ b/test/auth/.htaccess @@ -0,0 +1,4 @@ +AuthName "test-auth" + AuthType Basic + AuthUserFile /Users/diego/impa/luasocket/test/auth/.htpasswd + Require valid-user diff --git a/test/auth/.htpasswd b/test/auth/.htpasswd index fd9002b..cfb2603 100644 --- a/test/auth/.htpasswd +++ b/test/auth/.htpasswd @@ -1 +1 @@ -luasocket:l8n2npozPB.sQ +luasocket:$apr1$47u2O.Me$.m/5BWAtt7GVoxsouIPBR1 diff --git a/test/httptest.lua b/test/httptest.lua index d5fbb37..63ff921 100644 --- a/test/httptest.lua +++ b/test/httptest.lua @@ -1,4 +1,4 @@ --- needs Alias from /home/c/diego/tec/luasocket/test to +-- needs Alias from /home/c/diego/tec/luasocket/test to -- "/luasocket-test" and "/luasocket-test/" -- needs ScriptAlias from /home/c/diego/tec/luasocket/test/cgi -- to "/luasocket-test-cgi" and "/luasocket-test-cgi/" @@ -36,22 +36,22 @@ index = readfile(index_file) local check_result = function(response, expect, ignore) for i,v in pairs(response) do if not ignore[i] then - if v ~= expect[i] then + if v ~= expect[i] then local f = io.open("err", "w") f:write(tostring(v), "\n\n versus\n\n", tostring(expect[i])) f:close() - fail(i .. " differs!") + fail(i .. " differs!") end end end for i,v in pairs(expect) do if not ignore[i] then - if v ~= response[i] then + if v ~= response[i] then local f = io.open("err", "w") f:write(tostring(response[i]), "\n\n versus\n\n", tostring(v)) v = string.sub(type(v) == "string" and v or "", 1, 70) f:close() - fail(i .. " differs!") + fail(i .. " differs!") end end end @@ -61,10 +61,10 @@ end local check_request = function(request, expect, ignore) local t if not request.sink then request.sink, t = ltn12.sink.table() end - request.source = request.source or + request.source = request.source or (request.body and ltn12.source.string(request.body)) local response = {} - response.code, response.headers, response.status = + response.code, response.headers, response.status = socket.skip(1, http.request(request)) if t and #t > 0 then response.body = table.concat(t) end check_result(response, expect, ignore) @@ -82,7 +82,7 @@ else fail(back.query) end ------------------------------------------------------------------------ io.write("testing query string correctness: ") forth = "this+is+the+query+string" -back = http.request("http://" .. host .. cgiprefix .. +back = http.request("http://" .. host .. cgiprefix .. "/query-string?" .. forth) if similar(back, forth) then print("ok") else fail("failed!") end @@ -120,10 +120,10 @@ check_request(request, expect, ignore) ------------------------------------------------------------------------ io.write("testing invalid url: ") local r, e = http.request{url = host .. prefix} -assert(r == nil and e == "invalid host ''") +assert(r == nil and e == "invalid host ''") r, re = http.request(host .. prefix) -assert(r == nil and e == re, tostring(r) ..", " .. tostring(re) .. - " vs " .. tostring(e)) +assert(r == nil and e == re, tostring(r) ..", " .. tostring(re) .. + " vs " .. tostring(e)) print("ok") io.write("testing invalid empty port: ") @@ -212,7 +212,7 @@ os.remove(index_file .. "-back") io.write("testing ltn12.(sink|source).chain and mime.(encode|decode): ") local function b64length(len) - local a = math.ceil(len/3)*4 + local a = math.ceil(len/3)*4 local l = math.ceil(a/76) return a + l*2 end @@ -313,7 +313,7 @@ ignore = { headers = 1 } check_request(request, expect, ignore) - + ------------------------------------------------------------------------ io.write("testing document not found: ") request = { @@ -429,9 +429,9 @@ print("ok") io.write("testing host not found: ") local c, e = socket.connect("example.invalid", 80) local r, re = http.request{url = "http://example.invalid/does/not/exist"} -assert(r == nil and e == re, tostring(r) .. " " .. tostring(re)) +assert(r == nil and e == re, tostring(r) .. " " .. tostring(re)) r, re = http.request("http://example.invalid/does/not/exist") -assert(r == nil and e == re) +assert(r == nil and e == re) print("ok") ------------------------------------------------------------------------ diff --git a/test/ltn12test.lua b/test/ltn12test.lua index 74a45e8..e3f85fb 100644 --- a/test/ltn12test.lua +++ b/test/ltn12test.lua @@ -192,6 +192,21 @@ assert(filter(nil, 1), "filter not empty") print("ok") -------------------------------- +io.write("testing source.chain (with several filters): ") +local function double(x) -- filter turning "ABC" into "AABBCC" + if not x then return end + local b={} + for k in x:gmatch'.' do table.insert(b, k..k) end + return table.concat(b) +end +source = ltn12.source.string(s) +source = ltn12.source.chain(source, double, double, double) +sink, t = ltn12.sink.table() +assert(ltn12.pump.all(source, sink), "returned error") +assert(table.concat(t) == double(double(double(s))), "mismatch") +print("ok") + +-------------------------------- io.write("testing source.chain (with split) and sink.chain (with merge): ") source = ltn12.source.string(s) filter = split(5) @@ -206,6 +221,15 @@ assert(filter2(nil, 1), "filter2 not empty") print("ok") -------------------------------- +io.write("testing sink.chain (with several filters): ") +source = ltn12.source.string(s) +sink, t = ltn12.sink.table() +sink = ltn12.sink.chain(double, double, double, sink) +assert(ltn12.pump.all(source, sink), "returned error") +assert(table.concat(t) == double(double(double(s))), "mismatch") +print("ok") + +-------------------------------- io.write("testing filter.chain (and sink.chain, with split, merge): ") source = ltn12.source.string(s) filter = split(5) @@ -272,3 +296,4 @@ assert(filter3(nil, 1), "filter3 not empty") assert(filter4(nil, 1), "filter4 not empty") assert(filter5(nil, 1), "filter5 not empty") print("ok") +