From a712c4d8116371747ed3fda07eddc8e204fb626e Mon Sep 17 00:00:00 2001 From: Thijs Schreijer Date: Wed, 4 Mar 2015 11:04:56 +0100 Subject: [PATCH 1/4] expose parseRequest() methods for ftp and http requests --- src/ftp.lua | 47 ++++++++++++++++++++++++++++------------------- src/http.lua | 21 ++++++++++++++------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/ftp.lua b/src/ftp.lua index 917cd89..6286f90 100644 --- a/src/ftp.lua +++ b/src/ftp.lua @@ -232,17 +232,6 @@ 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") @@ -256,12 +245,17 @@ 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) @@ -277,9 +271,24 @@ _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 + 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 + return tget(gett) + end end) return _M \ No newline at end of file diff --git a/src/http.lua b/src/http.lua index d5457f6..550634c 100644 --- a/src/http.lua +++ b/src/http.lua @@ -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 @@ -329,11 +329,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) @@ -343,13 +346,17 @@ 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, trequest(reqt)) + return table.concat(t), code, headers, status + else + return trequest(reqt) + end end) return _M From 01a2ee90a8d0630c0f66c8382fd569e5787e2a8f Mon Sep 17 00:00:00 2001 From: Thijs Schreijer Date: Fri, 13 Mar 2015 17:42:22 +0100 Subject: [PATCH 2/4] Updated `create` to be a method call. This allows redirects over different protocols (http -> https) becasue the `create` function can now reflect on the contents of the request at hand and create the correct socket. --- src/http.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/http.lua b/src/http.lua index 550634c..15e4c01 100644 --- a/src/http.lua +++ b/src/http.lua @@ -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 @@ -294,7 +294,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) @@ -354,7 +354,8 @@ _M.request = socket.protect(function(reqt, body) reqt = _M.parseRequest(reqt, body) local t, code, headers, status = reqt.target, socket.skip(1, trequest(reqt)) return table.concat(t), code, headers, status - else + else + if not reqt.create then reqt.create = socket.tcp() end -- set default create method return trequest(reqt) end end) From 9016e912382b24938cfc6cc92be5127be3a69cf4 Mon Sep 17 00:00:00 2001 From: Thijs Schreijer Date: Fri, 13 Mar 2015 18:02:18 +0100 Subject: [PATCH 3/4] fix http, updated ftp & smtp with similar create method call --- src/ftp.lua | 14 +++++++++----- src/http.lua | 2 +- src/smtp.lua | 10 ++++++---- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/ftp.lua b/src/ftp.lua index 6286f90..1e9bc02 100644 --- a/src/ftp.lua +++ b/src/ftp.lua @@ -34,8 +34,9 @@ _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 c = function() return params:create() end -- wrap create as a method call + local tp = socket.try(tp.connect(params.server, params.port or _M.PORT, _M.TIMEOUT, c)) 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 +204,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 @@ -235,7 +236,7 @@ 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 @@ -262,7 +263,8 @@ _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,6 +279,7 @@ _M.put = socket.protect(function(putt, body) tput(putt) return table.concat(putt.target) else + putt.create = putt.create or socket.tcp return tput(putt) end end) @@ -287,6 +290,7 @@ _M.get = socket.protect(function(gett) tget(gett) return table.concat(gett.target) else + gett.create = gett.create or socket.tcp return tget(gett) end end) diff --git a/src/http.lua b/src/http.lua index 15e4c01..cecb3b4 100644 --- a/src/http.lua +++ b/src/http.lua @@ -355,7 +355,7 @@ _M.request = socket.protect(function(reqt, body) local t, code, headers, status = reqt.target, socket.skip(1, trequest(reqt)) return table.concat(t), code, headers, status else - if not reqt.create then reqt.create = socket.tcp() end -- set default create method + reqt.create = reqt.create or socket.tcp return trequest(reqt) end end) diff --git a/src/smtp.lua b/src/smtp.lua index b113d00..e60791f 100644 --- a/src/smtp.lua +++ b/src/smtp.lua @@ -113,9 +113,10 @@ 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 c = function() return mailt:create() end -- wrap to do a method call + local tp = socket.try(tp.connect(mailt.server or _M.SERVER, mailt.port or _M.PORT, + _M.TIMEOUT, c)) local s = base.setmetatable({tp = tp}, metat) -- make sure tp is closed if we get an exception s.try = socket.newtry(function() @@ -245,7 +246,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) From 8bc5ba604ec089c0002c1cad00f43a11ada0a29a Mon Sep 17 00:00:00 2001 From: Thijs Schreijer Date: Mon, 16 Mar 2015 17:06:32 +0100 Subject: [PATCH 4/4] removed 2 locals, fixed http --- src/ftp.lua | 8 ++++++-- src/http.lua | 2 +- src/smtp.lua | 9 ++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/ftp.lua b/src/ftp.lua index 1e9bc02..a894c1c 100644 --- a/src/ftp.lua +++ b/src/ftp.lua @@ -35,8 +35,12 @@ _M.PASSWORD = "anonymous@anonymous.org" local metat = { __index = {} } function _M.open(params) - local c = function() return params:create() end -- wrap create as a method call - local tp = socket.try(tp.connect(params.server, params.port or _M.PORT, _M.TIMEOUT, c)) + 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) diff --git a/src/http.lua b/src/http.lua index cecb3b4..d926e72 100644 --- a/src/http.lua +++ b/src/http.lua @@ -352,7 +352,7 @@ end _M.request = socket.protect(function(reqt, body) if base.type(reqt) == "string" then reqt = _M.parseRequest(reqt, body) - local t, code, headers, status = reqt.target, socket.skip(1, trequest(reqt)) + 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 diff --git a/src/smtp.lua b/src/smtp.lua index e60791f..ea52873 100644 --- a/src/smtp.lua +++ b/src/smtp.lua @@ -114,9 +114,12 @@ function metat.__index:send(mailt) end function _M.open(mailt) - local c = function() return mailt:create() end -- wrap to do a method call - local tp = socket.try(tp.connect(mailt.server or _M.SERVER, mailt.port or _M.PORT, - _M.TIMEOUT, c)) + 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()