PowerBuilder
PowerBuilder
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 PowerBuilder Downloads
integer li_rc
integer li_Success
oleobject loo_Http
string ls_Url
oleobject loo_Resp
integer li_RemoteFileSize
integer li_ChunkSize
oleobject loo_Http1
oleobject loo_Http2
oleobject loo_Http3
oleobject loo_Http4
oleobject loo_SbRange
integer li_NumReplaced
oleobject loo_Task1
oleobject loo_Task2
oleobject loo_Task3
oleobject loo_Task4
integer li_NumLive
integer li_NumErrors
oleobject loo_Fac
integer li_BSame
li_Success = 0
// This requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
loo_Http = create oleobject
li_rc = loo_Http.ConnectToNewObject("Chilkat.Http")
if li_rc < 0 then
destroy loo_Http
MessageBox("Error","Connecting to COM object failed")
return
end if
// First get the size of the file to be downloaded.
ls_Url = "https://www.chilkatsoft.com/hamlet.xml"
loo_Resp = create oleobject
li_rc = loo_Resp.ConnectToNewObject("Chilkat.HttpResponse")
li_Success = loo_Http.HttpNoBody("HEAD",ls_Url,loo_Resp)
if li_Success = 0 then
Write-Debug loo_Http.LastErrorText
destroy loo_Http
destroy loo_Resp
return
end if
li_RemoteFileSize = loo_Resp.ContentLength
Write-Debug "Downloading " + string(li_RemoteFileSize) + " bytes..."
// Let's download in 4 chunks.
// (the last chunk will be whatever remains after the 1st 3 equal sized chunks)
li_ChunkSize = li_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..
loo_Http1 = create oleobject
li_rc = loo_Http1.ConnectToNewObject("Chilkat.Http")
loo_Http2 = create oleobject
li_rc = loo_Http2.ConnectToNewObject("Chilkat.Http")
loo_Http3 = create oleobject
li_rc = loo_Http3.ConnectToNewObject("Chilkat.Http")
loo_Http4 = create oleobject
li_rc = loo_Http4.ConnectToNewObject("Chilkat.Http")
loo_SbRange = create oleobject
li_rc = loo_SbRange.ConnectToNewObject("Chilkat.StringBuilder")
loo_SbRange.SetString("bytes=<range-start>-<range-end>")
li_NumReplaced = loo_SbRange.ReplaceI("<range-start>",0)
li_NumReplaced = loo_SbRange.ReplaceI("<range-end>",li_ChunkSize - 1)
Write-Debug loo_SbRange.GetAsString()
loo_Http1.SetRequestHeader("Range",loo_SbRange.GetAsString())
loo_SbRange.SetString("bytes=<range-start>-<range-end>")
li_NumReplaced = loo_SbRange.ReplaceI("<range-start>",li_ChunkSize)
li_NumReplaced = loo_SbRange.ReplaceI("<range-end>",2 * li_ChunkSize - 1)
Write-Debug loo_SbRange.GetAsString()
loo_Http2.SetRequestHeader("Range",loo_SbRange.GetAsString())
loo_SbRange.SetString("bytes=<range-start>-<range-end>")
li_NumReplaced = loo_SbRange.ReplaceI("<range-start>",2 * li_ChunkSize)
li_NumReplaced = loo_SbRange.ReplaceI("<range-end>",3 * li_ChunkSize - 1)
Write-Debug loo_SbRange.GetAsString()
loo_Http3.SetRequestHeader("Range",loo_SbRange.GetAsString())
loo_SbRange.SetString("bytes=<range-start>-")
li_NumReplaced = loo_SbRange.ReplaceI("<range-start>",3 * li_ChunkSize)
Write-Debug loo_SbRange.GetAsString()
loo_Http4.SetRequestHeader("Range",loo_SbRange.GetAsString())
// Start each range download
loo_Task1 = loo_Http1.DownloadAsync(ls_Url,"qa_output/chunk1.dat")
loo_Task1.Run()
loo_Task2 = loo_Http2.DownloadAsync(ls_Url,"qa_output/chunk2.dat")
loo_Task2.Run()
loo_Task3 = loo_Http3.DownloadAsync(ls_Url,"qa_output/chunk3.dat")
loo_Task3.Run()
loo_Task4 = loo_Http4.DownloadAsync(ls_Url,"qa_output/chunk4.dat")
loo_Task4.Run()
// Wait for the downloads to complete.
li_NumLive = 4
do while li_NumLive > 0
li_NumLive = 0
if loo_Task1.Live = 1 then
li_NumLive = li_NumLive + 1
end if
if loo_Task2.Live = 1 then
li_NumLive = li_NumLive + 1
end if
if loo_Task3.Live = 1 then
li_NumLive = li_NumLive + 1
end if
if loo_Task4.Live = 1 then
li_NumLive = li_NumLive + 1
end if
if li_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..
loo_Task1.SleepMs(10)
end if
loop
// All should be downloaded now..
// Examine the result of each Download.
li_NumErrors = 0
if loo_Task1.GetResultBool() = 0 then
Write-Debug loo_Task1.ResultErrorText
li_NumErrors = li_NumErrors + 1
end if
if loo_Task2.GetResultBool() = 0 then
Write-Debug loo_Task2.ResultErrorText
li_NumErrors = li_NumErrors + 1
end if
if loo_Task3.GetResultBool() = 0 then
Write-Debug loo_Task3.ResultErrorText
li_NumErrors = li_NumErrors + 1
end if
if loo_Task4.GetResultBool() = 0 then
Write-Debug loo_Task4.ResultErrorText
li_NumErrors = li_NumErrors + 1
end if
if li_NumErrors > 0 then
destroy loo_Task1
destroy loo_Task2
destroy loo_Task3
destroy loo_Task4
destroy loo_Http
destroy loo_Resp
destroy loo_Http1
destroy loo_Http2
destroy loo_Http3
destroy loo_Http4
destroy loo_SbRange
return
end if
// All downloads were successful.
// Compose the file from the parts.
loo_Fac = create oleobject
li_rc = loo_Fac.ConnectToNewObject("Chilkat.FileAccess")
li_Success = loo_Fac.ReassembleFile("qa_output","chunk","dat","qa_output/hamlet.xml")
if li_Success = 0 then
Write-Debug loo_Fac.LastErrorText
else
Write-Debug "Success."
end if
destroy loo_Task1
destroy loo_Task2
destroy loo_Task3
destroy loo_Task4
// Let's download in the regular way, and then compare files..
li_Success = loo_Http.Download(ls_Url,"qa_output/hamletRegular.xml")
// Compare files.
li_BSame = loo_Fac.FileContentsEqual("qa_output/hamlet.xml","qa_output/hamletRegular.xml")
Write-Debug "bSame = " + string(li_BSame)
destroy loo_Http
destroy loo_Resp
destroy loo_Http1
destroy loo_Http2
destroy loo_Http3
destroy loo_Http4
destroy loo_SbRange
destroy loo_Fac