2.0 alpha RELEASED!

This commit is contained in:
Diego Nehab 2004-06-18 21:41:44 +00:00
parent ac4aac0909
commit 7ed89c97f7
14 changed files with 480 additions and 244 deletions

View file

@ -12,33 +12,21 @@
/*=========================================================================*\
* Internal function prototypes.
\*=========================================================================*/
static int global_try(lua_State *L);
static int global_protect(lua_State *L);
static int global_newtry(lua_State *L);
static int protected(lua_State *L);
static int finalize(lua_State *L);
static int do_nothing(lua_State *L);
/* except functions */
static luaL_reg func[] = {
{"try", global_try},
{"newtry", global_newtry},
{"protect", global_protect},
{NULL, NULL}
};
/*-------------------------------------------------------------------------*\
* Try method
\*-------------------------------------------------------------------------*/
static int global_try(lua_State *L) {
if (lua_isnil(L, 1) || (lua_isboolean(L, 1) && !lua_toboolean(L, 1))) {
lua_settop(L, 2);
lua_error(L);
return 0;
} else return lua_gettop(L);
}
/*-------------------------------------------------------------------------*\
* Finalizer factory
* Try factory
\*-------------------------------------------------------------------------*/
static int finalize(lua_State *L) {
if (lua_isnil(L, 1) || (lua_isboolean(L, 1) && !lua_toboolean(L, 1))) {
@ -50,7 +38,14 @@ static int finalize(lua_State *L) {
} else return lua_gettop(L);
}
static int do_nothing(lua_State *L) {
(void) L;
return 0;
}
static int global_newtry(lua_State *L) {
lua_settop(L, 1);
if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing);
lua_pushcclosure(L, finalize, 1);
return 1;
}

View file

@ -32,14 +32,10 @@ local metat = { __index = {} }
function open(server, port)
local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT))
local f = { tp = tp }
local f = setmetat({ tp = tp }, metat)
-- make sure everything gets closed in an exception
f.try = socket.newtry(function()
tp:close()
if f.data then f.data:close() end
if f.server then f.server:close() end
end)
return setmetatable(f, metat)
f.try = socket.newtry(function() f:close() end)
return f
end
function metat.__index:portconnect()
@ -173,13 +169,9 @@ function metat.__index:quit()
end
function metat.__index:close()
self.tp:close()
if self.data then self.data:close() end
if self.server then self.server:close() end
self.tp = nil
self.data = nil
self.server = nil
return 1
return self.tp:close()
end
-----------------------------------------------------------------------------

View file

