Skip to main content
이 문서는 Microsoft Game Development Kit (GDK) 타이틀에서 Windows HTTP Services (WinHTTP) 기능을 사용하는 방법을 설명합니다. 이는 PC와 XBOX 콘솔 Microsoft Game Development Kit (GDK) 타이틀에서 사용할 수 있는 하위 수준 HTTP 클라이언트 API입니다. 일반 HTTP 및 WebSocket 서비스 엔드포인트를 만들기 위해 사용할 수 있습니다. 하위 수준이기 때문에 타이틀에 안전하고 견고한 통신을 달성하기 위해 구현해야 할 고려 사항과 단계가 더 많습니다. 타이틀 구현이 모든 통신 보안 모범 사례(NDA 문서)를 준수하는 것이 좋습니다.

WinHTTP 버전 차이

일반적으로 Microsoft Game Development Kit (GDK) 타이틀은 Win32 애플리케이션에서 WinHTTP와 상호 작용하는 것과 동일한 방식으로 WinHTTP와 상호 작용합니다. Microsoft Game Development Kit (GDK) 타이틀을 개발할 때는 WinHTTP용 플랫 C/C++ API만 사용할 수 있습니다. 즉, HTTP 기능은 이 HTTP 클라이언트 API 위에 구축되어야 합니다.

XBOX 콘솔 프로젝트에 WinHTTP 추가

콘솔에서는 소스 파일에 #include <winhttp.h>를 추가해야 합니다. Winhttp.lib에 직접 링크하는 대신 XGamePlatform.lib에 링크해야 합니다. Microsoft Game Development Kit (GDK) 타이틀에서는 WINAPI_PARTITION_GAMES API 계열 아래의 API만 작동합니다. Windows PC에서는 계속해서 Winhttp.lib에 링크해야 합니다. Microsoft Game Development Kit (GDK) 타이틀에 WinHTTP를 통합하는 방법의 예제는 SimpleWinHttp 샘플을 참조하세요. 이는 자체 WinHTTP 구현의 확실한 출발점을 제공하며 WinHttpManager 클래스를 포함합니다. 간단한 비동기 API 표면을 노출합니다.

네트워크 초기화 및 WinHTTP

타이틀이 WinHttpOpen을 처음 호출하기 전에 Microsoft Game Development Kit (GDK) 타이틀은 네트워킹 스택이 초기화되었는지 확인해야 합니다. 타이틀의 시작 프로세스 중 너무 이른 시점에 WinHttpOpen이 호출되면 WinHttpOpen 또는 후속 WinHTTP 호출이 비결정적으로 실패하거나 크래시할 수 있습니다. 네트워크가 초기화된 것으로 선언되기 전에는 요청이 성공한 것처럼 보이지만 실제로 실패하거나 그 반대일 수 있습니다. 네트워킹 스택이 초기화된 시점을 확인하는 방법에 대한 자세한 내용은 네트워크 초기화를 참조하세요.

타이틀 일시 중지/재개 및 WinHTTP

타이틀은 타이틀 일시 중지 알림을 받을 때 모든 WinHTTP 핸들을 닫기 위한 프로세스를 시작해야 합니다. WinHTTP 핸들 정리는 비동기입니다. 결과적으로 다음 순서로 핸들을 닫아야 합니다. 모든 요청 핸들 다음으로 모든 연결 핸들, 그 다음으로 모든 세션 핸들입니다. WinHTTP 핸들 정리의 비동기 특성은 알림 스레딩 안전성을 보장하기 위한 것입니다. 비동기이지만 WinHTTP 핸들 정리는 어떤 기간에도 지연되지 않아 1초의 일시 중지 지연 시간 초과 내에 쉽게 맞습니다. 재개 시 타이틀은 앞의 네트워크 초기화 및 WinHTTP 섹션에 설명된 것과 동일한 절차를 따르고 WinHTTP 사용을 계속하기 전에 네트워크가 준비 상태로 다시 이동할 때까지 기다려야 합니다. 일시 중지와 재개 이벤트 사이에 오랜 시간이 지났을 수 있으므로 WinHTTP API가 다시 결정적이 되기 전에 네트워크가 다시 안정화되어야 합니다.

