Envío de Archivos

Salvo puede enviar archivos de varias maneras:

NamedFile

Salvo proporciona salvo::fs::NamedFile, que se puede utilizar para enviar archivos a los clientes de manera eficiente. No carga el archivo completo en memoria; en su lugar, lee y envía solo las partes solicitadas por el cliente según la cabecera Range.

En la práctica, usar Response::send_file es una forma simplificada de utilizar NamedFile. Si necesitas más control sobre la entrega de archivos, puedes usar NamedFileBuilder.

Puedes crear un NamedFileBuilder mediante NamedFile::builder:

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

Después de configurar el builder, puedes enviar el archivo:

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

Servir Archivos Estáticos

Middleware para servir archivos estáticos o archivos incrustados.

  • StaticDir proporciona soporte para servir archivos estáticos desde directorios locales. Puedes pasar una lista de múltiples directorios como argumentos. Por ejemplo:
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;
}

Si un archivo no se encuentra en el primer directorio, se buscará en el segundo directorio.

  • Proporciona soporte para rust-embed. Por ejemplo:
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;
}

El método with_fallback te permite especificar un archivo de respaldo para servir cuando no se encuentra el archivo solicitado. Esto es especialmente útil para aplicaciones de una sola página (SPA).