2

I'm trying to load a TImage starting from an URL as explained in this answer.

uses
  GIFImg;

procedure TForm1.Button1Click(Sender: TObject);
var
  Stream : TMemoryStream;
  GIF : TGIFImage;
begin
  Stream := TMemoryStream.Create;
  GIF := TGIFImage.Create;
  try
    IdHTTP1.Get('http://www.google.com/intl/en_ALL/images/logo.gif', Stream);
    //IdHTTP1.Get('https://www.google.com/intl/en_ALL/images/logo.gif', Stream);

    Stream.Position := 0;
    GIF.LoadFromStream(Stream);

    Image1.Picture.Assign(GIF);

  finally
    FreeAndNil(GIF);
    FreeAndNil(Stream);
  end;
end;

All works good if the URL starts with a simple HTTP.

When I try to load from an HTTPS URL, I get an EIdIOHandlerPropInvalid exception with message:

IOHandler value is not valid.

I've tried adding a TIdSSLIOHandlerSocketOpenSSL and setting it as IOHandler for the TIdHTTP component.

enter image description here enter image description here

After doing that, I get an EIdOSSLCouldNotLoadSSLLibrary exception with the following message:

Could not load SSL library.

Is there something wrong in the properties or some other problem?

Fabrizio
  • 7,603
  • 6
  • 44
  • 104

2 Answers2

8

You need the SSL library (two .DLL files) either installed in your Windows, or distributed along with your application.

Seems to be downloadable here:

https://slproweb.com/products/Win32OpenSSL.html

Or via their official web site (but I can't find downloadable binaries there - only source code):

https://www.openssl.org/source/

Pre-compiled .DLLs for use with Indy can be downloaded here:

https://indy.fulgan.com/SSL/ (Thanks, Zed)

HeartWare
  • 7,464
  • 2
  • 26
  • 30
5

When I try to load from an HTTPS URL, I get an EIdIOHandlerPropInvalid exception with message:

IOHandler value is not valid.

That error means you don't have an TIdSSLIOHandlerSocketBase-derived component attached to the TIdHTTP.IOHandler property, such as TIdSSLIOHandlerSocketOpenSSL.

This error also tells me that you are using an outdated version of Indy and need to upgrade. TIdHTTP automatically creates a default SSLIOHandler when requesting an HTTPS url and no IOHandler is currently assigned, and has done so for a long time.

I've tried adding a TIdSSLIOHandlerSocketOpenSSL and setting it as IOHandler for the TIdHTTP component.

That is the correct solution, if you do not want to upgrade, or if you need to customize the SSLIOHandler settings, such as for enabling TLS 1.1+ (which TIdSSLIOHandlerSocketOpenSSL does not do by default yet).

After doing that, I get an EIdOSSLCouldNotLoadSSLLibrary exception with the following message:

Could not load SSL library.

That error means that either

  • you have not deployed the OpenSSL DLLs (libeay32.dll and ssleay32.dll) with your app, or at least have them installed somewhere on your system's DLL search path.

  • you are using a version of the DLLs that is incompatible with your version of Indy. The current version of Indy supports OpenSSL 1.0.2 and earlier (support for OpenSSL 1.1.x is currently a work in progress).

After the error is raised, you can use Indy's WhichFailedToLoad() function in the IdSSLOpenSSLHeaders unit to determine the root cause of the failure - whether the DLLs themselves could not be loaded in memory (because they were not found, etc), or because they are missing specific exports that Indy requires.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • My application is 32 bit, I've placed in the executable folder the `libeay32.dll` and `ssleay32.dll` downloaded from _openssl-1.0.2q-i386-win32.zip_ at [this page](https://indy.fulgan.com/SSL/). After the error `WhichFailedToLoad` function results: `SSL_CTX_set_info_callback_indy X509_STORE_CTX_get_app_data_indy X509_get_notBefore_indy X509_get_notAfter_indy SSL_SESSION_get_id_indy SSL_SESSION_get_id_ctx_indy SSL_CTX_get_version_indy SSL_CTX_set_options_indy des_set_odd_parity des_set_key des_ecb_encrypt` – Fabrizio Sep 20 '19 at 10:34
  • I suspect that the DLLs are not compatible with my Indy version. I'm using the Indy version shipped with Delphi-2007 and in my design installed packages I can see "Indy 10 Core Design Time" and "Indy 10 Protocols Design Time". How can I know which is the right OpenSSL version for my Indy version? – Fabrizio Sep 20 '19 at 10:40
  • I've downloaded the two DLLs from `indy_openssl096k.zip` at [this page](https://indy.fulgan.com/SSL/Archive/). After this, the error is now `EIdOSSLConnectError` with message 'Error connecting with SSL.' and `WhichFailedToLoad()` results an empty string. – Fabrizio Sep 20 '19 at 10:51
  • @Fabrizio you are using an EXTREMELY OLD version of Indy. Indy stopped using the `..._indy` DLL functions many many years ago. They were custom functions added to early versions of OpenSSL's source code for Indy to access internal data for which standard APIs have since been added in later versions of OpenSSL. You need to upgrade your version of Indy in order to use official OpenSSL DLLs. The [current version](https://indy.fulgan.com/ZIP/) of Indy is 10.6.2.5517, and the latest version of OpenSSL supported by it is 1.0.2t. The `..._indy` functions don't exist in any OpenSSL DLLs beyond 0.9.6k – Remy Lebeau Sep 20 '19 at 15:12