HTTP is stateless, so it is possible that the TCP connection is closed at the end of the HTTP response, in which case TIdHTTP would close the socket before DoRequest() exits. Check if the Binding.HandleAllocated property is true before calling SetKeepAliveValues():
procedure TCustomActionCallerThread.Execute;
begin
V_CONNECTION.IndyHttpClient.Socket.Binding.SetKeepAliveValues(True, FTCPKeepAlive, FTCPKeepAlive);
Try
...
Finally
if V_CONNECTION.IndyHTTPClient.Socket.Binding.HandleAllocated then
V_CONNECTION.IndyHTTPClient.Socket.Binding.SetKeepAliveValues(False, 0, 0);
End;
end;
In fact, because HTTP is stateless, it is possible that there is no TCP connection yet when DoRequest() is called, in which case TIdHTTP would have to call Connect() internally. So, you will have to account for that, as well:
procedure TCustomActionCallerThread.Execute;
begin
if V_CONNECTION.IndyHTTPClient.Socket.Binding.HandleAllocated then
V_CONNECTION.IndyHttpClient.Socket.Binding.SetKeepAliveValues(True, FTCPKeepAlive, FTCPKeepAlive);
Try
...
Finally
if V_CONNECTION.IndyHTTPClient.Socket.Binding.HandleAllocated then
V_CONNECTION.IndyHTTPClient.Socket.Binding.SetKeepAliveValues(False, 0, 0);
End;
end;
In case there is no TCP connection yet before DoRequest() is called, you would have to use TIdHTTP's OnSocketAllocated, OnAfterBind, OnConnected, or OnStatus event to know when the Binding has a new socket assigned before you can then call SetKeepAliveValues() on it (there are no events to indicate when each HTTP request is started/finished).
That is not a guarantee. An HTTP keep-alive is a request from the client to the server, but the server is not obligated to honor that request. It is the server's decision whether the TCP connection stays open or not after the response is sent. Look at the TIdHTTP.Response.KeepAlive property after DoRequest() exits, if it is false then TIdHTTP would have closed the socket.
In recent years, I don't know which Indy revision has gone into each IDE release. When Indy was using SVN, I would tag each revision that Embarcadero released. But after Indy switched to GitHub (consequently losing its build numbers), I haven't been tagging the releases anymore. I do know that there were like a dozen checkins made to Indy between Delphi 10.4.0, 10.4.1, and 10.4.2. But offhand, I don't see anything in the change history that should affect handling of the underlying socket as you describe. However, Indy's source code is included with each IDE release, so you should be able to do a local diff between the versions.