Skip to content

Instantly share code, notes, and snippets.

@jpluimers
Created April 26, 2018 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpluimers/6cf1e768e54d78024beccbe5360727b3 to your computer and use it in GitHub Desktop.
Save jpluimers/6cf1e768e54d78024beccbe5360727b3 to your computer and use it in GitHub Desktop.
procedure Download;
var
ms: TFileStream; // where to store file
fSize: integer; // total size of download file
fSectionSize: longint; // size of the packet to get
sPos: int64; // range start position
ePos: int64; // range stop position
url: String; // URL to download
LocalFileName: String; // filename to save as
HTTP: TIdHTTP; // HTTP object
idx: integer; // index counter for getting packets
begin
HTTP := TIdHTTP.Create(nil);
url := 'http://car-partbidmate.com/cmw/cmw_qaupgrade_86_82_0.exe';
LocalFileName := 'cmw_qaupgrade_86_82_0.exe';
HTTP.Head(url); // calls the URL to grab the initial file size
ms := TFileStream.Create(LocalFileName, fmCreate or fmOpsenReadWrite);
ms.Position := 0;
fSize := HTTP.Response.ContentLength;
fSectionSize := fSize div (1024 * 1024);
// preset our range
sPos := 0;
ePos := 1024 * 1024 - 1;
for idx := 1 to fSectionSize + 1 do
begin
with HTTP.Request.Ranges.Add do // add our range
begin
StartPos := sPos;
endpos := ePos;
end;
if idx = fSectionSize then // if LAST packet range
begin
sPos := ePos + 1;
ePos := fSize - 1;
end
else
begin // anything BUT the LAST packet range
sPos := ePos + 1;
ePos := sPos + (1024 * 1024) - 1;
end;
// call and get the next packet to the file stream
HTTP.Get(url, ms);
HTTP.Request.Ranges.Clear; // make sure we clear out the last range
end;
freeandnil(ms);
freeandnil(HTTP);
end;
@jpluimers
Copy link
Author

wiert [9:20 AM]
“for idx := 1 to fSectionSize + 1 do” versus “if idx = fSectionSize then // if LAST packet range”

wiert [9:21 AM]
rename fSectionSize into fPartialSecionCount
Get your casing correct: freeandnil -> FreeAndNul
FreeAndNil even

wiert [9:22 AM]
Get your variable naming conventions right to. Some have prefixes, some don’t, some start with lowercase, others don’t

wiert [9:24 AM]
And where is the “recovery” code?
Rename idx into fPartialSectionIndex
Then keep an fSucceededTransfers: IList {or TArray}, then for each succeeded fPartialSectionIndex set it to True. Repeat loop until all true while skipping the succeeded transfers (or too many retries).
Ensure the server has a sha256/sha512 hash for each file, then finally match hashes. Or maybe better: hashes for each section.
Download over https instead of http to prevent man-in-the-middle modifications.

wiert [9:34 AM]
The FreeAndNil need to be in a try-finally section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment