Invio di File

Salvo può inviare file in diversi modi:

NamedFile

Salvo fornisce salvo::fs::NamedFile, che può essere utilizzato per inviare file ai client in modo efficiente. Non carica l'intero file in memoria; invece, legge e invia solo le porzioni richieste dal client in base all'intestazione Range.

Nella pratica, utilizzare Response::send_file è un modo semplificato per sfruttare NamedFile. Se hai bisogno di un maggiore controllo sulla consegna dei file, puoi utilizzare NamedFileBuilder.

Puoi creare un NamedFileBuilder tramite NamedFile::builder:

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

Dopo aver configurato il builder, puoi inviare il file:

#[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;
}

Servire File Statici

Middleware per servire file statici o file incorporati.

  • StaticDir fornisce supporto per servire file statici da directory locali. Puoi passare una lista di più directory come argomenti. Ad esempio:
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;
}

Se un file non viene trovato nella prima directory, verrà cercato nella seconda directory.

  • Fornisce supporto per rust-embed. Ad esempio:
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;
}

Il metodo with_fallback ti consente di specificare un file di fallback da servire quando il file richiesto non viene trovato. Questo è particolarmente utile per applicazioni a pagina singola (SPA).