4.2 HTTPサーバからの応答を取得する
API関数/HttpOpenRequestとAPI関数/HttpSendRequestを使ってリクエストを送信すると、HTTPサーバからはリクエストに対する応答が返ってきます。これらを受け取るときは、API関数/HttpQueryInfoを使います。

なお、HttpQueryInfoで受け取ることができるのは、ファイルサイズや更新日時、ファイルの有無、リクエストの受け付け結果、サーバの種類といった情報であり、リクエストしたファイルそのものではありません。リクエストしたファイルを受け取る方法は「4.3 HTTPサーバからファイルを取得する」を参照してください。

参考までに、この技はAccess VBA以外に、Excelマクロなど他のVBAでも使用することができます。
API関数/HttpQueryInfoを定義する
API関数を使うとき、まずはこの関数がどこにある・どんな関数であるかといった、この関数を使うための準備(API関数の宣言)が必要です。また、定義する場所はフォーム、モジュール、クラスモジュールの(General)(Declarations)です。

次の例は、API関数/HttpQueryInfoを使うときの記述例です。API関数を使用するときは、ついでにAPI関数で使用する定数も定義しておきましょう。

'(General)(Declarations)へ記述します
Private Declare Function HttpQueryInfo _
            Lib "wininet.dll" _
          Alias "HttpQueryInfoA" _
         (ByVal hRequest As Long _
        , ByVal dwInfoLevel As Long _
        , ByRef lpvBuffer As Any _
        , ByRef lpdwBufferLength As Long _
        , ByRef lpdwIndex As Long) As Integer

'dwInfoLevel(取得内容)
'コンテンツの種類
Private Const HTTP_QUERY_CONTENT_TYPE     As Long = 1
'データ長
Private Const HTTP_QUERY_CONTENT_LENGTH   As Long = 5
'サーバ日付
Private Const HTTP_QUERY_DATE             As Long = 9
'更新日時
Private Const HTTP_QUERY_LAST_MODIFIED    As Long = 11
'HTTPリクエストの結果コード
Private Const HTTP_QUERY_STATUS_CODE      As Long = 19
'ヘッダー情報
Private Const HTTP_QUERY_RAW_HEADERS_CRLF As Long = 22
'リダイレクト(Location)
Public Const HTTP_QUERY_LOCATION          As Long = 33
'サーバ情報
Private Const HTTP_QUERY_SERVER           As Long = 37
'セットクッキー
Private Const HTTP_QUERY_SET_COOKIE       As Long = 43
'クッキー
Private Const HTTP_QUERY_COOKIE           As Long = 44
'要求したメソッドの種類
Private Const HTTP_QUERY_REQUEST_METHOD   As Long = 45
 ※決まり事なので、悩まずにコピペして使ってしまいましょう

この関数の戻り値にはリクエストを受け付けたか、受け付けられなかったかが返ります。Trueが受け付けした、Falseが受け付けられなかったです。ただし、戻り値をCBool関数で変換してからTrue/Falseで判定しましょう。

 ◆HttpQueryInfoの引数
ByVal hRequest As Long HttpOpenRequestで取得したHTTPリクエストハンドルを指定します。
ByVal dwInfoLevel As Long 取得内容を指定します。定数で指定しましょう。
ByRef lpvBuffer As Any 結果を受け取るための領域を、固定長の文字列変数で指定します。変数の長さは1024文字ぐらいあれば十分です。
ByRef lpdwBufferLength As Long 初期値は受け取り領域の長さを指定、実行すると受け取った情報の長さが返ります。
ByRef lpdwIndex As Long 0を指定しておいてOKです。
サーバからの応答を取得する例
HttpQueryInfoを使って、リクエストに対する応答を取得する例です。Subプロシージャ「prcHTTPQueryInfoSample」を実行すると、リクエストに対する結果を表示します。

