ファイル送信

Salvo では以下の方法でファイルを送信できます:

NamedFile

Salvo は salvo::fs::NamedFile を提供しており、これを使用してクライアントに効率的にファイルを送信できます。ファイル全体をキャッシュに読み込むのではなく、リクエストの Range に基づいて部分的な内容を読み込み、クライアントに送信します。

実際には、Response::send_fileNamedFile の簡易的な使用法です。ファイル送信をより細かく制御する必要がある場合は、NamedFileBuilder を使用できます。

NamedFile::builder を使用して NamedFileBuilder を作成できます:

#[handler]
async fn send_file(req: &mut Request, res: &mut Response) {
    let builder = NamedFile::builder("/file/to/path");
}

設定を行った後、ファイルを送信できます:

#[handler]
async fn send_file(req: &mut Request, res: &mut Response) {
    NamedFile::builder("/file/to/path").attached_name("image.png").send(req.headers(), res).await;
}

静的ファイル提供

静的ファイルや埋め込みファイルをサービスとして提供するミドルウェアです。

  • StaticDir はローカルの静的フォルダをサポートします。複数のフォルダのリストを引数として渡すことができます。例:
main.rs
Cargo.toml
use salvo::prelude::*;
use salvo::serve_static::StaticDir;

#[tokio::main]
async fn main() {
    tracing_subscriber::fmt().init();

    let router = Router::with_path("{*path}").get(
        StaticDir::new([
            "static-dir-list/static/boy",
            "static-dir-list/static/girl",
            "static/boy",
            "static/girl",
        ])
        .include_dot_files(false)
        .defaults("index.html")
        .auto_list(true),
    );

    let acceptor = TcpListener::new("0.0.0.0:8698").bind().await;
    Server::new(acceptor).serve(router).await;
}

最初のフォルダに対応するファイルが見つからない場合、2番目のフォルダで検索します。

  • rust-embed のサポートを提供します。例:
main.rs
Cargo.toml
use rust_embed::RustEmbed;
use salvo::prelude::*;
use salvo::serve_static::static_embed;

#[derive(RustEmbed)]
#[folder = "static"]
struct Assets;

#[tokio::main]
async fn main() {
    tracing_subscriber::fmt().init();

    let router = Router::with_path("{*path}").get(static_embed::<Assets>().fallback("index.html"));

    let acceptor = TcpListener::new("0.0.0.0:8698").bind().await;
    Server::new(acceptor).serve(router).await;
}

with_fallback を使用すると、ファイルが見つからない場合に指定したファイルで代替できます。これは一部のシングルページアプリケーション(SPA)で有用です。