sgcQUIC を 5 分で

OpenSSL 内蔵の QUIC エンジン上で動作する、ネイティブ Object Pascal の QUIC と HTTP/3 です。4 つのコンポーネントが同梱されています。最短で動作させるには HTTP/3 クライアントが適しているため、このページでは 1 回のリクエストを送信してステータスコードを読み取り、必要な OpenSSL を正確に説明します。

QUIC RFC 9000 と HTTP/3 RFC 9114
クライアントには OpenSSL 3.2 以降
All-Access エディション

最初のリクエストに必要なもの

コンポーネント 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 の要件

クライアントには 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 に含まれており、エディションで有効になると表示されます。

1. 展開

sgcWebSockets のダウンロードをフォルダーに展開します。以下ではこのフォルダーを {$DIR} と呼びます。

2. ライブラリパス

ツール、オプション、ライブラリの順に開きます。{$DIR}\source と、お使いの IDE 用の lib フォルダー(たとえば {$DIR}\libD13\$(Platform))を追加します。

3. パッケージのビルド

{$DIR}\Packages\ の下で、お使いの IDE バージョン用のパッケージグループを開きます。最初に実行時の .dpk をコンパイルし、次にデザイン時の dcl をインストールします。QUIC 専用のパッケージはありません。

4. パレットの確認

SGC QUIC というページが表示され、TsgcQUICClient、TsgcQUICServer、TsgcHTTP3Client、TsgcHTTP3Server が含まれます。ページが表示されない場合、そのビルドは All-Access ではありません。SGC_PACK_QUIC は、そのブロック内の 872 行目でのみ定義されるためです。

5. OpenSSL を exe と同じ場所に置く

libcrypto-3.dll と libssl-3.dll を実行ファイルの隣にコピーします。クライアントには 3.2 以降、サーバーには 3.5 以降が必要です。Demos\22.QUIC_Protocol の下のすべてのフォルダーに同梱されているので、そこからコピーできます。

1 回の HTTP/3 リクエスト

クライアントを作成し、3 つのイベントを接続して、Get を呼び出します。返信は文字列として返り、ステータスコードは OnResponse で届きます。

FHTTP3Client.pas
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) は、最初のリクエストより前に接続を開き、両者を分けたい場合に使用します。

FHTTP3Client.pas
// 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 つのプロパティの本来の用途です。これらは接続を報告するものであり、設定するものではありません。

FQUICClient.pas
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 で囲んでいます。期待した長さの本文が得られることが最初の確認になります。

OnResponse

procedure(Sender: TObject; const aResponse: TsgcHTTP3Response)。StatusCode が実際に必要な数値で、Headers は TStringList、GetDataAsString でレスポンスオブジェクトから再び本文を取得できます。

OnConnect

通常の TNotifyEvent です。発生したということは、QUIC のネゴシエーションが完了して HTTP/3 セッションが開いたことを意味し、最初の実行で最も失敗しやすい部分です。

コードを疑う前に

IsOpenSSL_QUIC_Available は、最初に確認すべき唯一の問いに答えてくれます。また、QUIC は UDP 443 で動作しますが、TCP 443 を許可しているネットワークがそれを許可しているとは限りません。

初回によくあるつまずき

最初のリクエストが失敗する原因のほとんどは、6 つの問題のいずれかです。

Host や Port に代入できない

TsgcHTTP3Client では読み取り専用で、property Host: string read FHost と property Port: Integer read FPort として宣言されています。クライアントの接続先を報告するものです。接続先を指定するには、完全な URL を Get に渡すか、Connect(aHost, aPort) を呼び出します。

QUIC が利用できない

読み込んだ OpenSSL が古すぎるか、QUIC なしでビルドされています。クライアントには 3.2 以降、または quictls が必要です。ネットワークを疑う前に、IsOpenSSL_QUIC_Available で実行時に確認してください。

サーバーが起動しない

