i used this codes, but i am taking' "xxx.xxx" not understood' error message sometimes. And it doesn't download and than i am taking "unable to build data connection: connection time out" message.
My ConnectionTimeOut setting is 240000.
What can i do? Can you help me please? I am using Delphi XE.
Have nice day.
It is best to include your own code to solve your problem.but,To download my file,
I zip the file or folder on the server and then receive the following code in the client:
var
STListZip: TStringList;
SZipDown: String;
fFtp:TIdFTP;
begin
fFtp := TIdFTP.Create(nil);
fFtp.Passive := true;
fFtp.Host := 'myserver.com';
fFtp.Username := 'u1';
fFtp.Password := '1';
fFtp.port:='21';
fFtp.ConnectTimeout := 20000;
fFtp.TransferTimeout := 20000;
try
fFtp.Connect;
fFtp.ChangeDir('');
except
on E: Exception do
begin
ShowMessage('ERROR ftp not connect');
Exit;
end;
end;
if fFtp.Connected then
begin
STListZip := TStringList.Create;
fFtp.List(STListZip, 'abc.zip', false);
if STListZip.Count < 1 then
begin
ShowMessage('ERROR file not exist');
Exit;
end;
STListZip.Sort;
SZipDown := STListZip[STListZip.Count - 1];
try
fftp.BeginWork(wmRead);
fftp.Get(SZipDown, 'd:\', true, fftp.ResumeSupported);
fftp.Disconnect();
fftp.EndWork(wmRead);
except
on E: Exception do
begin
ShowMessage('ERROR File not download');
Exit;
end;
end;
end;
end;
Notice: Instead of abc.zip you can put *.zip to get all the zip file names.
Related
Please create a new FMX application, add a button and a memo to run this example. I have this code:
procedure TForm1.Button1Click(Sender: TObject);
begin
TTask.Run(procedure
var
client: TIdHTTP;
result: string;
begin
client := TIdHTTP.Create(nil);
try
try
client.ReadTimeout := 4000;
client.ConnectTimeout := 4000;
result := client.Get('a valid url here just as test');
TThread.Synchronize(nil, procedure
begin
Memo1.Lines.Add(result);
end);
except
on E: Exception do
begin
TThread.Synchronize(nil, procedure
begin
Memo1.Lines.Add(E.Message);
end);
end
end;
finally
client.Free;
end;
end);
end;
It works as I expect but the problem is in the IDE. If I place the cursor somewhere in the body of the anonymous function, I get the closing of the finally statement automatically.
How can I fix this?
First I am here
Then I press enter and I have this!
If you put the cursor at the beginning and not at the end of the line, you can add new spaces without the completion. How to solve this problem? Well, I have discovered that the issue happens because there is this code:
TThread.Synchronize(nil, procedure
begin
Memo1.Lines.Add(result);
end);
If you remove this code, the issue doens't happen anymore. Is this a bug in the IDE?
Is this a bug in the IDE?
Yes. This is a defect. Please submit a report to Quality Portal.
Is this a bug in the IDE?
Yes, this is a bug in the IDE. Your code is syntactically valid.
How can I fix this?
The best way to avoid this is to create your code and surround it with try...except... to handle any exception:
try
MyClass := TComponent.Create(Self);
try
finally
MyClass.Free;
end;
except on E: Exception do
end;
So your code will be:
TTask.Run(procedure
var
client: TIdHTTP;
result: string;
begin
try
Client := TIdHTTP.Create(nil);
try
client.ReadTimeout := 4000;
client.ConnectTimeout := 4000;
result := client.Get('a valid url here just as test');
TThread.Synchronize(nil, procedure
begin
Memo1.Lines.Add(result);
end);
finally
Client.Free;
end;
except on E: Exception do
begin
TThread.Synchronize(nil, procedure
begin
Memo1.Lines.Add(E.Message);
end);
end;
end;
end;
I have a problem in IdHttp using Indy (Delphi).
I try to using IdHttp to post XML in web service SOAP, but dont work. Return "Error connecting with SSL." in IdSSLOpenSSL.Connect#1437 from indy.
My code is simple:
procedure TForm1.Button1Click(Sender: TObject);
var
vRequest : TStringStream;
s : String;
begin
vRequest := TStringStream.Create((Memo1.Lines.Text));
try
IdHTTP1.Host := edHost.Text;
IdHTTP1.Request.ContentLength := length(Memo1.Lines.Text);
IdHTTP1.Request.ContentType := edContentType.Text;
IdHTTP1.Request.CustomHeaders.Text := 'SOAPAction: "removed for safe"'#13#10;
IdHTTP1.request.CacheControl := 'no-cache';
IdHTTP1.Request.AcceptEncoding := edAccept.Text;
IdHTTP1.HTTPOptions := [hoKeepOrigProtocol];
IdHTTP1.ProtocolVersion := pv1_1;
Memo2.Clear;
try
s := IdHTTP1.post(Edit1.Text, vRequest);
Memo2.Lines.Text := s;
except
on e: EIdHTTPProtocolException do begin
Label1.Caption := e.Message;
MEMO2.LINES.TEXT := e.Message;
end;
on e:Exception do begin
Label1.Caption := e.Message;
MEMO2.LINES.TEXT := e.Message;
end;
end;
requestHeaders.Lines.Text := IdHTTP1.Request.RawHeaders.Text;
responseHeaders.Lines.Text := IdHTTP1.Response.RawHeaders.Text;
finally
vRequest.Free;
end;
end;
In exe folder contain libeay32.dll and ssleay32.dll. Any sugestion?
I Used delphi 5, but in delphi 7 is the same problem.
By default, the SSLVersions property of TIdSSLIOHandlerSockOpenSSL is set to enable only TLS 1.0 1. But many websites are starting to phase out TLS 1.0 and only accept TLS 1.1+. So try enabling TLS 1.1 and TLS 1.2 in the SSLVersions property and see if it helps.
1: there is an open ticket in Indy's issue tracker to also enable TLS 1.1 and TLS 1.2 by default.
On a side note, there are some further tweaks you should make to your code:
do not assign any values to TIdHTTP's Host or ContentLength properties. They are populated automatically by TIdHTTP.
if you set the AcceptEncoding property manually, make sure NOT to include deflate or gzip unless you have a Compressor assigned to TIdHTTP, otherwise it will fail to decode a compressed response. You really should not assign anything to AcceptEncoding unless you are prepared to handle custom encodings. The Compressor handles deflate/gzip and TIdHTTP will update AcceptEncoding accordingly if a Compressor is assigned and ready for use.
use the CustomHeaders.Values property to set individual headers, not the CustomHeaders.Text property.
you do not need to catch EIdHTTPProtocolException explicitly, since that exception handler is not doing anything extra that the more generic Exception handler is not doing.
the RawHeaders property is a TStringList descendant, so it is more efficient to use Lines.Assign(RawHeaders) instead of Lines.Text := RawHeaders.Text.
Try this:
procedure TForm1.Button1Click(Sender: TObject);
var
vRequest : TStringStream;
s : String;
begin
IdHTTP1.Request.ContentType := edContentType.Text;
IdHTTP1.Request.CustomHeaders.Values['SOAPAction'] := 'removed for safe';
IdHTTP1.Request.CacheControl := 'no-cache';
IdHTTP1.HTTPOptions := [hoKeepOrigProtocol];
IdHTTP1.ProtocolVersion := pv1_1;
Memo2.Clear;
try
vRequest := TStringStream.Create(Memo1.Lines.Text);
try
s := IdHTTP1.Post(Edit1.Text, vRequest);
finally
vRequest.Free;
end;
Memo2.Lines.Text := s;
except
on e: Exception do begin
Label1.Caption := e.Message;
Memo2.Lines.Text := e.Message;
end;
end;
RequestHeaders.Lines.Assign(IdHTTP1.Request.RawHeaders);
ResponseHeaders.Lines.Assign(IdHTTP1.Response.RawHeaders);
end;
Im trying to send mail using this code:
With IdMessage1 Do Begin
Recipients.EMailAddresses := 'XXXXX#gmail.com';
From.Address := 'XXXXX#gmail.com';
From.Name := edit_from.Text;
CCList.EMailAddresses := '';
BccList.EMailAddresses := '';
Priority := mpNormal;
Subject := edit_subject.Text;
Body.Add(memo_body.Lines.Text);
End;
With IdSMTP1 Do Begin
Host := 'smtp.gmail.com';
Username := 'XXXXX#gmail.com';
Password := '*****';
IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(Self);
Port := 465;
UseTLS := utUseImplicitTLS;
Try
Connect;
Except
End;
If Not Connected Then Begin
Showmessage('Error');
Exit;
End;
Try
Send(IdMessage1);
Finally
Disconnect;
End;
End;
It works fine on my computer but when i test it on other machines the 'ERROR' (Error in If block before last Try block) will be raised...
Where is the problem?
This is not the proper way to do error handling with Indy. It should be more like this instead:
With IdSMTP1 Do Begin
IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(Self);
UseTLS := utUseImplicitTLS;
Host := 'smtp.gmail.com';
Username := 'XXXXX#gmail.com';
Password := '*****';
Port := 465;
Try
Connect;
Try
Send(IdMessage1);
Finally
Disconnect;
End;
Except
Showmessage('Error');
Exit;
End;
End;
Send() and Disconnect() can fail just as easily as Connect() can. If you want Connect() to be in its own try/except block, then at least don't use Connected to validate whether Connect() succeeded:
Try
Connect;
Except
Showmessage('Error connecting');
Exit;
End;
Try
Try
Send(IdMessage1);
Finally
Disconnect;
End;
Except
Showmessage('Error sending');
Exit;
End;
That being said, the exception tells you what actually failed, so do not ignore it. Had you displayed its content, you would have had a better idea of what was failing, eg:
Except
on E: Exception do
Begin
ShowMessage(Format('Error!'#10'[%s] %s', [E.ClassName, e.Message]));
Exit;
End;
End;
The most likely culprit is that you did not deploy the OpenSSL DLLs with your app. You can download them from OpenSSL's website, or from Indy's Fulgan mirror.
I have this delphi code that basically download files from a secure server (using Indy build 10.5.8 r4743 if I'm not mistaken):
The problem is: I'm getting random "Socket Error # 0" exceptions that I couldn't get fix or even understand:
Project MyProject.exe raised exception class EIdSocketError with message 'Socket Error # 0
Stack is here, pascal code is:
IdHTTP := TIdHTTP.Create(nil);
TheSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
TheCompressor := TIdCompressorZLib.Create(nil);
TheCookieManager := TIdCookieManager.Create(IdHTTP);
try SetupWebComponents(IdHTTP, TheSSL, TheCompressor, TheCookieManager); except end;
TheCookieManager.OnNewCookie := MainForm.SyncNewCookie;
// Go!
Stream := TMemoryStream.Create;
try
IsError := False;
try
with IdHTTP do
begin
OnWork := MainForm.IdHTTPWork_Download;
try
try
IsNewFile := (Not FileExists(LocalFile));
if IsNewFile then
TheFile := TFileStream.Create(LocalFile, fmCreate)
else
// File already exist, resume download
TheFile := TFileStream.Create(LocalFile, fmOpenReadWrite);
DoExit := False;
// Use [ Request.Referer ] it to pass VersionGUID to Work event (to record download progress in db)
Request.Referer := VersionGUID;
repeat
// Get resume byte
if IsNewFile then
begin
ResumeByte := 0;
IsNewFile := False;
end
else
ResumeByte := GetResumeByteFromDB();
if FileExists(LocalFile) then
begin
// File already exist, resume download
DoExit := (ResumeByte >= TheFileSize);
TheFile.Seek(ResumeByte, soFromBeginning);
end;
// Save ResumeByte, it will be used to record download progress in db & eventually use it to resume downloads)
IdHTTP.Tag := ResumeByte;
Request.Range := IntToStr(ResumeByte) + '-';
Get(TheURL, TheFile);
IsError := (Not (ResponseCode in [200, 206])) OR (Pos('login', URL.Document) <> 0);
// Break if there's any error (to allow retrying later in a clean fashion)
if IsError then
Break;
until DoExit;
Disconnect;
except
if (ResponseCode = 404) then
begin
// File doesn't exist, get out
Result := False;
Exit;
end;
end; // try/except
finally
FreeAndNil(TheFile);
end; // try/finally
end; // with
except
IsError := True;
end; // try/except
finally
Stream.Free;
end;
I posted a similar question some time ago, but that was regarding upload, not download. The code was fixed since then with the kind help of SO members, and the same code (used to deal with cookies, re-login, etc...) is being used now so I assume the problem is really in the download procedure shown above
Can someone please take a look at this tell me what I'm doing wrong?
Just like with your other question, you should upgrade to a more recent version, if possible, and verify the problem still occurs before then asking for help. The current version is 10.5.9 r4861.
I had all kind of problems with Indy and following someone’s recommendations (at stackoverflow) I have updated to the latest version of Indy - at least this is what I intended to do.
Before starting the installation, I have manually deleted all files containing the "indy" word from my Delphi and from registry. Then I have followed the standard install procedure: http://www.indyproject.org/sockets/Docs/Indy10Installation.en.aspx
Now the piece of code below is not working anymore. The code just returns FALSE;
function Download(CONST aSourceURL: string; CONST aDestFileName: string; OUT aErrm: String): Boolean;
VAR
Stream: TMemoryStream;
IDAntiFreeze: TIDAntiFreeze;
fIDHTTP : TIDHTTP;
begin
fIDHTTP := TIDHTTP.Create(NIL);
// fIDHTTP.ConnectTimeout:=5000; <- not recognized
fIDHTTP.ReadTimeout:= 1000;
fIDHTTP.HandleRedirects := TRUE;
fIDHTTP.AllowCookies := FALSE;
fIDHTTP.Request.UserAgent := 'Mozilla/4.0';
fIDHTTP.Request.Connection := 'Keep-Alive';
fIDHTTP.Request.ProxyConnection := 'Keep-Alive';
fIDHTTP.Request.CacheControl := 'no-cache';
IDAntiFreeze := TIDAntiFreeze.Create(NIL);
Stream := TMemoryStream.Create;
TRY
TRY
fIDHTTP.Get(aSourceURL, Stream);
{
if FileExists(aDestFileName)
then DeleteFile(PWideChar(aDestFileName)); }
Stream.SaveToFile(aDestFileName);
Result:= TRUE;
EXCEPT
On E: Exception do
begin
Result:= FALSE;
aErrm := E.Message + ' (' + IntToStr(fIDHTTP.ResponseCode) + ')';
end;
END;
FINALLY
Stream.Free;
IDAntiFreeze.Free;
fIDHTTP.Free;
END;
end;
There is any way to see which version of Indy I have installed?
Edit:
Also I get an "Unit idHTTP was compiled with a different version of IdException.IdException" message. Fixed.
You should first use the Delphi setup to uninstall the version of Indy that is installed with Delphi - then you can cleanup any remaining file. You should not start by cleaning folders and registry by hand.
Then you can install another version. Be aware some releases are "breaking"