0

I would like to retrieve results of Google search by Lazarus component TIdHTTP, part of Indy.

I have seen this already. I can use CUrl to retrieve some results.

To do the same with TIdHTTP, I have this :

queries:= TStringList.Create;
engine := 'http://www.google.com/search';
queries[0] := '?q=inurl:"foo"';
for i := 0 to queries.Count-1 do
begin
  Memo1.Lines.Add('Asking for : ' + engine + queries[i]);
  try
     IdHTTP1.Get(engine+queries[i], response);
     response.Position := 0;
     Memo2.Lines.LoadFromStream(response);
  finally
    response.Free;
  end;
end;              

The IdHTTP component's UserAgent property is set to Firefox/12.0 (property browser > request > UserAgent > Firefox/12.0 with upper case F). However, that is giving me this error :

"Project project1 raised exception class EIdIOHandlerPropInvalid with the message 'IOHandler value is not valid'"

In file 'xyz ... IdHTTP.pas at line 939
raise EIdIOHandlerPropInvalid.Create(RSIOHandlerPropInvalid)

That was translated from German to English.

Googling the error leads to this question on SO. I realize that it has something to do with an http request being redirected to an https server. However, the answer to the other SO question is targeted on windows platform.

Question:

Could anyone please help me to tell me how to implement the same on Linux platform where the mentioned DLLs (libeay32.dll, ssleay32.dll) do not exist?

I have tried out the solution without caring for the DLLs - it results in a new error :

"Project project1 has raised exception class EIdOSSLCouldNotLoadSSLLibrary with the message 'Couldn't load SSL library'"

Note:

core/openssl 1.0.2.k-1 is installed. Linux is Manjaro (64-bit).

Community
  • 1
  • 1
Sean
  • 789
  • 6
  • 26
  • You can use Indy's `WhichFailedToLoad()` function in the `IdSSLOpenSSLHeaders` unit to find out which library failed/not found. – RepeatUntil Apr 02 '17 at 22:51
  • @RepeatUntil OP is asking how to use the `libeay32.dll` and `ssleay32` libraries on a Linux platform. Speaking of which, most of the question's content is misleading to this point. It's mostly irrelevant, and we don't need to know that it has anything to do with Google Search, for example. – Jerry Dodge Apr 02 '17 at 22:57
  • 1
    @JerryDodge In short he can't use Win DLLs on linux, @Sean try to install both libssl and libcrypto using the following commands as root `pacman -Syu lib32-openssl` – RepeatUntil Apr 02 '17 at 23:02
  • @RepeatUntil I was literally typing the same thing just now, about how Windows DLL's cannot be used on Linux. OP needs the Linux equivalent. – Jerry Dodge Apr 02 '17 at 23:03
  • @RepeatUntil How should one recognize in future that the problem may lie in the 32 bit option? – Sean Apr 02 '17 at 23:04
  • @Both, yes, indeed we can't use DLLs in linux - thus i was wondering may be there is a *.so file i missed and/or there is a way to avoid this while working with google altogether – Sean Apr 02 '17 at 23:05
  • @RepeatUntil - i checked, and lib32-openssl is installed already. – Sean Apr 02 '17 at 23:08
  • Try a call to IdSSLOpenSSL.LoadOpenSSLLibrary first. – FredS Apr 03 '17 at 04:58
  • @FredS: You usually don't need to call `LoadOpenSSLLibrary()` manually, since Indy calls that internally for you. But you might need to call `IdOpenSSLSetLibPath()` instead, depending on where OpenSSL is installed. – Remy Lebeau Apr 03 '17 at 16:26
  • @RepeatUntil - whichfailedtoload leads to SSLV3_method, SSLV3_server_method and SSLV3_client_method – Sean Apr 03 '17 at 23:55

1 Answers1

2

EIdIOHandlerPropInvalid means TIdHTTP was instructed to send an HTTPS request but the TIdHTTP.IOHandler property had not been assigned an SSLIOHandler component (such as TIdSSLIOHandlerSocketOpenSSL) to handle the encryption.

Since you are sending a request to an HTTP URL, that means the server must be sending back an HTTP redirect to an HTTPS URL, and you have the TIdHTTP.HandleRedirects property set to true.

