Partager via


Portage d’applications WinINet vers WinHTTP

Microsoft Windows HTTP Services (WinHTTP) est destiné aux applications serveur de niveau intermédiaire et principal qui nécessitent l’accès à une pile de clients HTTP. Microsoft Windows Internet (WinINet) fournit une pile de clients HTTP pour les applications clientes, ainsi qu’un accès aux protocoles FTP (File Transfer Protocol), SOCKSv4 et Gopher. Cette vue d’ensemble peut vous aider à déterminer si le portage de vos applications WinINet vers WinHTTP serait bénéfique. Il décrit également les exigences de conversion spécifiques.

Éléments à prendre en compte avant le portage de votre application WinINet

Envisagez de porter votre application WinINet vers WinHTTP si votre application bénéficie des avantages suivants :

  • Pile de clients HTTP sécurisés pour le serveur.
  • Utilisation réduite de la pile.
  • Scalabilité d’une application serveur.
  • Moins de dépendances sur les API liées à la plateforme.
  • Prise en charge de l’emprunt d’identité de thread.
  • Une pile HTTP conviviale.
  • Accès à l’objet WinHttpRequest avec script.

N’envisagez pas de porter votre application WinINet vers WinHTTP si elle doit prendre en charge un ou plusieurs des éléments suivants :

  • Protocole FTP ou Gopher de la pile HTTP.
  • Prise en charge du protocole SOCKSv4 pour la communication avec les proxys SOCKS.
  • Services d’accès à distance automatique.

Si vous décidez de porter votre application vers WinHTTP, les sections suivantes vous guident tout au long du processus de conversion.

Pour obtenir un exemple d’application pour WinINet et WinHTTP, comparez l’exemple AsyncDemo pour WinINet à l’exemple AsyncDemo pour WinHTTP.

WinHTTP Équivalents aux fonctions WinINet

Le tableau suivant répertorie les fonctions WinINet liées à la pile de clients HTTP avec les équivalents WinHTTP.

Si votre application nécessite des fonctions WinINet qui ne sont pas répertoriées, ne transférez pas votre application vers WinHTTP.

Fonction WinINet Équivalent WinHTTP Modifications notables
HttpAddRequestHeaders WinHttpAddRequestHeaders Aucun.
HttpEndRequest WinHttpReceiveResponse La valeur de contexte est définie avec WinHttpSendRequest ou WinHttpSetOption. Les options de requête sont définies avec WinHttpOpenRequest. WinHttpReceiveResponse doit être appelé après l’envoi d’une demande.
HttpOpenRequest WinHttpOpenRequest La valeur de contexte est définie avec WinHttpSendRequest ou WinHttpSetOption.
HttpQueryInfo WinHttpQueryHeaders Aucun.
HttpSendRequest WinHttpSendRequest La valeur de contexte peut être définie avec WinHttpSendRequest.
HttpSendRequestEx WinHttpSendRequest Impossible de fournir des mémoires tampons.
InternetCanonicalizeUrl Pas d'équivalent Les URL sont désormais placées sous forme canonique dans WinHttpOpenRequest.
InternetCheckConnection Pas d'équivalent Non implémenté dans WinHTTP.
InternetCloseHandle WinHttpCloseHandle La fermeture d’un handle parent dans WinHTTP ne ferme pas les handles enfants de manière récursive.
InternetCombineUrl Pas d'équivalent Les URL peuvent être assemblées avec la fonction WinHttpCreateUrl .
InternetConfirmZoneCrossing Pas d'équivalent Non implémenté dans WinHTTP.
InternetConnect WinHttpConnect La valeur de contexte est définie avec WinHttpSendRequest ou WinHttpSetOption. Les options de requête sont définies avec WinHttpOpenRequest. Les informations d’identification de l’utilisateur sont définies avec WinHttpSetCredentials.
InternetCrackUrl WinHttpCrackUrl Comportement opposé de l’indicateur ICU_ESCAPE : avec InternetCrackUrl, cet indicateur entraîne la conversion des séquences d’échappement (%xx) en caractères, mais avec WinHttpCrackUrl, il entraîne la conversion en séquences d’échappement des caractères qui doivent être placés dans une requête HTTP en séquences d’échappement.
InternetCreateUrl WinHttpCreateUrl Aucun.
InternetErrorDlg Pas d'équivalent Étant donné que WinHTTP est destiné aux applications côté serveur, il n’implémente aucune interface utilisateur.
InternetGetCookie Pas d'équivalent WinHTTP ne conserve pas les données entre les sessions et ne peut pas accéder aux cookies WinINet.
InternetOpen WinHttpOpen Aucun.
InternetOpenUrl WinHttpConnect, WinHttpOpenRequest, WinHttpSendRequest, WinHttpReceiveResponse Cette fonctionnalité est disponible dans les fonctions WinHTTP répertoriées.
InternetQueryDataAvailable WinHttpQueryDataAvailable Aucun paramètre réservé.
InternetQueryOption WinHttpQueryOption WinHTTP offre un ensemble d’options différent de WinINet. Pour plus d’informations et les options offertes par WinHTTP, consultez Indicateurs d’option.
InternetReadFile WinHttpReadData Aucun.
InternetReadFileEx WinHttpReadData Plutôt qu’une structure, la mémoire tampon est une région de mémoire traitée avec un pointeur.
InternetSetOption WinHttpSetOption Aucun.
InternetSetStatusCallback WinHttpSetStatusCallback Pour plus d’informations, consultez « Gestion différente des demandes asynchrones » dans cette rubrique.
InternetTimeFromSystemTime WinHttpTimeFromSystemTime Aucun.
InternetTimeToSystemTime WinHttpTimeToSystemTime Aucun.
InternetWriteFile WinHttpWriteData Aucun.

 

