Envio de Arquivos

O Salvo pode enviar arquivos de várias maneiras:

NamedFile

O Salvo fornece salvo::fs::NamedFile, que pode ser usado para enviar arquivos de forma eficiente aos clientes. Ele não carrega o arquivo inteiro na memória; em vez disso, lê e envia apenas as partes solicitadas pelo cliente com base no cabeçalho Range.

Na prática, usar Response::send_file é uma forma simplificada de utilizar NamedFile. Se você precisar de mais controle sobre o envio do arquivo, pode usar NamedFileBuilder.

Você pode criar um NamedFileBuilder através de NamedFile::builder:

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

Após configurar o builder, você pode enviar o arquivo:

#[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 Arquivos Estáticos

Middleware para servir arquivos estáticos ou arquivos embutidos.

  • StaticDir fornece suporte para servir arquivos estáticos a partir de diretórios locais. Você pode passar uma lista de vários diretórios como argumentos. Por exemplo:
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 um arquivo não for encontrado no primeiro diretório, ele será procurado no segundo diretório.

  • Fornece suporte para rust-embed. Por exemplo:
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;
}

O método with_fallback permite especificar um arquivo de fallback para servir quando o arquivo solicitado não for encontrado. Isso é particularmente útil para aplicações de página única (SPAs).