Delphi 2010 - Wininet running out of handles
Asked Answered
D

2

6

I have an app that makes intensively uses of Wininet functions to get some data from internet. I am getting a very odd handle related error messages sometimes:

Internal error in ConnectToHost when trying to create a session 
ERROR_INTERNET_OUT_OF_HANDLES: No more handles could be generated at this time. Wininet error code = 12001;

When this occured i noticed that my application had more than 5000 handles created. I ran a resource profile and I found out that some handles created by wininet were not being freed.

So, I created a small application to reproduce the issue. The code is simple and does nothing but allocate some wininet handles and then free them. That is the code:

procedure request(const AUrl : AnsiString);
var
  sMethod     : AnsiString;
  pSession    : HINTERNET;
  pConnection : HINTERNET;
  pRequest    : HINTERNET;
  port        : Integer;
  flags       : DWord;
begin
  pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if Assigned(pSession) then
  try
    Port := INTERNET_DEFAULT_HTTP_PORT;
    pConnection := InternetConnectA(pSession, PAnsiChar(AUrl), port, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
    if Assigned(pConnection) then
      try
        sMethod := 'GET';
        flags := INTERNET_SERVICE_HTTP;
        pRequest := HTTPOpenRequestA(pConnection, PAnsiChar(sMethod), PAnsiChar(AUrl), nil, nil, nil, flags, 0);
        try
          if Assigned(pRequest) then
            ShowMessage('ok');
        finally
          InternetCloseHandle(pRequest);
        end;
      finally
        InternetCloseHandle(pConnection);
      end;
  finally
    InternetCloseHandle(pSession);
  end;
end;

Running this sample on my profiler, I get the same handle related issues.

I think that InternetCloseHandle is not freeing the handle as it should be because my resource profile tells me that I have 3 live handles when I close the application. Those are the handles that are not being freed:

pRequest
pConnection
pSession

Does anyone know how to get rid of this?

EDIT

The function InternetCloseHandle is working fine, the return value is true.

EDIT

I have searched a lot on the internet, but i was not able to find anybody complaining about that. But it is happening. I would like to know if anybody reproduced the issue or if it is just me.

Degradation answered 3/8, 2011 at 21:14 Comment(6)
AqTime: smartbear.com/products/development-tools/performance-profilingDegradation
You should avoid opening and closing handles if you're doing thousands of requests(IMHO), try opening a handle, do your stuff, and later reuse it, when application closes, close the handle and voila. However, if you're code is executed within a thread, then it's a different story, rethink the process and think of the fastest solution, I couldn't find someone else complaining about this error, I haven't searched too much tho'...Crowley
@Dorin Theres nothing I can do. Wininet needs some handles to be created per request, so i must create them and free them. The strange thing is, i was unable to find anybody complaining about that either. But the profiler is not lying, theres something wrong with InternetCloseHandle.Degradation
maybe use TIdHTTP and see if you experience the same result? I know it uses almost the same API calls, but there must be something we're missing, can you reproduce the issue on multiple PC/VM's?Crowley
I just ran a test(in Delphi XE), a simple loop which makes 30,000 http requests using your exact code, had no issue whatsoever, I assume you're doing something else in the code with a handle, it would be helpful if you would post the entire request code, otherwise it's a pain to try to assume what the issue might be.Crowley
I am having this issue with the code I posted here. Nothing changed, just that code. I am guessing that the problem is with AQTime. I will try some other program today. And btw, indy has no problem and works fine.Degradation
D
2

It turned out to be a AQtime problem. I downloaded another profiler and I also took a look at Task Manager and it seems that the handles are being released. But I still get the no more handles error sometimes and I have no idea why. But I will open another question, since this one was just to see why those handles were not being released.

Thanks for all help I got.

Degradation answered 5/8, 2011 at 13:12 Comment(2)
Hi Refael! Thanks for posting this question - the SmartBear Development Team was able to find the cause of the problem, and fix it. If you want to get a fix to get rid of the issue, please feel free to contact SmartBear Technical Support ( smartbear.com/support/message/?prod=AQtime ) and refer to this thread.Combined
No problem! Glad I could help. Thanks for having such a good support team.Degradation
A
-1

The Http protocol has some limits and the Wininet is using them. Check at WinInet limits connections per server:

WinInet limits connections to a single HTTP 1.0 server to four simultaneous connections. Connections to a single HTTP 1.1 server are limited to two simultaneous connections. The HTTP 1.1 specification (RFC2616) mandates the two-connection limit. The four-connection limit for HTTP 1.0 is a self-imposed restriction that coincides with the standard that is used by a number of popular Web browsers.

Maybe you should wait until connections are closed before attemping a new connection

Athodyd answered 3/8, 2011 at 21:34 Comment(4)
Sorry, but that is not what I asked. I am making connections to different servers. Also, I am setting INTERNET_OPTION_MAX_CONNS_PER_SERVER INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER to make sure. My connections are not in a thread. My code makes 1 connection at a time. But thanks anyway.Degradation
ok, did you tried check the return values at InternetCloseHandle?Athodyd
No, i did not. It was supposed to work but I will take a look at it.Degradation
InternetCloseHandle is working fine. The return value is true.Degradation

© 2022 - 2024 — McMap. All rights reserved.