QUIC サーバーは SSL_new_listener を呼び出すため、OpenSSL 3.5 以降が必要です。3.2 のビルドはクライアントには十分ですが、サーバーには不十分で、エラーメッセージにもそのことが明記されます。

OnConnect の引数の数が違う

このコンポーネントの OnConnect と OnDisconnect は通常の TNotifyEvent なので、ハンドラーは Sender: TObject のみを受け取ります。WebSocket コンポーネントとは異なり、接続オブジェクトは渡されません。

UDP がブロックされている

QUIC はポート 443 の UDP で動作しますが、多くの企業ネットワークは TCP 443 を許可し、UDP 443 を破棄します。ブラウザーが HTTP/3 でそのホストに到達できるのにアプリケーションが到達できない場合は、コードよりも先にファイアウォールを疑ってください。

パレットページが表示されない

SGC_PACK_QUIC は All-Access ブロック内の 872 行目でのみ定義されます。さらに SGC_INDY_LIB も必要です。894 行目から 899 行目のパックブロック全体がそのガードの内側にあるためです。

最初のリクエストの先へ

4 つの方向があり、いずれも同じパッケージの中にあります。

HTTP/3 サーバーを実行する

TsgcHTTP3Server は、QUIC 上で HTTP/3 を直接配信します。サーバー側には OpenSSL 3.5 以降が必要なことを忘れないでください。

HTTP/3 サーバーコンポーネント

HTTP なしの生の QUIC

TsgcQUICClient と TsgcQUICServer は、HTTP/3 レイヤーなしで QUIC ストリームを提供します。ヘッドオブラインブロッキングなしの多重化が必要な独自プロトコルに適しています。

QUIC クライアントとQUIC サーバー

WebTransport

HTTP/3 を介してブラウザーとの双方向ストリームとデータグラムを扱います。898 行目の SGC_WEBTRANSPORT で制御されます。2 つのデモが同梱されています。

sgcQUIC の機能

HTTP/2 から HTTP/3 を検出する

サーバーは Alt-Svc ヘッダーで HTTP/3 を通知します。OnAltSvc を処理すれば、オリジンが提供している場合に、既存の接続を QUIC にアップグレードできます。

HTTP/2 クライアント

リファレンス、デモ、ドキュメント

デモプロジェクトはダウンロードに含まれており、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 クイックスタートに関するよくある質問

SGC QUIC パレットページの、ユニット sgcQUIC にある TsgcHTTP3Client です。OnResponse のパラメーター型である TsgcHTTP3Response には sgcHTTP3_Classes を、OnAltSvc を処理する場合は sgcHTTP_AltSvc を追加してください。パレットページには TsgcQUICClient、TsgcQUICServer、TsgcHTTP3Server もあります。
どちら側を構築するかによって異なります。クライアントには OpenSSL 3.2 で追加された QUIC API、または quictls ビルドが必要で、ライブラリは発生させるメッセージでそれを示します。QUIC is not available. Requires quictls/openssl or OpenSSL 3.2+。サーバーは 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 行目です。
いいえ。体験版のインストーラーは IDE バージョンごとに用意されており、QUIC と HTTP/3 のコンポーネントがすでに含まれていて、QUIC 専用のパッケージファイルはありません。sgcWebSockets をインストールすると、エディションで有効になっている場合に SGC QUIC パレットページが表示されます。
はい、確認することをお勧めします。IsOpenSSL_QUIC_Available は、読み込んだ OpenSSL が QUIC クライアントメソッドを公開しているかどうかを返し、IsOpenSSL_QUIC_TLS_Available は QUIC の TLS コールバックについて同じことを行います。同梱の QUIC クライアントデモは起動時に両方をログに出力し、原因不明の接続失敗を 1 行の答えに変えます。
最もお得な選択: All-AccesseSeGeCe の全製品にプレミアムサポートが付いて、年間 €1,059 からご利用いただけます。
All-Access の価格を見る

Delphi から HTTP/3 を試す準備はできましたか?

体験版をダウンロードして、実際のオリジンに対して HTTP/3 クライアントのデモを実行してみてください。