WinINet 애플리케이션을 WinHTTP로 포팅

WinHTTP(Microsoft Windows HTTP 서비스)는 HTTP 클라이언트 스택에 액세스해야 하는 중간 계층 및 백 엔드 서버 애플리케이션을 대상으로 합니다. Microsoft WinINet(Windows Internet) 은 클라이언트 애플리케이션에 대한 HTTP 클라이언트 스택뿐만 아니라 FTP(파일 전송 프로토콜), SOCKSv4 및 Gopher 프로토콜에 대한 액세스를 제공합니다. 이 개요는 WinINet 애플리케이션을 WinHTTP로 포팅하는 것이 유용한지 여부를 결정하는 데 도움이 될 수 있습니다. 또한 특정 변환 요구 사항에 대해서도 설명합니다.

WinINet 애플리케이션을 포팅하기 전에 고려해야 할 사항

애플리케이션이 다음과 같은 이점을 얻을 경우 WinINet 애플리케이션을 WinHTTP로 포팅하는 것이 좋습니다.

  • 서버로부터 안전한 HTTP 클라이언트 스택입니다.
  • 스택 사용 최소화.
  • 서버 애플리케이션의 확장성입니다.
  • 플랫폼 관련 API에 대한 종속성이 줄어듭니다.
  • 스레드 가장 지원.
  • 서비스 친화적인 HTTP 스택입니다.
  • 스크립 팅 가능한 WinHttpRequest 개체에 액세스합니다.

다음 중 하나 이상을 지원해야 하는 경우 WinINet 애플리케이션을 WinHTTP로 포팅하는 것을 고려하지 마세요.

  • HTTP 스택의 FTP 또는 Gopher 프로토콜입니다.
  • SOCKS 프록시와 통신하기 위한 SOCKSv4 프로토콜 지원.
  • 자동 전화 접속 서비스.

애플리케이션을 WinHTTP로 이식하려는 경우 다음 섹션에서는 변환 프로세스를 안내합니다.

WinINet 및 WinHTTP 모두에 대한 샘플 애플리케이션의 경우 WinINet용 AsyncDemo 샘플을 WinHTTP용 AsyncDemo 샘플과 비교합니다.

WinHTTP Equivalents to WinINet Functions

다음 표에서는 WINHTTP와 함께 HTTP 클라이언트 스택과 관련된 WinINet 함수를 나열합니다.

애플리케이션에 나열되지 않은 WinINet 함수가 필요한 경우 애플리케이션을 WinHTTP로 이식하지 마세요.

