Fonction WinHttpReadData (winhttp.h)

La fonction WinHttpReadData lit les données d’un handle ouvert par la fonction WinHttpOpenRequest .

Consultez également WinHttpReadDataEx.

Syntaxe

WINHTTPAPI BOOL WinHttpReadData(
  [in]  HINTERNET hRequest,
  [out] LPVOID    lpBuffer,
  [in]  DWORD     dwNumberOfBytesToRead,
  [out] LPDWORD   lpdwNumberOfBytesRead
);

Paramètres

[in] hRequest

Handle HINTERNET valide retourné à partir d’un appel précédent à WinHttpOpenRequest. WinHttpReceiveResponse ou WinHttpQueryDataAvailable doit avoir été appelé pour ce handle et doit avoir terminé avant l’appel de WinHttpReadData . Bien que l’appel de WinHttpReadData immédiatement après la fin de WinHttpReceiveResponse évite le coût d’une copie de mémoire tampon, cela nécessite que l’application utilise une mémoire tampon de longueur fixe pour la lecture.

[out] lpBuffer

Pointeur vers une mémoire tampon qui reçoit les données lues. Assurez-vous que cette mémoire tampon reste valide jusqu’à ce que WinHttpReadData soit terminé.

[in] dwNumberOfBytesToRead

Valeur entière longue non signée qui contient le nombre d’octets à lire.

[out] lpdwNumberOfBytesRead

Pointeur vers une variable entière longue non signée qui reçoit le nombre d’octets lus. WinHttpReadData définit cette valeur sur zéro avant d’effectuer un travail ou une vérification des erreurs. Lorsque vous utilisez WinHTTP de manière asynchrone, définissez toujours ce paramètre sur NULL et récupérez les informations dans la fonction de rappel ; le fait de ne pas le faire peut provoquer une erreur de mémoire.

Valeur retournée

Retourne LA valeur TRUE si elle réussit ou FALSE dans le cas contraire. Pour obtenir des informations d’erreur étendues, appelez GetLastError. Le tableau suivant identifie les codes d’erreur retournés.

Code d'erreur Description
ERROR_WINHTTP_CONNECTION_ERROR
La connexion au serveur a été réinitialisée ou terminée, ou un protocole SSL incompatible a été rencontré. Par exemple, WinHTTP 5.1 ne prend pas en charge SSL2, sauf si le client l’active spécifiquement.
ERROR_WINHTTP_INCORRECT_HANDLE_STATE
L’opération demandée ne peut pas être effectuée, car le handle fourni n’est pas dans l’état correct.
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
Le type de handle fourni est incorrect pour cette opération.
ERROR_WINHTTP_INTERNAL_ERROR
Une erreur interne s'est produite.
ERROR_WINHTTP_OPERATION_CANCELLED
L’opération a été annulée, généralement parce que le handle sur lequel la demande fonctionnait a été fermé avant la fin de l’opération.
ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW
Retourné lorsqu’une réponse entrante dépasse une limite de taille WinHTTP interne.
ERROR_WINHTTP_TIMEOUT
Le délai d'attente de la requête a expiré.
ERROR_NOT_ENOUGH_MEMORY
La mémoire disponible n’était pas suffisante pour effectuer l’opération demandée. (Code d’erreur Windows)

Remarques

À compter de Windows Vista et De Windows Server 2008, WinHttp permet aux applications d’effectuer un encodage de transfert en bloc sur les données envoyées au serveur. Lorsque l’en-tête Transfer-Encoding est présent dans la réponse WinHttp, WinHttpReadData supprime les informations de segmentation avant de donner les données à l’application.

Même lorsque WinHTTP est utilisé en mode asynchrone (c’est-à-dire, lorsque WINHTTP_FLAG_ASYNC a été défini dans WinHttpOpen), cette fonction peut fonctionner de manière synchrone ou asynchrone. Si cette fonction retourne FALSE, cette fonction a échoué et vous pouvez appeler GetLastError pour obtenir des informations d’erreur étendues. Si cette fonction retourne TRUE, utilisez la WINHTTP_CALLBACK_STATUS_READ_COMPLETE complétion pour déterminer si cette fonction a réussi et la valeur des paramètres. La WINHTTP_CALLBACK_STATUS_REQUEST_ERROR’achèvement indique que l’opération s’est terminée de manière asynchrone, mais a échoué.

Avertissement Lorsque WinHTTP est utilisé en mode asynchrone, définissez toujours le paramètre lpdwNumberOfBytesRead sur NULL et récupérez les octets lus dans la fonction de rappel ; sinon, une erreur de mémoire peut se produire.
 
