HTTP/3 サポート

Salvo は HTTP/3 のサポートを提供しており、quinn フィーチャーを有効にすることでこの機能を利用できます。HTTP/3 は QUIC プロトコルを基盤としており、従来の HTTP/1.1 や HTTP/2 と比較して、特に不安定なネットワーク環境において、より低いレイテンシと優れたパフォーマンスを実現します。

HTTP/3 サポートの有効化

Salvo で HTTP/3 サポートを有効にするには、Cargo.toml ファイルで quinn フィーチャーを有効化する必要があります:

salvo = { workspace = true, features = ["quinn"] }

HTTP/3 の適用シナリオ

HTTP/3 は特に以下のシナリオに適しています:

  • モバイルデバイスや不安定なネットワーク環境でのアプリケーション
  • 低遅延が求められるリアルタイムアプリケーション
  • 多数の小規模ファイルを並行ダウンロードするシナリオ
  • 接続マイグレーションが必要なアプリケーション(例:WiFi から携帯ネットワークへの切り替え時に接続を維持)

サンプルコード

以下は、HTTP/3 (QUIC) と HTTPS (TCP) の両方をサポートするシンプルな HTTP/3 サーバーの例です:

use salvo::conn::rustls::{Keycert, RustlsConfig};
use salvo::prelude::*;

// ハンドラー関数、"Hello World" を返す
#[handler]
async fn hello() -> &'static str {
    "Hello World"
}

#[tokio::main]
async fn main() {
    // ロギングシステムの初期化
    tracing_subscriber::fmt().init();

    // 埋め込まれた PEM ファイルから TLS 証明書と秘密鍵を読み込む
    let cert = include_bytes!("../certs/cert.pem").to_vec();
    let key = include_bytes!("../certs/key.pem").to_vec();

    // ルーターを作成し、エンドポイントを追加
    let router = Router::new().get(hello);

    // Rustls を使用して TLS 設定を構成
    let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));

    // TLS 暗号化付きの TCP リスナーを作成し、ポート 8698 で待機
    let listener = TcpListener::new(("0.0.0.0", 8698)).rustls(config.clone());

    // QUIC リスナーを作成し、TCP リスナーと結合
    let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 8698))
        .join(listener)
        .bind()
        .await;

    // HTTP/3 (QUIC) と HTTPS (TCP) の両方をサポートするサーバーを起動
    Server::new(acceptor).serve(router).await;
}

主要コードの解説

TLS 設定

// Rustls を使用して TLS 設定を構成
let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));

HTTP/3 は QUIC プロトコルを基盤としており、QUIC は暗号化に TLS 1.3 を必要とするため、TLS 証明書と秘密鍵の設定が必要です。Salvo では、RustlsConfig を使用して TLS を設定します。

リスナーの結合

// TLS 暗号化付きの TCP リスナーを作成
let listener = TcpListener::new(("0.0.0.0", 8698)).rustls(config.clone());

// QUIC リスナーを作成し、TCP リスナーと結合
let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 8698))
    .join(listener)
    .bind()
    .await;

このコードは、Salvo で HTTP/3 を処理するための中心的な部分です。まず、TLS をサポートする TCP リスナー(HTTP/1.1 および HTTP/2 用)を作成し、次に QUIC リスナー(HTTP/3 用)を作成します。join メソッドを使用してこれら 2 つのリスナーを結合することで、サーバーは異なるプロトコルのリクエストを同時に処理できるようになります。

サンプルの実行

このサンプルを実行するには、有効な TLS 証明書と秘密鍵が必要です。開発環境では、自己署名証明書を使用できます。完全なサンプルコードは Salvo GitHub リポジトリ で確認できます。

現在、多くのクライアントが HTTP/3 を完全にはサポートしていないため、このサーバーが HTTP/3 と HTTPS の両方をサポートすることは非常に重要です。

注意事項

  1. HTTP/3 は TLS 1.3 のサポートを必要とするため、有効な証明書と秘密鍵の設定が必須です。
  2. クライアントが HTTP/3 プロトコルをサポートしている場合にのみこの機能を利用でき、そうでない場合は HTTP/1.1 または HTTP/2 にフォールバックします。
  3. 本番環境では、自己署名証明書ではなく、信頼された CA が発行した証明書を使用する必要があります。