Delphi HTTP/2 クライアントとサーバー — 多重化、ストリーミング、Push

RFC 9113 HTTP/2 のネイティブ Pascal 実装 — ストリーム多重化、HPACK ヘッダー圧縮、フロー制御、サーバープッシュ、HTTP/2 上の WebSocket 拡張(RFC 8441)。同じコンポーネント、クライアントまたはサーバー、Delphi 7 から Delphi 13。

純粋 Pascal の HTTP/2 スタック

WinHTTP や libcurl の薄いラッパーではなく — フレームレベルの制御を提供するゼロからの実装。

Delphi HTTP/2 クライアントはもはやオプションではありません: HTTP/2 はモダンな Web 全体が話すワイヤー形式です。Apple Push Notifications は HTTP/2 を要求します。Google API は HTTP/2 をネゴシエートします。AWS、Azure、CloudFront はデフォルトで HTTP/2 を使用します。利点は実体があります: 単一の TCP/TLS 接続が数十の進行中リクエストを多重化し、ヘッダーセットは HPACK で圧縮され、サーバーはクライアントがまだ要求していないリソースをプッシュできます。sgcWebSockets は TsgcHTTP2Client(クライアント)と TsgcWebSocketHTTPServer 内の HTTP/2 サポート(サーバー)を出荷します — 両方とも純粋 Pascal、両方とも Delphi コンパイラが対象とするすべてのプラットフォームで動作。

同じライブラリ内の Delphi HTTP/2 サーバーは、REST API をホストし、長寿命クライアントにイベントをプッシュし、HTTP/2 上の WebSocket アップグレード(RFC 8441)を受け付けられます — モダンなインフラストラクチャが HTTP/2 / HTTP/3 の上に WebSocket を層化する標準的な方法。

クライアント

TsgcHTTP2Client

サーバー

HTTP/2 有効化済み TsgcWebSocketHTTPServer

標準

RFC 9113(HTTP/2)、RFC 7541(HPACK)、RFC 8441(WS-over-H2)

TLS

OpenSSL、SChannel、HTTP.sys — ALPN ネゴシエート

HTTP/2 が重要な理由

HTTP/1.1 を超える 4 つの大きな勝利 — それらを機能させる運用詳細。

ストリーム多重化

単一の TCP+TLS 接続で SETTINGS_MAX_CONCURRENT_STREAMS までの進行中リクエスト — ヘッドオブラインブロッキングなし、調整する接続プールなし。

HPACK 圧縮

接続ごとの静的 + 動的ヘッダーテーブルが、HTTP/1.1 トラフィックを膨張させる繰り返しヘッダー(cookie、user-agent、accept)のキロバイトを排除。

サーバープッシュ

サーバーは、クライアントが要求する前に必要となるリソース(CSS、JS、JSON サブリソース)を先取り送信できます — リクエストラウンドトリップをカット。

ストリーム優先順位

ストリームごとの重みと依存関係ツリーにより、サーバーに分析 blob より先に index ドキュメントを送るよう指示できます。

フロー制御

ストリームごとと接続ごとの WINDOW_UPDATE により、遅いコンシューマーが送信者を溺れさせるのを防ぎます — ワイヤー形式に組み込まれたバックプレッシャー。

ALPN ネゴシエーション

TLS 層 ALPN が自動的に h2 をネゴシエート — クライアントとサーバーは最初のリクエストの前に HTTP/2 で合意し、ピアが話さない場合は HTTP/1.1 フォールバック。

HTTP/2 上の WebSocket

RFC 8441: WebSocket セッションを 1 つの HTTP/2 ストリーム内にトンネル — あらゆる HTTP/2 対応ロードバランサー(Envoy、nginx、ALB、GCLB)を通過。

トレーラーと gRPC 親和

HTTP トレーラー(RFC 7230 に従う)は第一級 — gRPC のステータス/メッセージメタデータの基盤。

多重化 GET リクエスト

1 つの接続で 10 個の並行 GET を発火 — HPACK と多重化により日常的に。

