Lua Requires Chilkat v11.0.0+
Lua
HTTP Download in Parallel with Simultaneous Range Requests
See more HTTP Examples
Demonstrates how to download a large file with parallel simultaneous requests, where each request downloads a segment (range) of the remote file.Chilkat Lua Downloads
-- In the following call to loadlib, change the path (./chilkat.dll) to the relative or absolute directory where the chilkat.dll, chilkat.so, or chilkat.dylib is located.
chilkat = assert(package.loadlib("./chilkat.dll", "luaopen_chilkat"))()
print(chilkat._VERSION)
local success = false
-- This requires the Chilkat API to have been previously unlocked.
-- See Global Unlock Sample for sample code.
local http = chilkat.newHttp{}
-- First get the size of the file to be downloaded.
local url = "https://www.chilkatsoft.com/hamlet.xml"
local resp = chilkat.newHttpResponse{}
success = http:HttpNoBody("HEAD",url,resp)
if success == false then
print(http:LastErrorText())
end
local remoteFileSize = resp:ContentLength()
print("Downloading ", remoteFileSize, " bytes...")
-- Let's download in 4 chunks.
-- (the last chunk will be whatever remains after the 1st 3 equal sized chunks)
local chunkSize = remoteFileSize / 4
-- The Range header is used to download a range from a resource
-- Range: bytes=<range-start>-<range-end>
-- or
-- Range: bytes=<range-start>-
-- We're writing code this way for clarity..
local http1 = chilkat.newHttp{}
local http2 = chilkat.newHttp{}
local http3 = chilkat.newHttp{}
local http4 = chilkat.newHttp{}
local sbRange = chilkat.newStringBuilder{}
sbRange:SetString("bytes=<range-start>-<range-end>")
local numReplaced = sbRange:ReplaceI("<range-start>",0)
numReplaced = sbRange:ReplaceI("<range-end>",chunkSize - 1)
print(sbRange:GetAsString())
http1:SetRequestHeader("Range",sbRange:GetAsString())
sbRange:SetString("bytes=<range-start>-<range-end>")
numReplaced = sbRange:ReplaceI("<range-start>",chunkSize)
numReplaced = sbRange:ReplaceI("<range-end>",2 * chunkSize - 1)
print(sbRange:GetAsString())
http2:SetRequestHeader("Range",sbRange:GetAsString())
sbRange:SetString("bytes=<range-start>-<range-end>")
numReplaced = sbRange:ReplaceI("<range-start>",2 * chunkSize)
numReplaced = sbRange:ReplaceI("<range-end>",3 * chunkSize - 1)
print(sbRange:GetAsString())
http3:SetRequestHeader("Range",sbRange:GetAsString())
sbRange:SetString("bytes=<range-start>-")
numReplaced = sbRange:ReplaceI("<range-start>",3 * chunkSize)
print(sbRange:GetAsString())
http4:SetRequestHeader("Range",sbRange:GetAsString())
-- Start each range download
local task1 = http1:DownloadAsync(url,"qa_output/chunk1.dat")
task1:Run()
local task2 = http2:DownloadAsync(url,"qa_output/chunk2.dat")
task2:Run()
local task3 = http3:DownloadAsync(url,"qa_output/chunk3.dat")
task3:Run()
local task4 = http4:DownloadAsync(url,"qa_output/chunk4.dat")
task4:Run()
-- Wait for the downloads to complete.
local numLive = 4
while numLive > 0 do
numLive = 0
if task1:Live() == true then
numLive = numLive + 1
end
if task2:Live() == true then
numLive = numLive + 1
end
if task3:Live() == true then
numLive = numLive + 1
end
if task4:Live() == true then
numLive = numLive + 1
end
if numLive > 0 then
-- SleepMs is a convenience method to cause the caller to sleep for N millisec.
-- It does not cause the given task to sleep..
task1:SleepMs(10)
end
end
-- All should be downloaded now..
-- Examine the result of each Download.
local numErrors = 0
if task1:GetResultBool() == false then
print(task1:ResultErrorText())
numErrors = numErrors + 1
end
if task2:GetResultBool() == false then
print(task2:ResultErrorText())
numErrors = numErrors + 1
end
if task3:GetResultBool() == false then
print(task3:ResultErrorText())
numErrors = numErrors + 1
end
if task4:GetResultBool() == false then
print(task4:ResultErrorText())
numErrors = numErrors + 1
end
if numErrors > 0 then
end
-- All downloads were successful.
-- Compose the file from the parts.
local fac = chilkat.newFileAccess{}
success = fac:ReassembleFile("qa_output","chunk","dat","qa_output/hamlet.xml")
if success == false then
print(fac:LastErrorText())
else
print("Success.")
end
-- Let's download in the regular way, and then compare files..
success = http:Download(url,"qa_output/hamletRegular.xml")
-- Compare files.
local bSame = fac:FileContentsEqual("qa_output/hamlet.xml","qa_output/hamletRegular.xml")
print("bSame = ", bSame)