none
Longpolling an upgraded connection with InternetReadFile() RRS feed

  • Question

  • Hello,

       

    I'm writing a cross platform app. I need to get data from a longpoll url.

    On Mac/Linux I can use curl, `curl_easy_perform()` takes care of everything automatically.

    On Windows I have to use native api. The code below works fine for normal urls, but when I try to use a longpoll url, it just quits immediately (`nr_read == 0`) instead of waiting until there's new data:


     ...
           flags =
         INTERNET_FLAG_HYPERLINK | INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
         INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
         INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
         INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | INTERNET_FLAG_NO_AUTH |
         INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI |
         INTERNET_FLAG_NO_COOKIES  |  
         INTERNET_FLAG_KEEP_CONNECTION |
         INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD 
         INTERNET_FLAG_SECURE;
        ...
    
        HINTERNET internet = InternetOpenA(user_agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
        HINTERNET connect = InternetConnectA(internet, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
        HINTERNET request = HttpOpenRequest(connect, req_typ, path, "HTTP/1.1", NULL, NULL, flags, NULL);
    
    
        #define BUF_MAX 1024
        TCHAR buf[BUF_MAX + 1];
        int nr_read = 0;
        while (1) {
             int ok = InternetReadFile(request, buf, BUF_MAX, &nr_read);
             if (!ok) {
                     puts("not ok");
                     break;
             }
             if (nr_read == 0) {
                     puts("nr read 0, breaking");
                     break;
             }
             buf[nr_read] = 0;
             printf("buf='%s'\n", buf);
             nr_read = 0;
        }

    I send an http request with the following headers:

    ```
    Connection: Upgrade
    Upgrade: websocket
    Sec-WebSocket-Key: key
    Sec-WebSocket-Version: 13
    ```

    Response headers I'm getting:

    ```
    HTTP/1.1 101
    Switching Protocols
    upgrade: websocket
    connection: upgrade
    ```

    After the handshake, libcurl keeps piping websocket data (which I can manually process), but `InternetReadFile()` just quits. 

    The server answers with the headers above and then libcurl gives me `{"type": "hello"}` and so on, but `InternetReadFile()` just exits. 

    I found a similar problem discussed here:

    https://stackoverflow.com/questions/8055054/trying-to-get-socket-from-wininet-http-connection

    Looks like after Windows XP WinInet  puts the connection back into a pool once the server response has been received. What's the best way to ask it not to di it?


    • Edited by asmaster Friday, May 24, 2019 12:17 PM
    Friday, May 24, 2019 12:16 PM