0

I have what seems to be a simple task - to make an HTTPS request, but I encountered an error:

Socket Error #10054 Connection reset by peer

Moreover, this error does not occur every time; out of 30 attempts, it may occur 2-3 times, maybe once, or not at all.

I'm using Delphi XE7. I have already tried using the latest DLL files from the Indy library, but it didn't have any effect. I obtained the DLL files from here: https://indy.fulgan.com/SSL/

Here is my code:

try
  IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  with IdSSLIOHandlerSocketOpenSSL1 do
  begin
    //SSLOptions.Method := sslvTLSv1_1;  //sslvSSLv23
    SSLOptions.SSLVersions := [sslvSSLv2, sslvSSLv3, sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
    SSLOptions.Mode := sslmClient;
    SSLOptions.VerifyMode := [];
    SSLOptions.VerifyDepth := 0;
  end;
except
  on E: Exception do
    Showmessage(e.Message);
end;
try
  IdHTTP1 := TIdHTTP.Create(nil);
  with IdHTTP1 do
  begin
    IOHandler := IdSSLIOHandlerSocketOpenSSL1;
    AllowCookies := True;
    HandleRedirects := true;
    ProxyParams.BasicAuthentication := false;
    ProxyParams.ProxyPort := 0;
    Request.CharSet := 'utf-8';
    Request.ContentType := 'application/json';
    Request.Ranges.Units := 'bytes';
    HTTPOptions := [];
    Intercept := IdLogEvent1;
    IOHandler.DefStringEncoding := enUTF8;
  end;
  //IdLogEvent1.Active := True;
except
  on E: Exception do
    ShowMessage(e.Message);
end;
cnt := 0;
repeat
  try
    if IdHTTP1 = nil then
      createIDHTTP;

    auth := ConvertToBase64('login1'+':'+'pass1');
    IdHTTP1.Request.CustomHeaders.FoldLines := False;
    IdHTTP1.Request.CustomHeaders.Clear;
    IdHTTP1.ConnectTimeout := 10000;
    IdHTTP1.Request.CustomHeaders.Add('Authorization: Basic ' + auth);
    IdHTTP1.Request.CustomHeaders.Add('User-Agent: PostmanRuntime/7.29.2');
    IdHTTP1.Request.CustomHeaders.Add('Accept: */*');
    IdHTTP1.Request.CustomHeaders.Add('Accept-Encoding: gzip, deflate, br');
    IdHTTP1.Request.CustomHeaders.Add('Connection: keep-alive');

    res := IdHTTP1.Get('https://isms.center/api/sms/report?message_id=61');
    memo2.Lines.Add(cnt.ToString() + ' ' +  GetJSONValue(res, 'status'));
    Sleep(1000);
  except
    on E: Exception do
    begin
      memo2.Lines.Add(cnt.ToString() + ' ' +  e.ClassName + ' error: ' + e.Message);
    end;
  end;
  DestroyIDHTTP;
  Inc(cnt);
until cnt > 30;

Where did I go wrong?

Aidyn
  • 5
  • 1
  • 3
  • The code you have posted is not really a [mre](https://stackoverflow.com/help/minimal-reproducible-example). The two blocks of code are incomplete and it is unclear how they are related. Sure, we can guess, but that is not how SO works. Read the link, and note what is said about completeness. – Tom Brunberg Jun 30 '23 at 06:47

1 Answers1

3

XE7 was released almost a decade ago. If you are using the version of Indy that shipped with it, then you need to upgrade to the latest version from Indy's GitHub repo (see Updating Indy).

Also, the Fulgan mirror was decommissioned several years ago, so make sure you are using OpenSSL DLLs from Indy's OpenSSL binaries GitHub repo. The TIdSSLIOHandlerSocketOpenSSL component supports up to OpenSSL 1.0.2u.

As for the code you have shown, I see a few problems with it:

  • you should not be enabling sslvSSLv2 or sslvSSLv3 at all, as they represent dead SSL versions that were compromised a long time ago. Nobody uses them anymore.

  • you should not be using the TIdHTTP.Request.CustomHeaders property to setup any of the HTTP headers you are configuring. TIdHTTP has properties for all of those headers.

  • you should not be telling the server that you accept the gzip, deflate, or br encodings, since your code is not setup to actually handle them at all. In fact, don't even set the Accept-Encoding header manually at all, let TIdHTTP manage that internally for you. The correct way to accept compressed responses is to assign a TIdZLibCompressorBase-derived component to the TIdHTTP.Compressor property, such as TIdCompressorZLib.

After making sure you have everything up to date, try this code instead:

try
  IdHTTP1 := TIdHTTP.Create(nil);
  IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
  with IdSSLIOHandlerSocketOpenSSL1 do
  begin
    SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
    SSLOptions.Mode := sslmClient;
    SSLOptions.VerifyMode := [];
    SSLOptions.VerifyDepth := 0;
    DefStringEncoding := enUTF8;
  end;
  with IdHTTP1 do
  begin
    ConnectTimeout := 10000;
    AllowCookies := True;
    HandleRedirects := True;
    HTTPOptions := [hoInProcessAuth];
    Request.BasicAuthentication := True;
    IOHandler := IdSSLIOHandlerSocketOpenSSL1;
    Intercept := IdLogEvent1;
  end;
  //IdLogEvent1.Active := True;
except
  on E: Exception do
    ShowMessage(e.Message);
end;
cnt := 0;
repeat
  try
    if IdHTTP1 = nil then
      createIDHTTP;

    IdHTTP1.Request.Clear;
    IdHTTP1.Request.Username := 'login1';
    IdHTTP1.Request.Password := 'pass1';
    IdHTTP1.Request.UserAgent := 'PostmanRuntime/7.29.2';
    IdHTTP1.Request.Accept := '*/*';
    IdHTTP1.Request.Connection :='keep-alive';

    res := IdHTTP1.Get('https://isms.center/api/sms/report?message_id=61');
    memo2.Lines.Add(cnt.ToString() + ' ' +  GetJSONValue(res, 'status'));
    Sleep(1000);
  except
    on E: Exception do
    begin
      memo2.Lines.Add(cnt.ToString() + ' ' +  e.ClassName + ' error: ' + e.Message);
    end;
  end;
  DestroyIDHTTP;
  Inc(cnt);
until cnt > 30;
Aidyn
  • 5
  • 1
  • 3
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank for answer! But it's not clear for me about username and password. API needs "Content-type" and "Authorization" headers, here is their doc: `Authorization: Basic base64.encode(login:password)` – Aidyn Jun 30 '23 at 09:44
  • 1
    @Aidyn The `Content-Type` header is not used in a `GET` request, as there is no body being sent. Setting `Request.BasicAuthentication=True` and providing `Request.Username` and `Request.Password` will handle the `Authorization: Basic` header for you, including the base64 portion. – Remy Lebeau Jun 30 '23 at 19:38
  • Yes, I already found it out =) thanks. I've tried your code yesterday on Delphi 11.3 Alexandria - and result was the same. The error may occur 2-3 times, maybe not at all. I guess it is problem on the hosts side? – Aidyn Jul 01 '23 at 08:53