Sessões HTTP

O WinINet permite que você acesse recursos na World Wide Web (WWW). Esses recursos podem ser acessados diretamente usando InternetOpenUrl (para obter mais informações, consulte Acessando URLs diretamente).

Os recursos no WWW são acessados usando http. As funções HTTP lidam com os protocolos subjacentes, permitindo que seu aplicativo acesse informações no WWW. À medida que o protocolo HTTP evolui, os protocolos subjacentes são atualizados para manter o comportamento da função.

O diagrama a seguir mostra as relações das funções usadas com o protocolo HTTP. As caixas sombreadas representam funções que retornam identificadores HINTERNET , enquanto as caixas simples representam funções que usam o identificador HINTERNET criado pela função da qual dependem.

Funções wininet usadas para http

Para obter mais informações, consulte Identificadores HINTERNET.

Usando as funções WinINet para acessar o WWW

As funções a seguir são usadas durante sessões HTTP para acessar o WWW.

Função Descrição
HttpAddRequestHeaders Adiciona cabeçalhos de solicitação HTTP ao identificador de solicitação HTTP. Essa função requer um identificador criado por HttpOpenRequest.
HttpOpenRequest Abre um identificador de solicitação HTTP. Essa função requer um identificador criado pelo InternetConnect.
HttpQueryInfo Consulta informações sobre uma solicitação HTTP. Essa função requer um identificador criado pela função HttpOpenRequest ou InternetOpenUrl .
HttpSendRequest Envia a solicitação HTTP especificada para o servidor HTTP. Essa função requer um identificador criado por HttpOpenRequest.
InternetErrorDlg Exibe caixas de diálogo predefinidas para condições comuns de erro da Internet. Essa função requer o identificador usado na chamada para HttpSendRequest.

 

Iniciando uma conexão com o WWW

Para iniciar uma conexão com o WWW, o aplicativo deve chamar a função InternetConnect na HINTERNET raiz retornada por InternetOpen. O InternetConnect deve estabelecer uma sessão HTTP declarando o tipo de serviço INTERNET_SERVICE_HTTP. Para obter mais informações sobre como usar o InternetConnect, consulte Usando InternetConnect.

Abrindo uma solicitação

A função HttpOpenRequest abre uma solicitação HTTP e retorna um identificador HINTERNET que pode ser usado pelas outras funções HTTP. Ao contrário das outras funções abertas (como FtpOpenFile e InternetOpenUrl), HttpOpenRequest não envia a solicitação para a Internet quando chamada. A função HttpSendRequest envia a solicitação e estabelece uma conexão pela rede.

HttpOpenRequest usa um identificador de sessão HTTP criado por InternetConnect e um verbo HTTP, nome do objeto, cadeia de caracteres de versão, referenciador, tipos de aceitação, sinalizadores e valor de contexto.

O verbo HTTP é uma cadeia de caracteres a ser usada na solicitação. Os verbos HTTP comuns usados nas solicitações incluem GET, PUT e POST. Se esse valor for definido como NULL, HttpOpenRequest usará o valor padrão GET.

O nome do objeto é uma cadeia de caracteres que contém o nome do objeto de destino do verbo HTTP especificado. Geralmente, esse é um nome de arquivo, um módulo executável ou um especificador de pesquisa. Se o nome do objeto fornecido for uma cadeia de caracteres vazia, HttpOpenRequest procurará a página padrão.

A cadeia de caracteres de versão deve conter a versão HTTP. Se esse parâmetro for NULL, a função usará ""HTTP/1.1"".

O referenciador especifica o endereço do documento do qual o nome do objeto foi obtido. Se esse parâmetro for NULL, nenhum referenciador será especificado.

