My initial question was misleading, I'll try to improve it:
I was able to write a small delphi programme, which is able to do a threaded download by using indy's idHTTP. It consists of 2 files:
the form:
interface type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; Button2: TButton; IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL; IdAntiFreeze1: TIdAntiFreeze; IdHTTP: TIdHTTP; ProgressBar1: TProgressBar; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } procedure UpdateLabel(BytesDone: Integer); procedure UpdateProgressBar(AWorkCount: Int64); procedure InitProgressBar(AWorkCountMax: Int64); procedure ResetProgressBar; end; var Form1: TForm1; uStopDownloading: Boolean; implementation {$R *.dfm} uses Unit2; procedure TForm1.Button1Click(Sender: TObject); var HTTPThread: TIdHTTPThread; begin HTTPThread := TIdHTTPThread.Create(True); HTTPThread.Url := 'https://www.bot-factory.de/tmp/lorem7.txt'; HTTPThread.EncodedStr := ''; HTTPThread.Filename := 'C:\test.txt'; HTTPThread.FreeOnTerminate := True; HTTPThread.Resume; end; procedure TForm1.Button2Click(Sender: TObject); begin idhttp.Disconnect; end; procedure TForm1.UpdateLabel(BytesDone: Integer); begin Label1.caption := format('%.0n',[extended(BytesDone+0.0)]) +' bytes loaded.'; end; procedure TForm1.UpdateProgressBar(AWorkCount: Int64); begin ProgressBar1.Position := AWorkCount; end; procedure TForm1.InitProgressBar(AWorkCountMax: Int64); begin Screen.Cursor := crHourGlass; ProgressBar1.Max := AWorkCountMax; ProgressBar1.Position := 0; end; procedure TForm1.ResetProgressBar; begin Screen.Cursor := crDefault; showmessage('Job is done'); end; END.
And the Thread-Unit:
interface uses Classes, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, sysutils; type TIdHTTPThread = class(TThread) private FURL: AnsiString; FencodedStr: string; FFilename: AnsiString; FBytesDone,FProgress,FWorkCountMax: Int64; IdHTTP: TIdHTTP; procedure OnWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); procedure OnWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); procedure OnWorkEnd(ASender: TObject; AWorkMode: TWorkMode); procedure Updatelabel; procedure UpdateProgressBar; procedure InitProgressBar; procedure ResetProgressBar; procedure Disconnect; public Constructor Create(CreateSuspended: Boolean); Destructor Destroy; override; property Url: AnsiString read FURL write FUrl; property encodedstr: String read FencodedStr write FencodedStr; property Filename: AnsiString read FFilename write FFilename; protected procedure Execute; override; end; implementation uses Unit1; // Formular Unit constructor TIdHTTPThread.Create(CreateSuspended: Boolean); begin inherited Create(Suspended); IdHTTP := TIdHTTP.Create; IdHTTP.OnWork := OnWork; IdHTTP.OnWorkBegin := OnWorkBegin; IdHTTP.OnWorkEnd := OnWorkEnd; //IdHTTP.Disconnect := Disconnect; end; destructor TIdHTTPThread.Destroy; begin IdHTTP.Free; inherited; end; procedure TIdHTTPThread.Execute; var DestStream: TFileStream; begin DestStream := TFileStream.Create(Filename, fmCreate); try IdHTTP.Get(Url, DestStream); finally DestStream.Free; end; end; procedure TIdHTTPThread.OnWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); begin FBytesDone := AWorkCount; FProgress := AWorkCount; Synchronize(Updatelabel); Synchronize(UpdateProgressBar); end; procedure TIdHTTPThread.OnWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); begin FWorkCountMax := AWorkCountMax; Synchronize(InitProgressBar); end; procedure TIdHTTPThread.Disconnect; begin idhttp.Disconnect; end; procedure TIdHTTPThread.OnWorkEnd(ASender: TObject; AWorkMode: TWorkMode); begin Synchronize(ResetProgressBar); end; procedure TIdHTTPThread.Updatelabel; begin Form1.UpdateLabel(FBytesDone); end; procedure TIdHTTPThread.UpdateProgressBar; begin Form1.UpdateProgressBar(FProgress); end; procedure TIdHTTPThread.InitProgressBar; begin Form1.initProgressBar(FWorkCountMax); end; procedure TIdHTTPThread.resetProgressBar; begin Form1.resetProgressBar; end; END.
I have in fact 2 questions:
- How can I interrupt the download of a (large) file ? I know that
idhttp.disconnect
should do the trick, but I do not know how to use it properly in my thread. - And furthermore: how can I use POST instead of GET?
I need to run this POST in a thread:
{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//submit_post
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
Procedure submit_post(url_string,EncodedStr,filename:string);
var
aStream: TMemoryStream;
Params: TStringStream;
begin
astream := TMemoryStream.create;
Params := TStringStream.create('');
Form1.IdHTTP.Request.Clear;
Form1.IdHTTP.HandleRedirects := TRUE;
try
with Form1.IdHTTP do
begin
Params.WriteString(EncodedStr);
Request.ContentType := 'application/x-www-form-urlencoded';
Request.Charset := 'utf-8';
try
Response.KeepAlive := False;
Post(url_string, params, astream);
except
on E: Exception do
begin
exit;
end;
end;
end;
astream.WriteBuffer(#0' ', 1);
astream.Position := 0;
astream.SaveToFile(filename);
finally
astream.Free;
Params.Free;
end;
end;