実際にサーバからの応答を取得する処理を行っているのは、Functionプロシージャ「fcHTTPQueryInfo」です。ポイントは受け取り領域と情報の長さの使い方で、受け取り領域には固定長の文字列変数を、長さには受け取り領域の大きさを指定する必要があります。例では、受け取り領域に1024文字の固定長の文字列変数(strBuffer)を使っているため、受け取り領域の大きさ(lngLength)も、それに合わせて1024を指定しています。また、受け取り領域をByValで渡しているのもポイントです。

そして、HttpQueryInfoを実行するとstrBufferに応答結果が格納され、同時にlngLengthには受け取った情報の長さがセットされます。例えば、Fujitsu WebServer 8.46.2400という情報が返ってきた場合のlngLengthの値は27です。受け取った情報だけを取り出したいときは、「Left(strBuffer, lngLength)」のように記述してください。もし、何も受け取れなかった場合は、lngLengthは元の値(例だと1024)のままです。

なお、APIを実行したときの結果コードErr.LastDllErrorに返ります。0なら正常終了、0以外は失敗です。

'変数の定義 ※(General)(Declarations)です
Private lngWinINet As Long 'インターネットハンドルの保存用
Private lngHttpHnd As Long 'HTTPハンドルの保存用
Private lngReqHnd  As Long 'HTTPリクエストハンドルの保存用
Private strBuffer  As String * 1024 'サーバからの応答保存用
Private lngLength  As Long '応答結果のデータ長


Sub prcHTTPQueryInfoSample()

    Dim lngRC As Long

    'インターネットサービスをオープンします
    lngRC = fcInternetOpen

    'オープンに成功したらHTTPサーバとの接続と切断を行います
    If lngRC = 0 Then

       'HTTPサーバへ接続します
       lngRC = fcHTTPConnect("www.uso-web-server.net")

       '接続に成功したらリクエストを初期化します
       If lngRC = 0 Then
          lngRC = fcHTTPOpenRequest("GET", "/document/news.html")
       End If

       'リクエストの初期化に成功したら、リクエストを送信します
       If lngRC = 0 Then
          lngRC = fcHTTPSendRequest
       End If

       'サーバからの応答を取得します(サーバ情報を取得する例)
       If lngRC = 0 Then
          lngRC = fcHTTPQueryInfo(HTTP_QUERY_SERVER)
          MsgBox Left(strBuffer, lngLength)
       End If

       'HTTPリクエストをクローズします
       Call fcHttpRequestClose

       'HTTPサーバから切断します
       Call fcHTTPDisConnect

    End If

    'インターネットサービスをクローズします
    Call fcInternetClose

End Sub


Function fcHTTPQueryInfo(lngInfoLevel As Long) As Long

    Dim tmpIndex As Long

    lngLength = 1024 '初期値はstrBufferの長さ
    strBuffer = vbNullString '受け取り領域は必ず初期化すること
    tmpIndex = 0

    'APIの実行/サーバからの応答を取得
    Call HttpQueryInfo(lngReqHnd _
                     , lngInfoLevel _
                     , ByVal strBuffer _
                     , lngLength _
                     , tmpIndex)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPQueryInfo = Err.LastDllError

End Function


