Skip to main content
Este artigo explica como usar a funcionalidade dos Serviços HTTP do Windows (WinHTTP) em um título do Microsoft Game Development Kit (GDK). Trata-se de uma API de cliente HTTP de nível mais baixo, disponível para títulos do Microsoft Game Development Kit (GDK) para PC e consoles XBOX. Você pode usá-la para criar pontos de extremidade de serviço HTTP e WebSocket comuns. Por ser de nível mais baixo, há mais considerações e etapas a implementar para que você possa obter uma comunicação segura e robusta para o seu título. Recomendamos que a implementação do seu título siga todas as práticas recomendadas de segurança da comunicação (artigo sob NDA).

Diferenças entre versões do WinHTTP

Em geral, os títulos do Microsoft Game Development Kit (GDK) interagem com o WinHTTP da mesma forma que os aplicativos Win32 interagem com o WinHTTP. Ao desenvolver títulos do Microsoft Game Development Kit (GDK), somente a API C/C++ simples do WinHTTP está disponível. Isso significa que as funcionalidades HTTP devem ser criadas com base nessa API de cliente HTTP.

Adicionar o WinHTTP ao seu projeto de console XBOX

No console, você deve usar #include <winhttp.h> nos seus arquivos de origem. Você deve vincular a XGamePlatform.lib, em vez de vincular diretamente a Winhttp.lib. Somente as APIs da família de APIs WINAPI_PARTITION_GAMES funcionam em títulos do Microsoft Game Development Kit (GDK). No PC com Windows, você deve continuar vinculando a Winhttp.lib. Para ver um exemplo de como integrar o WinHTTP ao seu título do Microsoft Game Development Kit (GDK), consulte o exemplo SimpleWinHttp. Ele fornece um ponto de partida sólido para a sua própria implementação do WinHTTP e inclui a classe WinHttpManager, que expõe uma superfície de API assíncrona simples.

Inicialização da rede e WinHTTP

Antes que o seu título faça a primeira chamada para WinHttpOpen, os títulos do Microsoft Game Development Kit (GDK) devem garantir que a pilha de rede esteja inicializada. Se WinHttpOpen for chamada muito cedo durante o processo de inicialização do título, WinHttpOpen ou as chamadas subsequentes do WinHTTP poderão falhar de forma não determinística. As solicitações podem parecer bem-sucedidas, mas na verdade falhar, ou vice-versa, antes que a rede seja declarada como inicializada. Para obter detalhes sobre como determinar quando a pilha de rede está inicializada, consulte Inicialização da rede.

Suspensão/retomada do título e WinHTTP

Os títulos devem iniciar o processo de fechamento de todos os identificadores do WinHTTP quando uma notificação de suspensão do título for recebida. A limpeza dos identificadores do WinHTTP é assíncrona. Como resultado, você deve fechar seus identificadores na seguinte ordem: todos os identificadores de solicitação, seguidos por todos os identificadores de conexão, seguidos por todos os identificadores de sessão. A natureza assíncrona da limpeza dos identificadores do WinHTTP serve para garantir a segurança de threads das notificações. Embora seja assíncrona, a limpeza dos identificadores do WinHTTP não sofre atrasos, o que faz com que ela caiba facilmente no tempo limite de adiamento de suspensão de um segundo. Na retomada, os títulos devem seguir o mesmo procedimento descrito na seção anterior, Inicialização da rede e WinHTTP, e aguardar até que a rede volte ao estado pronto antes de continuar usando o WinHTTP. Um longo período pode ter decorrido entre os eventos de suspensão e retomada, exigindo que a rede se estabilize novamente antes que as APIs do WinHTTP voltem a ser determinísticas.

Considerações sobre memória e simultaneidade

O número de solicitações simultâneas do WinHTTP deve sempre ser mantido abaixo de oito para garantir que o estado assíncrono no WinHTTP funcione corretamente e dentro do seu orçamento de memória. Esse limite se aplica a todas as operações simultâneas no tempo de execução do título, incluindo chamadas das APIs dos serviços XBOX e do XCurl. Como uma extensão das Considerações sobre memória do WinSock, ao receber dados, você deve garantir que sempre tenha um buffer pendente com WinHttpReadData (ou que esteja aguardando um retorno de chamada de uma chamada WinHttpQueryDataAvailable) para transferir os dados dos pools de memória do modo kernel para o seu processo do modo de usuário o mais rápido possível e minimizar a quantidade de memória do kernel consumida pela sua operação HTTP. A função getter WinHttpQueryHeaders requer alocações de memória transitórias. Ela aloca um buffer temporário de tamanho igual ao parâmetro lpdwBufferLength para uso interno (e o libera antes que a função retorne). Por esse motivo, você deve usar o padrão de chamada dupla com WINHTTP_NO_OUTPUT_BUFFER para minimizar o tamanho dos buffers temporários e limitar quantas chamadas simultâneas a WinHttpQueryHeaders você faz de uma vez, para evitar o uso excessivo de memória do sistema que poderia levar à instabilidade do sistema. O tamanho máximo padrão dos cabeçalhos é de 64 KB, conforme especificado pela opção WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE do WinHTTP.