WinINet 함수 WinHTTP 동등 주목할 만한 변경 사항
HttpAddRequestHeaders WinHttpAddRequestHeaders 없음
HttpEndRequest WinHttpReceiveResponse 컨텍스트 값은 WinHttpSendRequest 또는 WinHttpSetOption으로 설정됩니다. 요청 옵션은 WinHttpOpenRequest로 설정됩니다. 요청을 보낸 후 WinHttpReceiveResponse를 호출해야 합니다.
HttpOpenRequest WinHttpOpenRequest 컨텍스트 값은 WinHttpSendRequest 또는 WinHttpSetOption으로 설정됩니다.
HttpQueryInfo WinHttpQueryHeaders 없음
HttpSendRequest WinHttpSendRequest 컨텍스트 값은 WinHttpSendRequest를 사용하여 설정할 수 있습니다.
HttpSendRequestEx WinHttpSendRequest 버퍼를 제공할 수 없습니다.
InternetCanonicalizeUrl 동일한 요소 없음 URL은 이제 WinHttpOpenRequest에서 정식 형식으로 배치됩니다.
InternetCheckConnection 동일한 요소 없음 WinHTTP에서 구현되지 않았습니다.
InternetCloseHandle WinHttpCloseHandle WinHTTP에서 부모 핸들을 닫으면 자식 핸들이 재귀적으로 닫히지 않습니다.
InternetCombineUrl 동일한 요소 없음 URL은 WinHttpCreateUrl 함수를 사용하여 어셈블할 수 있습니다.
InternetConfirmZoneCrossing 동일한 요소 없음 WinHTTP에서 구현되지 않았습니다.
InternetConnect WinHttpConnect 컨텍스트 값은 WinHttpSendRequest 또는 WinHttpSetOption으로 설정됩니다. 요청 옵션은 WinHttpOpenRequest로 설정됩니다. 사용자 자격 증명은 WinHttpSetCredentials로 설정됩니다.
InternetCrackUrl WinHttpCrackUrl ICU_ESCAPE 플래그의 반대 동작: InternetCrackUrl을 사용하면 이 플래그로 인해 이스케이프 시퀀스(%xx)가 문자로 변환되지만 WinHttpCrackUrl을 사용하면 HTTP 요청에서 이스케이프 시퀀스로 변환되어야 하는 문자가 이스케이프 시퀀스로 변환됩니다.
InternetCreateUrl WinHttpCreateUrl 없음
InternetErrorDlg 동일한 요소 없음 WinHTTP는 서버 쪽 애플리케이션을 대상으로 하므로 사용자 인터페이스를 구현하지 않습니다.
InternetGetCookie 동일한 요소 없음 WinHTTP는 세션 간에 데이터를 유지하지 않으며 WinINet 쿠키에 액세스할 수 없습니다.
InternetOpen WinHttpOpen 없음
InternetOpenUrl WinHttpConnect, WinHttpOpenRequest, WinHttpSendRequest, WinHttpReceiveResponse 이 기능은 나열된 WinHTTP 함수에서 사용할 수 있습니다.
InternetQueryDataAvailable WinHttpQueryDataAvailable 예약된 매개 변수가 없습니다.
InternetQueryOption WinHttpQueryOption WinHTTP는 WinINet과 다른 옵션 집합을 제공합니다. WinHTTP에서 제공하는 자세한 내용 및 옵션은 옵션 플래그를 참조하세요.
InternetReadFile WinHttpReadData 없음
InternetReadFileEx WinHttpReadData 버퍼는 구조체가 아니라 포인터로 주소가 지정된 메모리 영역입니다.
InternetSetOption WinHttpSetOption 없음
InternetSetStatusCallback WinHttpSetStatusCallback 자세한 내용은 이 항목의 "비동기 요청의 다른 처리"를 참조하세요.
InternetTimeFromSystemTime WinHttpTimeFromSystemTime 없음
InternetTimeToSystemTime WinHttpTimeToSystemTime 없음
InternetWriteFile WinHttpWriteData 없음

 

비동기 요청의 다양한 처리

WinINet 및 WinHTTP에서 일부 함수는 동기적으로 또는 비동기적으로 비동기 요청을 완료할 수 있습니다. 애플리케이션은 두 상황을 모두 처리해야 합니다. WinINet 및 WinHTTP가 잠재적으로 비동기 함수를 처리하는 방법에는 상당한 차이가 있습니다.

Wininet

  • 동기 완료: 잠재적으로 비동기 WinINet 함수 호출이 동기적으로 완료되는 경우 함수의 OUT 매개 변수는 작업의 결과를 반환합니다. 오류가 발생하면 WinINet 함수 호출 후 GetLastError 를 호출하여 오류 코드를 검색합니다.

  • 비동기 완료: 잠재적으로 비동기 함수 호출이 비동기적으로 완료되면 콜백 함수에서 작업 결과와 오류에 액세스할 수 있습니다. 콜백 함수는 초기 함수를 호출한 스레드가 아닌 작업자 스레드에서 실행됩니다.

즉, 애플리케이션은 함수 호출 직후와 콜백 함수의 두 위치에서 이러한 작업의 결과를 처리하기 위해 논리를 복제해야 합니다.