A cadeia de caracteres terminada em nulo que contém os tipos de aceitação indica os tipos de conteúdo aceitos pelo aplicativo. Definir esse parâmetro como NULL indica que nenhum tipo de conteúdo é aceito pelo aplicativo. Se uma cadeia de caracteres vazia for fornecida, o aplicativo indicará que aceita apenas documentos do tipo ""text/*"". O valor ""text/*"" indica documentos somente texto, não imagens ou outros arquivos binários.

Os valores de sinalizador controlam o cache, os cookies e os problemas de segurança. Para MSN (Microsoft Network), NTLM e outros tipos de autenticação, defina o sinalizador INTERNET_FLAG_KEEP_CONNECTION .

Se o sinalizador INTERNET_FLAG_ASYNC tiver sido definido na chamada para InternetOpen, um valor de contexto diferente de zero deverá ser definido para a operação assíncrona adequada.

O exemplo a seguir é uma chamada de exemplo para HttpOpenRequest.

hHttpRequest = HttpOpenRequest( hHttpSession, "GET", "", NULL, "", NULL, 0, 0);

Adicionando cabeçalhos de solicitação

A função HttpAddRequestHeaders permite que os aplicativos adicionem um ou mais cabeçalhos de solicitação à solicitação inicial. Essa função permite que um aplicativo acrescente cabeçalhos de formato livre adicionais ao identificador de solicitação HTTP; destina-se ao uso por aplicativos sofisticados que exigem controle preciso sobre a solicitação enviada ao servidor HTTP.

HttpAddRequestHeaders precisa de um identificador de solicitação HTTP criado por HttpOpenRequest, uma cadeia de caracteres que contém os cabeçalhos, o comprimento dos cabeçalhos e modificadores.

Enviando uma solicitação

HttpSendRequest estabelece uma conexão com a Internet e envia a solicitação para o site especificado. Essa função requer um identificador HINTERNET criado por HttpOpenRequest. HttpSendRequest 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 HttpSendRequest enviar a solicitação, o aplicativo poderá usar as funções InternetReadFile, InternetQueryDataAvailable e InternetSetFilePointer no identificador HINTERNET criado por HttpOpenRequest para baixar os recursos do servidor.

Postando dados no servidor

Para postar dados em um servidor, o verbo HTTP na chamada para HttpOpenRequest deve ser POST ou PUT. O endereço do buffer que contém os dados POST deve ser passado para o parâmetro lpOptional em HttpSendRequest. O parâmetro dwOptionalLength deve ser definido como o tamanho dos dados.

Você também pode usar a função InternetWriteFile para postar dados em um identificador HINTERNET enviado usando HttpSendRequestEx.

Obtendo informações sobre uma solicitação

HttpQueryInfo permite que um aplicativo recupere informações sobre uma solicitação HTTP. A função requer um identificador HINTERNET criado por HttpOpenRequest ou InternetOpenUrl, um valor de nível de informação e um comprimento de buffer. HttpQueryInfo 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.

Baixando recursos do WWW

Depois de abrir uma solicitação com HttpOpenRequest e enviá-la para o servidor com HttpSendRequest, o aplicativo pode usar as funções InternetReadFile, InternetQueryDataAvailable e InternetSetFilePointer para baixar o recurso do servidor HTTP.

O exemplo a seguir baixa um recurso. A função aceita o identificador para a janela atual, o número de identificação de uma caixa de edição e um identificador HINTERNET criado por HttpOpenRequest e enviado por HttpSendRequest. Ele usa InternetQueryDataAvailable para determinar o tamanho do recurso e, em seguida, baixa-o usando InternetReadFile. Em seguida, o conteúdo é exibido na caixa de edição.

int WINAPI Dumper(HWND hX, int intCtrlID, HINTERNET hResource)
{
    LPTSTR lpszData;    // buffer for the data
    DWORD  dwSize;       // size of the data available
    DWORD  dwDownloaded; // size of the downloaded data
    DWORD  dwSizeSum=0;  // size of the data in the textbox
    LPTSTR lpszHolding;  // buffer to merge the textbox data and buffer

    // Set the cursor to an hourglass.
    SetCursor(LoadCursor(NULL,IDC_WAIT));

    // This loop handles reading the data.
    do
    {
        // The call to InternetQueryDataAvailable determines the
        // amount of data available to download.
        if (!InternetQueryDataAvailable(hResource,&dwSize,0,0))
        {
            printf("InternetQueryDataAvailable failed (%d)\n", GetLastError());
            SetCursor(LoadCursor(NULL,IDC_ARROW));
            return FALSE;
        }
        else
        {
            // Allocate a buffer of the size returned by
            // InternetQueryDataAvailable.
            lpszData = new TCHAR[dwSize+1];

            // Read the data from the HINTERNET handle.
            if(!InternetReadFile(hResource,
                                 (LPVOID)lpszData,
                                 dwSize,
                                 &dwDownloaded))
            {
                printf("InternetReadFile failed (%d)\n", GetLastError());
                delete[] lpszData;
                break;
            }
            else
            {
                // Add a null terminator to the end of the data buffer
                lpszData[dwDownloaded]='\0';

                // Allocate the holding buffer.
                lpszHolding = new TCHAR[dwSizeSum + dwDownloaded + 1];

                // Check if there has been any data written
                // to the textbox.
                if (dwSizeSum != 0)
                {
                    // Retrieve the data stored in the textbox if any
                    GetDlgItemText(hX,intCtrlID,
                                   (LPTSTR)lpszHolding,
                                   dwSizeSum);

                    // Add a null terminator at the end of the
                    // textbox data.
                    lpszHolding[dwSizeSum]='\0';
                }
                else
                {
                    // Make the holding buffer an empty string.
                    lpszHolding[0]='\0';
                }

                size_t cchDest = dwSizeSum + dwDownloaded + dwDownloaded + 1;
                LPTSTR* ppszDestEnd = 0;
                size_t* pcchRemaining = 0;

                // Add the new data to the holding buffer
                HRESULT hr = StringCchCatEx(lpszHolding,
                                            cchDest,
                                            lpszData,
                                            ppszDestEnd,
                                            pcchRemaining,
                                            STRSAFE_NO_TRUNCATION);

                if(SUCCEEDED(hr))
                {
                    // Write the holding buffer to the textbox.
                    SetDlgItemText(hX,intCtrlID,(LPTSTR)lpszHolding);

                    // Delete the two buffers.
                    delete[] lpszHolding;
                    delete[] lpszData;

                    // Add the size of the downloaded data to the
                    // textbox data size.
                    dwSizeSum = dwSizeSum + dwDownloaded + 1;

                    // Check the size of the remaining data.
                    // If it is zero, break.
                    if (dwDownloaded == 0)
                        break;
                    else
                    {
                    //  TODO: Insert error handling code here.
                    }
                }
            }
        }
    }
    while(TRUE);

    // Close the HINTERNET handle.
    InternetCloseHandle(hResource);

    // Set the cursor back to an arrow.
    SetCursor(LoadCursor(NULL,IDC_ARROW));

    return TRUE;
}

Observação

O WinINet não dá suporte a implementações de servidor. Além disso, ele não deve ser usado de um serviço. Para implementações ou serviços de servidor, use Os Serviços HTTP do Microsoft Windows (WinHTTP).