On a blank Delphi 11 project I dropped a button and an TIdHTTP component.
The button attempts to get a .txt file.
procedure TForm1.Button1Click(Sender: TObject);
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
try
IdHTTPGetProgramUpdateFile.Get('https://www.bookup.com/cowupdates/build129.txt',
Stream);
except
on E: Exception do
begin
MessageDlg(E.Message,
TMsgDlgType.mtInformation,
[TMsgDlgBtn.mbOK],
E.HelpContext);
end;
end;
Stream.SaveToFile('downloaded.txt');
Stream.Free;
end;
If the Windows project requests the URL with https then the error is "Could not load SSL Library."
If the project on Windows or Macintosh requests the URL with http then the error is "301 Moved Permanently". (The file is on the web site.)
If the project is run on a Macintosh with https then the PAServer reports the project "is loading libcrypto in an unsafe way."
When running for Windows, the project throws an exception in IdSSLOpenSSL.pas
with the source code comment:
an exception here probably means that you are using the wrong version of the openssl libraries. refer to comments at the top of this file.
The comments at the top of the file were not useful to me.
I'm trying to download the contents of a text file from a web site and I know very little about the internet protocols. What am I missing?
CodePudding user response:
If the Windows project requests the URL with https then the error is "Could not load SSL Library."
You are relying on TIdHTTP
using Indy's default TIdSSLIOHandlerSocketOpenSSL
component, which depends on OpenSSL 1.0.2 library files (ie, libeay32.dll
and ssleay32.dll
, etc), so make sure you deploy those files with your app, preferably in your app's installation folder. Or, if needed, Indy does have an IdOpenSSLSetLibPath()
function you can call at app startup to specify an alternate folder path where the libs are located.
If the project on Windows or Macintosh requests the URL with http then the error is "301 Moved Permanently". (The file is on the web site.)
301
is a redirect response. The server is telling you that the URL you have requested is old and the resource is available at a different URL (in this case, it is probably redirecting you to the HTTPS url), which will be provided to you in the TIdHTTP.Response.Location
property, and in the TIdHTTP.OnRedirect
event.
If you have TIdHTTP.HandleRedirects
set to true
(it is false
by default) then TIdHTTP
will automatically re-request the new URL for you. Otherwise, it will treat the 301
as an error condition, and you will have to manually request the new URL yourself.
If the project is run on a Macintosh with https then the PAServer reports the project "is loading libcrypto in an unsafe way."
By default, on 'Nix-based systems, Indy attempts to load the OpenSSL library files using unversioned symlinks, and if that fails then it falls back to loading specific versioned library files instead. Using symlinks is not safe because they may map to library versions you are not expecting. For instance, on modern systems, the OpenSSL unversioned symlinks may map to library files for OpenSSL 1.1.x or later, which TIdSSLIOHandlerSocketOpenSSL
does not support (use this SSLIOHandler instead). Indy has IdOpenSSLSetCanLoadSymLinks()
and IdOpenSSLSetLoadSymLinksFirst()
functions that you can call at app startup to prevent Indy from attempting to load symlinks. Then you can deploy specific versioned library files with your app, or point Indy to a folder where they reside.
When running for Windows, the project throws an exception in
IdSSLOpenSSL.pas
with the source code comment:an exception here probably means that you are using the wrong version of the openssl libraries. refer to comments at the top of this file.
The comments at the top of the file were not useful to me.
You can use Indy's WhichFailedToLoad()
function after the error occurs to find out whether Indy failed to load OpenSSL because the library files failed or load, or they were missing required function exports.