0
votes

I'm wondering if it is possible with the Windows API WinHTTP to use HTTP/2 multiplexing (multiple requests over one TCP connection). If so, is there example code how to archieve this?

I found this message from Microsoft (https://docs.microsoft.com/en-us/windows/win32/winhttp/about-winhttp):

Caution

WinHTTP is not reentrant except during asynchronous completion callback. That is, while a thread has a call pending to one of the WinHTTP functions such as WinHttpSendRequest, WinHttpReceiveResponse, WinHttpQueryDataAvailable, WinHttpSendData, or WinHttpWriteData, it must never call WinHTTP a second time until the first call has completed. One scenario under which a second call could occur is as follows: If an application queues an Asynchronous Procedure Call (APC) to the thread that calls into WinHTTP, and if WinHTTP performs an alertable wait internally, the APC can run. If the APC routine happens also to call WinHTTP, it reenters the WinHTTP API, and the internal state of WinHTTP can be corrupted.

That's why I'm not sure if asynchronous calls of WinHttpReadData are possible.

1

1 Answers

0
votes

I recently found out about WinHTTP's HTTP2 support and also wondered if full multiplexing was possible, as there is pretty much no documentation about it. Since the request / response in synchronous mode does not support sending a second request without reading the first one, I rearchitected my application to use the asynchronous mode, and issued multiple requests at once with the following options:

    const DWORD tlsProtocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 |
                   WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3;

    const DWORD enableHTTP2Flag = WINHTTP_PROTOCOL_FLAG_HTTP2;

    const DWORD decompression = WINHTTP_DECOMPRESSION_FLAG_ALL;

    HINTERNET hSession = WinHttpOpen(L"WinHttp Test",
                      WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY,
                      WINHTTP_NO_PROXY_NAME,
                      WINHTTP_NO_PROXY_BYPASS,
                      WINHTTP_FLAG_ASYNC);

    WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS,
             (LPVOID)&tlsProtocols, sizeof(tlsProtocols));

    WinHttpSetOption(hSession, WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL,
             (LPVOID)&enableHTTP2Flag, sizeof(enableHTTP2Flag));

    WinHttpSetOption(hSession, WINHTTP_OPTION_DECOMPRESSION,
             (LPVOID)&decompression, sizeof(decompression));

    WinHttpSetStatusCallback(hSession, WinhttpStatusCallback,
                 WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS, 0);

    HINTERNET hConnect = WinHttpConnect(hSession,
                         L"example.com",
                         INTERNET_DEFAULT_HTTPS_PORT, 0);

Despite only calling WinHttpConnect a single time, issuing multiple requests with WinHttpOpenRequest caused WinHTTP to internally open a new connection to the target server, which suggests that multiplexing is unfortunately not implemented.