HTTP 세션

WinINet을 사용하면 WWW(World Wide Web)에서 리소스에 액세스할 수 있습니다. 이러한 리소스는 InternetOpenUrl 을 사용하여 직접 액세스할 수 있습니다(자세한 내용은 URL 직접 액세스 참조).

WWW의 리소스는 http를 사용하여 액세스합니다. HTTP 함수는 기본 프로토콜을 처리하면서 애플리케이션이 WWW의 정보에 액세스할 수 있도록 합니다. HTTP 프로토콜이 발전함에 따라 기본 프로토콜은 함수 동작을 유지하도록 업데이트됩니다.

다음 다이어그램은 HTTP 프로토콜에 사용되는 함수의 관계를 보여 줍니다. 음영 처리된 상자는 HINTERNET 핸들을 반환하는 함수를 나타내고 일반 상자는 의존하는 함수에서 만든 HINTERNET 핸들을 사용하는 함수를 나타냅니다.

http에 사용되는 wininet 함수

자세한 내용은 HINTERNET 핸들을 참조하세요.

WinINet 함수를 사용하여 WWW 액세스

다음 함수는 HTTP 세션 중에 WWW에 액세스하는 데 사용됩니다.

함수 설명
HttpAddRequestHeaders HTTP 요청 핸들에 HTTP 요청 헤더를 추가합니다. 이 함수에는 HttpOpenRequest에서 만든 핸들이 필요합니다.
HttpOpenRequest HTTP 요청 핸들을 엽니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
HttpQueryInfo HTTP 요청에 대한 정보를 쿼리합니다. 이 함수에는 HttpOpenRequest 또는 InternetOpenUrl 함수에서 만든 핸들이 필요합니다.
HttpSendRequest 지정된 HTTP 요청을 HTTP 서버로 보냅니다. 이 함수에는 HttpOpenRequest에서 만든 핸들이 필요합니다.
InternetErrorDlg 일반적인 인터넷 오류 조건에 대한 미리 정의된 대화 상자를 표시합니다. 이 함수에는 HttpSendRequest 호출에 사용되는 핸들이 필요합니다.

 

WWW에 대한 연결 시작

WWW에 대한 연결을 시작하려면 애플리케이션이 InternetOpen에서 반환된 루트 HINTERNET에서 InternetConnect 함수를 호출해야 합니다. InternetConnect는 INTERNET_SERVICE_HTTP 서비스 유형을 선언하여 HTTP 세션을 설정해야 합니다. InternetConnect 사용에 대한 자세한 내용은 InternetConnect 사용을 참조하세요.

요청 열기

HttpOpenRequest 함수는 HTTP 요청을 열고 다른 HTTP 함수에서 사용할 수 있는 HINTERNET 핸들을 반환합니다. 다른 열린 함수(예: FtpOpenFileInternetOpenUrl)와 달리 HttpOpenRequest 는 호출될 때 인터넷에 요청을 보내지 않습니다. HttpSendRequest 함수는 요청을 보내고 네트워크를 통해 연결을 설정합니다.

HttpOpenRequestInternetConnect 에서 만든 HTTP 세션 핸들과 HTTP 동사, 개체 이름, 버전 문자열, 참조자, 허용 형식, 플래그 및 컨텍스트 값을 사용합니다.

HTTP 동사는 요청에 사용할 문자열입니다. 요청에 사용되는 일반적인 HTTP 동사에는 GET, PUT 및 POST가 포함됩니다. 이 값이 NULL로 설정된 경우 HttpOpenRequest 는 기본값 GET을 사용합니다.

개체 이름은 지정된 HTTP 동사의 대상 개체 이름을 포함하는 문자열입니다. 일반적으로 파일 이름, 실행 파일 모듈 또는 검색 지정자입니다. 제공된 개체 이름이 빈 문자열인 경우 HttpOpenRequest 는 기본 페이지를 찾습니다.

버전 문자열에는 HTTP 버전이 포함되어야 합니다. 이 매개 변수가 NULL이면 함수는 ""HTTP/1.1"을 사용합니다.

참조자는 개체 이름을 가져온 문서의 주소를 지정합니다. 이 매개 변수가 NULL이면 참조자가 지정되지 않습니다.