메모리 및 동시성 고려 사항

동시 WinHTTP 요청 수는 WinHTTP 내의 비동기 상태가 올바르게 그리고 메모리 예산 내에서 작동하도록 항상 8개 미만으로 유지해야 합니다. 이 제한은 XBOX 서비스 API 및 XCurl의 호출을 포함하여 타이틀 런타임 내의 모든 동시 작업에 적용됩니다. WinSock 메모리 고려 사항의 확장으로, 데이터를 수신할 때 커널 모드 메모리 풀에서 사용자 모드 프로세스로 데이터를 가능한 한 빠르게 전송하고 HTTP 작업에서 소비되는 커널 메모리 양을 최소화하기 위해 항상 WinHttpReadData로 대기 중인 버퍼가 있거나(또는 WinHttpQueryDataAvailable 호출로부터의 콜백을 기다리고 있어야) 함을 보장해야 합니다. WinHttpQueryHeaders getter 함수는 일시적인 메모리 할당이 필요합니다. 내부적으로 사용할 lpdwBufferLength 매개변수와 같은 크기의 스크래치 버퍼를 할당합니다(그리고 함수가 반환되기 전에 해제합니다). 이 때문에 스크래치 버퍼의 크기를 최소화하고 WinHttpQueryHeaders에 대한 동시 호출 수를 제한하기 위해 WINHTTP_NO_OUTPUT_BUFFER 이중 호출 패턴을 사용하여 시스템 불안정으로 이어질 수 있는 과도한 시스템 메모리 사용을 피해야 합니다. 헤더의 기본 최대 크기는 WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE WinHTTP 옵션에 지정된 대로 64 KB입니다.

WinHttpOpen 고려 사항

플래그

WinHttpOpen에 다음 표의 플래그를 전달해야 합니다. WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS의 조합은 Microsoft Game Development Kit (GDK) 플랫폼이 Fiddler 및 기타 특수한 네트워킹 환경과 같은 프록시를 자동으로 처리할 수 있게 합니다. WINHTTP_FLAG_SECURE_DEFAULTS 플래그는 권장되는 보안 연결 동작을 설정하여 Microsoft Game Development Kit (GDK) 타이틀이 보안 모범 사례를 준수하도록 돕기 위해 설계된 새 플래그입니다. XBOX One 콘솔에서 사용할 수 있으며 향후 Windows OS 업데이트에서 Windows PC에서도 사용할 수 있습니다. 기존 Windows OS 버전에서 WINHTTP_FLAG_SECURE_DEFAULTS를 전달하려고 하면 잘못된 매개변수 실패가 발생합니다. 이 플래그는 이 플래그가 암묵적으로 WINHTTP_FLAG_ASYNC 플래그를 포함하기 때문에 WinHTTP를 비동기 모드로 강제하는 중요한 부작용이 있습니다. 이 플래그를 지원하지 않는 Windows PC OS 버전에서는 나머지 WinHTTP 구현에서 차이를 최소화하기 위해 대신 WINHTTP_FLAG_ASYNC를 전달해야 합니다.
WINHTTP_FLAG_SECURE_DEFAULTS 플래그는 WinHttpOpenRequest에 전달되는 일치하는 WINHTTP_FLAG_SECURE 플래그가 필요하며 암호화되지 않은 HTTP 요청을 차단합니다. 내부 디버깅 및 테스트를 위한 개발 킷에서는 WinHTTP 세션 핸들을 만들고 WinHttpOpenWINHTTP_FLAG_ASYNC 플래그를 지정할 수 있습니다. 이 플래그를 사용하면 WinHttpOpenRequestWINHTTP_FLAG_SECURE 플래그를 지정하지 않음으로써 개발 중에 암호화되지 않은 HTTP 요청을 만들 수 있습니다. RETAIL에서 타이틀이 보는 요청 동작과 일치시키기 위해 비디버그 트래픽에는 여전히 WINHTTP_FLAG_SECURE_DEFAULTS로 열린 세션 핸들을 사용해야 합니다.

