This commit is contained in:
Thijs Schreijer 2016-02-25 11:42:28 +00:00
commit 1d38bcd87e
3 changed files with 70 additions and 40 deletions

View file

@ -34,8 +34,13 @@ _M.PASSWORD = "anonymous@anonymous.org"
-----------------------------------------------------------------------------
local metat = { __index = {} }
function _M.open(server, port, create)
local tp = socket.try(tp.connect(server, port or _M.PORT, _M.TIMEOUT, create))
function _M.open(params)
local tp = socket.try(tp.connect(
params.server,
params.port or _M.PORT,
_M.TIMEOUT,
function() return params:create() end -- wrap create as a method call
))
local f = base.setmetatable({ tp = tp }, metat)
-- make sure everything gets closed in an exception
f.try = socket.newtry(function() f:close() end)
@ -203,7 +208,7 @@ end
local function tput(putt)
putt = override(putt)
socket.try(putt.host, "missing hostname")
local f = _M.open(putt.host, putt.port, putt.create)
local f = _M.open(putt)
f:greet()
f:login(putt.user, putt.password)
if putt.type then f:type(putt.type) end
@ -232,21 +237,10 @@ local function parse(u)
return t
end
local function sput(u, body)
local putt = parse(u)
putt.source = ltn12.source.string(body)
return tput(putt)
end
_M.put = socket.protect(function(putt, body)
if base.type(putt) == "string" then return sput(putt, body)
else return tput(putt) end
end)
local function tget(gett)
gett = override(gett)
socket.try(gett.host, "missing hostname")
local f = _M.open(gett.host, gett.port, gett.create)
local f = _M.open(gett)
f:greet()
f:login(gett.user, gett.password)
if gett.type then f:type(gett.type) end
@ -256,19 +250,25 @@ local function tget(gett)
return f:close()
end
local function sget(u)
local gett = parse(u)
local t = {}
gett.sink = ltn12.sink.table(t)
tget(gett)
return table.concat(t)
-- parses a simple form into the advanced form
-- if `body` is provided, a PUT, otherwise a GET.
-- If GET, then a field `target` is added to store the results
_M.parseRequest = function(u, body)
local t = parse(u)
if body then
t.source = ltn12.source.string(body)
else
t.target = {}
t.sink = ltn12.sink.table(t.target)
end
end
_M.command = socket.protect(function(cmdt)
cmdt = override(cmdt)
socket.try(cmdt.host, "missing hostname")
socket.try(cmdt.command, "missing command")
local f = _M.open(cmdt.host, cmdt.port, cmdt.create)
cmdt.create = cmdt.create or socket.tcp
local f = _M.open(cmdt)
f:greet()
f:login(cmdt.user, cmdt.password)
f.try(f.tp:command(cmdt.command, cmdt.argument))
@ -277,9 +277,26 @@ _M.command = socket.protect(function(cmdt)
return f:close()
end)
_M.put = socket.protect(function(putt, body)
if base.type(putt) == "string" then
putt = _M.parseRequest(putt, body)
tput(putt)
return table.concat(putt.target)
else
putt.create = putt.create or socket.tcp
return tput(putt)
end
end)
_M.get = socket.protect(function(gett)
if base.type(gett) == "string" then return sget(gett)
else return tget(gett) end
if base.type(gett) == "string" then
gett = _M.parseRequest(gett)
tget(gett)
return table.concat(gett.target)
else
gett.create = gett.create or socket.tcp
return tget(gett)
end
end)
return _M

View file

@ -76,7 +76,7 @@ socket.sourcet["http-chunked"] = function(sock, headers)
-- was it the last chunk?
if size > 0 then
-- if not, get chunk and skip terminating CRLF
local chunk, err, part = sock:receive(size)
local chunk, err = sock:receive(size)
if chunk then sock:receive() end
return chunk, err
else
@ -106,15 +106,15 @@ end
-----------------------------------------------------------------------------
local metat = { __index = {} }
function _M.open(host, port, create)
-- create socket with user connect function, or with default
local c = socket.try((create or socket.tcp)())
function _M.open(reqt)
-- create socket with user connect function
local c = socket.try(reqt:create()) -- method call, passing reqt table as self!
local h = base.setmetatable({ c = c }, metat)
-- create finalized try
h.try = socket.newtry(function() h:close() end)
-- set timeout before connecting
h.try(c:settimeout(_M.TIMEOUT))
h.try(c:connect(host, port or _M.PORT))
h.try(c:connect(reqt.host, reqt.port or _M.PORT))
-- here everything worked
return h
end
@ -303,7 +303,7 @@ end
-- we loop until we get what we want, or
-- until we are sure there is no way to get it
local nreqt = adjustrequest(reqt)
local h = _M.open(nreqt.host, nreqt.port, nreqt.create)
local h = _M.open(nreqt)
-- send request line and headers
h:sendrequestline(nreqt.method, nreqt.uri)
h:sendheaders(nreqt.headers)
@ -338,11 +338,14 @@ end
return 1, code, headers, status
end
local function srequest(u, b)
-- parses a shorthand form into the advanced table form.
-- adds field `target` to the table. This will hold the return values.
_M.parseRequest = function(u, b)
local t = {}
local reqt = {
url = u,
sink = ltn12.sink.table(t)
sink = ltn12.sink.table(t),
target = t,
}
if b then
reqt.source = ltn12.source.string(b)
@ -352,13 +355,18 @@ local function srequest(u, b)
}
reqt.method = "POST"
end
local code, headers, status = socket.skip(1, trequest(reqt))
return table.concat(t), code, headers, status
return reqt
end
_M.request = socket.protect(function(reqt, body)
if base.type(reqt) == "string" then return srequest(reqt, body)
else return trequest(reqt) end
if base.type(reqt) == "string" then
reqt = _M.parseRequest(reqt, body)
local t, code, headers, status = reqt.target, socket.skip(1, _M.request(reqt))
return table.concat(t), code, headers, status
else
reqt.create = reqt.create or socket.tcp
return trequest(reqt)
end
end)
return _M

View file

@ -113,9 +113,13 @@ function metat.__index:send(mailt)
self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
end
function _M.open(server, port, create)
local tp = socket.try(tp.connect(server or _M.SERVER, port or _M.PORT,
_M.TIMEOUT, create))
function _M.open(mailt)
local tp = socket.try(tp.connect(
mailt.server or _M.SERVER,
mailt.port or _M.PORT,
_M.TIMEOUT,
function() return mailt:create() end -- wrap to do a method call
))
local s = base.setmetatable({tp = tp}, metat)
-- make sure tp is closed if we get an exception
s.try = socket.newtry(function()
@ -245,7 +249,8 @@ end
-- High level SMTP API
-----------------------------------------------------------------------------
_M.send = socket.protect(function(mailt)
local s = _M.open(mailt.server, mailt.port, mailt.create)
mailt.create = mailt.create or socket.tcp
local s = _M.open(mailt)
local ext = s:greet(mailt.domain)
s:auth(mailt.user, mailt.password, ext)
s:send(mailt)