Partilhar via


Visão geral das sessões WinHTTP

O Microsoft Windows HTTP Services (WinHTTP) expõe 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 são normalmente chamadas ao interagir com um servidor HTTP. As caixas sombreadas representam funções que geram um handle de HINTERNET, enquanto as caixas simples representam funções que usam esses handles.

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 um servidor HTTPS (Protocolo de Transferência de Hipertexto Seguro).

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.

 

Abrir uma solicitação

A função WinHttpOpenRequest abre uma solicitação HTTP para um recurso específico e retorna um identificador de HINTERNET que pode ser usado pelas outras funções HTTP. WinHttpOpenRequest não envia a solicitação para o servidor quando chamado. O 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çãoWinHttpAddRequestHeaders permite que um aplicativo acrescente cabeçalhos de solicitação de formato livre adicionais ao identificador de solicitação HTTP. Destina-se ao uso por aplicativos sofisticados que exigem controle preciso sobre as solicitações enviadas ao servidor HTTP.

A funçãoWinHttpAddRequestHeaders 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 com o mesmo nome.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA Mescla cabeçalhos de mesmo nome usando uma vírgula. Por exemplo, adicionar "Accept: text/*" seguido de "Accept: audio/*" com este sinalizador forma o cabeçalho único "Accept: text/*, audio/*", fazendo com que o primeiro cabeçalho encontrado seja mesclado. Cabe ao aplicativo de chamada garantir um esquema coeso em relação aos cabeçalhos mesclados/separados.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON Mescla cabeçalhos com o mesmo nome usando um 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.

 

Enviar um pedido

A função WinHttpSendRequest estabelece uma ligação com o servidor e envia o pedido para o site especificado. Esta função requer um identificador de 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.

Lançamento de 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 para o endereço de um buffer que contém dados para postar no servidor. Ao usar esta técnica, deve definir os parâmetros dwOptionalLength e dwTotalLength de WinHttpSendRequest para serem o tamanho dos dados a serem postados. Chamar WinHttpSendRequest dessa maneira elimina a necessidade de chamar WinHttpWriteData.

Obter informações sobre um pedido

A função WinHttpQueryHeaders permite que um aplicativo recupere informações sobre uma solicitação HTTP. A função requer um handle de 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áginaQuery Info Flags com um modificador para controlar o formato no qual as informações são armazenadas no parâmetro lpvBuffer de WinHttpQueryHeaders.

Download de recursos da Web

Depois de abrir uma solicitação com a função WinHttpOpenRequest, enviá-la para o servidor com a função WinHttpSendRequest e preparar o identificador de solicitação para receber uma resposta com a função 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 interface de programação de aplicativo (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. Este processo é repetido até que todo o documento tenha sido 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 );