WINHTTP_OPTION_SECURE_PROTOCOLS

WinHttpOpen으로 새 세션 핸들을 만든 후, 이 세션 핸들이 사용될 일치하는 URL에 대해 XNetworkingQuerySecurityInformationForUrlUtf16Async 호출로 검색된 해당 XNetworkingSecurityInformation::enabledHttpSecurityProtocolFlags를 전달하며 옵션 WINHTTP_OPTION_SECURE_PROTOCOLS와 함께 WinHttpSetOption을 호출해야 합니다. 또한 나중에 TLS/SSL 핸드셰이크를 검증할 때 사용할 수 있도록 컨텍스트 객체에 XNetworkingSecurityInformation 구조체를 저장해야 합니다.

세션 핸들 캐싱

WinHttpOpen을 통해 생성된 HTTP 세션 핸들은 메모리 관점에서 비용이 많이 들고 첫 번째 HTTP 요청을 지연시키는 큰 시작 비용이 발생합니다. 이러한 비용을 피하기 위해 타이틀 내에서 HTTP 세션 핸들을 가능한 한 캐시하는 것이 좋습니다. 그러나 세션 핸들에서 WINHTTP_OPTION_SECURE_PROTOCOLS 옵션을 변경하는 것은 불가능합니다. 각기 다른 보안 프로토콜 플래그에 대해 다른 세션 핸들이 있도록 하려면 WinHTTP 세션 핸들에 매핑된 XNetworkingSecurityInformation::enabledHttpSecurityProtocolFlags 값의 캐시를 유지해야 합니다. 타이틀이 유지하는 캐시는 일시 중지 알림 시 지워야 하며 재개 시 처음부터 다시 구축되어야 합니다(네트워크가 초기화될 때까지 기다린 후).

WinHttpConnect 고려 사항

세션 핸들과 달리 WinHttpConnect를 통해 생성된 연결 핸들은 절대 캐시해서는 안 됩니다. 모든 새 요청 및/또는 재시도 시도에 대해 새 핸들을 만들어야 합니다. WinHTTP 연결 핸들은 이름과 달리 기본 서버 TCP(Transmission Control Protocol) 연결과 관계가 없습니다. WinHTTP는 세션 핸들로 기본 서버 연결의 수명을 관리하고 가능한 경우 새 연결 핸들에 대해 열린 서버 연결을 자동으로 재사용합니다.

URL 정규화

WinHTTP는 모든 URL이 a-z, A-Z 및 0-9 US-ASCII 문자로 정규화되기를 기대합니다. 정규화에 대한 자세한 내용은 WinHTTP의 URL(Uniform Resource Locators)을 참조하세요. 가능한 한 타이틀에서 사용하는 URL을 정규화된 형식으로 하드 코딩하는 것이 좋습니다. 이 형식은 WinHttpCrackUrlWinHttpCreateUrl 함수를 사용하여 URL을 동적으로 정규화함으로써 발생하는 메모리 할당 및 성능 문제를 피합니다.

URL 분할

WinHTTP는 WinHttpConnect에 null 종료 호스트 이름 문자열이 전달되어야 하는 반면, 경로 및 객체는 WinHttpOpenRequest에 전달됩니다. 타이틀은 일부 위치에서 전체 URL, 즉 연결된 호스트 이름과 경로를 전달해야 하고 다른 위치에서는 호스트 이름 또는 경로만 전달해야 합니다. 동적으로 URL을 연결하거나 분할하기 위해 WinHttpCrackUrlWinHttpCreateUrl을 사용해야 하는 필요를 피하기 위해 타이틀에 둘 다 하드 코딩하는 것이 좋습니다.

WinHttpOpenRequest 고려 사항

WinHTTP 연결 핸들과 마찬가지로 WinHttpOpenRequest 함수를 통해 생성된 WinHTTP 요청 핸들은 절대 캐시해서는 안 됩니다. 모든 새 요청 및/또는 재시도 시도에 대해 새 핸들을 만들어야 합니다. 보안 모범 사례로, 타이틀은 WinHttpOpenRequest 함수를 호출할 때 항상 dwFlags 매개변수에 WINHTTP_FLAG_SECURE 플래그를 전달해야 합니다.

