sgcQUIC を 5 分で
OpenSSL 内蔵の QUIC エンジン上で動作する、ネイティブ Object Pascal の QUIC と HTTP/3 です。4 つのコンポーネントが同梱されています。最短で動作させるには HTTP/3 クライアントが適しているため、このページでは 1 回のリクエストを送信してステータスコードを読み取り、必要な OpenSSL を正確に説明します。
OpenSSL 内蔵の QUIC エンジン上で動作する、ネイティブ Object Pascal の QUIC と HTTP/3 です。4 つのコンポーネントが同梱されています。最短で動作させるには HTTP/3 クライアントが適しているため、このページでは 1 回のリクエストを送信してステータスコードを読み取り、必要な OpenSSL を正確に説明します。
コンポーネント 1 つ、URL 1 つ、そして実行ファイルと同じ場所に置く OpenSSL ライブラリ 2 つです。
TsgcHTTP3Client は SGC QUIC パレットページにあり、sgcQUIC.pas で宣言されています。このページには TsgcQUICClient、TsgcQUICServer、TsgcHTTP3Server もあります。
コンポーネントには sgcQUIC を使用します。TsgcHTTP3Response には sgcHTTP3_Classes を、Alt-Svc イベントを処理する場合は sgcHTTP_AltSvc を追加します。
Get(aURL) は本文を string として返し、失敗した場合は例外を発生させます。ステータスコードとヘッダーは OnResponse で別途届きます。
クライアントには OpenSSL 3.2 以降の QUIC API、または quictls ビルドが必要です。サーバーは 3.5 以降が必要です。そこにしか存在しない API を呼び出すためです。すべてのデモフォルダーと同様に、libcrypto-3.dll と libssl-3.dll を実行ファイルと同じ場所に配置してください。
エディションの列は、コードを制御する define と、それが Source/sgcVer.inc の何行目にあるかを示しています。
| 項目 | 内容 |
|---|---|
| IDE | Delphi 7 から RAD Studio 13、および C++Builder 2007 から 13。sgcQUIC の個別のダウンロードはありません。コンポーネントは sgcWebSockets のパッケージグループに含まれています。 |
| uses 句 | sgcQUIC に加えて、レスポンスオブジェクトには sgcHTTP3_Classes、Alt-Svc の型には sgcHTTP_AltSvc を使用します。 |
| パックの define | SGC_PACK_QUIC は 872 行目、870 行目から 874 行目までの {$IFDEF SGC_EDT_ALL} ブロック内で定義されています。つまり All-Access です。 |
| 機能の define | 894 行目から 899 行目の {$IFDEF SGC_PACK_QUIC} ブロック内にあります。SGC_QUIC は 896 行目、SGC_HTTP3 は 897 行目、SGC_WEBTRANSPORT は 898 行目です。3 つとも 895 行目の {$IFDEF SGC_INDY_LIB} の内側にあるため、カスタム Indy ライブラリを使用しないビルドではいずれも有効になりません。 |
| OpenSSL(クライアント) | 3.2 以降、または quictls ビルドです。ライブラリ自身がそれを示します。QUIC が利用できない場合に発生するエラーは QUIC is not available. Requires quictls/openssl or OpenSSL 3.2+ です。 |
| OpenSSL(サーバー) | 3.5 以降です。QUIC サーバーは SSL_new_listener を呼び出し、それが存在しない場合に発生するエラーは QUIC Server requires OpenSSL 3.5 or later です。msquic は使用されず、必要ありません。 |
| プラットフォーム | sgcQUIC.pas、sgcQUIC_Client.pas、sgcHTTP3_Client.pas、sgcHTTP3_Server.pas にはユニットスコープのプラットフォームガードがなく、4 つのコンポーネントすべてが ComponentPlatforms(0) で登録されています。サーバーユニットは、Windows 用と POSIX 用の両方の分岐を持ち、プラットフォームごとにソケット API を選択します。 |
実行時にエンジンが存在するか分からない場合は、IsOpenSSL_QUIC_Available を呼び出してください。読み込んだ OpenSSL が QUIC クライアントメソッドを公開しているかどうかを返します。同梱の QUIC クライアントデモは、まさにこの理由で起動時にこれをログに出力します。
sgcQUIC 専用のインストーラーはありません。コンポーネントは sgcWebSockets に含まれており、エディションで有効になると表示されます。
sgcWebSockets のダウンロードをフォルダーに展開します。以下ではこのフォルダーを {$DIR} と呼びます。
ツール、オプション、ライブラリの順に開きます。{$DIR}\source と、お使いの IDE 用の lib フォルダー(たとえば {$DIR}\libD13\$(Platform))を追加します。
{$DIR}\Packages\ の下で、お使いの IDE バージョン用のパッケージグループを開きます。最初に実行時の .dpk をコンパイルし、次にデザイン時の dcl をインストールします。QUIC 専用のパッケージはありません。
SGC QUIC というページが表示され、TsgcQUICClient、TsgcQUICServer、TsgcHTTP3Client、TsgcHTTP3Server が含まれます。ページが表示されない場合、そのビルドは All-Access ではありません。SGC_PACK_QUIC は、そのブロック内の 872 行目でのみ定義されるためです。
libcrypto-3.dll と libssl-3.dll を実行ファイルの隣にコピーします。クライアントには 3.2 以降、サーバーには 3.5 以降が必要です。Demos\22.QUIC_Protocol の下のすべてのフォルダーに同梱されているので、そこからコピーできます。
クライアントを作成し、3 つのイベントを接続して、Get を呼び出します。返信は文字列として返り、ステータスコードは OnResponse で届きます。
uses
Classes, SysUtils,
// sgc
sgcQUIC, sgcHTTP3_Classes;
procedure TfrmHTTP3Client.FormCreate(Sender: TObject);
begin
FClient := TsgcHTTP3Client.Create(nil);
FClient.OnConnect := OnH3Connect;
FClient.OnError := OnH3Error;
FClient.OnResponse := OnH3Response;
FClient.TLSOptions.VerifyCertificate := True;
FClient.ConnectTimeout := 10000;
FClient.ReadTimeout := 30000;
FClient.UserAgent := 'sgcWebSockets/HTTP3Client';
end;
procedure TfrmHTTP3Client.btnGetClick(Sender: TObject);
var
vResult: string;
begin
try
// the target comes from the URL, because Host and Port
// are read-only on this component
vResult := FClient.Get('https://www.google.com/');
memoBody.Lines.Text := vResult;
DoLog('Response received: ' + IntToStr(Length(vResult)) + ' bytes');
except
on E: Exception do
DoLog('Error: ' + E.Message);
end;
end;
Post、Put、Delete も同じ形で、それぞれ文字列に保持したくない本文のためのストリームオーバーロードがあります。Connect(const aHost: string; aPort: Integer = 443) は、最初のリクエストより前に接続を開き、両者を分けたい場合に使用します。
// OnConnect and OnDisconnect are plain TNotifyEvent on this
// component: one parameter, no connection object.
procedure TfrmHTTP3Client.OnH3Connect(Sender: TObject);
begin
DoLog('Connected to ' + FClient.Host + ':' + IntToStr(FClient.Port));
end;
procedure TfrmHTTP3Client.OnH3Error(Sender: TObject; const aError: string);
begin
DoLog('Error: ' + aError);
end;
procedure TfrmHTTP3Client.OnH3Response(Sender: TObject;
const aResponse: TsgcHTTP3Response);
begin
DoLog('Status: ' + IntToStr(aResponse.StatusCode));
memoHeaders.Lines.Assign(aResponse.Headers);
end;
OnConnect 内で FClient.Host と FClient.Port を読み取るのが、この 2 つのプロパティの本来の用途です。これらは接続を報告するものであり、設定するものではありません。
uses
Classes, SysUtils,
// sgc
sgcIdSSLOpenSSLHeaders;
procedure TfrmQUICClient.FormCreate(Sender: TObject);
begin
DoLog('OpenSSL QUIC Support:');
DoLog(' quictls API: ' +
BoolToStr(IsOpenSSL_QUIC_TLS_Available, True));
DoLog(' Builtin QUIC (3.2+): ' +
BoolToStr(IsOpenSSL_QUIC_Available, True));
end;
他の何よりも先に、これを一度実行してください。両方とも false を返す場合、実行ファイルと同じ場所にある OpenSSL に QUIC がなく、その後のあらゆる接続失敗は、ネットワークではなくこの 1 つの事実の現れです。
最初の 2 つのタブは、同梱のデモ Demos\22.QUIC_Protocol\03.HTTP3_Client\FHTTP3Client.pas から、フォームコントロールをリテラルに置き換えたものです。3 つ目は 01.QUIC_Client\FQUICClient.pas の実行時の利用可否チェックです。そのフォルダーには、WebTransport のペアを含む 6 つの QUIC デモがあります。
Get は本文を返します。それ以外のすべてはレスポンスオブジェクトが持っており、専用のイベントで届きます。
Get はレスポンスの本文を string として返し、失敗した場合は例外を発生させるため、デモでは try except で囲んでいます。期待した長さの本文が得られることが最初の確認になります。
OnResponseprocedure(Sender: TObject; const aResponse: TsgcHTTP3Response)。StatusCode が実際に必要な数値で、Headers は TStringList、GetDataAsString でレスポンスオブジェクトから再び本文を取得できます。
OnConnect通常の TNotifyEvent です。発生したということは、QUIC のネゴシエーションが完了して HTTP/3 セッションが開いたことを意味し、最初の実行で最も失敗しやすい部分です。
IsOpenSSL_QUIC_Available は、最初に確認すべき唯一の問いに答えてくれます。また、QUIC は UDP 443 で動作しますが、TCP 443 を許可しているネットワークがそれを許可しているとは限りません。
最初のリクエストが失敗する原因のほとんどは、6 つの問題のいずれかです。
TsgcHTTP3Client では読み取り専用で、property Host: string read FHost と property Port: Integer read FPort として宣言されています。クライアントの接続先を報告するものです。接続先を指定するには、完全な URL を Get に渡すか、Connect(aHost, aPort) を呼び出します。
読み込んだ OpenSSL が古すぎるか、QUIC なしでビルドされています。クライアントには 3.2 以降、または quictls が必要です。ネットワークを疑う前に、IsOpenSSL_QUIC_Available で実行時に確認してください。
QUIC サーバーは SSL_new_listener を呼び出すため、OpenSSL 3.5 以降が必要です。3.2 のビルドはクライアントには十分ですが、サーバーには不十分で、エラーメッセージにもそのことが明記されます。
このコンポーネントの OnConnect と OnDisconnect は通常の TNotifyEvent なので、ハンドラーは Sender: TObject のみを受け取ります。WebSocket コンポーネントとは異なり、接続オブジェクトは渡されません。
QUIC はポート 443 の UDP で動作しますが、多くの企業ネットワークは TCP 443 を許可し、UDP 443 を破棄します。ブラウザーが HTTP/3 でそのホストに到達できるのにアプリケーションが到達できない場合は、コードよりも先にファイアウォールを疑ってください。
SGC_PACK_QUIC は All-Access ブロック内の 872 行目でのみ定義されます。さらに SGC_INDY_LIB も必要です。894 行目から 899 行目のパックブロック全体がそのガードの内側にあるためです。
4 つの方向があり、いずれも同じパッケージの中にあります。
TsgcHTTP3Server は、QUIC 上で HTTP/3 を直接配信します。サーバー側には OpenSSL 3.5 以降が必要なことを忘れないでください。
TsgcQUICClient と TsgcQUICServer は、HTTP/3 レイヤーなしで QUIC ストリームを提供します。ヘッドオブラインブロッキングなしの多重化が必要な独自プロトコルに適しています。
HTTP/3 を介してブラウザーとの双方向ストリームとデータグラムを扱います。898 行目の SGC_WEBTRANSPORT で制御されます。2 つのデモが同梱されています。
サーバーは Alt-Svc ヘッダーで HTTP/3 を通知します。OnAltSvc を処理すれば、オリジンが提供している場合に、既存の接続を QUIC にアップグレードできます。
デモプロジェクトはダウンロードに含まれており、Demos\22.QUIC_Protocol の下に 6 つあります。
HTTP/3 クライアントコンポーネント
TsgcHTTP3Client が公開しているものを、プロパティごとに説明します。
|
開く | |
| HTTP/3 サーバーコンポーネント OpenSSL 3.5 の要件を含む、サーバー側の説明です。 | 開く | |
| QUIC クライアントコンポーネント HTTP/3 レイヤーなしの生の QUIC ストリームです。 | 開く | |
| sgcQUIC の機能 QPACK、0-RTT、コネクションマイグレーション、WebTransport などです。 | 開く | |
| 体験版のダウンロード IDE バージョンごとに 1 つのインストーラーで、QUIC コンポーネントがあらかじめ含まれています。 | 開く | |
| オンラインヘルプ 自動生成されたリファレンスで、常に最新リリースに対応しています。 | 開く |
関連資料:QUIC クライアントとサーバーのコンポーネントとHTTP/3 コンポーネント。トランスポートを選ぶ際は、リアルタイムトランスポートガイドで比較できます。各製品にはそれぞれクイックスタートがあり、はじめにのページに一覧があります。
sgcQUIC にある TsgcHTTP3Client です。OnResponse のパラメーター型である TsgcHTTP3Response には sgcHTTP3_Classes を、OnAltSvc を処理する場合は sgcHTTP_AltSvc を追加してください。パレットページには TsgcQUICClient、TsgcQUICServer、TsgcHTTP3Server もあります。
SSL_new_listener を呼び出すため 3.5 以降が必要で、そのエラーメッセージにもバージョンが明記されます。libcrypto-3.dll と libssl-3.dll を実行ファイルと同じ場所に配置してください。msquic は使用されません。
TsgcHTTP3Client はこれらを property Host: string read FHost と property Port: Integer read FPort として宣言しているため、設定するのではなく現在の接続を報告します。Get、Post、Put、Delete に完全な URL を渡すか、先に Connect(const aHost: string; aPort: Integer = 443) を呼び出してください。
TNotifyEvent で、procedure(Sender: TObject) です。OnDisconnect も同様です。イベントが TsgcWSConnection を渡す WebSocket コンポーネントとは異なり、最初のコンパイルエラーの一般的な原因になります。OnResponse は procedure(Sender: TObject; const aResponse: TsgcHTTP3Response)、OnError は procedure(Sender: TObject; const aError: string) です。
OnResponse のレスポンスオブジェクトから読み取ります。TsgcHTTP3Response は StatusCode、TStringList としての Headers、本文用の GetDataAsString を公開しています。Get メソッド自体は本文のみを文字列として返すため、デモでは OnResponse も接続しています。
SGC_PACK_QUIC は sgcVer.inc の 872 行目で、870 行目から 874 行目までの {$IFDEF SGC_EDT_ALL} ブロック内で定義されています。つまり All-Access です。894 行目から 899 行目のパックブロック自体も {$IFDEF SGC_INDY_LIB} の内側にあるため、カスタム Indy ライブラリもビルドに含める必要があります。そのブロック内で、SGC_QUIC は 896 行目、SGC_HTTP3 は 897 行目、SGC_WEBTRANSPORT は 898 行目です。
IsOpenSSL_QUIC_Available は、読み込んだ OpenSSL が QUIC クライアントメソッドを公開しているかどうかを返し、IsOpenSSL_QUIC_TLS_Available は QUIC の TLS コールバックについて同じことを行います。同梱の QUIC クライアントデモは起動時に両方をログに出力し、原因不明の接続失敗を 1 行の答えに変えます。