Gestion différente des demandes asynchrones

N’oubliez pas que dans WinINet et WinHTTP, certaines fonctions peuvent effectuer des requêtes asynchrones de manière synchrone ou asynchrone. Votre application doit gérer l’une ou l’autre des situations. Il existe des différences significatives dans la façon dont WinINet et WinHTTP gèrent ces fonctions potentiellement asynchrones.

Wininet

  • Achèvement synchrone : si un appel de fonction WinINet potentiellement asynchrone se termine de manière synchrone, les paramètres OUT de la fonction retournent les résultats de l’opération. Lorsqu’une erreur se produit, récupérez le code d’erreur en appelant GetLastError après l’appel de fonction WinINet.

  • Achèvement asynchrone : si un appel de fonction potentiellement asynchrone se termine de manière asynchrone, les résultats de l’opération et les erreurs éventuelles sont accessibles dans la fonction de rappel. La fonction de rappel est exécutée sur un thread de travail, et non sur le thread qui a effectué l’appel de fonction initial.

En d’autres termes, votre application doit dupliquer la logique pour gérer les résultats de telles opérations à deux endroits : immédiatement après l’appel de fonction et dans la fonction de rappel.

WinHTTP simplifie ce modèle en vous permettant d’implémenter la logique opérationnelle uniquement dans la fonction de rappel, qui reçoit une notification d’achèvement, que l’opération se soit terminée de manière synchrone ou asynchrone. Lorsque l’opération asynchrone est activée, les paramètres OUT des fonctions WinHTTP ne retournent pas de données significatives et doivent être définis sur NULL.

La seule différence significative entre l’exécution asynchrone et synchrone dans WinHTTP, du point de vue de l’application, réside dans l’emplacement où la fonction de rappel est exécutée.

WinHTTP

  • Achèvement synchrone : lorsqu’une opération se termine de manière synchrone, les résultats sont retournés dans une fonction de rappel qui s’exécute dans le même thread que l’appel de fonction d’origine.

  • Achèvement asynchrone : lorsqu’une opération se termine de manière asynchrone, les résultats sont retournés dans une fonction de rappel qui s’exécute dans un thread de travail.

Bien que la plupart des erreurs puissent également être gérées entièrement dans la fonction de rappel, les applications WinHTTP doivent toujours être préparées pour qu’une fonction retourne FALSE en raison d’une ERROR_INVALID_PARAMETER ou d’une autre erreur similaire récupérée en appelant GetLastError.

Contrairement à WinINet, qui peut exécuter plusieurs opérations asynchrones simultanément, WinHTTP applique une stratégie d’une opération asynchrone en attente par handle de requête. Si une opération est en attente et qu’une autre fonction WinHTTP est appelée, la deuxième fonction échoue et GetLastError retourne ERROR_INVALID_OPERATION.

WinHTTP simplifie ce modèle en vous permettant d’implémenter la logique opérationnelle uniquement dans la fonction de rappel, qui reçoit une notification d’achèvement, que l’opération se soit terminée de manière synchrone ou asynchrone. Lorsque l’opération asynchrone est activée, les paramètres OUT des fonctions WinHTTP ne retournent pas de données significatives et doivent être définis sur NULL.

Différences dans les notifications de rappel WinHTTP

La fonction de rappel status reçoit des mises à jour sur la status des opérations via des indicateurs de notification. Dans WinHTTP, les notifications sont sélectionnées à l’aide du paramètre dwNotificationFlags de la fonction WinHttpSetStatusCallback . Utilisez l’indicateur WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS pour être informé de toutes les mises à jour status.

Les notifications qui indiquent qu’une opération particulière est terminée sont appelées notifications d’achèvement, ou simplement achèvements. Dans WinINet, chaque fois que la fonction de rappel reçoit une fin, le paramètre lpvStatusInformation contient une structure INTERNET_ASYNC_RESULT . Dans WinHTTP, cette structure n’est pas disponible pour toutes les complétions. Il est important de consulter la page de référence pour WINHTTP_STATUS_CALLBACK, qui contient des informations sur les notifications et le type de données à attendre pour chacune d’elles.

Dans WinHTTP, une seule saisie semi-automatique , WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, indique qu’une opération a échoué. Toutes les autres saisies indiquent une opération réussie.