Lorsque la mémoire tampon de lecture est très petite, WinHttpReadData peut se terminer de manière synchrone. Si le WINHTTP_CALLBACK_STATUS_READ_COMPLETE d’achèvement déclenche un autre appel à WinHttpReadData, la situation peut entraîner un dépassement de capacité de la pile. En général, il est préférable d’utiliser une mémoire tampon de lecture de taille comparable ou supérieure à la mémoire tampon de lecture interne utilisée par WinHTTP, qui est de 8 Ko.

Si vous utilisez WinHttpReadData de manière synchrone et que la valeur de retour est TRUE et que le nombre d’octets lus est égal à zéro, le transfert a été effectué et il n’y a plus d’octets à lire sur le handle. Cela est analogue à l’atteinte de la fin du fichier dans un fichier local. Si vous utilisez la fonction de manière asynchrone, le rappel WINHTTP_CALLBACK_STATUS_READ_COMPLETE est appelé avec le paramètre dwStatusInformationLength défini sur zéro lorsque la fin d’une réponse est trouvée.

WinHttpReadData tente de remplir la mémoire tampon pointée vers lpBuffer jusqu’à ce qu’il n’y ait plus de données disponibles à partir de la réponse. Si suffisamment de données ne sont pas arrivées du serveur, la mémoire tampon n’est pas remplie.

Pour les handles HINTERNET créés par la fonction WinHttpOpenRequest et envoyés par WinHttpSendRequest, un appel à WinHttpReceiveResponse doit être effectué sur le handle avant que WinHttpReadData puisse être utilisé.

Les caractères d’octets uniques récupérés avec WinHttpReadData ne sont pas convertis en caractères sur plusieurs octets.

Lorsque la mémoire tampon de lecture est très petite, WinHttpReadData peut se terminer de manière synchrone et si l’WINHTTP_CALLBACK_STATUS_READ_COMPLETE achèvement déclenche un autre appel à WinHttpReadData, un dépassement de capacité de la pile peut se produire. Il est préférable d’utiliser une mémoire tampon de lecture d’une taille supérieure ou égale à 8 Kilooctets.

Si suffisamment de données ne sont pas arrivées du serveur, WinHttpReadData ne remplit pas entièrement la mémoire tampon pointée vers lpBuffer. La mémoire tampon doit être suffisamment grande au moins pour contenir les en-têtes HTTP lors de la première lecture, et lors de la lecture des entrées de répertoire encodées HTML, elle doit être suffisamment grande pour contenir au moins une entrée complète.

Si une fonction de rappel status a été installée à l’aide de WinHttpSetStatusCallback, celles des notifications suivantes qui ont été définies dans le paramètre dwNotificationFlags de WinHttpSetStatusCallback indiquent la progression de la vérification des données disponibles :

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
  • WINHTTP_CALLBACK_STATUS_READ_COMPLETE
Note Pour Windows XP et Windows 2000, consultez la section Conditions d’exécution de la page de démarrage WinHttp.
 

Exemples

L’exemple suivant montre comment utiliser la sémantique de transaction sécurisée pour télécharger une ressource à partir d’un serveur HTTPS (Secure Hypertext Transfer Protocol). L’exemple de code initialise l’interface de programmation d’application (API) WinHTTP, sélectionne un serveur HTTPS cible, puis ouvre et envoie une demande pour cette ressource sécurisée.
WinHttpQueryDataAvailable est utilisé avec le handle de demande pour déterminer la quantité de données disponibles en téléchargement, puis WinHttpReadData est utilisé pour lire ces données. Ce processus se répète jusqu’à ce que l’intégralité du document ait été récupérée et affichée.

    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());
                break;
            }
            
            // No more available data.
            if (!dwSize)
                break;

            // Allocate space for the buffer.
            pszOutBuffer = new char[dwSize+1];
            if (!pszOutBuffer)
            {
                printf("Out of memory\n");
                break;
            }
            
            // 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;

            // This condition should never be reached since WinHttpQueryDataAvailable
            // reported that there are bits to read.
            if (!dwDownloaded)
                break;
                
        } while (dwSize > 0);
    }
    else
    {
        // Report any errors.
        printf( "Error %d has occurred.\n", GetLastError() );
    }

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

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows XP, Windows 2000 Professionnel avec SP3 [applications de bureau uniquement]
Serveur minimal pris en charge Windows Server 2003, Windows 2000 Server avec SP3 [applications de bureau uniquement]
Plateforme cible Windows
En-tête winhttp.h
Bibliothèque Winhttp.lib
DLL Winhttp.dll
Composant redistribuable WinHTTP 5.0 et Internet Explorer 5.01 ou version ultérieure sur Windows XP et Windows 2000.

Voir aussi

À propos de Microsoft Windows HTTP Services (WinHTTP)

WinHTTP Versions

WinHttpCloseHandle

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest

WinHttpQueryDataAvailable

WinHttpSendRequest

WinHttpWriteData