Différences entre les versions de WinHTTP
En général, les titres Microsoft Game Development Kit (GDK) interagissent avec WinHTTP de la même façon que les applications Win32. Lors du développement de titres Microsoft Game Development Kit (GDK), seule l’API C/C++ plate de WinHTTP est disponible. Cela signifie que les fonctionnalités HTTP doivent être construites sur cette API cliente HTTP.Ajouter WinHTTP à votre projet pour console XBOX
Sur console, vous devez utiliser#include <winhttp.h> dans vos fichiers sources. Vous devez effectuer la liaison avec XGamePlatform.lib, plutôt que directement avec Winhttp.lib. Seules les API de la famille d’API WINAPI_PARTITION_GAMES fonctionnent dans les titres Microsoft Game Development Kit (GDK). Sur PC Windows, vous devez continuer d’effectuer la liaison avec Winhttp.lib.
Pour un exemple d’intégration de WinHTTP dans votre titre Microsoft Game Development Kit (GDK), consultez l’exemple SimpleWinHttp. Il constitue un solide point de départ pour votre propre mise en œuvre de WinHTTP et comprend la classe WinHttpManager. Celle-ci expose une surface d’API asynchrone simple.
Initialisation du réseau et WinHTTP
Avant que votre titre effectue le premier appel à WinHttpOpen, les titres Microsoft Game Development Kit (GDK) doivent s’assurer que la pile réseau est initialisée. SiWinHttpOpen est appelée trop tôt pendant le processus de lancement du titre, WinHttpOpen ou les appels WinHTTP subséquents pourraient échouer ou planter de façon non déterministe. Avant que le réseau soit déclaré initialisé, des requêtes peuvent sembler réussir alors qu’elles échouent en réalité, ou inversement. Pour savoir comment déterminer quand la pile réseau est initialisée, consultez Initialisation du réseau.
Suspension et reprise du titre et WinHTTP
Les titres doivent lancer le processus de fermeture de tous les handles WinHTTP lorsqu’une notification de suspension du titre est reçue. Le nettoyage des handles WinHTTP est asynchrone. Par conséquent, vous devez fermer vos handles dans l’ordre suivant : tous les handles de requête, puis tous les handles de connexion, puis tous les handles de session. La nature asynchrone du nettoyage des handles WinHTTP vise à garantir la sécurité des threads de notification. Même s’il est asynchrone, le nettoyage des handles WinHTTP n’entraîne aucun délai, ce qui lui permet de s’inscrire facilement dans le délai d’expiration de report de suspension d’une seconde. Lors de la reprise, les titres doivent suivre la même procédure que celle décrite dans la section précédente, Initialisation du réseau et WinHTTP, et attendre que le réseau revienne à l’état prêt avant de poursuivre l’utilisation de WinHTTP. Une longue période peut s’être écoulée entre les événements de suspension et de reprise, ce qui exige que le réseau se stabilise de nouveau avant que les API WinHTTP redeviennent déterministes.Considérations relatives à la mémoire et à la simultanéité
Le nombre de requêtes WinHTTP simultanées doit toujours être maintenu sous huit afin que l’état asynchrone de WinHTTP fonctionne correctement et respecte son budget de mémoire. Cette limite s’applique à toutes les opérations simultanées dans l’environnement d’exécution du titre, y compris les appels provenant des API des XBOX services et deXCurl.
En complément des Considérations relatives à la mémoire WinSock, lors de la réception de données, vous devez vous assurer d’avoir toujours une mémoire tampon en attente avec WinHttpReadData (ou d’attendre un rappel d’un appel à WinHttpQueryDataAvailable) afin de transférer les données des pools de mémoire en mode noyau vers votre processus en mode utilisateur le plus rapidement possible et de réduire au minimum la quantité de mémoire noyau consommée par votre opération HTTP.
La fonction d’accès WinHttpQueryHeaders nécessite des allocations de mémoire temporaires. Elle alloue une mémoire tampon de travail de taille égale au paramètre lpdwBufferLength pour usage interne (et la libère avant le retour de la fonction). Pour cette raison, vous devez utiliser le modèle de double appel avec WINHTTP_NO_OUTPUT_BUFFER pour réduire au minimum la taille des mémoires tampons de travail et limiter le nombre d’appels simultanés à WinHttpQueryHeaders afin d’éviter une utilisation excessive de la mémoire système qui pourrait entraîner une instabilité du système. La taille maximale par défaut des en-têtes est de 64 Ko, comme le spécifie l’option WinHTTP WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE.
Considérations relatives à WinHttpOpen
Indicateurs
Vous devez transmettre les indicateurs du tableau suivant à WinHttpOpen.
La combinaison de
WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME et WINHTTP_NO_PROXY_BYPASS permet à la plateforme Microsoft Game Development Kit (GDK) de gérer automatiquement les proxys tels que Fiddler et d’autres environnements réseau atypiques.
L’indicateur WINHTTP_FLAG_SECURE_DEFAULTS est un nouvel indicateur conçu pour aider les titres Microsoft Game Development Kit (GDK) à respecter les meilleures pratiques de sécurité en définissant le comportement de connexion sécurisée recommandé. Il est disponible sur les consoles XBOX One et le sera sur PC Windows dans une future mise à jour du système d’exploitation Windows. Tenter de transmettre WINHTTP_FLAG_SECURE_DEFAULTS sur les versions existantes du système d’exploitation Windows entraîne un échec pour paramètre non valide. Cet indicateur a un effet secondaire important : il force WinHTTP en mode asynchrone, car il inclut implicitement l’indicateur WINHTTP_FLAG_ASYNC. Sur les versions du système d’exploitation Windows pour PC qui ne prennent pas en charge cet indicateur, vous devez plutôt transmettre WINHTTP_FLAG_ASYNC afin de réduire au minimum les différences dans le reste de votre mise en œuvre de WinHTTP.
L’indicateur
WINHTTP_FLAG_SECURE_DEFAULTS exige qu’un indicateur WINHTTP_FLAG_SECURE correspondant soit transmis à WinHttpOpenRequest et bloque les requêtes HTTP non chiffrées. Sur les trousses de développement, pour le débogage et les tests internes, vous pouvez créer un handle de session WinHTTP et spécifier l’indicateur WINHTTP_FLAG_ASYNC à WinHttpOpen. Cet indicateur vous permet d’effectuer une requête HTTP non chiffrée pendant le développement en ne spécifiant pas l’indicateur WINHTTP_FLAG_SECURE à WinHttpOpenRequest. Vous devez tout de même utiliser des handles de session ouverts avec WINHTTP_FLAG_SECURE_DEFAULTS pour le trafic hors débogage afin de reproduire le comportement des requêtes que votre titre observe en RETAIL.WINHTTP_OPTION_SECURE_PROTOCOLS
Après avoir créé un nouveau handle de session avecWinHttpOpen, vous devez appeler WinHttpSetOption avec l’option WINHTTP_OPTION_SECURE_PROTOCOLS et transmettre la valeur XNetworkingSecurityInformation::enabledHttpSecurityProtocolFlags correspondante, récupérée par un appel à XNetworkingQuerySecurityInformationForUrlUtf16Async pour une URL correspondante pour laquelle ce handle de session sera utilisé. Vous devez également stocker la structure XNetworkingSecurityInformation dans votre objet de contexte pour l’utiliser plus tard lors de la validation de la négociation TLS/SSL.
Mise en cache des handles de session
Les handles de session HTTP créés au moyen deWinHttpOpen sont coûteux en mémoire et entraînent un coût de démarrage important qui retarde la première requête HTTP. Nous vous recommandons de mettre en cache les handles de session HTTP autant que possible dans votre titre pour éviter ces coûts.
Toutefois, il n’est pas possible de modifier l’option WINHTTP_OPTION_SECURE_PROTOCOLS sur un handle de session. Vous devez conserver un cache des valeurs XNetworkingSecurityInformation::enabledHttpSecurityProtocolFlags associées aux handles de session WinHTTP afin de vous assurer d’avoir un handle de session différent pour chaque indicateur de protocole sécurisé différent.
Le cache maintenu par votre titre doit être vidé lors des notifications de suspension et doit être reconstruit de zéro lors de la reprise (après avoir attendu que le réseau soit initialisé).
Considérations relatives à WinHttpConnect
Contrairement aux handles de session, les handles de connexion créés au moyen de WinHttpConnect ne doivent jamais être mis en cache. De nouveaux handles doivent être créés pour chaque nouvelle requête ou nouvelle tentative. Malgré leur nom, les handles de connexion WinHTTP n’ont aucun lien avec les connexions TCP (Transmission Control Protocol) sous-jacentes au serveur. WinHTTP gère la durée de vie des connexions sous-jacentes au serveur avec le handle de session et réutilise automatiquement les connexions ouvertes au serveur, lorsque c’est possible, pour les nouveaux handles de connexion.Canonisation des URL
WinHTTP s’attend à ce que toutes les URL soient canonisées en caractères US-ASCII a-z, A-Z et 0-9. Pour plus d’informations sur la canonisation, consultez Uniform Resource Locators (URL) dans WinHTTP. Dans la mesure du possible, nous vous recommandons de coder en dur les URL utilisées par votre titre sous forme canonisée. Cette forme évite les allocations de mémoire et les problèmes de performances qu’entraîne l’utilisation des fonctions WinHttpCrackUrl et WinHttpCreateUrl pour canoniser dynamiquement vos URL.Fractionnement des URL
WinHTTP exige qu’une chaîne de nom d’hôte terminée par un caractère nul soit transmise àWinHttpConnect, tandis que le chemin et l’objet sont transmis à WinHttpOpenRequest. Votre titre doit transmettre à certains endroits l’URL complète, soit le nom d’hôte et le chemin concaténés, et à d’autres seulement le nom d’hôte ou le chemin. Nous vous recommandons de coder les deux en dur dans votre titre afin d’éviter d’avoir à utiliser WinHttpCrackUrl et WinHttpCreateUrl pour concaténer ou fractionner dynamiquement les URL.
Considérations relatives à WinHttpOpenRequest
Comme les handles de connexion WinHTTP, les handles de requête WinHTTP créés au moyen de la fonction WinHttpOpenRequest ne doivent jamais être mis en cache. De nouveaux handles doivent être créés pour chaque nouvelle requête ou nouvelle tentative. Comme meilleure pratique de sécurité, les titres doivent toujours transmettre l’indicateurWINHTTP_FLAG_SECURE pour le paramètre dwFlags lors de l’appel de la fonction WinHttpOpenRequest.
Récupération et application des jetons des XBOX services
Les jetons ne sont pas insérés automatiquement pour les titres Microsoft Game Development Kit (GDK). Le titre doit plutôt récupérer les jetons et les signatures d’authentification des XBOX services avec les API XUser du Microsoft Game Development Kit (GDK). Une fois que le titre dispose d’un utilisateur, il doit appeler XUserGetTokenAndSignatureUtf16Async pour récupérer les chaînes de jeton et de signature pour chaque requête individuelle. Ces deux chaînes doivent ensuite être transmises comme en-têtes dans l’appel àWinHttpAddRequestHeadersEx, WinHttpSendRequest ou WinHttpAddRequestHeaders.
Pour générer une signature appropriée, XUserGetTokenAndSignatureUtf16Async s’attend à ce que le titre transmette tous les en-têtes et le corps complet. Pour un POST ou un PUT avec un corps volumineux, le titre peut transmettre un sous-ensemble du corps qui a été configuré dans l’Espace partenaires. Pour plus d’informations, consultez Services web (rubrique sous NDA). Pour le moment, le réseau XBOX ne fournit aucun mécanisme permettant de récupérer cette configuration. Les clients doivent soit coder les valeurs en dur, soit les récupérer au moyen d’un point de terminaison personnalisé propre au titre.
XUserGetTokenAndSignatureUtf16Async effectue en interne toute la mise en cache nécessaire et doit être appelée pour chaque tentative HTTP, y compris une nouvelle tentative. Si le titre reçoit un code d’état de réponse HTTP 401 Unauthorized pour une requête HTTP, il doit réessayer la requête et forcer l’actualisation du jeton d’authentification des XBOX services. Cette actualisation s’effectue en récupérant un nouveau jeton avec XUserGetTokenAndSignatureUtf16Async et en transmettant la valeur d’énumération XUserGetTokenAndSignatureOptions::ForceRefresh.
Une fois que le titre dispose des données XUserGetTokenAndSignatureUtf16Data récupérées par un appel à XUserGetTokenAndSignatureUtf16Async, il doit transformer XUserGetTokenAndSignatureUtf16Data::Token et XUserGetTokenAndSignatureUtf16Data::Signature en en-têtes HTTP à transmettre à WinHTTP. Une nouvelle API WinHTTP, WinHttpAddRequestHeadersEx, a été ajoutée précisément pour réduire la complexité pour les titres Microsoft Game Development Kit (GDK). Un exemple d’utilisation de cette nouvelle API est présenté ci-dessous. Cette nouvelle API est disponible sur les consoles XBOX One et le sera sur PC Windows dans une future mise à jour du système d’exploitation Windows. Sur console, nous vous recommandons d’utiliser WinHttpAddRequestHeadersEx pour éviter les allocations supplémentaires et les changements de format de chaîne.
L’appareil ou un compte connecté doit avoir accès au bac à sable auquel il est associé. Sinon,
XUserGetTokenAndSignatureUtf16Data échoue.Utilisation de la liste d’autorisation de sécurité réseau XBOX (NSAL)
Le réseau XBOX utilise la NSAL pour s’assurer que les clients établissent des connexions sécurisées et authentifiées avec vos services web. Les titres gèrent le contenu de la NSAL dans le cadre de leur configuration dans l’Espace partenaires. Pour plus d’informations, consultez Configuration des services web dans l’Espace partenaires (rubrique sous NDA). La configuration de la NSAL est ensuite téléchargée automatiquement pour chaque titre. Elle sert à la fois à générer les jetons des XBOX services appropriés et à effectuer l’épinglage de certificats pour les points de terminaison propres à votre titre.}Considérations relatives à la machine à états asynchrone de WinHTTP
La machine à états asynchrone de WinHTTP est la même sur console que sur PC Windows. Pour inscrire une fonction de rappel pour une ou plusieurs notifications, utilisez la fonction WinHttpSetStatusCallback. Nous recommandons d’utiliser l’indicateurWINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS pour le paramètre dwNotificationFlags à des fins de débogage, car WinHTTP est relativement détaillé et transparent sur ce qu’il fait. Bien que la plupart des notifications ne nécessitent aucune action de votre part, la journalisation des données peut être utile pour découvrir la cause racine des problèmes.
WinHTTP utilise un seul thread pour les notifications. Les titres doivent éviter autant que possible de bloquer une fonction de notification, car cela empêche la progression de toutes les requêtes HTTP de votre processus. Les notifications non traitées peuvent également augmenter la mémoire en mode noyau, ce qui peut entraîner des plantages.
WinHTTP ne copie pas vos mémoires tampons d’envoi ou de réception et exige que vous les gardiez allouées jusqu’au rappel d’achèvement correspondant. Assurez-vous de garder vos mémoires tampons d’envoi allouées et valides à partir du moment où vous appelez WinHttpSendRequest jusqu’à la réception de la notification WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE correspondante. De même, chaque fois que vous appelez WinHttpReadData, assurez-vous de garder votre mémoire tampon de réception allouée et valide jusqu’à la réception de la notification WINHTTP_CALLBACK_STATUS_READ_COMPLETE correspondante. Nous recommandons également d’utiliser une mémoire tampon de réception d’au moins 8 Ko pour éviter les problèmes de récursion pouvant entraîner l’épuisement de la pile.
Les titres doivent également s’assurer que les mémoires tampons WinHTTP sont correctement vidées en poursuivant le cycle asynchrone WinHttpQueryDataAvailable/WinHttpReadData et en ne bloquant jamais les rappels WinHTTP.
Validation de la négociation TLS (Transport Layer Security)/SSL (Secure Sockets Layer)
Comme meilleure pratique de sécurité, les titres doivent valider la négociation TLS/SSL et utiliser uniquement TLS 1.2. Une validation supplémentaire est effectuée dans la notificationWINHTTP_CALLBACK_STATUS_SENDING_REQUEST. Dans cette notification, vous devez appeler la fonction XNetworkingVerifyServerCertificate et transmettre la structure XNetworkingSecurityInformation récupérée lors d’un appel correspondant précédent à XNetworkingQuerySecurityInformationForUrlUtf16Async. Cette fonction échoue si la chaîne de certificats n’est pas valide. Vous devez fermer immédiatement le handle WinHTTP avant la fin du rappel afin de garantir qu’aucune donnée n’est transférée vers le serveur compromis ou à partir de celui-ci.
En plus de valider les chaînes de certificats, la fonction XNetworkingVerifyServerCertificate est requise pour le fonctionnement de Fiddler sur console.
Débogage de WinHTTP
Fiddler est un outil utile pour afficher et déboguer votre trafic WinHTTP. Pour que Fiddler capture le trafic de votre titre, vous devez transmettre les indicateursWINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME et WINHTTP_NO_PROXY_BYPASS à WinHttpOpen. Vous devez également appeler XNetworkingVerifyServerCertificate dans le rappel de la notification WINHTTP_CALLBACK_STATUS_SENDING_REQUEST.
HTTP Monitor ne fonctionne pas avec les titres Microsoft Game Development Kit (GDK).
Documentation de référence des API
- Xuser (contenu de l’API)
- Fonctions
- Structures
- xnetworking (contenu de l’API)