Considerações sobre WinHttpOpen

Sinalizadores

Você deve passar os sinalizadores da tabela a seguir para WinHttpOpen. A combinação de WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME e WINHTTP_NO_PROXY_BYPASS permite que a plataforma do Microsoft Game Development Kit (GDK) trate automaticamente proxies como o Fiddler e outros ambientes de rede de casos extremos. O sinalizador WINHTTP_FLAG_SECURE_DEFAULTS é um novo sinalizador projetado para ajudar os títulos do Microsoft Game Development Kit (GDK) a seguir as práticas recomendadas de segurança, definindo o comportamento de conexão segura recomendado. Ele está disponível em consoles XBOX One e estará disponível no PC com Windows em uma atualização futura do sistema operacional Windows. Tentar passar WINHTTP_FLAG_SECURE_DEFAULTS nas versões existentes do sistema operacional Windows resulta em uma falha de parâmetro inválido. Esse sinalizador tem um efeito colateral significativo: ele força o WinHTTP a entrar no modo assíncrono, pois inclui implicitamente o sinalizador WINHTTP_FLAG_ASYNC. Nas versões do sistema operacional Windows para PC que não dão suporte a esse sinalizador, você deve passar WINHTTP_FLAG_ASYNC para minimizar as diferenças no restante da sua implementação do WinHTTP.
O sinalizador WINHTTP_FLAG_SECURE_DEFAULTS requer um sinalizador WINHTTP_FLAG_SECURE correspondente passado para WinHttpOpenRequest e bloqueia solicitações HTTP não criptografadas. Em kits de desenvolvimento, para depuração e testes internos, você pode criar um identificador de sessão do WinHTTP e especificar o sinalizador WINHTTP_FLAG_ASYNC para WinHttpOpen. Esse sinalizador permite que você faça uma solicitação HTTP não criptografada durante o desenvolvimento, não especificando o sinalizador WINHTTP_FLAG_SECURE para WinHttpOpenRequest. Você ainda deve usar identificadores de sessão abertos com WINHTTP_FLAG_SECURE_DEFAULTS para o tráfego que não é de depuração, para corresponder ao comportamento de solicitação que o seu título apresenta no RETAIL.

WINHTTP_OPTION_SECURE_PROTOCOLS

Depois de criar um novo identificador de sessão com WinHttpOpen, você deve chamar WinHttpSetOption com a opção WINHTTP_OPTION_SECURE_PROTOCOLS e passar o XNetworkingSecurityInformation::enabledHttpSecurityProtocolFlags correspondente, recuperado com uma chamada a XNetworkingQuerySecurityInformationForUrlUtf16Async para uma URL correspondente para a qual esse identificador de sessão será usado. Você também deve armazenar a estrutura XNetworkingSecurityInformation no seu objeto de contexto para uso posterior ao validar o handshake TLS/SSL.

Armazenar identificadores de sessão em cache

Os identificadores de sessão HTTP criados por meio de WinHttpOpen são caros do ponto de vista de memória e geram um grande custo de inicialização que atrasa a primeira solicitação HTTP. Recomendamos que você armazene em cache os identificadores de sessão HTTP o máximo possível no seu título para evitar esses custos. No entanto, não é possível alterar a opção WINHTTP_OPTION_SECURE_PROTOCOLS em um identificador de sessão. Você deve manter um cache de valores de XNetworkingSecurityInformation::enabledHttpSecurityProtocolFlags mapeados para identificadores de sessão do WinHTTP, para garantir que você tenha um identificador de sessão diferente para cada sinalizador de protocolo seguro diferente. O cache mantido pelo seu título deve ser limpo nas notificações de suspensão e deve ser reconstruído do zero na retomada (depois de aguardar a inicialização da rede).

Considerações sobre WinHttpConnect

