發送檔案

Salvo 可透過以下幾種方式發送檔案:

NamedFile

Salvo 提供了 salvo::fs::NamedFile,可用於高效地將檔案發送至客戶端。它不會將整個檔案載入快取,而是根據請求中的 Range 標頭載入部分內容傳送給客戶端。

實際上,透過 Response::send_file 只是使用 NamedFile 的一種簡化方式。若需對發送的檔案進行更精細的控制,可使用 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;
}

若在首個資料夾中找不到對應檔案,會自動嘗試第二個資料夾。

  • 提供對 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 可設定當檔案不存在時,以指定檔案替代。這對於某些單頁網站應用相當實用。