HTTP/3 サポート

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

HTTP/3サポートの有効化

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

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リスナーを作成、5800ポートで待機
    let listener = TcpListener::new(("0.0.0.0", 5800)).rustls(config.clone());

    // QUICリスナーを作成し、TCPリスナーと結合
    let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 5800))
        .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による暗号化が必須です。SalvoではRustlsConfigを使用してTLS証明書と秘密鍵を設定します。

リスナーの結合

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

// QUICリスナーを作成し、TCPリスナーと結合
let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 5800))
    .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から発行された証明書を使用する必要があります。