HTTP クライアントの使用
マルチデバイス アプリケーションでの RTL の使用 への移動
RTL では、サーバーに HTTP 要求を送信し、その応答を処理できるよう、次の 2 つのコンポーネントを提供しています。
目次
設計時のアプリケーションの構成
HTTP クライアントを作成する
HTTP 要求の送信に使用できる HTTP クライアントを作成するには、[ツール パレット]からアプリケーションのフォームまたはデータ モジュールへ、TNetHTTPClient をドラッグします。TNetHTTPClient の初期構成は必要ありません。
HTTP 要求を作成し構成する
また、1 つ以上の TNetHTTPRequest コンポーネントをフォームまたはデータ モジュールにドロップする必要があります。
新しい HTTP 要求コンポーネントをドロップしたら、[オブジェクト インスペクタ]で Client プロパティをダブルクリックし、その値に先ほどドロップした HTTP クライアント コンポーネントを設定します。
要求コンポーネントは、必要な数だけ使用することができます。ただし、異なる複数の HTTP 要求を送信する必要がある場合、1 つの HTTP 要求コンポーネントを使用して、実行時にそのコンポーネントを再構成してそれぞれの要求を送信する方がよいでしょう。
要求の送信と応答の処理
HTTP 要求を送信する
HTTP 要求を送信するには、少なくとも以下を指定しなければなりません。
- HTTP 要求メソッド
- リソース URL
HTTP 要求メソッドによって、指定された URL にあるリソース上でサーバーに実行させるアクション(リソースのデータを送り返す、要求に含まれるデータでリソースを更新する、など)が決まります。
TNetHTTPRequest コンポーネントを使用して HTTP 要求を送信する方法は、使用する HTTP 要求メソッドによって異なります。
DELETE、GET、HEAD、OPTIONS、または TRACE HTTP 要求メソッドを使用して HTTP 要求を送信する
以下の HTTP 要求メソッドには、送信先リソースの URL 以外の入力データは必要ありません。
この HTTP 要求メソッドのいずれかを使用して HTTP 要求を送信するには、まず、設計時に要求を以下のように構成します。
- URL プロパティを、送信先リソースの URL に構成します。
- MethodString プロパティを、使用したい HTTP 要求メソッドの名前に構成します。
その後、Execute を呼び出して要求を送信します。
MERGE、PATCH、または PUT HTTP 要求メソッドを使用して HTTP 要求を送信する
以下の HTTP 要求メソッドには、送信先リソースの URL の他にも入力データが必要です。
この HTTP 要求メソッドのいずれかを使用して HTTP 要求を送信するには、次の表に示す対応する関数を呼び出します。呼び出し時には、第 1 引数に送信先リソースの URL を、第 2 引数に TStream のインスタンスを指定します。
HTTP 要求メソッド | TNetHTTPRequest の関数 |
---|---|
PUT | Put |
PATCH | Patch |
MERGE | Merge |
PUT 経由の PATCH* | PatchAlternative |
PUT 経由の MERGE* | MergeAlternative |
- * HTTP プロキシの中には、最新の標準 HTTP 要求メソッド(PATCH など)や非標準の HTTP 要求メソッド(MERGE など)をサポートしていないものがあります。その場合には、別の HTTP 要求メソッドを代理として HTTP 要求メソッドを実行することができます。そのためには、別の要求に、実行したい HTTP 要求メソッドを指定するヘッダーを含めます。
POST HTTP 要求メソッドを使用して HTTP 要求を送信する
POST HTTP 要求メソッドには、送信先リソースの URL の他にも入力データが必要です。
POST HTTP 要求メソッドを使用して HTTP 要求を送信するには、Post を呼び出します。その呼び出しの第 1 引数に、送信先リソースの URL を指定します。残りの引数は、要求の入力データを渡す方法によって異なります。
- ローカル ファイルの内容を送信する場合は、そのファイルへのローカル パスを呼び出しの第 2 引数に指定します。
- ストリームの内容を送信する場合は、TStream のインスタンスを呼び出しの第 2 引数に指定します。
- HTML 4 標準に沿って MIME マルチパート メッセージとしてエンコードされたフォーム データを送信する場合は、TMultipartFormData のインスタンスを呼び出しの第 2 引数に指定します。
- 文字列リストの内容を送信する場合は、TStrings のインスタンスを呼び出しの第 2 引数に指定します。このとき文字列のエンコードが UTF-8 でなければ、TEncoding のインスタンスを第 4 引数に指定します。次に例を示します。
NetHTTPRequest1.Post('http://www.example.com/rest/items', String1, nil, TEncoding.Default);
NetHTTPRequest1->Post("http://www.example.com/rest/items", String1, NULL, TEncoding::Default);
HTTP 応答を処理する
ターゲット サーバーが要求に対する応答を送信すると、HTTP 要求コンポーネントの OnRequestCompleted イベントが発生します。このイベントのイベント ハンドラを定義して、サーバー応答からデータを読み取ります。要求の実行中にエラーが発生した場合は、HTTP 要求コンポーネントの OnRequestError イベントが発生します。
OnRequestCompleted のイベント ハンドラは、次の 2 つのパラメータを受け取ります。
Sender
: HTTP 要求コンポーネントAResponse
: IHTTPResponse インターフェイスを実装したオブジェクト
応答データはすべて、AResponse
から取得することができます。
- Version は、サーバーが使用する HTTP プロトコルのバージョンを示します。
- StatusCode には、応答のステータス コードが含まれます。StatusText には、そのステータスについての、人が読んでわかるテキストが含まれます。たとえば StatusCode が 200 のときには "OK" が含まれます。
- ContentAsString には、レスポンスの本体が文字列として含まれます。 また、レスポンスの本体の raw データを、ContentStream からストリームとして読み込むことができます。
- Headers、HeaderValue、ContainsHeader を使用して応答ヘッダーを読み取ることができます。また、共通の HTTP 応答ヘッダー フィールドの値を、ヘルパ プロパティ ContentCharSet、ContentEncoding、ContentLanguage、ContentLength、Date、LastModified、MimeType から読み取ることもできます。
- Cookies には、サーバー応答のクッキーが含まれます。
クッキーの管理
HTTP クライアント コンポーネントの AllowCookies プロパティを使用すると、サーバーからの応答で送信されるクッキーを受け入れるかどうかを指定できます。
AllowCookies が True
の場合、HTTP クライアントでは、受け取ったクッキーを自分の CookieManager プロパティに保存します。
リダイレクトの処理
HandleRedirects プロパティを使用すると、HTTP クライアント コンポーネントでのリダイレクトの処理方法を制御できます。デフォルト値は True
で、HTTP クライアント コンポーネントがリダイレクトに自動的に従うことを意味します。
HTTP クライアント コンポーネントの MaxRedirects プロパティを使用すると、コンポーネントで従うことができるリダイレクトの回数の上限を指定できます。HTTP クライアント コンポーネントが、指定されたリダイレクト回数の上限に達すると、ENetHTTPRequestException 型の例外が発生します。
応答データのダウンロードの処理
要求に対する応答を HTTP クライアントがダウンロードしている間、HTTP 要求オブジェクトの OnReceiveData イベントが発生し続けます。OnReceiveData のイベント ハンドラを用意すると、応答データのダウンロードの進行状況を追跡できます。このイベント ハンドラは次のパラメータを受け取ります。
Sender
: HTTP 要求オブジェクトAContentLength
: 応答データの予想される長さ(バイト数)AReadCount
: HTTP クライアントがこれまでにダウンロードした応答データのバイト数Abort
: ダウンロードをキャンセルするかどうかを示す論理型パラメータ
ダウンロードが終了すると、最後に OnReceiveData イベントが発生し、このときの AContentLength
と AReadCount
の値は同じです。その後すぐに OnRequestCompleted イベントが発生します。
応答データのダウンロードの進行状況を追跡する
応答データのダウンロードの進行状況を追跡するには、OnReceiveData イベントのイベント ハンドラで AContentLength
と AReadCount
の値を使用します。
次の例では、ダウンロードしたデータの割合(%)を計算しています。
procedure TForm1.NetHTTPRequest1ReceiveData(const Sender: TObject;
AContentLength, AReadCount: Int64; var Abort: Boolean);
var
percentageDownloaded:Double;
begin
if AContentLength > 0 then
percentageDownloaded := (AReadCount / AContentLength) * 100;
else
// the server did not provide the Content-Length header
end;
void __fastcall TForm1::NetHTTPRequest1ReceiveData(TObject * const Sender, __int64 AContentLength,
__int64 AReadCount, bool &Abort)
{
float percentageDownloaded;
if (AContentLength > 0)
{
percentageDownloaded = ((float)AReadCount / (float)AContentLength) * 100.f;
}
else
{
// the server did not provide the Content-Length header
}
}
応答データのダウンロードをキャンセルする
応答データのダウンロードをキャンセルするには、OnReceiveData イベント ハンドラの中で、Abort
の値を True
に変更します。
カスタム ヘッダーを含んだ要求の送信
HTTP クライアント コンポーネントでも HTTP 要求コンポーネントでも、カスタム ヘッダーを設定することができます。 指定可能なカスタム ヘッダーは次のとおりです。
- HTTP クライアント コンポーネントでは:
- HTTP 要求コンポーネントでは:
要求を実行すると、HTTP フレームワークの THTTPClient.Execute メソッドにより、HTTP クライアント コンポーネントからのカスタム ヘッダーと、対応する HTTP 要求コンポーネントからのカスタム ヘッダーが結合され、その一体化されたヘッダーが最終的な要求に付け加えられます。
セキュアな接続の処理
HTTP クライアント コンポーネントでは、セキュアな接続(HTTPS 接続)をサポートしています。発生して必要に応じて下記の適切なイベントを起動する証明書要求はすべて、HTTP フレームワークで自動的に処理されます。
- OnNeedClientCertificate(サーバーがクライアントに証明書を要求した場合)
- OnValidateServerCertificate(サーバーから提供された証明書が無効な場合)
証明書の処理の詳細については、「サーバー側の証明書を処理する」セクションと「クライアント側の証明書を処理する」セクションを参照してください。
認証と証明書の処理
HTTP 基本アクセス認証を処理する
HTTP 基本アクセス認証が必要なサーバーに HTTP 要求を送信すると、HTTP クライアント オブジェクトの OnAuthEvent イベントが発生します。アクセス資格情報を送信するには、このイベントのイベント ハンドラを用意し、イベント ハンドラが受け取る第 2 パラメータ(AnAuthTarget
)の値が TAuthTargetType.Server の場合に、AUserName
変数と APassword
変数に HTTP アクセスのユーザー名とパスワードを設定します。次に例を示します。
procedure TForm1.NetHTTPClient1AuthEvent(const Sender: TObject;
AnAuthTarget: TAuthTargetType; const ARealm, AURL: string;
var AUserName, APassword: string; var AbortAuth: Boolean;
var Persistence: TAuthPersistenceType);
begin
if AnAuthTarget = TAuthTargetType.Server then
begin
AUserName := 'MyUsername';
APassword := '1234';
end;
end;
void __fastcall TForm1::NetHTTPClient1AuthEvent(TObject * const Sender,
TAuthTargetType AnAuthTarget, const UnicodeString ARealm,
const UnicodeString AURL, UnicodeString &AUserName, UnicodeString &APassword,
bool &AbortAuth, TAuthPersistenceType &Persistence)
{
if (AnAuthTarget == TAuthTargetType::Server) {
AUserName = "MyUsername";
APassword = "1234";
}
}
また、このイベント ハンドラは、認証が必要な HTTP サーバーの領域(ARealm
)と、要求の送信先 URL(AURL
)も受け取ります。
HTTP 認証プロセスを中止するには、AbortAuth
の値を True
に変更します。
プロキシ経由で要求を送信する
認証が必要なプロキシを経由して送信する場合は、認証に使用されるプロキシ設定を定義できます。 その方法を次の例で説明します。
NetHTTPClient1.ProxySettings := TProxySettings.Create('192.168.1.1', 8080, 'MyUserName', 'MyPassword');
TProxySettings MyProxySettings("192.168.1.1", 8080, "MyUserName", "MyPassword", "");
NetHTTPClient1->ProxySettings = MyProxySettings;
プロキシ設定を指定するには、プロキシ関連情報を含んだ URL 文字列を渡す方法もあります。
NetHTTPClient1.ProxySettings := TProxySettings.Create('http://MyUserName:[email protected]:8080');
TProxySettings MyProxySettings("http://MyUserName:[email protected]:8080");
NetHTTPClient1->ProxySettings = MyProxySettings;
あるいは、プロキシ認証の資格情報を OnAuthEvent イベントのイベント ハンドラで指定することもできます。「HTTP 基本アクセス認証を処理する」セクションを参照し、AnAuthTarget
の値が TAuthTargetType.Server
ではなく TAuthTargetType.Proxy
になっていることを確認してください。
HTTP クライアントでのシステム プロキシ設定の扱い
以下の表は、HTTP クライアントがシステム プロキシ設定をどう扱うかをプラットフォームごとにまとめたものです。
プラットフォーム | 動作 |
---|---|
Windows |
HTTP クライアントはシステム プロキシ設定を使用します。システム プロキシ設定を無視したり、HTTP クライアント用に別のプロキシ設定を指定することも可能です。
システム プロキシ設定を無視するには、HTTP クライアント用のプロキシ設定を作成し、URL に |
macOS |
HTTP クライアントは常にシステム プロキシ設定を使用します。HTTP クライアント用に別のプロキシ設定を指定した場合でも、HTTP クライアントではシステム プロキシ設定が使用されます。 |
iOS |
HTTP クライアントは常にシステム プロキシ設定を使用します。HTTP クライアント用に別のプロキシ設定を指定した場合でも、HTTP クライアントではシステム プロキシ設定が使用されます。 |
Android |
HTTP クライアントはシステム プロキシ設定を使用します。この設定を無視することはできませんが、HTTP クライアント用に別のプロキシ設定を指定することは可能です。 |
Linux |
HTTP クライアントはシステム プロキシ設定を使用します。この設定を無視することはできませんが、HTTP クライアント用に別のプロキシ設定を指定することは可能です。 |
ユーザー資格情報のストレージを管理する
TNetHTTPClient では、HTTP 認証またはプロキシ認証の資格情報を保存することができます。保存される各資格情報には、ユーザー名、パスワード、認証ターゲットの種類、領域、ターゲット URL を含めることができます。
TNetHTTPClient.CredentialsStorage を使用して資格情報を保存したあと、基本認証が必要な HTTP サーバーに接続する際にその資格情報を使用して認証を行う方法を次の例で説明します。
- 次のように、資格情報を作成して資格情報ストレージに追加します。Delphi の場合:
NetHTTPClient1.CredentialsStorage.AddCredentials(TCredentialsStorage.TCredential.Create(TAuthTargetType.Server, '', '', 'MyUserName', 'MyPassword');
C++ の場合:TCredentialsStorage::TCredential *MyCredential = new TCredentialsStorage::TCredential(TAuthTargetType::Server, "", "", "MyUserName", "MyPassword"); NetHTTPClient1->CredentialsStorage->AddCredential(*MyCredential);
- 保存した資格情報を使用します。
たとえば、OnAuthEvent イベントのイベント ハンドラを記述し、その中で次の処理を行うことができます。
- TCredentialsStorage.FindAccurateCredential を使用して、必要な認証タイプ(
TAuthTargetType.Server
)と一致する資格情報を検索する。 - 該当する資格情報から得られたユーザー名とパスワードを使用して認証を行う。
Delphi の場合:procedure TForm1.NetHTTPClient1AuthEvent(const Sender: TObject; AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName, APassword: string; var AbortAuth: Boolean; var Persistence: TAuthPersistenceType); var MyCredential: TCredentialsStorage.TCredential; begin MyCredential := NetHTTPClient1.CredentialsStorage.FindAccurateCredential(AnAuthTarget, ''); AUserName := MyCredential.UserName; APassword := MyCredential.Password; end;
C++ の場合:void __fastcall TForm2::NetHTTPClient1AuthEvent(TObject * const Sender, TAuthTargetType AnAuthTarget, const UnicodeString ARealm, const UnicodeString AURL, UnicodeString &AUserName, UnicodeString &APassword, bool &AbortAuth, TAuthPersistenceType &Persistence) { TCredentialsStorage::TCredential MyCredential; MyCredential = NetHTTPClient1->CredentialsStorage->FindAccurateCredential(AnAuthTarget, ""); AUserName = MyCredential.UserName; APassword = MyCredential.Password; }
- TCredentialsStorage.FindAccurateCredential を使用して、必要な認証タイプ(
サーバー側の証明書を処理する
サーバーが SSL 証明書を提供していて、その証明書が無効だった場合、OnValidateServerCertificate イベントが発生します。OnValidateServerCertificate
のイベント ハンドラを作成し、そこでサーバー証明書(Certificate
)を確認して、サーバー証明書を受け入れるかどうかを判断します。サーバー証明書を受け入れる場合には、Accept
パラメータの値を True
に変更します。
クライアント側の証明書を処理する
サーバーでクライアント証明書が要求される場合、OnNeedClientCertificate イベントが発生します。OnNeedClientCertificate
のイベント ハンドラを作成し、そこでクライアント証明書のリスト(ACertificateList
)を確認して、どの証明書をサーバーに送信するかを判断します。リスト内の特定の証明書を送信するには、AnIndex
の値を ACertificateList
における対象の証明書のインデックスに変更します。
非同期に要求を送信する
要求はデフォルトでは、同期をとります。要求の間、アプリケーションの実行は要求が開始されたところで停止し、サーバーから応答を受け取るか、要求がタイムアウトしたときのみ再開します。
要求がアプリケーションの実行を停止させないよう、要求を非同期に行いたい場合、クライアント コンポーネントの Asynchronous プロパティか、要求コンポーネントの Asynchronous プロパティを有効にしなければなりません。どちらのコンポーネントかは、要求の実行にどちらを使用するかによります。