I had this function that worked for HTTP. Now, with the wide spread of HTTPS it didn't work anymore. I was getting an "IOHandler value is not valid" error.
So, I created an SSLIOHandler object as shown below, but now I get a new error:
Exception class EIdOSSLUnderlyingCryptoError with message 'Error connecting with SSL. error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version'
How do I setup the SSLIOHandler object properly?
{ Only suitable for small files because the whole download will be saved to RAM before writing it to disk. }
function DownloadFile(CONST SourceURL, DestFileName: string; OUT ErrorMsg: String): Boolean;
VAR
Indy: TIDHTTP;
Stream: TFileStream;
IDAntiFreeze: TIDAntiFreeze;
IOHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
Indy:= TIDHTTP.Create(NIL);
IOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(NIL);
IDAntiFreeze:= TIDAntiFreeze.Create(NIL);
Stream:= TFileStream.Create(DestFileName, fmCreate);
TRY
IOHandler.Destination := SourceURL;
IOHandler.Host := SourceURL;
IOHandler.MaxLineAction := maException;
//IOHandler.Port := 587;
//IOHandler.DefaultPort := 0;
//IOHandler.OnStatusInfo := SSLIOHandlerStatusInfo;
Indy.ConnectTimeout := 0; { Indy default value: zero }
Indy.ReadTimeout := -1; { Indy default value: -1 }
Indy.HandleRedirects := TRUE; { http://stackoverflow.com/questions/4549809/indy-idhttp-how-to-handle-page-redirects }
Indy.AllowCookies := FALSE;
Indy.Request.UserAgent := 'Mozilla/4.0';
Indy.Request.Connection := 'Keep-Alive';
Indy.Request.ProxyConnection := 'Keep-Alive';
Indy.Request.CacheControl := 'no-cache';
Indy.IOHandler:= IOHandler;
// Indy.OnWork:= HttpWork;
TRY
Indy.Get(SourceURL, Stream);
Result:= TRUE;
EXCEPT
On E: Exception DO
begin
Result:= FALSE;
ErrorMsg := E.Message + ' (' + IntToStr(Indy.ResponseCode) + ')';
end;
END;
FINALLY
FreeAndNil(Stream);
FreeAndNil(IDAntiFreeze);
FreeAndNil(IOHandler);
FreeAndNil(Indy);
END;
end;
PS: The libeay32.dll
and ssleay32.dll
are present in the app's folder.