2018-01-31 11:39:04 +00:00
|
|
|
local http = require("socket.http")
|
|
|
|
local https = require("ssl.https")
|
|
|
|
local logger = require("logger")
|
|
|
|
local ltn12 = require("ltn12")
|
2018-01-31 22:37:19 +00:00
|
|
|
local socket = require('socket')
|
2018-01-31 11:39:04 +00:00
|
|
|
local socket_url = require("socket.url")
|
|
|
|
|
|
|
|
local InternalDownloadBackend = {}
|
2018-04-12 14:05:50 +00:00
|
|
|
local max_redirects = 5; --prevent infinite redirects
|
2018-01-31 11:39:04 +00:00
|
|
|
|
2018-01-31 22:37:19 +00:00
|
|
|
function InternalDownloadBackend:getResponseAsString(url, redirectCount)
|
|
|
|
if not redirectCount then
|
|
|
|
redirectCount = 0
|
|
|
|
elseif redirectCount == max_redirects then
|
|
|
|
error("InternalDownloadBackend: reached max redirects: ", redirectCount)
|
|
|
|
end
|
|
|
|
logger.dbg("InternalDownloadBackend: url :", url)
|
|
|
|
local request, sink = {}, {}
|
|
|
|
request['sink'] = ltn12.sink.table(sink)
|
|
|
|
request['url'] = url
|
2018-01-31 11:39:04 +00:00
|
|
|
local parsed = socket_url.parse(url)
|
2018-01-31 22:37:19 +00:00
|
|
|
|
|
|
|
local httpRequest = parsed.scheme == 'http' and http.request or https.request;
|
|
|
|
local code, headers, status = socket.skip(1, httpRequest(request))
|
|
|
|
|
|
|
|
if code ~= 200 then
|
|
|
|
logger.dbg("InternalDownloadBackend: HTTP response code <> 200. Response status: ", status)
|
|
|
|
if code and code > 299 and code < 400 and headers and headers["location"] then -- handle 301, 302...
|
|
|
|
local redirected_url = headers["location"]
|
|
|
|
logger.dbg("InternalDownloadBackend: Redirecting to url: ", redirected_url)
|
|
|
|
return self:getResponseAsString(redirected_url, redirectCount + 1)
|
|
|
|
else
|
|
|
|
error("InternalDownloadBackend: Don't know how to handle HTTP response status: ", status)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return table.concat(sink)
|
2018-01-31 11:39:04 +00:00
|
|
|
end
|
|
|
|
|
2018-01-31 22:37:19 +00:00
|
|
|
function InternalDownloadBackend:download(url, path)
|
|
|
|
local response = self:getResponseAsString(url)
|
|
|
|
local file = io.open(path, 'w')
|
|
|
|
file:write(response)
|
|
|
|
file:close()
|
2018-01-31 11:39:04 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
return InternalDownloadBackend
|