Ao contrário dos identificadores de sessão, os identificadores de conexão criados por meio de WinHttpConnect nunca devem ser armazenados em cache. Novos identificadores devem ser criados para cada nova solicitação e/ou tentativa de repetição. Os identificadores de conexão do WinHTTP, apesar do nome, não têm relação com as conexões TCP (Transmission Control Protocol) subjacentes com o servidor. O WinHTTP gerencia o tempo de vida das conexões subjacentes com o servidor por meio do identificador de sessão e reutiliza automaticamente as conexões abertas com o servidor, quando possível, para novos identificadores de conexão.

Canonização de URL

O WinHTTP espera que todas as URLs sejam canonizadas nos caracteres US-ASCII a-z, A-Z e 0-9. Para obter mais informações sobre canonização, consulte URLs (Uniform Resource Locators) no WinHTTP. Sempre que possível, recomendamos que você codifique de forma fixa as URLs usadas pelo seu título na forma canonizada. Essa forma evita as alocações de memória e os problemas de desempenho decorrentes do uso das funções WinHttpCrackUrl e WinHttpCreateUrl para canonizar suas URLs dinamicamente.

Divisão de URL

O WinHTTP exige que uma cadeia de caracteres de nome de host terminada em nulo seja passada para WinHttpConnect, enquanto o caminho e o objeto são passados para WinHttpOpenRequest. Seu título deve passar a URL completa (o nome do host e o caminho concatenados) em alguns lugares e apenas o nome do host ou o caminho em outros. Recomendamos que você codifique ambos de forma fixa no seu título para evitar a necessidade de usar WinHttpCrackUrl e WinHttpCreateUrl para concatenar ou dividir as URLs dinamicamente.

Considerações sobre WinHttpOpenRequest

Assim como os identificadores de conexão do WinHTTP, os identificadores de solicitação do WinHTTP criados por meio da função WinHttpOpenRequest nunca devem ser armazenados em cache. Novos identificadores devem ser criados para cada nova solicitação e/ou tentativa de repetição. Como prática recomendada de segurança, os títulos devem sempre passar o sinalizador WINHTTP_FLAG_SECURE no parâmetro dwFlags ao chamar a função WinHttpOpenRequest.

Recuperar e aplicar tokens dos serviços XBOX

Os tokens não são inseridos automaticamente para títulos do Microsoft Game Development Kit (GDK). Em vez disso, o título deve recuperar os tokens e as assinaturas de autenticação dos serviços XBOX com as APIs XUser do Microsoft Game Development Kit (GDK). Depois que o título tiver um usuário, ele deverá chamar XUserGetTokenAndSignatureUtf16Async para recuperar as cadeias de caracteres de token e assinatura para cada solicitação individual. Essas duas cadeias de caracteres devem então ser passadas como cabeçalhos na chamada para WinHttpAddRequestHeadersEx, WinHttpSendRequest ou WinHttpAddRequestHeaders. Para gerar uma assinatura adequada, XUserGetTokenAndSignatureUtf16Async espera que o título passe todos os cabeçalhos e o corpo inteiro. Para um POST ou PUT com um corpo grande, o título pode passar um subconjunto do corpo que foi configurado no Partner Center. Para obter mais informações, consulte Serviços Web (tópico sob NDA). No momento, a rede XBOX não fornece um mecanismo para recuperar essa configuração. Espera-se que os clientes codifiquem os valores de forma fixa ou os recuperem por meio de um ponto de extremidade personalizado e específico do título. XUserGetTokenAndSignatureUtf16Async realiza internamente todo o armazenamento em cache necessário e deve ser chamada para cada tentativa HTTP, incluindo uma repetição. Se o título receber um código de status de resposta HTTP 401 Unauthorized para qualquer solicitação HTTP, ele deverá repetir a solicitação e forçar uma atualização do token de autenticação dos serviços XBOX. Essa atualização é feita recuperando um novo token com XUserGetTokenAndSignatureUtf16Async e passando o valor de enumeração XUserGetTokenAndSignatureOptions::ForceRefresh. Depois que o título tiver os XUserGetTokenAndSignatureUtf16Data recuperados com uma chamada a XUserGetTokenAndSignatureUtf16Async, ele deverá transformar XUserGetTokenAndSignatureUtf16Data::Token e XUserGetTokenAndSignatureUtf16Data::Signature em cabeçalhos HTTP a serem passados para o WinHTTP. Uma nova API do WinHTTP, WinHttpAddRequestHeadersEx, foi adicionada especificamente para reduzir a complexidade para títulos do Microsoft Game Development Kit (GDK). Um exemplo de como usar essa nova API é mostrado a seguir. Essa nova API está disponível em consoles XBOX One e estará disponível no PC com Windows em uma atualização futura do sistema operacional Windows. No console, recomendamos que você use WinHttpAddRequestHeadersEx para evitar as alocações extras e as alterações de formato de cadeia de caracteres.
O dispositivo ou uma conta conectada precisa ter acesso à área restrita para a qual está configurado. Caso contrário, XUserGetTokenAndSignatureUtf16Data falhará.

