Send File
Salvo can send files in a number of ways:
NamedFile
Salvo provides salvo::::NamedFile
, which can be used to efficiently send files to the client. It does not load all files into the cache, but loads part of the content according to the requested Range
sent to the client.
Actually, passing Response::send_file
is just a simplified way of using NamedFile
, if you need more control over the sent file, you can use NamedFileBuilder
.
A NamedFileBuilder
can be created via NamedFile::builder
:
#[handler]
async fn send_file(req: &mut Request, res: &mut Response) {
let builder = NamedFile::builder("/file/to/path");
}
You can do some settings, and then send the 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;
}
Serve Static
Middleware that serves static files or embedded files as a service.
StaticDir
provides support for static local folders. It can take a list of multiple folders as an argument. For example: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([ "examples/static-dir-list/static/boy", "examples/static-dir-list/static/girl", ]) .defaults("index.html") .auto_list(true), ); let acceptor = TcpListener::new("127.0.0.1:5800").bind().await; Server::new(acceptor).serve(router).await; }
[package] name = "example-static-dir-list" version = "0.1.0" edition = "2021" publish = false [dependencies] salvo = { workspace = true, features = ["serve-static"] } tokio = { version = "1", features = ["macros"] } tracing = "0.1" tracing-subscriber = "0.3"
If the corresponding file is not found in the first folder, it will be found in the second folder.
Provided support for
rust-embed
, such as: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("127.0.0.1:5800").bind().await; Server::new(acceptor).serve(router).await; }
[package] name = "example-static-embed-files" version = "0.1.0" edition = "2021" publish = false [dependencies] rust-embed = { workspace = true } salvo = { workspace = true, features = ["serve-static"] } tokio = { version = "1", features = ["macros"] } tracing = "0.1" tracing-subscriber = "0.3"
with_fallback
can be set to use the file set here instead when the file cannot be found. This is still useful for some single-page website applications.