Diferencias de versión de WinHTTP
En general, los títulos del Microsoft Game Development Kit (GDK) interactúan con WinHTTP de la misma manera que interactúan con WinHTTP en aplicaciones Win32. Al desarrollar títulos del Microsoft Game Development Kit (GDK), solo está disponible la API plana de C/C++ de WinHTTP. Esto significa que las funcionalidades HTTP deben crearse sobre esta API cliente HTTP.Agregar WinHTTP a su proyecto de consola XBOX
En consola, debe incluir#include <winhttp.h> en sus archivos de código fuente. Debe vincular con XGamePlatform.lib, en lugar de directamente con Winhttp.lib. Solo las API de la familia de API WINAPI_PARTITION_GAMES funcionan en títulos del Microsoft Game Development Kit (GDK). En PC con Windows, debe seguir vinculando con Winhttp.lib.
Para ver un ejemplo de cómo integrar WinHTTP en su título del Microsoft Game Development Kit (GDK), consulte el ejemplo SimpleWinHttp. Proporciona un sólido punto de partida para su propia implementación de WinHTTP e incluye la clase WinHttpManager. Expone una superficie de API asincrónica sencilla.
Inicialización de la red y WinHTTP
Antes de que su título realice la primera llamada a WinHttpOpen, los títulos del Microsoft Game Development Kit (GDK) deben asegurarse de que la pila de red esté inicializada. Si se llama aWinHttpOpen demasiado pronto durante el proceso de inicio del título, WinHttpOpen o las llamadas posteriores a WinHTTP podrían producir errores o bloquearse de forma no determinista. Las solicitudes pueden parecer que se completan correctamente pero fallar en realidad, o viceversa, antes de que la red se declare inicializada. Para obtener más información sobre cómo determinar cuándo está inicializada la pila de red, consulte Inicialización de la red.
Suspensión/reanudación del título y WinHTTP
Los títulos deben iniciar el proceso de cierre de todos los identificadores de WinHTTP cuando se reciba una notificación de suspensión del título. La limpieza de los identificadores de WinHTTP es asincrónica. Como resultado, debe cerrar sus identificadores en el orden siguiente: todos los identificadores de solicitud, seguidos de todos los identificadores de conexión y, después, todos los identificadores de sesión. La naturaleza asincrónica de la limpieza de identificadores de WinHTTP tiene como fin garantizar la seguridad de los subprocesos de notificación. Aunque es asincrónica, la limpieza de identificadores de WinHTTP no se demora durante ningún período de tiempo, lo que hace que encaje fácilmente dentro del tiempo de espera de aplazamiento de suspensión de un segundo. Al reanudarse, los títulos deben seguir el mismo procedimiento descrito en la sección anterior Inicialización de la red y WinHTTP, y esperar a que la red vuelva al estado listo antes de continuar con el uso de WinHTTP. Es posible que haya transcurrido un largo período de tiempo entre los eventos de suspensión y reanudación, por lo que la red debe estabilizarse de nuevo antes de que las API de WinHTTP vuelvan a ser deterministas.Consideraciones sobre memoria y simultaneidad
El número de solicitudes WinHTTP simultáneas siempre debe mantenerse por debajo de ocho para garantizar que el estado asincrónico dentro de WinHTTP funcione correctamente y dentro de su presupuesto de memoria. Este límite se aplica a todas las operaciones simultáneas dentro del entorno de ejecución del título, incluidas las llamadas desde las API de servicios de XBOX yXCurl.
Como extensión de las consideraciones sobre la memoria de WinSock, debe asegurarse de que, al recibir datos, siempre tenga un búfer pendiente con WinHttpReadData (o esté esperando una devolución de llamada de una llamada a WinHttpQueryDataAvailable) para transferir los datos a su proceso en modo usuario desde los grupos de memoria en modo kernel lo más rápido posible y minimizar la cantidad de memoria del kernel consumida por su operación HTTP.
La función captadora WinHttpQueryHeaders requiere asignaciones de memoria transitorias. Asigna un búfer temporal de tamaño igual al parámetro lpdwBufferLength para uso interno (y lo libera antes de que la función devuelva el control). Por este motivo, debe usar el patrón de doble llamada WINHTTP_NO_OUTPUT_BUFFER para minimizar el tamaño de los búferes temporales y limitar cuántas llamadas simultáneas a WinHttpQueryHeaders realiza a la vez, para evitar un uso excesivo de la memoria del sistema que podría provocar inestabilidad en el sistema. El tamaño máximo predeterminado de los encabezados es de 64 KB, tal como especifica la opción de WinHTTP WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE.
Consideraciones sobre WinHttpOpen
Marcas
Debe pasar las marcas de la tabla siguiente a WinHttpOpen.
La combinación de
WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME y WINHTTP_NO_PROXY_BYPASS permite a la plataforma del Microsoft Game Development Kit (GDK) gestionar automáticamente proxies como Fiddler y otros entornos de red de casos extremos.
La marca WINHTTP_FLAG_SECURE_DEFAULTS es una nueva marca diseñada para ayudar a los títulos del Microsoft Game Development Kit (GDK) a cumplir los procedimientos recomendados de seguridad estableciendo el comportamiento de conexión segura recomendado. Está disponible en consolas XBOX One y estará disponible en PC con Windows en una futura actualización del sistema operativo Windows. Intentar pasar WINHTTP_FLAG_SECURE_DEFAULTS en las versiones existentes del sistema operativo Windows produce un error de parámetro no válido. Esta marca tiene un efecto secundario significativo: fuerza a WinHTTP a entrar en modo asincrónico porque esta marca incluye implícitamente la marca WINHTTP_FLAG_ASYNC. En las versiones del sistema operativo Windows para PC que no admiten esta marca, debe pasar WINHTTP_FLAG_ASYNC en su lugar para minimizar las diferencias en el resto de su implementación de WinHTTP.
La marca
WINHTTP_FLAG_SECURE_DEFAULTS requiere una marca WINHTTP_FLAG_SECURE correspondiente pasada a WinHttpOpenRequest y bloquea las solicitudes HTTP sin cifrar. En los kits de desarrollo, para depuración y pruebas internas, puede crear un identificador de sesión de WinHTTP y especificar la marca WINHTTP_FLAG_ASYNC a WinHttpOpen. Esta marca le permite realizar una solicitud HTTP sin cifrar durante el desarrollo si no especifica la marca WINHTTP_FLAG_SECURE a WinHttpOpenRequest. Aun así, debe usar identificadores de sesión abiertos con WINHTTP_FLAG_SECURE_DEFAULTS para el tráfico que no sea de depuración, con el fin de igualar el comportamiento de solicitud que su título ve en RETAIL.WINHTTP_OPTION_SECURE_PROTOCOLS
Después de crear un nuevo identificador de sesión conWinHttpOpen, debe llamar a WinHttpSetOption con la opción WINHTTP_OPTION_SECURE_PROTOCOLS y pasar el valor correspondiente de XNetworkingSecurityInformation::enabledHttpSecurityProtocolFlags que se recuperó con una llamada a XNetworkingQuerySecurityInformationForUrlUtf16Async para una URL coincidente para la que se usará este identificador de sesión. También debe almacenar la estructura XNetworkingSecurityInformation en su objeto de contexto para usarla más adelante al validar el protocolo de enlace TLS/SSL.
Almacenamiento en caché de identificadores de sesión
Los identificadores de sesión HTTP que se crearon medianteWinHttpOpen son costosos desde el punto de vista de la memoria e incurren en un gran costo de inicio que retrasa la primera solicitud HTTP. Recomendamos que almacene en caché los identificadores de sesión HTTP tanto como sea posible dentro de su título para evitar estos costos.
Sin embargo, no es posible cambiar la opción WINHTTP_OPTION_SECURE_PROTOCOLS en un identificador de sesión. Debe mantener una caché de valores de XNetworkingSecurityInformation::enabledHttpSecurityProtocolFlags asignados a identificadores de sesión de WinHTTP para asegurarse de tener un identificador de sesión diferente para cada marca de protocolo seguro distinta.
La caché que mantiene su título debe borrarse cuando se reciban notificaciones de suspensión y debe reconstruirse desde cero al reanudarse (después de esperar a que la red se inicialice).
Consideraciones sobre WinHttpConnect
A diferencia de los identificadores de sesión, los identificadores de conexión que se crean mediante WinHttpConnect nunca deben almacenarse en caché. Deben crearse nuevos identificadores para cada nueva solicitud o intento de reintento. Los identificadores de conexión de WinHTTP, a pesar de su nombre, no tienen ninguna relación con las conexiones subyacentes del Protocolo de control de transmisión (TCP) con el servidor. WinHTTP administra el ciclo de vida de las conexiones subyacentes con el servidor mediante el identificador de sesión y reutiliza automáticamente las conexiones abiertas con el servidor cuando es posible para los nuevos identificadores de conexión.Canonicalización de URL
WinHTTP espera que todas las URL estén canonicalizadas con los caracteres US-ASCII a-z, A-Z y 0-9. Para obtener más información sobre la canonicalización, consulte Localizadores uniformes de recursos (URL) en WinHTTP. Siempre que sea posible, recomendamos codificar de forma rígida las URL que usa su título en forma canonicalizada. Esta forma evita las asignaciones de memoria y los problemas de rendimiento en los que se incurre al usar las funciones WinHttpCrackUrl y WinHttpCreateUrl para canonicalizar dinámicamente sus URL.División de URL
WinHTTP requiere que se pase una cadena de nombre de host terminada en nulo aWinHttpConnect, mientras que la ruta de acceso y el objeto se pasan a WinHttpOpenRequest. Su título debe pasar tanto la URL completa, es decir, la concatenación del nombre de host y la ruta de acceso, en algunos lugares como solo el nombre de host o la ruta de acceso en otros. Recomendamos codificar ambos de forma rígida en su título para evitar la necesidad de usar WinHttpCrackUrl y WinHttpCreateUrl para concatenar o dividir dinámicamente las URL.
Consideraciones sobre WinHttpOpenRequest
De forma similar a los identificadores de conexión de WinHTTP, los identificadores de solicitud de WinHTTP que se crearon mediante la función WinHttpOpenRequest nunca deben almacenarse en caché. Deben crearse nuevos identificadores para cada nueva solicitud o intento de reintento. Como procedimiento recomendado de seguridad, los títulos siempre deben pasar la marcaWINHTTP_FLAG_SECURE en el parámetro dwFlags al llamar a la función WinHttpOpenRequest.
Recuperación y aplicación de tokens de los servicios de XBOX
Los tokens no se insertan automáticamente para los títulos del Microsoft Game Development Kit (GDK). En su lugar, el título debe recuperar los tokens de autenticación y las firmas de los servicios de XBOX con las API XUser del Microsoft Game Development Kit (GDK). Una vez que el título tenga un usuario, el título debe llamar a XUserGetTokenAndSignatureUtf16Async para recuperar las cadenas de token y firma para cada solicitud individual. Estas dos cadenas deben pasarse después como encabezados en la llamada aWinHttpAddRequestHeadersEx, WinHttpSendRequest o WinHttpAddRequestHeaders.
Para generar una firma correcta, XUserGetTokenAndSignatureUtf16Async espera que el título pase todos los encabezados y el cuerpo completo. Para un POST o PUT con un cuerpo grande, el título puede pasar un subconjunto del cuerpo que se configuró en el Partner Center. Para obtener más información, consulte Servicios web (tema con NDA). En este momento, la red de XBOX no proporciona un mecanismo para recuperar esta configuración. Se espera que los clientes codifiquen los valores de forma rígida o los recuperen a través de un punto de conexión personalizado específico del título.
XUserGetTokenAndSignatureUtf16Async realiza internamente todo el almacenamiento en caché necesario y debe llamarse para cada intento HTTP, incluido un reintento. Si el título recibe un código de estado de respuesta HTTP 401 No autorizado para cualquier solicitud HTTP, el título debe reintentar la solicitud y forzar una actualización del token de autenticación de los servicios de XBOX. Esta actualización se logra recuperando un nuevo token con XUserGetTokenAndSignatureUtf16Async y pasando el valor de enumeración XUserGetTokenAndSignatureOptions::ForceRefresh.
Una vez que el título tiene los datos XUserGetTokenAndSignatureUtf16Data que se recuperaron con una llamada a XUserGetTokenAndSignatureUtf16Async, el título debe transformar XUserGetTokenAndSignatureUtf16Data::Token y XUserGetTokenAndSignatureUtf16Data::Signature en encabezados HTTP que se pasarán a WinHTTP. Se agregó una nueva API de WinHTTP, WinHttpAddRequestHeadersEx, específicamente para reducir la complejidad para los títulos del Microsoft Game Development Kit (GDK). A continuación se muestra un ejemplo de cómo usar esta nueva API. Esta nueva API está disponible en consolas XBOX One y estará disponible en PC con Windows en una futura actualización del sistema operativo Windows. En consola, recomendamos usar WinHttpAddRequestHeadersEx para evitar las asignaciones adicionales y los cambios de formato de cadena.
El dispositivo o una cuenta con sesión iniciada debe tener acceso al sandbox en el que está configurado. De lo contrario,
XUserGetTokenAndSignatureUtf16Data produce un error.Uso de la lista de autorización de seguridad de red de XBOX (NSAL)
La red de XBOX usa la NSAL para garantizar que los clientes establezcan conexiones seguras y autenticadas con sus servicios web. Los títulos administran el contenido de la NSAL como parte de su configuración en el Partner Center. Para obtener más información, consulte Configuración de servicios web en el Partner Center (tema con NDA). La configuración de la NSAL se descarga después automáticamente para cada título. Se usa tanto para generar los tokens de servicios de XBOX adecuados como para realizar el anclaje de certificados para los puntos de conexión específicos de su título.}Consideraciones sobre la máquina de estados asincrónica de WinHTTP
La máquina de estados asincrónica de WinHTTP es la misma en consola que en PC con Windows. Para registrar una función de devolución de llamada con una o varias notificaciones, use la función WinHttpSetStatusCallback. Recomendamos usar la marcaWINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS en el parámetro dwNotificationFlags con fines de depuración, porque WinHTTP es relativamente detallado y transparente sobre lo que está haciendo. Aunque la mayoría de las notificaciones no requieren ninguna acción por su parte, registrar los datos puede ser útil para descubrir la causa raíz de los problemas.
WinHTTP usa un único subproceso para las notificaciones. Los títulos deben evitar bloquear cualquier función de notificación siempre que sea posible, porque impedirá que progresen todas las solicitudes HTTP dentro de su proceso. Las notificaciones sin atender también pueden aumentar la memoria en modo kernel, lo que puede provocar bloqueos.
WinHTTP no copia sus búferes de envío o recepción y requiere que mantenga estos búferes asignados hasta la devolución de llamada de finalización correspondiente. Asegúrese de mantener sus búferes de envío asignados y válidos desde que llama a WinHttpSendRequest hasta que se reciba la notificación WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE correspondiente. De forma similar, cada vez que llame a WinHttpReadData, asegúrese de mantener su búfer de recepción asignado y válido hasta que se reciba la notificación WINHTTP_CALLBACK_STATUS_READ_COMPLETE correspondiente. También recomendamos usar un búfer de recepción de al menos 8 KB de tamaño para evitar problemas de recursión que pueden llevar al agotamiento de la pila.
Los títulos también deben asegurarse de que los búferes de WinHTTP se vacíen correctamente continuando el ciclo asincrónico WinHttpQueryDataAvailable/WinHttpReadData y no bloqueando las devoluciones de llamada de WinHTTP durante ningún período de tiempo.
Validación del protocolo de enlace de Seguridad de la capa de transporte (TLS)/Capa de sockets seguros (SSL)
Como procedimiento recomendado de seguridad, los títulos deben realizar la validación del protocolo de enlace TLS/SSL y usar solo TLS 1.2. Se realiza una validación adicional dentro de la notificaciónWINHTTP_CALLBACK_STATUS_SENDING_REQUEST. Dentro de esta notificación, debe llamar a la función XNetworkingVerifyServerCertificate y pasar la estructura XNetworkingSecurityInformation que se recuperó de una llamada correspondiente anterior a XNetworkingQuerySecurityInformationForUrlUtf16Async. Esta función produce un error si la cadena de certificados no es válida. Debe cerrar inmediatamente el identificador de WinHTTP antes de que se complete la devolución de llamada, asegurándose de que no se transfieran datos hacia o desde el servidor en peligro.
Además de validar las cadenas de certificados, la función XNetworkingVerifyServerCertificate es necesaria para la funcionalidad de Fiddler en consola.
Depuración de WinHTTP
Fiddler es una herramienta útil para ver y depurar su tráfico de WinHTTP. Para que Fiddler capture el tráfico de su título, debe pasar las marcasWINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME y WINHTTP_NO_PROXY_BYPASS a WinHttpOpen. También debe llamar a XNetworkingVerifyServerCertificate dentro de la devolución de llamada de la notificación WINHTTP_CALLBACK_STATUS_SENDING_REQUEST.
HTTP Monitor no funciona con títulos del Microsoft Game Development Kit (GDK).
Documentación de referencia de la API
- Xuser (contenido de la API)
- Funciones
- Estructuras
- xnetworking (contenido de la API)
