Partager via


Vue d’ensemble des sessions WinHTTP

Les services HTTP Microsoft Windows (WinHTTP) exposent un ensemble de fonctions C/C++ qui permettent à votre application d’accéder aux ressources HTTP sur le Web. Cette rubrique fournit une vue d’ensemble de la façon dont ces fonctions sont utilisées pour interagir avec un serveur HTTP.

Utilisation de l’API WinHTTP pour accéder au web

Le diagramme suivant montre l’ordre dans lequel les fonctions WinHTTP sont généralement appelées lors de l’interaction avec un serveur HTTP. Les zones ombrées représentent des fonctions qui génèrent un handle HINTERNET , tandis que les zones simples représentent des fonctions qui utilisent ces handles.

fonctions qui créent des handles

Initialisation de WinHTTP

Avant d’interagir avec un serveur, WinHTTP doit être initialisé en appelant WinHttpOpen. WinHttpOpen crée un contexte de session pour conserver les détails de la session HTTP et retourne un handle de session. À l’aide de ce handle, la fonction WinHttpConnect peut ensuite spécifier un serveur HTTP ou HTTPS (Secure Hypertext Transfer Protocol).

Notes

Un appel à WinHttpConnect n’entraîne pas une connexion réelle au serveur HTTP tant qu’une demande n’est pas effectuée pour une ressource spécifique.

 

Ouverture d’une demande

La fonction WinHttpOpenRequest ouvre une requête HTTP pour une ressource particulière et retourne un handle HINTERNET qui peut être utilisé par les autres fonctions HTTP. WinHttpOpenRequest n’envoie pas la demande au serveur lorsqu’elle est appelée. La fonction WinHttpSendRequest établit une connexion sur le réseau et envoie la requête.

L’exemple suivant montre un exemple d’appel à WinHttpOpenRequest qui utilise les options par défaut.

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

Ajout d’en-têtes de requête

La fonction WinHttpAddRequestHeaders permet à une application d’ajouter des en-têtes de requête de format libre supplémentaires au handle de requête HTTP. Il est destiné à être utilisé par des applications sophistiquées qui nécessitent un contrôle précis sur les requêtes envoyées au serveur HTTP.

La fonction WinHttpAddRequestHeaders nécessite un handle de requête HTTP créé par WinHttpOpenRequest, une chaîne qui contient les en-têtes, la longueur des en-têtes et les modificateurs éventuels.

Les modificateurs suivants peuvent être utilisés avec WinHttpAddRequestHeaders.

Modificateur Description
WINHTTP_ADDREQ_FLAG_ADD Ajoute l’en-tête s’il n’existe pas. Utilisé avec WINHTTP_ADDREQ_FLAG_REPLACE.
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW Ajoute l’en-tête uniquement s’il n’existe pas déjà ; sinon, une erreur est retournée.
WINHTTP_ADDREQ_FLAG_COALESCE Fusionne les en-têtes du même nom.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA Fusionne les en-têtes du même nom à l’aide d’une virgule. Par exemple, l’ajout de « Accept: text/* » suivi de « Accept : audio/* » avec cet indicateur forme l’en-tête unique « Accept: text/*, audio/* », ce qui entraîne la fusion du premier en-tête. Il incombe à l’application appelante de garantir un schéma cohérent en ce qui concerne les en-têtes fusionnés/distincts.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON Fusionne les en-têtes du même nom à l’aide d’un point-virgule.
WINHTTP_ADDREQ_FLAG_REPLACE Remplace ou supprime un en-tête. Si la valeur de l’en-tête est vide et que l’en-tête est trouvé, il est supprimé. Si la valeur d’en-tête n’est pas vide, la valeur d’en-tête est remplacée.

 

Envoi d’une demande

La fonction WinHttpSendRequest établit une connexion au serveur et envoie la demande au site spécifié. Cette fonction nécessite un handle HINTERNET créé par WinHttpOpenRequest. WinHttpSendRequest peut également envoyer des en-têtes supplémentaires ou des informations facultatives. Les informations facultatives sont généralement utilisées pour les opérations qui écrivent des informations sur le serveur, telles que PUT et POST.

Une fois la fonction WinHttpSendRequest envoyée la demande, l’application peut utiliser les fonctions WinHttpReadData et WinHttpQueryDataAvailable sur le handle HINTERNET pour télécharger les ressources du serveur.

Publication de données sur le serveur

Pour publier des données sur un serveur, le verbe HTTP dans l’appel à WinHttpOpenRequest doit être POST ou PUT. Lorsque WinHttpSendRequest est appelé, le paramètre dwTotalLength doit être défini sur la taille des données en octets. Ensuite, utilisez WinHttpWriteData pour publier les données sur le serveur.

Vous pouvez également définir le paramètre lpOptional de WinHttpSendRequest sur l’adresse d’une mémoire tampon qui contient les données à publier sur le serveur. Lorsque vous utilisez cette technique, vous devez définir les paramètres dwOptionalLength et dwTotalLength de WinHttpSendRequest pour qu’ils soient de la taille des données publiées. L’appel de WinHttpSendRequest de cette manière élimine la nécessité d’appeler WinHttpWriteData.

Obtention d’informations sur une demande

La fonction WinHttpQueryHeaders permet à une application de récupérer des informations sur une requête HTTP. La fonction nécessite un handle HINTERNET créé par WinHttpOpenRequest, une valeur au niveau des informations et une longueur de mémoire tampon. WinHttpQueryHeaders accepte également une mémoire tampon qui stocke les informations et un index d’en-tête de base zéro qui énumère plusieurs en-têtes portant le même nom.

Utilisez l’une des valeurs de niveau information de la page Indicateurs d’informations de requête avec un modificateur pour contrôler le format dans lequel les informations sont stockées dans le paramètre lpvBuffer de WinHttpQueryHeaders.

Téléchargement de ressources à partir du web

Après avoir ouvert une requête avec la fonction WinHttpOpenRequest , l’avoir envoyée au serveur avec WinHttpSendRequest et avoir préparé le handle de demande pour recevoir une réponse avec WinHttpReceiveResponse, l’application peut utiliser les fonctions WinHttpReadData et WinHttpQueryDataAvailable pour télécharger la ressource à partir du serveur HTTP.

L’exemple de code suivant montre comment télécharger une ressource avec une sémantique de transaction sécurisée. 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 est répété 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( ) );

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