How to upload a file in Lua, but write to a local file as it works

I am trying to do an update, so when the Lua application is out of date, it will use LuaSocket to load a new .exe file (which can run my Lua code).

Inside this update module, I want it to show how much has been downloaded so far. However, with the following HTTP request, it blocks the application until it is fully loaded:

local b, c, h = http.request("https://www.example.com/Download/Example.exe?from="..Game.Version)

I use streams to load it, however I still cannot write to a file until the download is complete inside the stream, so the progress bar will go 0%, 100%, without anything in between.

Is there anything you can do to download the remote file, but save it in a local file as it is downloaded?

cURL can do this. I don't know if LuaSocket or anything else for Lua can. :(

+5
source share
2 answers

You are right - cURL can do it. LuaSocket does not have this feature. You can create an LTN12 receiver that reports on progress, but you won’t know the total file size until you download it completely, so it’s useless. Why not use luacurl instead?

local curl = require "luacurl"
local c = curl.new()

function GET(url)
    c:setopt(curl.OPT_URL, url)
    local t = {} -- this will collect resulting chunks
    c:setopt(curl.OPT_WRITEFUNCTION, function (param, buf)
        table.insert(t, buf) -- store a chunk of data received
        return #buf
    end)
    c:setopt(curl.OPT_PROGRESSFUNCTION, function(param, dltotal, dlnow)
        print('%', url, dltotal, dlnow) -- do your fancy reporting here
    end)
    c:setopt(curl.OPT_NOPROGRESS, false) -- use this to activate progress
    assert(c:perform())
    return table.concat(t) -- return the whole data as a string
end

local s = GET 'http://www.lua.org/'
print(s)
+10
source

You can save cURL dependency by making a HEAD request and getting the file size from the Content-Length header:

require "socket.http"

local resp, stat, hdr = socket.http.request{
  url     = "http://www.lua.org/ftp/lua-5.2.1.tar.gz",
  method  = "HEAD",
}

print(hdr["content-length"])
-- 249882

However, if that's all you're using LuaSocket, then cURL is probably the best choice.

+3
source

All Articles