Usar a Lista de Autorização de Segurança de Rede (NSAL) do XBOX

A rede XBOX usa a NSAL para garantir que os clientes estabeleçam conexões seguras e autenticadas com seus serviços Web. Os títulos gerenciam o conteúdo da NSAL como parte da sua configuração no Partner Center. Para obter mais informações, consulte Configurar serviços Web no Partner Center (tópico sob NDA). A configuração da NSAL é então baixada automaticamente para cada título. Ela é usada tanto para gerar os tokens adequados dos serviços XBOX quanto para realizar a fixação de certificados para os pontos de extremidade específicos do seu título.}

Considerações sobre a máquina de estado assíncrona do WinHTTP

A máquina de estado assíncrona do WinHTTP é a mesma no console e no PC com Windows. Para registrar uma função de retorno de chamada com uma ou mais notificações, use a função WinHttpSetStatusCallback. Recomendamos usar o sinalizador WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS no parâmetro dwNotificationFlags para fins de depuração, pois o WinHTTP é relativamente detalhado e transparente sobre o que está fazendo. Embora a maioria das notificações não exija nenhuma ação sua, registrar os dados em log pode ser útil para descobrir a causa raiz dos problemas. O WinHTTP usa um único thread para notificações. Os títulos devem evitar bloquear qualquer função de notificação sempre que possível, pois isso impedirá o progresso de todas as solicitações HTTP no seu processo. Notificações não atendidas também podem aumentar a memória do modo kernel, o que pode levar a falhas. O WinHTTP não copia seus buffers de envio ou recebimento e exige que você mantenha esses buffers alocados até o retorno de chamada de conclusão correspondente. Certifique-se de manter seus buffers de envio alocados e válidos desde o momento em que você chama WinHttpSendRequest até que a notificação WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE correspondente seja recebida. Da mesma forma, toda vez que você chamar WinHttpReadData, certifique-se de manter seu buffer de recebimento alocado e válido até que a notificação WINHTTP_CALLBACK_STATUS_READ_COMPLETE correspondente seja recebida. Também recomendamos usar um buffer de recebimento de pelo menos 8 KB para evitar problemas de recursão que podem levar ao esgotamento da pilha. Os títulos também devem garantir que os buffers do WinHTTP sejam esvaziados corretamente, continuando o ciclo assíncrono WinHttpQueryDataAvailable/WinHttpReadData e não bloqueando os retornos de chamada do WinHTTP por nenhum período.

Validar o handshake TLS (Transport Layer Security)/SSL (Secure Sockets Layer)

Como prática recomendada de segurança, os títulos devem realizar a validação do handshake TLS/SSL e usar somente o TLS 1.2. Uma validação extra é realizada na notificação WINHTTP_CALLBACK_STATUS_SENDING_REQUEST. Nessa notificação, você deve chamar a função XNetworkingVerifyServerCertificate e passar a estrutura XNetworkingSecurityInformation recuperada de uma chamada anterior correspondente a XNetworkingQuerySecurityInformationForUrlUtf16Async. Essa função falhará se a cadeia de certificados for inválida. Você deve fechar imediatamente o identificador do WinHTTP antes que o retorno de chamada seja concluído, garantindo que nenhum dado seja transferido de/para o servidor comprometido. Além de validar cadeias de certificados, a função XNetworkingVerifyServerCertificate é necessária para a funcionalidade do Fiddler no console.

Depurar o WinHTTP

O Fiddler é uma ferramenta útil para exibir e depurar seu tráfego do WinHTTP. Para que o Fiddler capture o tráfego do seu título, você deve passar os sinalizadores WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME e WINHTTP_NO_PROXY_BYPASS para WinHttpOpen. Você também deve chamar XNetworkingVerifyServerCertificate no retorno de chamada da notificação WINHTTP_CALLBACK_STATUS_SENDING_REQUEST.
O HTTP Monitor não funciona com títulos do Microsoft Game Development Kit (GDK).

Documentação de referência da API

Confira também

Serviços HTTP do Windows (WinHTTP) Visão geral da XSAPI C (link seguro) XUser Configurar serviços Web no Partner Center (artigo sob NDA) Fiddler em consoles XBOX One Visão geral das práticas recomendadas de segurança da comunicação (artigo sob NDA)
Last modified on October 6, 2026