HTTP セッション

WinINet を使用すると、World Wide Web (WWW) 上のリソースにアクセスできます。 これらのリソースには、 InternetOpenUrl を使用して直接アクセスできます (詳細については、「 URL への直接アクセス」を参照してください)。

WWW 上のリソースには http を使用してアクセスします。 HTTP 関数は基になるプロトコルを処理しますが、アプリケーションは WWW 上の情報にアクセスできます。 HTTP プロトコルが進化すると、基になるプロトコルが更新され、関数の動作が維持されます。

次の図は、HTTP プロトコルで使用される関数の関係を示しています。 網かけのボックスは HINTERNET ハンドルを返す関数を表し、プレーン ボックスは、それらが依存する関数によって作成された HINTERNET ハンドルを使用する関数を表します。

http に使用される wininet 関数

詳細については、「 HINTERNET ハンドル」を参照してください。

WinINet 関数を使用した WWW へのアクセス

次の関数は、WWW にアクセスするために HTTP セッション中に使用されます。

機能 説明
HttpAddRequestHeaders HTTP 要求ヘッダーを HTTP 要求ハンドルに追加します。 この関数には、 HttpOpenRequest によって作成されたハンドルが必要です。
HttpOpenRequest HTTP 要求ハンドルを開きます。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
HttpQueryInfo HTTP 要求に関する情報を照会します。 この関数には、 HttpOpenRequest 関数または InternetOpenUrl 関数によって作成されたハンドルが必要です。
HttpSendRequest 指定した HTTP 要求を HTTP サーバーに送信します。 この関数には、 HttpOpenRequest によって作成されたハンドルが必要です。
InternetErrorDlg 一般的なインターネット エラー状態の定義済みのダイアログ ボックスを表示します。 この関数には、 HttpSendRequest の呼び出しで使用されるハンドルが必要です。

 

WWW への接続の開始

WWW への接続を開始するには、InternetOpen によって返されるルート HINTERNETInternetConnect 関数を呼び出す必要があります。 InternetConnect では、INTERNET_SERVICE_HTTP サービスの種類を宣言して HTTP セッションを確立する必要があります。 InternetConnect の使用の詳細については、「InternetConnect の使用」を参照してください。

要求を開く

HttpOpenRequest 関数は HTTP 要求を開き、他の HTTP 関数で使用できる HINTERNET ハンドルを返します。 他のオープン関数 ( FtpOpenFileInternetOpenUrl など) とは異なり、 HttpOpenRequest は呼び出されたときにインターネットに要求を送信しません。 HttpSendRequest 関数は要求を送信し、ネットワーク経由で接続を確立します。

HttpOpenRequest、InternetConnect によって作成された HTTP セッション ハンドルと、HTTP 動詞、オブジェクト名、バージョン文字列、参照元、受け入れ型、フラグ、コンテキスト値を受け取ります。

HTTP 動詞は、要求で使用される文字列です。 要求で使用される一般的な HTTP 動詞には、GET、PUT、POST があります。 この値が NULL に設定されている場合、 HttpOpenRequest は既定値 GET を使用します。

オブジェクト名は、指定された HTTP 動詞のターゲット オブジェクトの名前を含む文字列です。 これは通常、ファイル名、実行可能モジュール、または検索指定子です。 指定されたオブジェクト名が空の文字列の場合、 HttpOpenRequest は既定のページを検索します。

バージョン文字列には HTTP バージョンが含まれている必要があります。 このパラメーターが NULL の場合、関数は ""HTTP/1.1" を使用します。

参照元は、オブジェクト名の取得元のドキュメントのアドレスを指定します。 このパラメーターが NULL の場合、参照元は指定されません。

受け入れ型を含む null で終わる文字列は、アプリケーションで受け入れられるコンテンツ タイプを示します。 このパラメーターを NULL に設定すると、アプリケーションで受け入れられるコンテンツ タイプがないことを示します。 空の文字列が指定されている場合、アプリケーションは""text/*"型のドキュメントのみを受け入れることを示します。 値 ""text/*"" は、画像やその他のバイナリ ファイルではなく、テキストのみのドキュメントを示します。

フラグ値は、キャッシュ、Cookie、およびセキュリティの問題を制御します。 Microsoft Network (MSN)、NTLM、およびその他の種類の認証の場合は、 INTERNET_FLAG_KEEP_CONNECTION フラグを設定します。

InternetOpen の呼び出しでINTERNET_FLAG_ASYNC フラグが設定されている場合は、適切な非同期操作のために 0 以外のコンテキスト値を設定する必要があります。

次の例は、 HttpOpenRequest のサンプル呼び出しです。

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

要求ヘッダーの追加

HttpAddRequestHeaders 関数を使用すると、アプリケーションは 1 つ以上の要求ヘッダーを最初の要求に追加できます。 この関数を使用すると、アプリケーションは HTTP 要求ハンドルに追加のフリーフォーマット ヘッダーを追加できます。これは、HTTP サーバーに送信される要求を正確に制御する必要がある高度なアプリケーションで使用することを目的としています。

HttpAddRequestHeaders には、 HttpOpenRequest によって作成された HTTP 要求ハンドル、ヘッダー、ヘッダーの長さ、修飾子を含む文字列が必要です。

要求の送信

HttpSendRequest はインターネットへの接続を確立し、指定したサイトに要求を送信します。 この関数には、HttpOpenRequest によって作成された HINTERNET ハンドルが必要です。 HttpSendRequest は、追加のヘッダーまたはオプションの情報を送信することもできます。 オプションの情報は、通常、PUT や POST などの情報をサーバーに書き込む操作に使用されます。

HttpSendRequest が要求を送信した後、アプリケーションは HttpOpenRequest によって作成された HINTERNET ハンドルで InternetReadFileInternetQueryDataAvailableおよび InternetSetFilePointer 関数を使用して、サーバーのリソースをダウンロードできます。

サーバーへのデータの投稿

サーバーにデータをポストするには、 HttpOpenRequest の呼び出しの HTTP 動詞が POST または PUT である必要があります。 POST データを含むバッファーのアドレスは、HttpSendRequestlpOptional パラメーターに渡す必要があります。 dwOptionalLength パラメーターは、データのサイズに設定する必要があります。

InternetWriteFile 関数を使用して、HttpSendRequestEx を使用して送信された HINTERNET ハンドルにデータをポストすることもできます。

要求に関する情報の取得

HttpQueryInfo を使用すると、アプリケーションは HTTP 要求に関する情報を取得できます。 この関数には、HttpOpenRequest または InternetOpenUrl によって作成された HINTERNET ハンドル、情報レベル値、およびバッファー長が必要です。 HttpQueryInfo は、情報を格納するバッファーと、同じ名前の複数のヘッダーを列挙する 0 から始まるヘッダー インデックスも受け入れます。

WWW からリソースをダウンロードする

HttpOpenRequest で要求を開き、HttpSendRequest を使用してサーバーに送信した後、アプリケーションは InternetReadFileInternetQueryDataAvailableおよび InternetSetFilePointer 関数を使用して、HTTP サーバーからリソースをダウンロードできます。

次の例では、リソースをダウンロードします。 関数は、現在のウィンドウへのハンドル、編集ボックスの識別番号、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;
}

Note

WinINet では、サーバーの実装はサポートされていません。 また、サービスから使用しないでください。 サーバーの実装またはサービスの場合は、 Microsoft Windows HTTP サービス (WinHTTP) を使用します。