Function fcHTTPOpenRequest(strMethod As String, strURL As String) As Long

    Dim tmpURL    As String * 255

    'URLは255バイトの固定長文字列で渡す
    tmpURL = strURL

    'APIの実行/リクエストを初期化
    lngReqHnd = HttpOpenRequest(lngHttpHnd _
                              , strMethod _
                              , tmpURL _
                              , "HTTP/1.1" _
                              , vbNullString _
                              , 0 _
                              , INTERNET_FLAG_RELOAD _
                              , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPOpenRequest = Err.LastDllError

End Function


Function fcHTTPSendRequest() As Long

    'APIの実行/リクエストを送信
    Call HttpSendRequest(lngReqHnd _
                       , vbNullString _
                       , 0 _
                       , vbNullString _
                       , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPSendRequest = Err.LastDllError

End Function


Function fcHttpRequestClose() As Long

    'APIの実行/インターネットサービスをクローズ
    Call InternetCloseHandle(lngReqHnd)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHttpRequestClose = Err.LastDllError

End Function


Function fcHTTPConnect(Server As String) As Long

    'APIの実行/HTTPサーバへ接続
    lngHttpHnd = InternetConnect(lngWinINet _
                              , Server _
                              , INTERNET_DEFAULT_HTTP_PORT _
                              , vbNullString _
                              , vbNullString _
                              , INTERNET_SERVICE_HTTP _
                              , 0 _
                              , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPConnect = Err.LastDllError

End Function


Function fcHTTPDisConnect() As Long

    'APIの実行/HTTPサーバから切断
    Call InternetCloseHandle(lngHttpHnd)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPDisConnect = Err.LastDllError

End Function


Function fcInternetOpen() As Long

    'APIの実行/インターネットサービスをオープン
    lngWinINet = InternetOpen(vbNullString _
                            , INTERNET_OPEN_TYPE_PRECONFIG _
                            , vbNullString _
                            , vbNullString _
                            , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcInternetOpen = Err.LastDllError

End Function


Function fcInternetClose() As Long

    'APIの実行/インターネットサービスをクローズ
    Call InternetCloseHandle(lngWinINet)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcInternetClose = Err.LastDllError

End Function
 ※この他に、API関数を定義する必要があります。
 ※www.uso-web-server.netは架空のドメイン名です。
リクエストの結果取得例/コンテンツタイプ
HTTP_QUERY_CONTENT_TYPEを指定すると、取得しようとしているコンテンツ(ファイル)の種類が、次のように返ります。

 ■代表例
htmlファイルの場合
text/html; charset=iso-8859-1

gifファイルの場合
image/gif

jpegファイルの場合
image/jpeg

FLASHの場合
application/x-shockwave-flash
リクエストの結果取得例/サーバ日付
HTTP_QUERY_DATEを指定すると、サーバの日付・時刻が次のように返ります。

Sat, 02 Apr 2005 15:04:37 GMT
リクエストの結果取得例/ファイル更新日付
HTTP_QUERY_LAST_MODIFIEDを指定すると、取得しようとしたファイルの更新日付・時刻が次のように返ります。

Thu, 07 Oct 2004 09:29:34 GMT
リクエストの結果取得例/HTTPステータスコード
HTTP_QUERY_STATUS_CODEを指定すると、HTTPステータスコードを取得することができます。基本的に200番台がリクエストを正常に受け付けた、それ以外は受け付けられなかったと扱えばOKです。

なお、HTTPステータスコードについて詳しく知りたいときはこのあたりを参照してみてください。
リクエストの結果取得例/取得ファイルのヘッダー情報
HTTP_QUERY_RAW_HEADERS_CRLFを指定すると、取得しようとしたファイルのヘッダー情報が次のように返ります。

HTTP/1.1 200 OK
Date: Sat, 02 Apr 2005 14:08:50 GMT
Server: Apache/1.3.33 (Unix) mod_perl/1.29
Last-Modified: Fri, 20 Aug 2004 08:03:51 GMT
ETag: "12e103-1c1-4125b067"
Accept-Ranges: bytes
Content-Length: 449
Content-Type: text/html
リクエストの結果取得例/サーバの種類
HTTP_QUERY_SERVERを指定すると、サーバの情報が次のように返ります。

 ■代表例
Apacheの場合
Apache/1.3.33 (Unix) PHP/4.3.10 mod_ssl/2.8.22 OpenSSL/0.9.6m

IISの場合
Microsoft-IIS/6.0

富士通のウェブサーバの場合
Fujitsu WebServer 8.46.2400

ネットスケープのウェブサーバの場合
Netscape-Enterprise/6.0
Copyright(C) 1999-2006 結城圭介。 All rights reserved