Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions actix-files/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Option to supply multiple index fallbacks now supported.
- Minimum supported Rust version (MSRV) is now 1.75.

## 0.6.6
Expand Down
16 changes: 10 additions & 6 deletions actix-files/src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use crate::{
pub struct Files {
mount_path: String,
directory: PathBuf,
index: Option<String>,
indexes: Vec<String>,
show_index: bool,
redirect_to_slash: bool,
default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
Expand All @@ -61,7 +61,7 @@ impl Clone for Files {
fn clone(&self) -> Self {
Self {
directory: self.directory.clone(),
index: self.index.clone(),
indexes: self.indexes.clone(),
show_index: self.show_index,
redirect_to_slash: self.redirect_to_slash,
default: self.default.clone(),
Expand Down Expand Up @@ -108,7 +108,7 @@ impl Files {
Files {
mount_path: mount_path.trim_end_matches('/').to_owned(),
directory: dir,
index: None,
indexes: Vec::new(),
show_index: false,
redirect_to_slash: false,
default: Rc::new(RefCell::new(None)),
Expand Down Expand Up @@ -192,15 +192,19 @@ impl Files {
self
}

/// Set index file
/// Set an index file
///
/// Shows specific index file for directories instead of
/// showing files listing.
///
/// This function can be called multiple times to configure
/// a list of index fallbacks with their priority set to the
/// order of their addition.
///
/// If the index file is not found, files listing is shown as a fallback if
/// [`Files::show_files_listing()`] is set.
pub fn index_file<T: Into<String>>(mut self, index: T) -> Self {
self.index = Some(index.into());
self.indexes.push(index.into());
self
}

Expand Down Expand Up @@ -357,7 +361,7 @@ impl ServiceFactory<ServiceRequest> for Files {
fn new_service(&self, _: ()) -> Self::Future {
let mut inner = FilesServiceInner {
directory: self.directory.clone(),
index: self.index.clone(),
indexes: self.indexes.clone(),
show_index: self.show_index,
redirect_to_slash: self.redirect_to_slash,
default: None,
Expand Down
25 changes: 14 additions & 11 deletions actix-files/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Deref for FilesService {

pub struct FilesServiceInner {
pub(crate) directory: PathBuf,
pub(crate) index: Option<String>,
pub(crate) indexes: Vec<String>,
pub(crate) show_index: bool,
pub(crate) redirect_to_slash: bool,
pub(crate) default: Option<HttpService>,
Expand Down Expand Up @@ -141,7 +141,7 @@ impl Service<ServiceRequest> for FilesService {
if path.is_dir() {
if this.redirect_to_slash
&& !req.path().ends_with('/')
&& (this.index.is_some() || this.show_index)
&& (!this.indexes.is_empty() || this.show_index)
{
let redirect_to = format!("{}/", req.path());

Expand All @@ -152,15 +152,18 @@ impl Service<ServiceRequest> for FilesService {
));
}

match this.index {
Some(ref index) => {
let named_path = path.join(index);
match NamedFile::open_async(named_path).await {
Ok(named_file) => Ok(this.serve_named_file(req, named_file)),
Err(_) if this.show_index => Ok(this.show_index(req, path)),
Err(err) => this.handle_err(err, req).await,
}
}
let index = this
.indexes
.iter()
.map(|i| path.join(i))
.find(|p| p.exists());

match index {
Some(ref named_path) => match NamedFile::open_async(named_path).await {
Ok(named_file) => Ok(this.serve_named_file(req, named_file)),
Err(_) if this.show_index => Ok(this.show_index(req, path)),
Err(err) => this.handle_err(err, req).await,
},
None if this.show_index => Ok(this.show_index(req, path)),
None => Ok(ServiceResponse::from_err(
FilesError::IsDirectory,
Expand Down
Loading