Ruby
Ruby
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 Ruby Downloads
require 'chilkat'
success = false
# This requires the Chilkat API to have been previously unlocked.
# See Global Unlock Sample for sample code.
http = Chilkat::CkHttp.new()
# First get the size of the file to be downloaded.
url = "https://www.chilkatsoft.com/hamlet.xml"
resp = Chilkat::CkHttpResponse.new()
success = http.HttpNoBody("HEAD",url,resp)
if (success == false)
print http.lastErrorText() + "\n";
exit
end
remoteFileSize = resp.get_ContentLength()
print "Downloading " + remoteFileSize.to_s() + " bytes..." + "\n";
# Let's download in 4 chunks.
# (the last chunk will be whatever remains after the 1st 3 equal sized chunks)
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..
http1 = Chilkat::CkHttp.new()
http2 = Chilkat::CkHttp.new()
http3 = Chilkat::CkHttp.new()
http4 = Chilkat::CkHttp.new()
sbRange = Chilkat::CkStringBuilder.new()
sbRange.SetString("bytes=<range-start>-<range-end>")
numReplaced = sbRange.ReplaceI("<range-start>",0)
numReplaced = sbRange.ReplaceI("<range-end>",chunkSize - 1)
print sbRange.getAsString() + "\n";
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() + "\n";
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() + "\n";
http3.SetRequestHeader("Range",sbRange.getAsString())
sbRange.SetString("bytes=<range-start>-")
numReplaced = sbRange.ReplaceI("<range-start>",3 * chunkSize)
print sbRange.getAsString() + "\n";
http4.SetRequestHeader("Range",sbRange.getAsString())
# Start each range download
# task1 is a CkTask
task1 = http1.DownloadAsync(url,"qa_output/chunk1.dat")
task1.Run()
# task2 is a CkTask
task2 = http2.DownloadAsync(url,"qa_output/chunk2.dat")
task2.Run()
# task3 is a CkTask
task3 = http3.DownloadAsync(url,"qa_output/chunk3.dat")
task3.Run()
# task4 is a CkTask
task4 = http4.DownloadAsync(url,"qa_output/chunk4.dat")
task4.Run()
# Wait for the downloads to complete.
numLive = 4
while numLive > 0
numLive = 0
if (task1.get_Live() == true)
numLive = numLive + 1
end
if (task2.get_Live() == true)
numLive = numLive + 1
end
if (task3.get_Live() == true)
numLive = numLive + 1
end
if (task4.get_Live() == true)
numLive = numLive + 1
end
if (numLive > 0)
# 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.
numErrors = 0
if (task1.GetResultBool() == false)
print task1.resultErrorText() + "\n";
numErrors = numErrors + 1
end
if (task2.GetResultBool() == false)
print task2.resultErrorText() + "\n";
numErrors = numErrors + 1
end
if (task3.GetResultBool() == false)
print task3.resultErrorText() + "\n";
numErrors = numErrors + 1
end
if (task4.GetResultBool() == false)
print task4.resultErrorText() + "\n";
numErrors = numErrors + 1
end
if (numErrors > 0)
exit
end
# All downloads were successful.
# Compose the file from the parts.
fac = Chilkat::CkFileAccess.new()
success = fac.ReassembleFile("qa_output","chunk","dat","qa_output/hamlet.xml")
if (success == false)
print fac.lastErrorText() + "\n";
else
print "Success." + "\n";
end
# Let's download in the regular way, and then compare files..
success = http.Download(url,"qa_output/hamletRegular.xml")
# Compare files.
bSame = fac.FileContentsEqual("qa_output/hamlet.xml","qa_output/hamletRegular.xml")
print "bSame = " + bSame.to_s() + "\n";