静态文件

static-files.md
commit - 529bebcd66999fdd46e759712394c32e3bc0ed3a - 2020.02.11

单个文件

可以使用自定义路径模式和 NamedFile 提供服务所需静态文件,为了匹配路径尾部,我们可以使用正则表达式 [.*]

use actix_files::NamedFile;
use actix_web::{HttpRequest, Result};
use std::path::PathBuf;

async fn index(req: HttpRequest) -> Result<NamedFile> {
    let path: PathBuf = req.match_info().query("filename").parse().unwrap();
    Ok(NamedFile::open(path)?)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{web, App, HttpServer};

    HttpServer::new(|| App::new().route("/{filename:.*}", web::get().to(index)))
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

目录

为了提供来自特定目录和其子目录的文件,可以使用 FilesFiles 必须通过 App::service() 方法注册,否则它将无法为子路径提供服务。

use actix_files as fs;
use actix_web::{App, HttpServer};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new().service(fs::Files::new("/static", ".").show_files_listing())
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

默认情况下,子目录的文件列表被禁用。尝试加载目录列表将返回响应 404 Not Found。要启用文件列表,请使用 Files::show_files_listing() 方法。

可以重定向到特定的索引文件,而不是显示目录的文件列表。重定向可使用 Files::index_file() 方法配置。

配置

NamedFiles 可以指定服务文件的各种选项:

  • set_content_disposition - 此函数用于将文件的 mime 值映射到相应的 Content-Disposition 类型。
  • use_etag - 指定是否应计算 ETag 并将其包含在消息标头中。
  • use_last_modified - 指定是否应使用文件修改的时间戳,并将其添加到消息标头 Last-Modified

以上所有设定方法都是可选的,并提供了最佳的默认值,但是你可以自定义其中任何一个。

use actix_files as fs;
use actix_web::http::header::{ContentDisposition, DispositionType};
use actix_web::{get, App, Error, HttpRequest, HttpServer};

#[get("/{filename:.*}")]
async fn index(req: HttpRequest) -> Result<fs::NamedFile, Error> {
    let path: std::path::PathBuf = req.match_info().query("filename").parse().unwrap();
    let file = fs::NamedFile::open(path)?;
    Ok(file
        .use_last_modified(true)
        .set_content_disposition(ContentDisposition {
            disposition: DispositionType::Attachment,
            parameters: vec![],
        }))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().service(index))
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

该配置也可以应用于目录服务:

use actix_files as fs;
use actix_web::{App, HttpServer};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new().service(
            fs::Files::new("/static", ".")
                .show_files_listing()
                .use_last_modified(true),
        )
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}