XBOX 서비스 토큰 검색 및 적용

토큰은 Microsoft Game Development Kit (GDK) 타이틀용으로 자동으로 삽입되지 않습니다. 대신 타이틀은 Microsoft Game Development Kit (GDK) XUser API로 XBOX 서비스 인증 토큰 및 서명을 검색해야 합니다. 타이틀에 사용자가 있으면 타이틀은 각 개별 요청에 대한 토큰 및 서명 문자열을 검색하기 위해 XUserGetTokenAndSignatureUtf16Async를 호출해야 합니다. 그런 다음 이 두 문자열은 WinHttpAddRequestHeadersEx, WinHttpSendRequest 또는 WinHttpAddRequestHeaders 호출에서 헤더로 전달되어야 합니다. 적절한 서명을 생성하려면 XUserGetTokenAndSignatureUtf16Async는 타이틀이 모든 헤더와 전체 본문을 전달할 것으로 기대합니다. 큰 본문이 있는 POST 또는 PUT의 경우 타이틀은 Partner Center에서 구성된 본문의 하위 집합을 전달할 수 있습니다. 자세한 내용은 웹 서비스(NDA topic)를 참조하세요. 이 때, XBOX 네트워크는 이 구성을 검색하기 위한 메커니즘을 제공하지 않습니다. 클라이언트는 값을 하드 코딩하거나 사용자 지정 타이틀별 엔드포인트를 통해 검색해야 합니다. XUserGetTokenAndSignatureUtf16Async는 필요한 모든 캐싱을 내부적으로 수행하며, 재시도를 포함하여 각 HTTP 시도에 대해 호출되어야 합니다. 타이틀이 HTTP 요청에 대해 401 Unauthorized HTTP 응답 상태 코드를 받으면 타이틀은 요청을 재시도하고 XBOX 서비스 인증 토큰의 새로 고침을 강제해야 합니다. 이 새로 고침은 XUserGetTokenAndSignatureUtf16Async로 새 토큰을 검색하고 XUserGetTokenAndSignatureOptions::ForceRefresh 열거형 값을 전달함으로써 달성됩니다. 타이틀이 XUserGetTokenAndSignatureUtf16Async 호출로 검색된 XUserGetTokenAndSignatureUtf16Data를 가지면 타이틀은 XUserGetTokenAndSignatureUtf16Data::TokenXUserGetTokenAndSignatureUtf16Data::Signature를 WinHTTP에 전달할 HTTP 헤더로 변환해야 합니다. 새로운 WinHTTP API인 WinHttpAddRequestHeadersEx는 특히 Microsoft Game Development Kit (GDK) 타이틀의 복잡성을 줄이기 위해 추가되었습니다. 이 새 API를 사용하는 방법에 대한 예제는 다음과 같습니다. 이 새 API는 XBOX One 콘솔에서 사용할 수 있으며 향후 Windows OS 업데이트에서 Windows PC에서도 사용할 수 있습니다. 콘솔에서는 추가 할당과 문자열 형식 변경을 피하기 위해 WinHttpAddRequestHeadersEx를 사용하는 것이 좋습니다.
디바이스 또는 로그인한 계정은 설정된 샌드박스에 대한 액세스 권한이 있어야 합니다. 그렇지 않으면 XUserGetTokenAndSignatureUtf16Data가 실패합니다.

XBOX 네트워크 보안 승인 목록(NSAL) 사용

XBOX 네트워크는 NSAL을 사용하여 클라이언트가 웹 서비스에 안전하고 인증된 연결을 설정하도록 합니다. 타이틀은 Partner Center에서의 구성의 일부로 NSAL의 내용을 관리합니다. 자세한 내용은 Partner Center에서 웹 서비스 설정(NDA topic)을 참조하세요. 그런 다음 각 타이틀에 대해 NSAL 구성이 자동으로 다운로드됩니다. 이는 적절한 XBOX 서비스 토큰을 생성하고 타이틀의 특정 엔드포인트에 대한 인증서 고정을 수행하는 데 모두 사용됩니다.}