uses
  sgcHTTP2_Client, sgcHTTP_Classes;

var
  HTTP2: TsgcHTTP2Client;
  i: Integer;
begin
  HTTP2 := TsgcHTTP2Client.Create(nil);
  HTTP2.Host := 'api.example.com';
  HTTP2.Port := 443;
  HTTP2.TLS  := True;
  HTTP2.TLSOptions.ALPNProtocols.Add('h2');
  HTTP2.OnResponse := DoResponse;

  HTTP2.Connect;

  // 10 concurrent GETs on ONE connection, ONE TLS handshake
  for i := 1 to 10 do
    HTTP2.Get(Format('/items/%d', [i]));
end;

procedure TForm1.DoResponse(Sender: TObject;
  const aStreamId: Cardinal;
  aHeaders: TsgcHTTP2Headers;
  aData: TBytes);
begin
  Memo1.Lines.Add(Format('stream %d  status %s  bytes %d',
    [aStreamId, aHeaders.Status, Length(aData)]));
end;

クライアントが要求する前にサブリソースをプッシュ

OnCommandGet ハンドラー内で PushPromise を呼び出し、/style.css/index.html と並行して先取り送信。

uses
  sgcWebSocket, sgcHTTP_Classes;

procedure TForm1.WSServerCommandGet(Sender: TObject;
  aContext: TsgcWSConnection;
  ARequestInfo: TsgcWSRequestInfo;
  AResponseInfo: TsgcWSResponseInfo);
begin
  if ARequestInfo.URI = '/index.html' then
  begin
    // Push the CSS so the browser doesn’t round-trip for it
    AResponseInfo.PushPromise('/style.css');
    AResponseInfo.PushPromise('/app.js');

    AResponseInfo.ContentType := 'text/html; charset=utf-8';
    AResponseInfo.ContentText :=
      '<!doctype html><link rel="stylesheet" href="/style.css">' +
      '<script src="/app.js" defer></script>' +
      '<h1>HTTP/2 from Delphi</h1>';
  end;
end;

HTTP/2 がオプションではなく必須の場所

Apple Push Notifications

APNs は HTTP/2 のみを受け入れます — 1 つの永続接続、毎秒数千のストリーム、JWT または証明書ベース認証。Apple Push ページを参照。

Google FCM v1

HTTP v1 FCM API は HTTP/2 で動作。Google FCM ページを参照。

gRPC サービス

gRPC は protobuf とトレーラーを持つ HTTP/2 です。ここの HTTP/2 スタックは Pascal gRPC クライアントが構築する基盤です。

HTTP/2 上の WebSocket

HTTP/2 アップストリームを好むモダンなロードバランサーと CDN を通じて WebSocket をデプロイする最もクリーンな方法。

高スループット REST クライアント

1 つの接続、数百の進行中リクエスト — クローラー、マーケットデータ取り込み、ファンアウトワーカーに最適。

ロングポール置き換え

単一の HTTP/2 ストリーム上で JSON-lines または SSE スタイルのレスポンスをストリーム — バックプレッシャー込み。

より深い探求

HTTP/2 リファレンス

HTTP/2 クライアントとサーバーの完全なコンポーネントリファレンス。

HTTP/2 クライアント

専用のクライアントコンポーネントページ。

HTTP/2 サーバー

専用のサーバーコンポーネントページ。

WebSocket コンポーネント

HTTP/2 上の WebSocket(RFC 8441)と HTTP/1.1 上(RFC 6455)。

ブログ: HTTP/2 初期サーバーサポート

オリジナルの発表と設計ノート。

ブログ: HTTP/2 vs HTTP/1 パフォーマンス

多重化と HPACK の利得に関するベンチマーク数値。

ブログ: HTTP/2 適合性テスト

サーバーに対する h2spec スイートの実行。

ブログ: HTTP/2 上の APNs

実践的 HTTP/2 の例: APNs 通知。

今日リクエストを多重化

トライアルをダウンロード — HTTP/2 クライアントとサーバーのデモは両方ともそのままコンパイル。