Compartilhar via


Visão geral das sessões do WinHTTP

Os Serviços HTTP do Microsoft Windows (WinHTTP) expõem um conjunto de funções C/C++ que permitem que seu aplicativo acesse recursos HTTP na Web. Este tópico fornece uma visão geral de como essas funções são usadas para interagir com um servidor HTTP.

Usando a API WinHTTP para acessar a Web

O diagrama a seguir mostra a ordem na qual as funções WinHTTP normalmente são chamadas ao interagir com um servidor HTTP. As caixas sombreadas representam funções que geram um identificador HINTERNET , enquanto as caixas simples representam funções que usam esses identificadores.

funções que criam identificadores

Inicializando o WinHTTP

Antes de interagir com um servidor, o WinHTTP deve ser inicializado chamando WinHttpOpen. WinHttpOpen cria um contexto de sessão para manter detalhes sobre a sessão HTTP e retorna um identificador de sessão. Usando esse identificador, a função WinHttpConnect é capaz de especificar um servidor HTTP de destino ou HTTPS (Secure Hypertext Transfer Protocol).

Observação

Uma chamada para WinHttpConnect não resulta em uma conexão real com o servidor HTTP até que uma solicitação seja feita para um recurso específico.

 

Abrindo uma solicitação

A função WinHttpOpenRequest abre uma solicitação HTTP para um recurso específico e retorna um identificador HINTERNET que pode ser usado pelas outras funções HTTP. WinHttpOpenRequest não envia a solicitação para o servidor quando chamado. A função WinHttpSendRequest realmente estabelece uma conexão pela rede e envia a solicitação.

O exemplo a seguir mostra uma chamada de exemplo para WinHttpOpenRequest que usa as opções padrão.

HINTERNET hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, NULL, NULL, 0);

Adicionando cabeçalhos de solicitação

A função WinHttpAddRequestHeaders permite que um aplicativo acrescente cabeçalhos de solicitação de formato livre adicionais ao identificador de solicitação HTTP. Ele destina-se ao uso por aplicativos sofisticados que exigem controle preciso sobre as solicitações enviadas ao servidor HTTP.

A função WinHttpAddRequestHeaders requer um identificador de solicitação HTTP criado por WinHttpOpenRequest, uma cadeia de caracteres que contém os cabeçalhos, o comprimento dos cabeçalhos e quaisquer modificadores.

Os modificadores a seguir podem ser usados com WinHttpAddRequestHeaders.

Modificador Descrição
WINHTTP_ADDREQ_FLAG_ADD Adiciona o cabeçalho se ele não existir. Usado com WINHTTP_ADDREQ_FLAG_REPLACE.
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW Adiciona o cabeçalho somente se ele ainda não existir; caso contrário, um erro será retornado.
WINHTTP_ADDREQ_FLAG_COALESCE Mescla cabeçalhos de mesmo nome.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA Mescla cabeçalhos de mesmo nome usando uma vírgula. Por exemplo, adicionar "Aceitar: texto/*" seguido por "Aceitar: áudio/*" com esse sinalizador forma o cabeçalho único "Aceitar: texto/*, áudio/*", fazendo com que o primeiro cabeçalho encontrado seja mesclado. Cabe ao aplicativo de chamada garantir um esquema coeso em relação a cabeçalhos mesclados/separados.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON Mescla cabeçalhos de mesmo nome usando ponto e vírgula.
WINHTTP_ADDREQ_FLAG_REPLACE Substitui ou remove um cabeçalho. Se o valor do cabeçalho estiver vazio e o cabeçalho for encontrado, ele será removido. Se o valor do cabeçalho não estiver vazio, o valor do cabeçalho será substituído.

 

Enviando uma solicitação

A função WinHttpSendRequest estabelece uma conexão com o servidor e envia a solicitação para o site especificado. Essa função requer um identificador HINTERNET criado por WinHttpOpenRequest. WinHttpSendRequest também pode enviar cabeçalhos adicionais ou informações opcionais. As informações opcionais geralmente são usadas para operações que gravam informações no servidor, como PUT e POST.

Depois que a função WinHttpSendRequest envia a solicitação, o aplicativo pode usar as funções WinHttpReadData e WinHttpQueryDataAvailable no identificador HINTERNET para baixar os recursos do servidor.

Postando dados no servidor

Para postar dados em um servidor, o verbo HTTP na chamada para WinHttpOpenRequest deve ser POST ou PUT. Quando WinHttpSendRequest é chamado, o parâmetro dwTotalLength deve ser definido como o tamanho dos dados em bytes. Em seguida, use WinHttpWriteData para postar os dados no servidor.

Como alternativa, defina o parâmetro lpOptional de WinHttpSendRequest como o endereço de um buffer que contém dados a serem postados no servidor. Ao usar essa técnica, você deve definir os parâmetros dwOptionalLength e dwTotalLength de WinHttpSendRequest para ter o tamanho dos dados que estão sendo postados. Chamar WinHttpSendRequest dessa maneira elimina a necessidade de chamar WinHttpWriteData.

Obtendo informações sobre uma solicitação

A função WinHttpQueryHeaders permite que um aplicativo recupere informações sobre uma solicitação HTTP. A função requer um identificador HINTERNET criado por WinHttpOpenRequest, um valor de nível de informação e um comprimento de buffer. WinHttpQueryHeaders também aceita um buffer que armazena as informações e um índice de cabeçalho baseado em zero que enumera vários cabeçalhos com o mesmo nome.

Use qualquer um dos valores de nível de informação encontrados na página Sinalizadores de Informações de Consulta com um modificador para controlar o formato no qual as informações são armazenadas no parâmetro lpvBuffer de WinHttpQueryHeaders.

Baixando recursos da Web

Depois de abrir uma solicitação com a função WinHttpOpenRequest , enviá-la para o servidor com WinHttpSendRequest e preparar o identificador de solicitação para receber uma resposta com WinHttpReceiveResponse, o aplicativo pode usar as funções WinHttpReadData e WinHttpQueryDataAvailable para baixar o recurso do servidor HTTP.

O código de exemplo a seguir mostra como baixar um recurso com semântica de transação segura. O código de exemplo inicializa a API (interface de programação de aplicativo) 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 é repetido até que todo o documento seja recuperado e exibido.

  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 );

  // Keep checking for data until there is nothing left.
  if( bResults )
  {
    do 
    {
      // Check for 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", 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 any open handles.
  if( hRequest ) WinHttpCloseHandle( hRequest );
  if( hConnect ) WinHttpCloseHandle( hConnect );
  if( hSession ) WinHttpCloseHandle( hSession );