1

When working with Binance REST API using WinHTTP, I noticed that requests sometimes are failed with the error

12030 the connection with the server was terminated abnormally

Each request is made like this: (the complete example is here)

WinHttpOpen(...)
WinHttpConnect(...)
{... making request itself;   }
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);

However, despite I close handles, the connection is reused (which I see in the HttpAnalyzer).

I suppose that this is the issue: the server starts dropping connection after N requests or seconds, accoring to server's keep-alive settings; At the same moment my client starts new request which failed with 12030.

Moreover. inspesting successful requests headers, I noticed that

Connection: Close

is passed from the server from time to time; I'd like to reconnect in such cases.

The question is: how do I prevent WInHTTP from trying to reuse connection which is about to be dropped by server?

Changing the registry "TcpTimedWaitDelay" parameter would not be efficient because request count per time may vary.

The same quesstion is actual for Delphi TNetHTTPClient (which uses WinHTTP) and Indy TIdHTTP.

As for Indy, releasing of the TIdHTTP object does not close the connection; however in this case we have source codes. The following patch in the IdSSLOpenSSL.pas solves it:

If SSL_shutdown(fSSL) = 0
  then SSL_shutdown(fSSL);
//    SSL_shutdown(fSSL); <= was in original Indy10 IdSSLOpenSSL
  • "*As for Indy, releasing of the TIdHTTP object does not close the connection*" - yes, it does, as the socket is closed by `TIdHTTP`'s destructor if it is still open. – Remy Lebeau Dec 14 '20 at 18:36
  • AFAIK, WinHTTP does not have any flags for controlling connection reuse (WinInet does, though they are for *enabling* reuse, not *disabling* it). You might try manually using [`WinHTTPAddRequestHeaders()`](https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpaddrequestheaders) to manually add a `Connection: close` header to your HTTP request, which will instruct the server to close the connection after sending the response. You can do the same thing in `TIdHTTP` via the `TIdHTTP.Request.Connection` property. – Remy Lebeau Dec 14 '20 at 18:41
  • @RemyLebeau Thanks, indeed TIdHTTP does close the connection. I observed it firstly in the httpAnalyzer, w/o it second SSL_shutdown not needed. So the only way to disconnect is to use TIdHTTP - the `Connection: close` header wouldn't work cause may lead to the same issue (at least with binance API:) - server close the connection while client issue new request... – Mike Mercer Dec 15 '20 at 14:00
  • per the HTTP spec, if a client issues `Connection: close` in a request, the server is *required* to issue the same in the response and actually close its end of the connection after sending the response. Regardless of the request, if a server sends `Connection: close`, the client is *required* to actually close its end of the connection upon receiving the response. I find it very unlikely that WinHTTP would not do this correctly. – Remy Lebeau Dec 15 '20 at 15:35

0 Answers0