WinHTTP는 작업이 동기적으로 또는 비동기적으로 완료되었는지 여부에 관계없이 완료 알림을 수신하는 콜백 함수에서만 운영 논리를 구현할 수 있도록 하여 이 모델을 간소화합니다. 비동기 작업을 사용하도록 설정하면 WinHTTP 함수의 OUT 매개 변수는 의미 있는 데이터를 반환하지 않으며 NULL로 설정해야 합니다.

애플리케이션 관점에서 WinHTTP의 비동기 완료와 동기 완료 간의 유일한 중요한 차이점은 콜백 함수가 실행되는 위치입니다.

WinHTTP

  • 동기 완료: 작업이 동기적으로 완료되면 원래 함수 호출과 동일한 스레드에서 실행되는 콜백 함수에서 결과가 반환됩니다.

  • 비동기 완료: 작업이 비동기적으로 완료되면 결과가 작업자 스레드에서 실행되는 콜백 함수에 반환됩니다.

대부분의 오류는 콜백 함수 내에서 완전히 처리될 수도 있지만 GetLastError를 호출하여 검색된 ERROR_INVALID_PARAMETER 또는 기타 유사한 오류로 인해 함수가 FALSE를 반환할 수 있도록 WinHTTP 애플리케이션을 준비해야 합니다.

여러 비동기 작업을 동시에 실행할 수 있는 WinINet과 달리 WinHTTP는 요청 핸들당 하나의 보류 중인 비동기 작업 정책을 적용합니다. 한 작업이 보류 중이고 다른 WinHTTP 함수가 호출되면 두 번째 함수가 실패하고 GetLastError가 ERROR_INVALID_OPERATION 반환합니다.

WinHTTP는 작업이 동기적으로 또는 비동기적으로 완료되었는지 여부에 관계없이 완료 알림을 수신하는 콜백 함수에서만 운영 논리를 구현할 수 있도록 하여 이 모델을 간소화합니다. 비동기 작업을 사용하도록 설정하면 WinHTTP 함수의 OUT 매개 변수는 의미 있는 데이터를 반환하지 않으며 NULL로 설정해야 합니다.

WinHTTP 콜백 알림의 차이점

상태 콜백 함수는 알림 플래그를 통해 작업의 상태 대한 업데이트를 수신합니다. WinHTTP에서 WinHttpSetStatusCallback 함수의 dwNotificationFlags 매개 변수를 사용하여 알림이 선택됩니다. WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS 플래그를 사용하여 모든 상태 업데이트에 대한 알림을 받습니다.

특정 작업이 완료되었음을 나타내는 알림을 완료 알림 또는 완료라고 합니다. WinINet에서 콜백 함수가 완료를 받을 때마다 lpvStatusInformation 매개 변수에는 INTERNET_ASYNC_RESULT 구조가 포함됩니다. WinHTTP에서 이 구조체는 모든 완료에 사용할 수 없습니다. 알림에 대한 정보와 각각에 대해 예상할 수 있는 데이터 유형이 포함된 WINHTTP_STATUS_CALLBACK 대한 참조 페이지를 검토하는 것이 중요합니다.

WinHTTP에서 WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 단일 완료는 작업이 실패했음을 나타냅니다. 다른 모든 완료는 성공적인 작업을 나타냅니다.

WinINet 및 WinHTTP는 모두 사용자 정의 컨텍스트 값을 사용하여 기본 스레드의 정보를 작업자 스레드에서 실행할 수 있는 상태 콜백 함수로 전달합니다. WinINet에서 상태 콜백 함수에서 사용하는 컨텍스트 값은 여러 함수 중 하나를 호출하여 설정됩니다. WinHTTP에서 컨텍스트 값은 WinHttpSendRequest 또는 WinHttpSetOption으로만 설정됩니다. 이 때문에 컨텍스트 값이 설정되기 전에 WinHTTP에서 알림이 발생할 수 있습니다. 컨텍스트 값이 설정되기 전에 콜백 함수가 알림을 수신하는 경우 애플리케이션은 콜백 함수의 dwContext 매개 변수에서 NULL을 받을 수 있도록 준비해야 합니다.

인증 차이점

WinINet에서 사용자 자격 증명은 다음 코드 예제에 제공된 것과 유사한 코드를 사용하여 InternetSetOption 함수를 호출하여 설정됩니다.

// 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 );

호환성을 위해 WinHttpSetOption 함수를 사용하여 WinHTTP에서 사용자 자격 증명을 유사하게 설정할 수 있지만 보안 취약성이 발생할 수 있으므로 권장되지 않습니다.

대신 애플리케이션이 WinHTTP에서 401 상태 코드를 수신하는 경우 자격 증명을 설정하는 권장 방법은 먼저 WinHttpQueryAuthSchemes를 사용하여 인증 체계를 식별하고 두 번째로 WinHttpSetCredentials를 사용하여 자격 증명을 설정하는 것입니다. 다음 코드 예제에서는 이 작업을 수행하는 방법을 보여줍니다.

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 );

WinHTTP에는 InternetErrorDlg 와 동일하지 않으므로 사용자 인터페이스를 통해 자격 증명을 가져오는 애플리케이션은 자체 인터페이스를 제공해야 합니다.

WinINet과 달리 WinHTTP는 암호를 캐시하지 않습니다. 각 요청에 대해 유효한 사용자 자격 증명을 제공해야 합니다.

WinHTTP는 WinINet에서 지원하는 DPA(분산 암호 인증) 체계를 지원하지 않습니다. 그러나 WinHTTP는 Microsoft Passport 1.4를 지원합니다. WinHTTP에서 Passport 인증을 사용하는 방법에 대한 자세한 내용은 WinHTTP의 Passport 인증을 참조하세요.

WinHTTP는 인터넷 Explorer 설정을 사용하여 자동 로그온 정책을 결정하지 않습니다. 대신 자동 로그온 정책은 WinHttpSetOption으로 설정됩니다. 자동 로그온 정책을 포함하여 WinHTTP의 인증에 대한 자세한 내용은 WinHTTP의 인증을 참조하세요.

보안 HTTP 트랜잭션의 차이점

WinINet에서 HttpOpenRequest 또는 InternetConnect를 사용하여 보안 세션을 시작하지만 WinHTTP에서는 WINHTTP_FLAG_SECURE 플래그를 사용하여 WinHttpOpenRequest를 호출해야 합니다.

보안 HTTP 트랜잭션에서 서버 인증서를 사용하여 클라이언트에 서버를 인증할 수 있습니다. WinINet에서 서버 인증서에 오류가 포함된 경우 HttpSendRequest 가 실패하고 인증서 오류에 대한 세부 정보를 제공합니다.

WinHttp에서 서버 인증서 오류는 다음과 같이 버전에 따라 처리됩니다.

  • WinHttp 5.1부터 서버 인증서가 실패하거나 오류가 포함된 경우 WinHttpSendRequest 호출은 콜백 함수의 WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 보고합니다. WinHttpSendRequest에서 생성된 오류가 무시되면 WinHttpReceiveResponse에 대한 후속 호출이 실패하고 ERROR_WINHTTP_OPERATION_CANCELLED 오류가 발생합니다.
  • WinHTTP 5.0에서는 기본적으로 서버 인증서의 오류로 인해 요청이 실패하지 않습니다. 대신 WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 알림과 함께 콜백 함수에서 오류가 보고됩니다.

일부 이전 플랫폼에서 WinINet은 Windows XP에서는 지원되지 않지만 PCT(Private Communication Technology) 및/또는 Fortezza 프로토콜을 지원했습니다.

WinHTTP는 모든 플랫폼에서 PCT 및 Fortezza 프로토콜을 지원하지 않으며 대신 SSL(Secure Sockets Layer) 2.0, SSL 3.0 또는 TLS(전송 계층 보안) 1.0을 사용합니다.