2.0 alpha RELEASED!
This commit is contained in:
parent
ac4aac0909
commit
7ed89c97f7
14 changed files with 480 additions and 244 deletions
23
src/except.c
23
src/except.c
|
@ -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;
|
||||
}
|
||||
|
|
16
src/ftp.lua
16
src/ftp.lua
|
@ -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
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
|
23
src/http.lua
23
src/http.lua
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
49
src/tp.lua
49
src/tp.lua
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue