Caché インターネット・ユーティリティの使用法
HTTP 要求の送信
[Home] [Back] [Next]
InterSystems: The power behind what matters   
Class Reference   
Search:    

この章では、HTTP 要求 (POST や GET など) の送信方法および応答の処理方法について説明します。ここでは、以下のトピックについて説明します。

HTTP 要求の概要
%Net.HttpRequest のインスタンスを作成して、さまざまな種類の HTTP 要求を送信し、応答を受信します。このオブジェクトは、Web ブラウザと同等であり、このオブジェクトを使用して、複数の要求を行うことができます。自動的に正しい Cookie が送信され、必要に応じて Referer ヘッダが設定されます。
HTTP 要求を作成するには、以下の一般的なプロセスを使用します。
  1. %Net.HttpRequest のインスタンスを作成します。
  2. このインスタンスのプロパティを設定し、通信する Web サーバを指定します。基本的なプロパティは以下のとおりです。
  3. 必要に応じて、HTTP 要求のプロパティの指定 で説明されているとおり、HTTP 要求のその他のプロパティと呼び出しメソッドを設定します。
  4. その後、HTTP 要求の送信 で説明されているとおり、%Net.HttpRequest のインスタンスの Get() メソッドまたはその他のメソッドを呼び出し、HTTP 要求を送信します。
    インスタンスから複数の要求を行うことができ、それによって、Cookie および Referer ヘッダが自動的に処理されます。
    Note:
    Ensemble 発信アダプタ (EnsLib.HTTP.OutboundAdapter) で使用するためにこの HTTP 要求を作成した場合は、代わりにそのアダプタのメソッドを使用して要求を送信します。
  5. %Net.HttpRequest の同じインスタンスを使用して、必要に応じて追加の HTTP 要求を送信します。既定により、Caché は TCP/IP ソケットのオープン状態を維持するので、ソケットを閉じてから再び開くことなく、再利用できます。
    詳細は、ソケット再利用の管理 を参照してください。
HTTP 要求のプロパティの指定
HTTP 要求を送信する前に (HTTP 要求の送信 を参照)、以下のセクションの説明に従って、プロパティを指定することができます。
Location プロパティ
Location プロパティでは、Web サーバから要求するリソースを指定します。このプロパティを設定すると、Get()Head()Post()、または Put() の各メソッドを呼び出す際、場所の引数を省略できます。
例えば、URL http://machine_name/cache/index.html に HTTP 要求を送信しているとします。
この場合、以下の値を使用します。
%Net.HttpRequest のプロパティの例
プロパティ
Server machine_name
Location cache/index.html
インターネット・メディア・タイプと文字エンコードの指定
以下のプロパティを使用して、インターネット・メディア・タイプ (MIME タイプ とも呼ばれます)、および %Net.HttpRequest のインスタンスとそのレスポンス内の文字エンコードを指定できます。
プロキシ・サーバの使用法
プロキシ・サーバにより、HTTP 要求を送信できます。これを設定するには、HTTP 要求の以下のプロパティを指定します。
詳細は、%Net.HttpRequest のクラス・ドキュメントを参照してください。
ログイン資格情報の提供
宛先サーバがログイン資格情報を必要とする場合、資格情報を提供する HTTP Authorization ヘッダを HTTP 要求に含めることができます。
Note:
%Net.HttpRequest クラスは、基本 HTTP 認証のみをサポートします。つまり、資格情報は、Base 64 のエンコード形式で送信されます。このタイプの認証は、SSL を使用しない限り安全ではありません (SSL を使用した接続 を参照)。
以下の 2 つの一般的なオプションがあります。
プロキシ・サーバを使用している場合、プロキシ・サーバに対してもログイン資格情報を指定できます。そのためには、ProxyAuthorization プロパティを設定します。プロキシ・サーバの使用法 を参照してください。
詳細は、%Net.HttpRequest のクラス・ドキュメントを参照してください。
SSL を使用した接続
%Net.HttpRequest クラスは、SSL 接続をサポートします。SSL によって要求を送信する手順は以下のとおりです。
  1. SSLConfiguration プロパティを使用する有効化した SSL/TLS 構成の名前に設定します。
    SSL/TLS 構成の作成と管理の詳細は、"Caché セキュリティ管理ガイド" の Caché での SSL/TLS の使用法 を参照してください。SSL/TLS 構成には、[構成名] と呼ばれるオプションが含まれています。これは、この設定で使用する文字列です。
  2. プロキシ・サーバを使用しているかどうかによって、以下のいずれかを行います。
指定のサーバへの SSL 接続を使用する場合、そのサーバでの既定ポートは 443 (HTTPS ポート) と見なされます。例えば、プロキシ・サーバを使用しておらず、Https が True の場合、これによって、既定の Port プロパティが 443 に変更されます。
プロキシ・サーバの使用法 も参照してください。
サーバ ID の確認
既定では、%Net.HttpRequest のインスタンスは、SSL/TLS でセキュリティ保護された Web サーバに接続するときに、証明書サーバ名と、そのサーバへの接続に使用した DNS 名が一致しているかどうかを確認します。これらの名前が一致していないと、接続は許可されません。この既定の動作は、“中間者” 攻撃を防止するもので、RFC 2818 のセクション 3.1 に説明があります。また、RFC 2595 のセクション 2.4 も参照してください。
この確認を無効にするには、SSLCheckServerIdentity プロパティを 0 に設定します。
HTTPVersion、Timeout、WriteTimeout、および FollowRedirect プロパティ
%Net.HttpRequest には、以下のプロパティもあります。
HTTP ヘッダの設定と取得
HTTP ヘッダの値を設定および取得できます。
%Net.HttpRequest の以下の各プロパティには、対応する名前を持つ HTTP ヘッダの値が含まれます。これらのプロパティを設定しなかった場合、これらは自動的に計算されます。
%Net.HttpRequest クラスは、主要 HTTP ヘッダの設定および取得に使用できる一般的なメソッドを提供します。これらのメソッドは、Content-Type およびその他のエンティティ・ヘッダを無視します。
ReturnHeaders()
この要求の主要 HTTP ヘッダを含む文字列を返します。
OutputHeaders()
現在のデバイスに主要 HTTP ヘッダを書き込みます。
GetHeader()
この要求に設定されているすべての主要 HTTP ヘッダの現在の値を取得します。このメソッドは、1 つの引数、すなわちヘッダ名を取ります (大文字と小文字を区別しない)。これは、HostDate などの文字列です。
SetHeader()
ヘッダの値を設定します。通常は、これを使用して、標準以外のヘッダを設定します。通常のほとんどのヘッダは、Date などのプロパティによって設定されます。このメソッドは、以下の 2 つの引数を取ります。
  1. コロン (:) の区切り文字のないヘッダの名前 (大文字と小文字を区別しない)。これは、HostDate などの文字列です。
  2. そのヘッダの値
このメソッドを使用して、エンティティ・ヘッダまたは読み取り専用のヘッダ (Content-Length および Connection) を設定することはできません。
詳細は、%Net.HttpRequest のクラス・ドキュメントを参照してください。
キープ・アライブ動作の管理
%Net.HttpRequest の同じインスタンスを再利用して、複数の HTTP 要求を送信する場合、既定により、Caché は TCP/IP ソケットのオープン状態を維持するので、閉じてから再び開く必要はありません。
TCP/IP ソケットを再利用する必要がない場合、以下のいずれかの操作を行います。
%Net.HttpRequestSocketTimeout プロパティにより、Caché で指定されたソケットを再利用する予定期間の時間ウィンドウを秒単位で指定します。このタイムアウトには、ファイアウォールにより密かに閉じられた可能性のあるソケットの使用を避ける目的があります。このプロパティの既定値は 115 です。このプロパティには、別の値を設定できます。
HTTP 要求のパラメータの処理
HTTP 要求を送信する際 (HTTP 要求の送信 を参照)、パラメータを location 引数で指定できます。例えば、"/test.html?PARAM=%25VALUE" は、PARAM を %VALUE に設定します。
以下のメソッドを使用して、%Net.HttpRequest のインスタンスがパラメータを処理する方法を制御することもできます。
InsertParam()
要求にパラメータを挿入します。このメソッドは、パラメータ名とパラメータの値の 2 つの文字列引数をとります。以下はその例です。
 do req.InsertParam("arg1","1")
指定のパラメータに対して、複数の値を挿入できます。その場合、値は、1 で始まる添え字を受け取ります。その他のメソッド内で、これらの添え字を使用して、目的の値を参照します。
DeleteParam()
要求からパラメータを削除します。最初の引数は、パラメータの名前です。2 番目の引数は、削除する値の添え字です。同じパラメータに対して複数の値が要求に含まれている場合にのみこれを使用します。
CountParam()
指定のパラメータに関連付けられた値の数を数えます。
GetParam()
要求内の指定のパラメータの値を取得します。最初の引数は、パラメータの名前です。2 番目の引数は、要求にこの名前のパラメータがない場合に返す既定値です。この既定値の初期値は、NULL 値です。3 番目の引数は、取得する値の添え字です。同じパラメータに対して複数の値が要求に含まれている場合にのみこれを使用します。
IsParamDefined()
指定のパラメータが定義されているかどうかを確認します。このメソッドは、パラメータに値がある場合、True を返します。この引数は、DeleteParam() のものと同じです。
NextParam()
$Order() によってパラメータ名を並べ替えた後で、次にパラメータがある場合は、その名前を取得します。
ReturnParams()
この要求に含まれるパラメータのリストを返します。
詳細は、%Net.HttpRequest のクラス・ドキュメントを参照してください。
要求の本文を含める
HTTP 要求には、要求の本文またはフォーム・データのいずれかを含めることができます。要求の本文を含める手順は以下のとおりです。
  1. %GlobalBinaryStream のインスタンスまたはサブクラスを作成します。HTTP 要求の EntityBody プロパティにはこのインスタンスを使用します。
  2. データをこのストリームに書き込むには、標準のストリーム・インタフェースを使用します。以下はその例です。
     Do oref.EntityBody.Write("Data into stream")
例えば、ファイルを読み取り、それをカスタム HTTP 要求のエンティティ本文として使用できます。
 set file=##class(%File).%New("G:\customer\catalog.xml")
 set status=file.Open("RS")
 if $$$ISERR(status) do $System.Status.DisplayError(status)
 set hr=##class(%Net.HttpRequest).%New()
 do hr.EntityBody.CopyFrom(file)
 do file.Close()
チャンクされた要求の送信
HTTP 1.1 を使用すると、HTTP要求をチャンクで送信できます。これには、Transfer-Encoding を設定してメッセージがチャンクされていることを示し、0 サイズのチャンクを使用して完了を示す必要があります。
チャンク・エンコードは、サーバが大量のデータを返しており、要求が完全に処理されるまで応答の合計サイズが分からない場合に便利です。そのような場合、通常、コンテンツの長さが計算できるまで (これは、%Net.HttpRequest が自動的に行います)、メッセージ全体をバッファする必要があります。
チャンクされた要求を送信する手順は以下のとおりです。
  1. データをチャンクで書き込むためのインタフェースを定義する抽象ストリーム・クラスである、%Net.ChunkedWriter のサブクラスを作成します。
    このサブクラス内に、OutputStream() メソッドを実装します。
  2. %Net.HttpRequest のインスタンスで、%Net.ChunkedWriter サブクラスのインスタンスを作成し、送信する要求データを入力します。
  3. %Net.HttpRequest インスタンスの EntityBody プロパティを %Net.ChunkedWriter のこのインスタンスと等しくなるように設定します。
    HTTP 要求を送信すると (HTTP 要求の送信 を参照)、EntityBody プロパティの OutputStream() メソッドが呼び出されます。
%Net.ChunkedWriter のサブクラスで、OutputStream() メソッドはストリーム・データを調べ、これをチャンクするかどうかとその方法を決定し、クラスの継承されたメソッドを呼び出して出力を記述します。
以下のメソッドを使用できます。
WriteSingleChunk()
文字列の引数を受け入れ、この文字列を非チャンク出力として記述します。
WriteFirstChunk()
文字列引数を受け入れます。適切な Transfer-Encoding ヘッダを記述してチャンクされたメッセージを示し、続いて、その文字列を最初のチャンクとして記述します。
WriteChunk()
文字列の引数を受け入れ、この文字列をチャンクとして記述します。
WriteLastChunk()
文字列の引数を受け入れ、文字列をチャンクとして記述し、続いて、終了を表す長さが 0 のチャンクを記述します。
NULL でない場合、TranslateTable プロパティは、記述する際に各文字列の変換に使用する変換テーブルを指定します。前述のメソッドはすべてこのプロパティを確認します。
フォーム・データの送信
HTTP 要求には、要求の本文またはフォーム・データのいずれかを含めることができます。フォーム・データを含めるには、以下のメソッドを使用します。
InsertFormData()
要求にフォーム・データを挿入します。このメソッドは、フォーム項目名と関連付けられた値の 2 つの文字列引数をとります。指定のフォーム項目に複数の値を挿入できます。その場合、値は、1 で始まる添え字を受け取ります。その他のメソッド内で、これらの添え字を使用して、目的の値を参照します。
DeleteFormData()
要求からフォーム・データを削除します。最初の引数は、フォーム項目の名前です。2 番目の引数は、削除する値の添え字です。同じフォーム項目に対して複数の値が要求に含まれている場合にのみこれを使用します。
CountFormData()
要求内の指定の名前に関連付けられた値の数を数えます。
IsFormDataDefined()
指定の名前が定義されているかどうかを確認します。
NextFormData()
$Order() によってパラメータ名を並べ替えた後で、次にフォーム項目がある場合は、その名前を取得します。
これらのメソッドの詳細は、%Net.HttpRequest のクラス・ドキュメントを参照してください。
例 1
フォーム・データを挿入後、通常、Post() メソッドを呼び出します。以下はその例です。
    Do httprequest.InsertFormData("element","value")
    Do httprequest.Post("/cgi-bin/script.CGI")