@ -32,11 +32,12 @@ local metat = { __index = {} }
function open(host, port)
local c = socket.try(socket.tcp())
local h = setmetatable({ c = c }, metat)
-- make sure the connection gets closed on exception
local try = socket.newtry(function() c:close() end)
try(c:settimeout(TIMEOUT))
try(c:connect(host, port or PORT))
return setmetatable({ c = c, try = try }, metat)
h.try = socket.newtry(function() h:close() end)
h.try(c:settimeout(TIMEOUT))
h.try(c:connect(host, port or PORT))
return h
end
function metat.__index:sendrequestline(method, uri)
@ -57,9 +58,8 @@ function metat.__index:sendbody(headers, source, step)
source = source or ltn12.source.empty()
step = step or ltn12.pump.step
-- if we don't know the size in advance, send chunked and hope for the best
local mode
if headers["content-length"] then mode = "keep-open"
else mode = "http-chunked" end
local mode = "http-chunked"
if headers["content-length"] then mode = "keep-open" end
return self.try(ltn12.pump.all(source, socket.sink(mode, self.c), step))
end
@ -99,10 +99,9 @@ function metat.__index:receivebody(headers, sink, step)
step = step or ltn12.pump.step
local length = tonumber(headers["content-length"])
local TE = headers["transfer-encoding"]
local mode
local mode = "default" -- connection close
if TE and TE ~= "identity" then mode = "http-chunked"
elseif tonumber(headers["content-length"]) then mode = "by-length"
else mode = "default" end
elseif tonumber(headers["content-length"]) then mode = "by-length" end
return self.try(ltn12.pump.all(socket.source(mode, self.c, length),
sink, step))
end
@ -191,9 +190,9 @@ function tauthorize(reqt)
end
function tredirect(reqt, headers)
-- the RFC says the redirect URL has to be absolute, but some
-- servers do not respect that
return trequest {
-- the RFC says the redirect URL has to be absolute, but some
-- servers do not respect that
url = url.absolute(reqt, headers["location"]),
source = reqt.source,
sink = reqt.sink,

View file

@ -60,7 +60,7 @@ function metat.__index:quit()
end
function metat.__index:close()
return self.try(self.tp:close())
return self.tp:close()
end
function metat.__index:login(user, password)
@ -104,9 +104,10 @@ end
function open(server, port)
local tp = socket.try(tp.connect(server or SERVER, port or PORT, TIMEOUT))
local s = setmetatable({tp = tp}, metat)
-- make sure tp is closed if we get an exception
local try = socket.newtry(function() tp:close() end)
return setmetatable({ tp = tp, try = try}, metat)
local try = socket.newtry(function() s:close() end)
return s
end
---------------------------------------------------------------------------

View file

@ -37,6 +37,8 @@ function socket.bind(host, port, backlog)
return sock
end
socket.try = socket.newtry()
function socket.choose(table)
return function(name, opt1, opt2)
if type(name) ~= "string" then

View file

@ -20,16 +20,16 @@ TIMEOUT = 60
-- Implementation
-----------------------------------------------------------------------------
-- gets server reply (works for SMTP and FTP)
local function get_reply(control)
local function get_reply(c)
local code, current, sep
local line, err = control:receive()
local line, err = c:receive()
local reply = line
if err then return nil, err end
code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
if not code then return nil, "invalid server reply" end
if sep == "-" then -- reply is multiline
repeat
line, err = control:receive()
line, err = c:receive()
if err then return nil, err end
current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
reply = reply .. "\n" .. line
@ -43,7 +43,7 @@ end
local metat = { __index = {} }
function metat.__index:check(ok)
local code, reply = get_reply(self.control)
local code, reply = get_reply(self.c)
if not code then return nil, reply end
if type(ok) ~= "function" then
if type(ok) == "table" then
@ -59,50 +59,55 @@ function metat.__index:check(ok)
end
function metat.__index:command(cmd, arg)
if arg then return self.control:send(cmd .. " " .. arg.. "\r\n")
else return self.control:send(cmd .. "\r\n") end
if arg then return self.c:send(cmd .. " " .. arg.. "\r\n")
else return self.c:send(cmd .. "\r\n") end
end
function metat.__index:sink(snk, pat)
local chunk, err = control:receive(pat)
local chunk, err = c:receive(pat)
return snk(chunk, err)
end
function metat.__index:send(data)
return self.control:send(data)
return self.c:send(data)
end
function metat.__index:receive(pat)
return self.control:receive(pat)
return self.c:receive(pat)
end
function metat.__index:getfd()
return self.control:getfd()
return self.c:getfd()
end
function metat.__index:dirty()
return self.control:dirty()
return self.c:dirty()
end
function metat.__index:getcontrol()
return self.control
return self.c
end
function metat.__index:source(source, step)
local sink = socket.sink("keep-open", self.control)
local sink = socket.sink("keep-open", self.c)
return ltn12.pump.all(source, sink, step or ltn12.pump.step)
end
-- closes the underlying control
-- closes the underlying c
function metat.__index:close()
self.control:close()
self.c:close()
return 1
end
-- connect with server and return control object
connect = socket.protect(function(host, port, timeout)
local control = socket.try(socket.tcp())
socket.try(control:settimeout(timeout or TIMEOUT))
socket.try(control:connect(host, port))
return setmetatable({control = control}, metat)
end)
-- connect with server and return c object
function connect(host, port, timeout)
local c, e = socket.tcp()
if not c then return nil, e end
c:settimeout(timeout or TIMEOUT)
local r, e = c:connect(host, port)
if not r then
c:close()
return nil, e
end
return setmetatable({c = c}, metat)
end