Função WinHttpQueryDataAvailable (winhttp.h)

A função WinHttpQueryDataAvailable retorna a quantidade de dados, em bytes, disponíveis para leitura com WinHttpReadData.

Sintaxe

WINHTTPAPI BOOL WinHttpQueryDataAvailable(
  [in]  HINTERNET hRequest,
  [out] LPDWORD   lpdwNumberOfBytesAvailable
);

Parâmetros

[in] hRequest

Um identificador HINTERNET válido retornado por WinHttpOpenRequest. WinHttpReceiveResponse deve ter sido chamado para esse identificador e ter sido concluído antes de WinHttpQueryDataAvailable ser chamado.

[out] lpdwNumberOfBytesAvailable

Um ponteiro para uma variável de inteiro longo sem sinal que recebe o número de bytes disponíveis. Quando WinHTTP é usado no modo assíncrono, sempre defina esse parâmetro como NULL e recupere dados na função de retorno de chamada; não fazer isso pode causar uma falha de memória.

Valor retornado

Retorna TRUE se a função for bem-sucedida ou FALSE caso contrário. Para obter dados de erro estendidos, chame GetLastError. Entre os códigos de erro retornados estão os seguintes.

Código do Erro Descrição
ERROR_WINHTTP_CONNECTION_ERROR
A conexão com o servidor foi redefinida ou encerrada ou um protocolo SSL incompatível foi encontrado. Por exemplo, o WinHTTP versão 5.1 não dá suporte ao SSL2, a menos que o cliente o habilite especificamente.
ERROR_WINHTTP_INCORRECT_HANDLE_STATE
A operação solicitada não pode ser concluída porque o identificador fornecido não está no estado correto.
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
O tipo de identificador fornecido está incorreto para esta operação.
ERROR_WINHTTP_INTERNAL_ERROR
Ocorreu um erro interno.
ERROR_WINHTTP_OPERATION_CANCELLED
A operação foi cancelada, geralmente porque o identificador no qual a solicitação estava operando foi fechado antes da conclusão da operação.
ERROR_WINHTTP_TIMEOUT
O tempo limite da solicitação foi atingido.
ERROR_NOT_ENOUGH_MEMORY
Não havia memória suficiente disponível para concluir a operação solicitada. (Código de erro do Windows)

Comentários

Mesmo quando WinHTTP é usado no modo assíncrono (ou seja, quando WINHTTP_FLAG_ASYNC foi definido no WinHttpOpen), essa função pode operar de forma síncrona ou assíncrona. Se ele retornar FALSE, ele falhará e você poderá chamar GetLastError para obter informações de erro estendidas. Se retornar TRUE, use o WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE conclusão para determinar se essa função foi bem-sucedida e o valor dos parâmetros. A conclusão do WINHTTP_CALLBACK_STATUS_REQUEST_ERROR indica que a operação foi concluída de forma assíncrona, mas falhou.

Aviso Quando WinHTTP é usado no modo assíncrono, sempre defina o parâmetro lpdwNumberOfBytesAvailable como NULL e recupere os bytes disponíveis na função de retorno de chamada; caso contrário, uma falha de memória pode ocorrer.
 
Essa função retorna o número de bytes de dados que estão disponíveis para leitura imediatamente por uma chamada subsequente para WinHttpReadData. Se nenhum dado estiver disponível e o final do arquivo não tiver sido atingido, uma das duas coisas acontecerá. Se a sessão for síncrona, a solicitação aguardará até que os dados fiquem disponíveis. Se a sessão for assíncrona, a função retornará TRUE e, quando os dados estiverem disponíveis, chamará a função de retorno de chamada com WINHTTP_STATUS_CALLBACK_DATA_AVAILABLE e indicará o número de bytes imediatamente disponíveis para leitura chamando WinHttpReadData.

A quantidade de dados restantes não é recalculada até que todos os dados disponíveis indicados pela chamada para WinHttpQueryDataAvailable sejam lidos.

Use o valor retornado de WinHttpReadData para determinar quando uma resposta foi completamente lida.

Importante Não use o valor retornado de WinHttpQueryDataAvailable para determinar se o fim de uma resposta foi atingido, pois nem todos os servidores encerram as respostas corretamente e uma resposta terminada incorretamente faz com que WinHttpQueryDataAvailable antecipe mais dados.
 
Para identificadores HINTERNET criados pela função WinHttpOpenRequest e enviados por WinHttpSendRequest, uma chamada para WinHttpReceiveResponse deve ser feita no identificador antes que WinHttpQueryDataAvailable possa ser usada.