例 2
別の例を示します。
    Set httprequest=##class(%Net.HttpRequest).%New()
    set httprequest.SSLConfiguration="MySSLConfiguration"
    set httprequest.Https=1
    set httprequest.Server="myserver.com"
    set httprequest.Port=443
    Do httprequest.InsertFormData("portalid","2000000")
    set tSc = httprequest.Post("/url-path/")
    Quit httprequest.HttpResponse
Cookie の挿入、リスト、および削除
%Net.HttpRequest は、サーバから送信された cookie を自動的に管理します。サーバが cookie を送信すると、%Net.HttpRequest のインスタンスが次の要求でこの cookie を返します (このメカニズムが機能するためには、%Net.HttpRequest の同じインスタンスを再利用する必要があります)。
%Net.HttpRequest のインスタンス内で cookie を管理するには、以下のメソッドを使用します。
InsertCookie()
要求に cookie を挿入します。以下の引数を指定します。
  1. cookie 名。
  2. cookie の値。
  3. cookie を保存するパス。
  4. cookie のダウンロード元のマシン名。
  5. cookie の期限が切れる日付と時刻。
GetFullCookieList()
cookie の数と、cookie の配列を (参照によって) 返します。
DeleteCookie()
要求から cookie を削除します。
cookie は、HTTP サーバに固有であることに留意してください。cookie を挿入する際は、特定のサーバへの接続を使用しており、その cookie は他のサーバでは使用できません。
これらのメソッドの詳細は、%Net.HttpRequest のクラス・ドキュメントを参照してください。
HTTP 要求の送信
HTTP 要求を作成した後、以下のメソッドのいずれかを使用してこの HTTP 要求を送信します。
Get()
method Get(location As %String = "", 
           test As %Integer = 0, 
           reset As %Boolean = 1) as %Status
HTTP GET 要求を発行します。このメソッドにより、Web サーバは要求されたページを返します。
Head()
method Head(location As %String, 
            test As %Integer = 0, 
            reset As %Boolean = 1) as %Status
HTTP HEAD 要求を発行します。このメソッドにより、Web サーバは応答のヘッダのみを返します。本文は返しません。
Post()
method Post(location As %String = "", 
            test As %Integer = 0, 
            reset As %Boolean = 1) as %Status
HTTP POST 要求を発行します。フォームの結果などのデータを Web サーバに送信したり、ファイルをアップロードするには、このメソッドを使用します。使用例は、フォーム・データの送信 を参照してください。
Put()
method Put(location As %String = "", 
           test As %Integer = 0, 
           reset As %Boolean = 1) as %Status
HTTP PUT 要求を発行します。データを Web サーバにアップロードするには、このメソッドを使用します。PUT 要求は通常ありません。
Send()
method Send(type As %String, 
            location As %String, 
            test As %Integer = 0, 
            reset As %Boolean = 1) as %Status
指定されたタイプの HTTP 要求をサーバに送信します。このメソッドは、通常、他のメソッドによって呼び出されますが、異なる HTTP 動詞を使用したい場合に使用するために用意されています。ここでは、type は、"POST" などの HTTP 動詞を指定する文字列です。
いずれの場合も、
以下はその例です。
 Set httprequest=##class(%Net.HttpRequest).%New()
 Set httprequest.Server="www.intersystems.com"
 Do httprequest.Get("/")
他の例については、%Net.HttpRequest のクラス・ドキュメントを参照してください。
マルチパート POST 要求の作成と送信
マルチパート POST 要求の作成と送信を行うには、%Net.MIMEPart クラスを使用します。詳細は、このドキュメントで後述します。以下の例では、2 つの部分を有する POST 要求を送信します。最初の部分はファイルのバイナリ・データ、2 番目の部分はファイル名を含んでいます。
ClassMethod CorrectWriteMIMEMessage3(header As %String) 
{
     // Create root MIMEPart
     Set RootMIMEPart=##class(%Net.MIMEPart).%New()

     //Create binary subpart and insert file data
     Set BinaryMIMEPart=##class(%Net.MIMEPart).%New()
     Set contentdisp="form-data; name="_$CHAR(34)_"file"_$CHAR(34)_"; filename="
                     _$CHAR(34)_"task4059.txt"_$CHAR(34)
     Do BinaryMIMEPart.SetHeader("Content-Disposition",contentdisp)

     Set stream=##class(%FileBinaryStream).%New()
     Set stream.Filename="/home/tabaiba/prueba.txt"
     Do stream.LinkToFile("/home/tabaiba/prueba.txt")

     Set BinaryMIMEPart.Body=stream
     Do BinaryMIMEPart.SetHeader("Content-Type","text/plain")

    // Create text subpart
    Set TextMIMEPart=##class(%Net.MIMEPart).%New()
    Set TextMIMEPart.Body=##class(%GlobalCharacterStream).%New()
    Do TextMIMEPart.Body.Write("/home/tabaiba/prueba.txt")

    // specify some headers
    Set TextMIMEPart.ContentType="text/plain"
    Set TextMIMEPart.ContentCharset="us-ascii"
    Do TextMIMEPart.SetHeader("Custom-header",header)

    // Insert both subparts into the root part
    Do RootMIMEPart.Parts.Insert(BinaryMIMEPart)

    // create MIME writer; write root MIME message
    Set writer=##class(%Net.MIMEWriter).%New()

    // Prepare outputting to the HttpRequestStream
    Set SentHttpRequest=##class(%Net.HttpRequest).%New()
    Set status=writer.OutputToStream(SentHttpRequest.EntityBody)
    if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit}

    // Now write down the content
    Set status=writer.WriteMIMEBody(RootMIMEPart)
    if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit}

    Set SentHttpRequest.Server="congrio"
    Set SentHttpRequest.Port = 8080

    Set ContentType= "multipart/form-data; boundary="_RootMIMEPart.Boundary
    Set SentHttpRequest.ContentType=ContentType

    set url="alfresco/service/sample/upload.json?"
            _"alf_ticket=TICKET_caee62bf36f0ea5bd51194fce161f99092b75f62"

    set status=SentHttpRequest.Post(url,0) 
    if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit}
}
HTTP 応答へのアクセス
HTTP 要求を送信後、要求の HttpResponse プロパティが更新されます。このプロパティは、%Net.HttpResponse のインスタンスです。ここでは、応答オブジェクトの使用法について説明します。ここでは、以下のトピックについて説明します。
詳細は、%Net.HttpRequest のクラス・ドキュメントを参照してください。
応答のデータへのアクセス
HTTP 応答の本文は、応答の Data プロパティに含まれています。このプロパティには、ストリーム・オブジェクト (具体的には %GlobalBinaryStream) が含まれています。このストリームを使用するには、標準ストリーム・メソッドの Write()WriteLine()Read()ReadLine()Rewind()MoveToEnd()、および Clear() を使用します。また、ストリームの Size プロパティも使用できます。
要求ReadRawMode プロパティは、応答の本文を読み取る方法を制御します。
また、OutputToDevice() メソッドを使用して、完全な応答を現在のデバイスに書き込むこともできます。ヘッダは、Web サーバによって生成された順序と同じ順序ではありません。
名前による HTTP ヘッダの取得
%Net.HttpResponse クラスは、Caché 多次元配列内にその HTTP ヘッダを保存します。ヘッダにアクセスするには、以下のメソッドを使用します。
GetHeader()
指定したヘッダの値を返します。
GetNextHeader()
指定したヘッダの次のヘッダの名前を返します。
これらの各メソッドは、HTTP ヘッダの名前の文字列である単一の引数を取ります。
また、OutputHeaders() メソッドを使用して、HTTP ヘッダを現在のデバイスに書き込むこともできます (ただし、生成された順番と同じ順番ではありません)。
応答に関するその他の情報へのアクセス
%Net.HttpResponse クラスは、HTTP 応答のその他の特定の部分を保存するプロパティを提供します。