We wrote an article: Lua: Retrieve partial ftp file at specific range about method 1, but in some case, we see when you receive more than 60000 you won’t receive exact range, example get range from 10000-80000, but you will receive content of range 10000-end.
So we must write second method, use command REST.
Step 1: Edit file /usr/share/lua/5.1/socket/ftp.lua
Add function rest
:
function metat.__index:rest(start) local x,y = self.try(self.tp:command("rest", start)) local a,b = self.try(self.tp:check(350)) return 1 end
Edit function tget
local function tget(gett) gett = override(gett) socket.try(gett.host, "missing hostname") local f = _M.open(gett.host, gett.port, gett.create) f:greet() f:login(gett.user, gett.password) if gett.type then f:type(gett.type) end --f:size(gett) --you can use to get filesize, but must use function size at end of this tutorial if gett.rang then local pp = gett.rang:gsub(" .+","") pp = tonumber(pp) if pp>0 then f:rest(pp) end end if gett.rang and gett.rang ~= '' then gett._tp = f end f:epsv() f:receive(gett) f:quit() return f:close() end
Step 2: Lua code
function download(u,rang,sink) local t = {} local p = url.parse(u) p.command = "retr" p.type = "i" if sink then p.sink = sink(t) else p.sink = ltn12.sink.table(t) end p.argument = string.gsub(p.path, "^/", "") if p.argument == "" then p.argument = nil end p.check = 250 if rang and rang ~= "" then p.rang = rang p._count = 0 local x1,_ = rang:gsub(".+ (.+)","%1") local x2,_ = rang:gsub(" .+","") p._max = tonumber(x1)-tonumber(x2) +1 p.sink = function (chunk,err) if chunk then p._count = p._count + chunk:len() if p._count>=p._max then table.insert(t, chunk:sub(1,chunk:len() - p._count + p._max)) if p._tp then p._count = nil p._max = nil p._tp:close() p._tp = nil end return nil else table.insert(t, chunk) end end return 1 end end local a,b = ftp.get(p) return table.concat(t,'') -- , p.size --to get more filesize end
Example of usage function download
:
local content = download(ftp_link,rang) ngx.say(content)
Bunus: function size
function metat.__index:size(path) local x,y = self.try(self.tp:command("size",path.path)) local a,b = self.try(self.tp:check{"1..","2..",213}) if b then local l = b:gsub(".+ (.+)","%1") path.size = tonumber(l) --store filesize here end return 1 end
1 Comment
Lua: Retrieve partial ftp file at specific range | Free Online Tutorials
(May 19, 2022 - 3:52 pm)[…] Lua: Retrieve partial ftp file at specific range – Method 2 […]