Se uma função de retorno de chamada status tiver sido instalada com WinHttpSetStatusCallback, as seguintes notificações que foram definidas no parâmetro dwNotificationFlags de WinHttpSetStatusCallback indicam progresso na verificação de dados disponíveis:

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
Nota Para obter mais informações sobre o Windows XP e o Windows 2000, consulte Requisitos de tempo de execução.
 

Exemplos

O exemplo a seguir mostra como usar a semântica de transação segura para baixar um recurso de um servidor HTTPS. O código de exemplo inicializa a API WinHTTP, seleciona um servidor HTTPS de destino e, em seguida, abre e envia uma solicitação para esse recurso seguro.
WinHttpQueryDataAvailable é usado com o identificador de solicitação para determinar quantos dados estão disponíveis para download e, em seguida, WinHttpReadData é usado para ler esses dados. Esse processo se repete até que todo o documento seja recuperado e exibido.

Importante

Se você quiser alguns dados o mais rápido possível (ou seja, está processando e analisando dados conforme os recebe), chame WinHttpQueryDataAvailable e WinHttpReadData. Se você estiver tentando baixar toda a resposta o mais rápido possível, chame WinHttpReadData diretamente, pois WinHttpReadData tenta preencher o buffer antes de concluir.

Além disso, o exemplo de código abaixo aloca em cada iteração de loop. Para o código de produção, onde o desempenho é importante, você pode começar com um buffer de tamanho apropriado (talvez 1 megabyte) e redimensioná-lo, se necessário. Na prática, WinHttpQueryDataAvailable não retorna mais de 8 quilobytes.


    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer;
    BOOL  bResults = FALSE;
    HINTERNET  hSession = NULL, 
               hConnect = NULL,
               hRequest = NULL;

    // Use WinHttpOpen to obtain a session handle.
    hSession = WinHttpOpen( L"WinHTTP Example/1.0",  
                            WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                            WINHTTP_NO_PROXY_NAME, 
                            WINHTTP_NO_PROXY_BYPASS, 0);

    // Specify an HTTP server.
    if (hSession)
        hConnect = WinHttpConnect( hSession, L"www.microsoft.com",
                                   INTERNET_DEFAULT_HTTPS_PORT, 0);

    // Create an HTTP request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
                                       NULL, WINHTTP_NO_REFERER, 
                                       WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                       WINHTTP_FLAG_SECURE);

    // Send a request.
    if (hRequest)
        bResults = WinHttpSendRequest( hRequest,
                                       WINHTTP_NO_ADDITIONAL_HEADERS,
                                       0, WINHTTP_NO_REQUEST_DATA, 0, 
                                       0, 0);

 
    // End the request.
    if (bResults)
        bResults = WinHttpReceiveResponse( hRequest, NULL);

    // Continue to verify data until there is nothing left.
    if (bResults)
        do 
        {

            // Verify available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
                printf( "Error %u in WinHttpQueryDataAvailable.\n",
                        GetLastError());

            // Allocate space for the buffer.
            pszOutBuffer = new char[dwSize+1];
            if (!pszOutBuffer)
            {
                printf("Out of memory\n");
                dwSize=0;
            }
            else
            {
                // Read the Data.
                ZeroMemory(pszOutBuffer, dwSize+1);

                if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                                      dwSize, &dwDownloaded))
                    printf( "Error %u in WinHttpReadData.\n", GetLastError());
                else
                    printf( "%s\n", pszOutBuffer);
            
                // Free the memory allocated to the buffer.
                delete [] pszOutBuffer;
            }

        } while (dwSize > 0);


    // Report any errors.
    if (!bResults)
        printf( "Error %d has occurred.\n", GetLastError());

    // Close open handles.
    if (hRequest) WinHttpCloseHandle(hRequest);
    if (hConnect) WinHttpCloseHandle(hConnect);
    if (hSession) WinHttpCloseHandle(hSession);

Requisitos

   
Cliente mínimo com suporte Windows XP, Windows 2000 Professional com SP3 [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows Server 2003, Windows 2000 Server com SP3 [somente aplicativos da área de trabalho]
Plataforma de Destino Windows
Cabeçalho winhttp.h
Biblioteca Winhttp.lib
DLL Winhttp.dll
Redistribuível WinHTTP 5.0 e Internet Explorer 5.01 ou posterior no Windows XP e Windows 2000.

Confira também

Sobre os Serviços HTTP do Microsoft Windows (WinHTTP)

Versões do WinHTTP

WinHttpCloseHandle

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest

WinHttpReadData

WinHttpSendRequest