WinINet et WinHTTP utilisent une valeur de contexte définie par l’utilisateur pour transmettre des informations du thread main à la fonction de rappel status, qui peut être exécutée sur un thread de travail. Dans WinINet, la valeur de contexte utilisée par la fonction de rappel status est définie en appelant l’une des fonctions suivantes. Dans WinHTTP, la valeur de contexte est définie uniquement avec WinHttpSendRequest ou WinHttpSetOption. Pour cette raison, il est possible dans WinHTTP qu’une notification se produise avant qu’une valeur de contexte soit définie. Si la fonction de rappel reçoit une notification avant que la valeur de contexte soit définie, l’application doit être prête à recevoir NULL dans le paramètre dwContext de la fonction de rappel.

Différences d’authentification

Dans WinINet, les informations d’identification de l’utilisateur sont définies en appelant la fonction InternetSetOption , à l’aide d’un code similaire à celui fourni dans l’exemple de code suivant.

// Use the WinINet InternetSetOption function to set the 
// user credentials to the user name contained in strUsername 
// and the password to the contents of strPassword.
       
InternetSetOption( hRequest, INTERNET_OPTION_PROXY_USERNAME, 
                   strUsername, strlen(strUsername) + 1 );

InternetSetOption( hRequest, INTERNET_OPTION_PROXY_PASSWORD, 
                   strPassword, strlen(strPassword) + 1 );

Pour la compatibilité, les informations d’identification utilisateur peuvent être définies de la même façon dans WinHTTP à l’aide de la fonction WinHttpSetOption , mais cela n’est pas recommandé, car cela peut présenter une vulnérabilité de sécurité.

Au lieu de cela, lorsqu’une application reçoit un code 401 status dans WinHTTP, la méthode recommandée pour définir les informations d’identification consiste d’abord à identifier un schéma d’authentification à l’aide de WinHttpQueryAuthSchemes et, deuxièmement, à définir les informations d’identification à l’aide de WinHttpSetCredentials. L’exemple de code suivant montre comment procéder.

DWORD dwSupportedSchemes;
DWORD dwPrefered;
DWORD dwTarget;

// Obtain the supported and first schemes.
WinHttpQueryAuthSchemes( hRequest, &dwSupportedSchemes, &dwPrefered, &dwTarget );

// Set the credentials before resending the request.
WinHttpSetCredentials( hRequest, dwTarget, dwPrefered, strUsername, strPassword, NULL );

Étant donné qu’il n’existe pas d’équivalent à InternetErrorDlg dans WinHTTP, les applications qui obtiennent des informations d’identification via une interface utilisateur doivent fournir leur propre interface.

Contrairement à WinINet, WinHTTP ne met pas en cache les mots de passe. Des informations d’identification utilisateur valides doivent être fournies pour chaque requête.

WinHTTP ne prend pas en charge le schéma d’authentification par mot de passe distribué (DPA) pris en charge par WinINet. WinHTTP prend toutefois en charge Microsoft Passport 1.4. Pour plus d’informations sur l’utilisation de l’authentification Passport dans WinHTTP, consultez Authentification passport dans WinHTTP.

WinHTTP ne s’appuie pas sur les paramètres de Explorer Internet pour déterminer la stratégie d’ouverture de session automatique. Au lieu de cela, la stratégie d’ouverture de session automatique est définie avec WinHttpSetOption. Pour plus d’informations sur l’authentification dans WinHTTP, y compris la stratégie d’ouverture de session automatique, consultez Authentification dans WinHTTP.

Différences dans les transactions HTTP sécurisées

Dans WinINet, lancez une session sécurisée à l’aide de HttpOpenRequest ou d’InternetConnect, mais dans WinHTTP, vous devez appeler WinHttpOpenRequest à l’aide de l’indicateur WINHTTP_FLAG_SECURE .

Dans une transaction HTTP sécurisée, les certificats de serveur peuvent être utilisés pour authentifier un serveur auprès du client. Dans WinINet, si un certificat de serveur contient des erreurs, HttpSendRequest échoue et fournit des détails sur les erreurs de certificat.

Dans WinHttp, les erreurs de certificat de serveur sont gérées en fonction de la version comme suit :

  • À compter de WinHttp 5.1, si un certificat de serveur échoue ou contient des erreurs, l’appel à WinHttpSendRequest signale un WINHTTP_CALLBACK_STATUS_SECURE_FAILURE dans la fonction de rappel. Si l’erreur générée par WinHttpSendRequest est ignorée, les appels ultérieurs à WinHttpReceiveResponse échouent avec une erreur ERROR_WINHTTP_OPERATION_CANCELLED.
  • Dans WinHTTP 5.0, les erreurs dans les certificats de serveur ne provoquent pas, par défaut, l’échec d’une demande. Au lieu de cela, les erreurs sont signalées dans la fonction de rappel avec la notification WINHTTP_CALLBACK_STATUS_SECURE_FAILURE .

Sur certaines plateformes antérieures, WinINet prend en charge les protocoles PCT (Private Communication Technology) et/ou Fortezza, mais pas sur Windows XP.

WinHTTP ne prend pas en charge les protocoles PCT et Fortezza sur n’importe quelle plateforme, et s’appuie plutôt sur SSL (Secure Sockets Layer) 2.0, SSL 3.0 ou TLS (Transport Layer Security) 1.0.