Share via


Função WinHttpWriteData (winhttp.h)

A função WinHttpWriteData grava dados de solicitação em um servidor HTTP.

Sintaxe

WINHTTPAPI BOOL WinHttpWriteData(
  [in]  HINTERNET hRequest,
  [in]  LPCVOID   lpBuffer,
  [in]  DWORD     dwNumberOfBytesToWrite,
  [out] LPDWORD   lpdwNumberOfBytesWritten
);

Parâmetros

[in] hRequest

Identificador HINTERNET válido retornado por WinHttpOpenRequest. Aguarde até que WinHttpSendRequest seja concluído antes de chamar essa função.

[in] lpBuffer

Ponteiro para um buffer que contém os dados a serem enviados para o servidor. Certifique-se de que esse buffer permaneça válido até que WinHttpWriteData seja concluído.

[in] dwNumberOfBytesToWrite

Valor inteiro longo sem sinal que contém o número de bytes a serem gravados no arquivo.

[out] lpdwNumberOfBytesWritten

Ponteiro para uma variável de inteiro longo sem sinal que recebe o número de bytes gravados no buffer. A função WinHttpWriteData define esse valor como zero antes de fazer qualquer verificação de erro ou trabalho. Ao usar WinHTTP de forma assíncrona, esse parâmetro deve ser definido como NULL e recuperar as informações na função de retorno de chamada. Não fazer isso pode causar uma falha de memória.

Valor retornado

Retorna TRUE se tiver êxito ou FALSE caso contrário. Para obter informações de erro estendidas, chame GetLastError. Entre os códigos de erro retornados estão:

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 executada 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 essa função retornar FALSE, você poderá chamar GetLastError para obter informações de erro estendidas. Se essa função retornar TRUE, use o WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE 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 Ao usar WinHTTP de forma assíncrona, sempre defina o parâmetro lpdwNumberOfBytesWritten comoNULL e recupere os bytes gravados na função de retorno de chamada; caso contrário, uma falha de memória pode ocorrer.
 
Quando o aplicativo está enviando dados, ele pode chamar WinHttpReceiveResponse para encerrar a transferência de dados. Se WinHttpCloseHandle for chamado, a transferência de dados será anulada.

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 no envio de dados para o servidor:

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_DATA_WRITTEN
  • WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
  • WINHTTP_CALLBACK_STATUS_REQUEST_SENT
  • WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
Dois problemas podem surgir ao tentar enviar dados POST (ou PUT) para proxies ou servidores que desafiam o uso da autenticação NTLM ou Negotiate. Primeiro, esses proxies ou servidores podem enviar desafios 401/407 e fechar a conexão antes que todos os dados possam ser post'ed, nesse caso não só WinHttpWriteData falha, mas também WinHTTP não pode lidar com os desafios de autenticação. NTLM e Negotiate exigem que todos os handshakes de autenticação sejam trocados na mesma conexão de soquete, portanto, a autenticação falhará se a conexão for interrompida prematuramente.

Em segundo lugar, NTLM e Negotiate podem exigir vários handshakes para concluir a autenticação, o que exige que os dados sejam re-POST'ed para cada etapa de autenticação. Isso pode ser muito ineficiente para carregamentos de dados grandes.

Para contornar esses dois problemas, uma solução é enviar uma solicitação de aquecimento idempotente, como HEAD para o v-dir de autenticação primeiro, lidar com os desafios de autenticação associados a essa solicitação e, em seguida, apenas dados POST. Desde que o mesmo soquete seja reutilizado para lidar com o POST'ing, nenhum desafio de autenticação adicional deve ser encontrado e todos os dados podem ser carregados de uma só vez. Como um soquete autenticado só pode ser reutilizado para solicitações subsequentes na mesma sessão, o POST deve sair no mesmo soquete, desde que o soquete não seja agrupado com solicitações simultâneas competindo por ele.

Nota Para Windows XP e Windows 2000, consulte a seção Requisitos de tempo de execução da página inicial do WinHTTP.
 

Exemplos

Este exemplo mostra o código que grava dados em um servidor HTTP. O nome do servidor fornecido no exemplo, www.wingtiptoys.com, é fictício e deve ser substituído pelo nome de um servidor para o qual você tem acesso de gravação.

    PCSTR pszData = "WinHttpWriteData Example";
    DWORD dwBytesWritten = 0;
    BOOL  bResults = FALSE;
    HINTERNET hSession = NULL,
              hConnect = NULL,
              hRequest = NULL;

    // Use WinHttpOpen to obtain a session handle.
    hSession = WinHttpOpen(  L"A WinHTTP Example Program/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.wingtiptoys.com",
                                   INTERNET_DEFAULT_HTTP_PORT, 0);

    // Create an HTTP Request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest( hConnect, L"PUT", 
                                       L"/writetst.txt", 
                                       NULL, WINHTTP_NO_REFERER, 
                                       WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                       0);

    // Send a Request.
    if (hRequest) 
        bResults = WinHttpSendRequest( hRequest, 
                                       WINHTTP_NO_ADDITIONAL_HEADERS,
                                       0, WINHTTP_NO_REQUEST_DATA, 0, 
                                       (DWORD)strlen(pszData), 0);

    // Write data to the server.
    if (bResults)
        bResults = WinHttpWriteData( hRequest, pszData, 
                                     (DWORD)strlen(pszData), 
                                     &dwBytesWritten);

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

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


    // Close any 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

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest