다음을 통해 공유


WinHTTP 세션 개요

WinHTTP(Microsoft Windows HTTP 서비스)는 애플리케이션이 웹의 HTTP 리소스에 액세스할 수 있도록 하는 C/C++ 함수 집합을 노출합니다. 이 항목에서는 이러한 함수를 사용하여 HTTP 서버와 상호 작용하는 방법에 대한 개요를 제공합니다.

WinHTTP API를 사용하여 웹 액세스

다음 다이어그램은 HTTP 서버와 상호 작용할 때 WinHTTP 함수가 일반적으로 호출되는 순서를 보여 줍니다. 음영 처리된 상자는 HINTERNET 핸들을 생성하는 함수를 나타내고 일반 상자는 해당 핸들을 사용하는 함수를 나타냅니다.

핸들을 생성하는 함수

WinHTTP 초기화

서버와 상호 작용하기 전에 WinHttpOpen호출하여 WinHTTP를 초기화해야 합니다. WinHttpOpen HTTP 세션에 대한 세부 정보를 유지 관리하는 세션 컨텍스트를 만들고 세션 핸들을 반환합니다. 이 핸들을 사용하여 WinHttpConnect 함수는 대상 HTTP 또는 HTTPS(보안 하이퍼텍스트 전송 프로토콜) 서버를 지정할 수 있습니다.

메모

WinHttpConnect호출하면 특정 리소스에 대한 요청이 수행될 때까지 HTTP 서버에 대한 실제 연결이 발생하지 않습니다.

 

요청 열기

WinHttpOpenRequest 함수는 특정 리소스에 대한 HTTP 요청을 열고 다른 HTTP 함수에서 사용할 수 있는 HINTERNET 핸들을 반환합니다. WinHttpOpenRequest 호출 시 서버에 요청을 보내지 않습니다. WinHttpSendRequest 함수는 실제로 네트워크를 통해 연결을 설정하고 요청을 보냅니다.

다음 예제에서는 기본 옵션을 사용하는 WinHttpOpenRequest 대한 샘플 호출을 보여 있습니다.

HINTERNET hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, NULL, NULL, 0);

요청 헤더 추가

WinHttpAddRequestHeaders 함수를 사용하면 애플리케이션이 HTTP 요청 핸들에 추가 자유 형식 요청 헤더를 추가할 수 있습니다. HTTP 서버로 전송된 요청을 정확하게 제어해야 하는 정교한 애플리케이션에서 사용하기 위한 것입니다.

WinHttpAddRequestHeaders 함수에는 WinHttpOpenRequest생성된 HTTP 요청 핸들, 헤더, 헤더 길이, 한정자가 포함된 문자열을 필요로 합니다.

다음 한정자는 WinHttpAddRequestHeaders와 함께 사용할 수 있습니다.

수식어 묘사
WINHTTP_ADDREQ_FLAG_ADD 헤더가 없는 경우 헤더를 추가합니다. WINHTTP_ADDREQ_FLAG_REPLACE함께 사용됩니다.
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW 헤더가 아직 없는 경우에만 추가합니다. 그렇지 않으면 오류가 반환됩니다.
WINHTTP_ADDREQ_FLAG_COALESCE 같은 이름의 헤더를 병합합니다.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA 쉼표로 같은 이름의 헤더를 병합합니다. 예를 들어 이 플래그와 함께 "Accept: text/*" 뒤에 "Accept: audio/*"를 추가하면 단일 헤더 "Accept: text/*, audio/*"가 형성되어 첫 번째 헤더가 병합됩니다. 병합/별도의 헤더와 관련하여 응집력 있는 체계를 보장하는 것은 호출 애플리케이션에 달려 있습니다.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON 세미콜론을 사용하여 동일한 이름의 헤더를 병합합니다.
WINHTTP_ADDREQ_FLAG_REPLACE 헤더를 바꾸거나 제거합니다. 헤더 값이 비어 있을 때 헤더가 발견되면 제거됩니다. 헤더 값이 비어 있지 않으면 헤더 값이 대체됩니다.

 

요청 보내기

WinHttpSendRequest 함수는 서버에 대한 연결을 설정하고 지정된 사이트에 요청을 보냅니다. 이 함수에는 WinHttpOpenRequest만든 HINTERNET 핸들이 필요합니다. WinHttpSendRequest 추가 헤더 또는 선택적 정보를 보낼 수도 있습니다. 선택적 정보는 일반적으로 PUT 및 POST와 같은 정보를 서버에 쓰는 작업에 사용됩니다.

WinHttpSendRequest 함수가 요청을 보낸 후 애플리케이션은 HINTERNET 핸들에서 WinHttpReadDataWinHttpQueryDataAvailable 함수를 사용하여 서버의 리소스를 다운로드할 수 있습니다.

서버에 데이터 게시

서버에 데이터를 게시하려면 WinHttpOpenRequest 호출에서 HTTP 동사 POST 또는 PUT이어야 합니다. WinHttpSendRequest 호출되면 dwTotalLength 매개 변수를 데이터 크기(바이트)로 설정해야 합니다. 그런 다음 WinHttpWriteData 사용하여 데이터를 서버에 게시합니다.