허용 형식을 포함하는 null로 종료된 문자열은 애플리케이션에서 허용하는 콘텐츠 형식을 나타냅니다. 이 매개 변수를 NULL 로 설정하면 애플리케이션에서 허용되는 콘텐츠 형식이 없음을 나타냅니다. 빈 문자열이 제공된 경우 애플리케이션은 ""text/*"" 형식의 문서만 허용한다고 나타냅니다. ""text/*"" 값은 그림이나 다른 이진 파일이 아닌 텍스트 전용 문서를 나타냅니다.

플래그 값은 캐싱, 쿠키 및 보안 문제를 제어합니다. MSN(Microsoft Network), NTLM 및 기타 유형의 인증의 경우 INTERNET_FLAG_KEEP_CONNECTION 플래그를 설정합니다.

InternetOpen 호출에서 INTERNET_FLAG_ASYNC 플래그를 설정한 경우 적절한 비동기 작업을 위해 0이 아닌 컨텍스트 값을 설정해야 합니다.

다음 예제는 HttpOpenRequest에 대한 샘플 호출입니다.

hHttpRequest = HttpOpenRequest( hHttpSession, "GET", "", NULL, "", NULL, 0, 0);

요청 헤더 추가

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

HttpAddRequestHeaders 에는 헤더, 헤더 길이 및 한정자가 포함된 문자열인 HttpOpenRequest에서 만든 HTTP 요청 핸들이 필요합니다.

요청 보내기

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

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

서버에 데이터 게시

서버에 데이터를 게시하려면 HttpOpenRequest 호출의 HTTP 동사는 POST 또는 PUT이어야 합니다. POST 데이터가 포함된 버퍼의 주소는 HttpSendRequestlpOptional 매개 변수에 전달되어야 합니다. dwOptionalLength 매개 변수는 데이터 크기로 설정해야 합니다.

InternetWriteFile 함수를 사용하여 HttpSendRequestEx를 사용하여 보낸 HINTERNET 핸들에 데이터를 게시할 수도 있습니다.

요청에 대한 정보 가져오기

HttpQueryInfo 를 사용하면 애플리케이션이 HTTP 요청에 대한 정보를 검색할 수 있습니다. 함수에는 HttpOpenRequest 또는 InternetOpenUrl, 정보 수준 값 및 버퍼 길이에서 만든 HINTERNET 핸들이 필요합니다. 또한 HttpQueryInfo 는 정보를 저장하는 버퍼와 이름이 같은 여러 헤더를 열거하는 0부터 시작하는 헤더 인덱스를 허용합니다.

WWW에서 리소스 다운로드

HttpOpenRequest를 사용하여 요청을 열고 HttpSendRequest를 사용하여 서버로 보낸 후 애플리케이션은 InternetReadFile,InternetQueryDataAvailableInternetSetFilePointer 함수를 사용하여 HTTP 서버에서 리소스를 다운로드할 수 있습니다.

다음 예제에서는 리소스를 다운로드합니다. 함수는 현재 창에 대한 핸들, 편집 상자의 ID 번호 및 HttpOpenRequest에서 만들고 HttpSendRequest에서 보낸 HINTERNET 핸들을 허용합니다. InternetQueryDataAvailable을 사용하여 리소스 크기를 확인한 다음 InternetReadFile을 사용하여 다운로드합니다. 그러면 내용이 편집 상자에 표시됩니다.

int WINAPI Dumper(HWND hX, int intCtrlID, HINTERNET hResource)
{
    LPTSTR lpszData;    // buffer for the data
    DWORD  dwSize;       // size of the data available
    DWORD  dwDownloaded; // size of the downloaded data
    DWORD  dwSizeSum=0;  // size of the data in the textbox
    LPTSTR lpszHolding;  // buffer to merge the textbox data and buffer

    // Set the cursor to an hourglass.
    SetCursor(LoadCursor(NULL,IDC_WAIT));

    // This loop handles reading the data.
    do
    {
        // The call to InternetQueryDataAvailable determines the
        // amount of data available to download.
        if (!InternetQueryDataAvailable(hResource,&dwSize,0,0))
        {
            printf("InternetQueryDataAvailable failed (%d)\n", GetLastError());
            SetCursor(LoadCursor(NULL,IDC_ARROW));
            return FALSE;
        }
        else
        {
            // Allocate a buffer of the size returned by
            // InternetQueryDataAvailable.
            lpszData = new TCHAR[dwSize+1];

            // Read the data from the HINTERNET handle.
            if(!InternetReadFile(hResource,
                                 (LPVOID)lpszData,
                                 dwSize,
                                 &dwDownloaded))
            {
                printf("InternetReadFile failed (%d)\n", GetLastError());
                delete[] lpszData;
                break;
            }
            else
            {
                // Add a null terminator to the end of the data buffer
                lpszData[dwDownloaded]='\0';

                // Allocate the holding buffer.
                lpszHolding = new TCHAR[dwSizeSum + dwDownloaded + 1];

                // Check if there has been any data written
                // to the textbox.
                if (dwSizeSum != 0)
                {
                    // Retrieve the data stored in the textbox if any
                    GetDlgItemText(hX,intCtrlID,
                                   (LPTSTR)lpszHolding,
                                   dwSizeSum);

                    // Add a null terminator at the end of the
                    // textbox data.
                    lpszHolding[dwSizeSum]='\0';
                }
                else
                {
                    // Make the holding buffer an empty string.
                    lpszHolding[0]='\0';
                }

                size_t cchDest = dwSizeSum + dwDownloaded + dwDownloaded + 1;
                LPTSTR* ppszDestEnd = 0;
                size_t* pcchRemaining = 0;

                // Add the new data to the holding buffer
                HRESULT hr = StringCchCatEx(lpszHolding,
                                            cchDest,
                                            lpszData,
                                            ppszDestEnd,
                                            pcchRemaining,
                                            STRSAFE_NO_TRUNCATION);

                if(SUCCEEDED(hr))
                {
                    // Write the holding buffer to the textbox.
                    SetDlgItemText(hX,intCtrlID,(LPTSTR)lpszHolding);

                    // Delete the two buffers.
                    delete[] lpszHolding;
                    delete[] lpszData;

                    // Add the size of the downloaded data to the
                    // textbox data size.
                    dwSizeSum = dwSizeSum + dwDownloaded + 1;

                    // Check the size of the remaining data.
                    // If it is zero, break.
                    if (dwDownloaded == 0)
                        break;
                    else
                    {
                    //  TODO: Insert error handling code here.
                    }
                }
            }
        }
    }
    while(TRUE);

    // Close the HINTERNET handle.
    InternetCloseHandle(hResource);

    // Set the cursor back to an arrow.
    SetCursor(LoadCursor(NULL,IDC_ARROW));

    return TRUE;
}

참고

WinINet은 서버 구현을 지원하지 않습니다. 또한 서비스에서 사용하지 않아야 합니다. 서버 구현 또는 서비스의 경우 WinHTTP(Microsoft Windows HTTP 서비스)를 사용합니다.