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.

Alex
  • 587
  • 3
  • 9
Rafael Colucci
  • 6,018
  • 4
  • 52
  • 121
  • AqTime: http://smartbear.com/products/development-tools/performance-profiling/ – Rafael Colucci Aug 03 '11 at 22:01
  • 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'... –  Aug 04 '11 at 05:03
  • 1
    @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. – Rafael Colucci Aug 04 '11 at 13:47
  • 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? –  Aug 04 '11 at 13:59
  • 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. –  Aug 04 '11 at 14:53
  • 1
    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. – Rafael Colucci Aug 04 '11 at 16:50

2 Answers2

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.

Rafael Colucci
  • 6,018
  • 4
  • 52
  • 121
  • 1
    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 ( http://smartbear.com/support/message/?prod=AQtime ) and refer to this thread. – Alex Sep 20 '11 at 11:42
  • No problem! Glad I could help. Thanks for having such a good support team. – Rafael Colucci Sep 20 '11 at 11:56
-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

Daniel Luyo
  • 1,326
  • 13
  • 19
  • 1
    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. – Rafael Colucci Aug 03 '11 at 21:43
  • ok, did you tried check the return values at InternetCloseHandle? – Daniel Luyo Aug 03 '11 at 21:49
  • No, i did not. It was supposed to work but I will take a look at it. – Rafael Colucci Aug 03 '11 at 21:57
  • InternetCloseHandle is working fine. The return value is true. – Rafael Colucci Aug 03 '11 at 21:59