You must assign an SSLIOHandler component in order for TIdHTTP to send HTTPS requests. Had you sent a request directly to an HTTPS URL, TIdHTTP could handle that assignment for you (see this blog article for details), but since you are sending to an HTTP URL first, you will have to assign the IOHandler manually beforehand.

The solution you read about for Windows will also work for other platforms, including Linux. You just have to distribute the appropriate OpenSSL binaries if they don't already exist (Linux uses .so files, not .dll files), and optionally call Indy's IdOpenSSLSetLibPath() function at runtime to let Indy know where the binaries are located.

You are not limited to OpenSSL specifically. That just happens to be Indy's default SSL/TLS library of choice. But you can use any SSL/TLS library you want, as long as you can find (or write) a custom TIdSSLIOHandlerSocketBase-derived class to wrap it. Some 3rd party SSL/TLS libraries do provide an Indy IOHandler class (for instance, Eldos SecureBlackBox).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I have done : uses ......... IdSSLOpenSSLHeaders ; IdSSLOpenSSLHeaders.IdOpenSSLSetLibPath('path'); This gives : `unit1.pas(111,1) Error: Identifier not found "IdOpenSSLSetLibPath"` – Sean Apr 03 '17 at 23:25
  • Some more search has found out, that these three lines : `@IdSslMethodV3 := LoadFunction(fn_SSLv3_method); @IdSslMethodServerV3 := LoadFunction(fn_SSLv3_server_method); @IdSslMethodClientV3 := LoadFunction(fn_SSLv3_client_method);` are the culprits. Loadfunction has them as critical, and `Result := GetProcAddress(hIdSSL, PChar(FceName));` is returning nil. What do? – Sean Apr 04 '17 at 00:21
  • @Sean: You are using a build of OpenSSL that was compiled without SSLv3 enabled, but you are using a *very* outdated version of Indy that requires it (and I know it is outdated because `IdSslMethodV3`, `IdSslMethodServerV3`, and `IdSslMethodClientV3` were renamed 7 years ago, and the SSLv2, SSLv3, and SSLv23 functions were updated to non-critical 2 years ago). Please upgrade to an up-to-date version of Indy. – Remy Lebeau Apr 04 '17 at 01:18
  • I downloaded the 10.2.0.3 from here http://www.indyproject.org/Sockets/fpc/indy-10.2.0.3.tar.gz - what am I missing? – Sean Apr 04 '17 at 01:39
  • The current version of Indy is 10.6.2, and it has had native support for FPC built-in for a long time. That FPC page and download is *VERY VERY OLD*. – Remy Lebeau Apr 04 '17 at 01:40
  • I can't seem to find the link to download indy 10.6.2 by a google search. could you please share a link? – Sean Apr 04 '17 at 01:44
  • @Sean: if you re-read the same [FPC page](http://www.indyproject.org/Sockets/fpc/index.aspx) more carefully, it tells you exactly where to download from: "***Download source from the [Development Snapshot](http://www.indyproject.org/Sockets/Download/DevSnapshot.aspx)** ...*". You didn't read the description above the 10.2.0.3 download carefully enough: "***An older code** from the version control system that was organized into a sensible distribution. **This was updated on 11/13/2007**.*" Don't use the download that is 10 years old. – Remy Lebeau Apr 04 '17 at 01:56
  • I am sorry for again asking the stupid question. I **did** check it, but http://subversion.tigris.org/ is locked, and the nightly zips (https://indy.fulgan.com/ZIP/) only have up to indy10.5.4 - but not 10.6. thus I went for google, and got even more confused. – Sean Apr 04 '17 at 02:10
  • 1
    @Sean look at indy.fulgan.com again, it is updated *daily* with the latest snapshot. Again, please read the download instructions more carefully: "*Note: when downloading Indy10_XXXX.zip, **XXXX specifies the SVN revision number** that it contains.*" so `Indy10_5410.zip` is not Indy 10.5.4, it is Indy 10 SVN revision 5410, and the ZIP is dated earlier today. – Remy Lebeau Apr 04 '17 at 03:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139915/discussion-between-sean-and-remy-lebeau). – Sean Apr 05 '17 at 02:11