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:
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;
}
[package]
name = "example-static-dir-list"
version.workspace = true
edition.workspace = true
publish.workspace = true
rust-version.workspace = true
[dependencies]
salvo = { workspace = true, features = ["serve-static"] }
tokio = { workspace = true, features = ["macros"] }
tracing.workspace = true
tracing-subscriber.workspace = true
Si un archivo no se encuentra en el primer directorio, se buscará en el segundo directorio.
- Proporciona soporte para
rust-embed. Por ejemplo:
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;
}
[package]
name = "example-static-embed-files"
version.workspace = true
edition.workspace = true
publish.workspace = true
rust-version.workspace = true
[dependencies]
rust-embed.workspace = true
salvo = { workspace = true, features = ["serve-static"] }
tokio = { workspace = true, features = ["macros"] }
tracing.workspace = true
tracing-subscriber.workspace = true
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).