또는 WinHttpSendRequestlpOptional 매개 변수를 서버에 게시할 데이터가 포함된 버퍼의 주소로 설정합니다. 이 기술을 사용하는 경우 WinHttpSendRequestdwOptionalLengthdwTotalLength 매개 변수를 모두 게시되는 데이터의 크기로 설정해야 합니다. 이러한 방식으로 WinHttpSendRequest 호출하면 winHttpWriteData호출할 필요가 없습니다.

요청에 대한 정보 가져오기

WinHttpQueryHeaders 함수를 사용하면 애플리케이션이 HTTP 요청에 대한 정보를 검색할 수 있습니다. 이 함수에는 WinHttpOpenRequest에 의해 생성된 HINTERNET 핸들, 정보 수준 값 및 버퍼 길이가 필요합니다. WinHttpQueryHeaders 동일한 이름의 여러 헤더를 열거하는 정보 및 0부터 시작하는 헤더 인덱스를 저장하는 버퍼도 허용합니다.

쿼리 정보 플래그 페이지에 있는 정보 수준 값을 한정자와 함께 사용하여 WinHttpQueryHeaderslpvBuffer 매개 변수에 정보가 저장되는 형식을 제어합니다.

웹에서 리소스 다운로드

WinHttpOpenRequest 함수를 사용하여 요청을 연 후 winHttpSendRequest사용하여 서버에 전송하고 WinHttpReceiveResponse응답을 수신하도록 요청 핸들을 준비하면 애플리케이션은 WinHttpReadData 사용하고 WinHttpQueryDataAvailable함수를사용하여 HTTP 서버에서 리소스를 다운로드할 수 있습니다.

다음 샘플 코드에서는 보안 트랜잭션 의미 체계를 사용하여 리소스를 다운로드하는 방법을 보여 줍니다. 샘플 코드는 WinHTTP API(애플리케이션 프로그래밍 인터페이스)를 초기화하고 대상 HTTPS 서버를 선택한 다음 이 보안 리소스에 대한 요청을 열고 보냅니다. WinHttpQueryDataAvailable 요청 핸들과 함께 사용하여 다운로드할 수 있는 데이터의 양을 확인한 다음, WinHttpReadData 사용하여 해당 데이터를 읽습니다. 이 프로세스는 전체 문서를 검색하고 표시할 때까지 반복됩니다.

  DWORD dwSize = 0;
  DWORD dwDownloaded = 0;
  LPSTR pszOutBuffer;
  BOOL  bResults = FALSE;
  HINTERNET  hSession = NULL, 
             hConnect = NULL,
             hRequest = NULL;

  // Use WinHttpOpen to obtain a session handle.
  hSession = WinHttpOpen( L"WinHTTP Example/1.0",  
                          WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                          WINHTTP_NO_PROXY_NAME, 
                          WINHTTP_NO_PROXY_BYPASS, 0 );

  // Specify an HTTP server.
  if( hSession )
    hConnect = WinHttpConnect( hSession, L"www.microsoft.com",
                               INTERNET_DEFAULT_HTTPS_PORT, 0 );

  // Create an HTTP request handle.
  if( hConnect )
    hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
                                   NULL, WINHTTP_NO_REFERER, 
                                   WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                   WINHTTP_FLAG_SECURE );

  // Send a request.
  if( hRequest )
    bResults = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                                   WINHTTP_NO_REQUEST_DATA, 0, 
                                   0, 0 );


  // End the request.
  if( bResults )
    bResults = WinHttpReceiveResponse( hRequest, NULL );

  // Keep checking for data until there is nothing left.
  if( bResults )
  {
    do 
    {
      // Check for available data.
      dwSize = 0;
      if( !WinHttpQueryDataAvailable( hRequest, &dwSize ) )
        printf( "Error %u in WinHttpQueryDataAvailable.\n",
                GetLastError( ) );

      // Allocate space for the buffer.
      pszOutBuffer = new char[dwSize+1];
      if( !pszOutBuffer )
      {
        printf( "Out of memory\n" );
        dwSize=0;
      }
      else
      {
        // Read the data.
        ZeroMemory( pszOutBuffer, dwSize+1 );

        if( !WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                              dwSize, &dwDownloaded ) )
          printf( "Error %u in WinHttpReadData.\n", GetLastError( ) );
        else
          printf( "%s", pszOutBuffer );

        // Free the memory allocated to the buffer.
        delete [] pszOutBuffer;
      }
    } while( dwSize > 0 );
  }


  // Report any errors.
  if( !bResults )
    printf( "Error %d has occurred.\n", GetLastError( ) );

  // Close any open handles.
  if( hRequest ) WinHttpCloseHandle( hRequest );
  if( hConnect ) WinHttpCloseHandle( hConnect );
  if( hSession ) WinHttpCloseHandle( hSession );