WinHTTP 비동기 상태 머신 고려 사항

WinHTTP 비동기 상태 머신은 콘솔에서와 Windows PC에서 동일합니다. 하나 이상의 알림에 콜백 함수를 등록하려면 WinHttpSetStatusCallback 함수를 사용합니다. WinHTTP는 자신이 하는 일에 대해 비교적 상세하고 투명하기 때문에 디버깅 목적으로 dwNotificationFlags 매개변수에 WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS 플래그를 사용하는 것이 좋습니다. 대부분의 알림은 어떤 조치도 필요하지 않지만 데이터를 로깅하는 것은 문제의 근본 원인을 발견하는 데 유용할 수 있습니다. WinHTTP는 알림에 단일 스레드를 사용합니다. 타이틀은 프로세스 내의 모든 HTTP 요청 진행을 방해할 것이므로 가능한 한 알림 함수를 차단하지 않아야 합니다. 처리되지 않은 알림도 커널 모드 메모리를 증가시켜 크래시로 이어질 수 있습니다. WinHTTP는 송신 또는 수신 버퍼를 복사하지 않으며 해당 완료 콜백까지 이러한 버퍼를 할당된 상태로 유지해야 합니다. WinHttpSendRequest를 호출할 때부터 해당하는 WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE 알림을 받을 때까지 송신 버퍼를 할당하고 유효한 상태로 유지해야 합니다. 마찬가지로, WinHttpReadData를 호출할 때마다 해당하는 WINHTTP_CALLBACK_STATUS_READ_COMPLETE 알림을 받을 때까지 수신 버퍼를 할당하고 유효한 상태로 유지해야 합니다. 스택 소진으로 이어질 수 있는 재귀 문제를 피하기 위해 최소 8 KB 크기의 수신 버퍼를 사용하는 것도 좋습니다. 타이틀은 또한 비동기 WinHttpQueryDataAvailable/WinHttpReadData 주기를 계속하고 어떤 기간 동안 WinHTTP 콜백을 차단하지 않음으로써 WinHTTP 버퍼가 올바르게 비워지도록 해야 합니다.

TLS(Transport Layer Security)/SSL(Secure Sockets Layer) 핸드셰이크 검증

보안 모범 사례로, 타이틀은 TLS/SSL 핸드셰이크의 검증을 수행하고 TLS 1.2만 사용해야 합니다. WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 알림 내에서 추가 검증이 수행됩니다. 이 알림 내에서 XNetworkingVerifyServerCertificate 함수를 호출하고 이전의 해당 XNetworkingQuerySecurityInformationForUrlUtf16Async 호출에서 검색된 XNetworkingSecurityInformation 구조체를 전달해야 합니다. 인증서 체인이 유효하지 않으면 이 함수는 실패합니다. 침해된 서버로/에서 데이터가 전송되지 않도록 콜백이 완료되기 전에 즉시 WinHTTP 핸들을 닫아야 합니다. 인증서 체인 검증 외에도 XNetworkingVerifyServerCertificate 함수는 콘솔에서 Fiddler 기능에 필요합니다.

WinHTTP 디버깅

Fiddler는 WinHTTP 트래픽을 보고 디버깅하는 데 유용한 도구입니다. Fiddler가 타이틀 트래픽을 캡처하려면 WinHttpOpenWINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS 플래그를 전달해야 합니다. 또한 WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 알림 콜백 내에서 XNetworkingVerifyServerCertificate를 호출해야 합니다.
HTTP Monitor는 Microsoft Game Development Kit (GDK) 타이틀에서 작동하지 않습니다.

참조 API 문서

참고 항목

Windows HTTP Services (WinHTTP) XSAPI C 개요 (secure link) XUser Partner Center에서 웹 서비스 설정(NDA 문서) XBOX One 콘솔의 Fiddler 통신 보안 모범 사례 개요(NDA 문서)
마지막 수정일 2026년 8월 24일