Skip to content

Commit

Permalink
Add html_as_default_extension option to ServeDir
Browse files Browse the repository at this point in the history
This mirrors the common behaviour of file servers
  • Loading branch information
its-the-shrimp committed Sep 21, 2024
1 parent aeca262 commit 18109da
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
20 changes: 17 additions & 3 deletions tower-http/src/services/fs/serve_dir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl ServeDir<DefaultServeDirFallback> {
precompressed_variants: None,
variant: ServeVariant::Directory {
append_index_html_on_directories: true,
html_as_default_extension: true,
},
fallback: None,
call_fallback_on_method_not_allowed: false,
Expand Down Expand Up @@ -105,16 +106,27 @@ impl<F> ServeDir<F> {
/// Defaults to `true`.
pub fn append_index_html_on_directories(mut self, append: bool) -> Self {
match &mut self.variant {
ServeVariant::Directory {
append_index_html_on_directories,
} => {
ServeVariant::Directory { append_index_html_on_directories, .. } => {
*append_index_html_on_directories = append;
self
}
ServeVariant::SingleFile { mime: _ } => self,
}
}

/// If the requested path doesn't specify a file extension, append `.html`.
///
/// Defaults to `true`.
pub fn html_as_default_extension(mut self, append: bool) -> Self {
match &mut self.variant {
ServeVariant::Directory { html_as_default_extension, .. } => {
*html_as_default_extension = append;
self
}
ServeVariant::SingleFile { mime: _ } => self,
}
}

/// Set a specific read buffer chunk size.
///
/// The default capacity is 64kb.
Expand Down Expand Up @@ -443,6 +455,7 @@ opaque_future! {
enum ServeVariant {
Directory {
append_index_html_on_directories: bool,
html_as_default_extension: bool,
},
SingleFile {
mime: HeaderValue,
Expand All @@ -454,6 +467,7 @@ impl ServeVariant {
match self {
ServeVariant::Directory {
append_index_html_on_directories: _,
html_as_default_extension: _,
} => {
let path = requested_path.trim_start_matches('/');

Expand Down
18 changes: 13 additions & 5 deletions tower-http/src/services/fs/serve_dir/open_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub(super) async fn open_file(
let mime = match variant {
ServeVariant::Directory {
append_index_html_on_directories,
html_as_default_extension,
} => {
// Might already at this point know a redirect or not found result should be
// returned which corresponds to a Some(output). Otherwise the path might be
Expand All @@ -67,6 +68,7 @@ pub(super) async fn open_file(
&mut path_to_file,
req.uri(),
append_index_html_on_directories,
html_as_default_extension,
)
.await
{
Expand Down Expand Up @@ -254,18 +256,23 @@ async fn maybe_redirect_or_append_path(
path_to_file: &mut PathBuf,
uri: &Uri,
append_index_html_on_directories: bool,
html_as_default_extension: bool,
) -> Option<OpenFileOutput> {
if !is_dir(path_to_file).await {
if is_dir(path_to_file).await == Some(false) {
return None;
}

if !append_index_html_on_directories {
if !append_index_html_on_directories && !html_as_default_extension {
return Some(OpenFileOutput::FileNotFound);
}

if uri.path().ends_with('/') {
let path = uri.path();
if append_index_html_on_directories && path.ends_with('/') {
path_to_file.push("index.html");
None
} else if html_as_default_extension && path_to_file.extension().is_none() {
path_to_file.set_extension("html");
None
} else {
let location =
HeaderValue::from_str(&append_slash_on_path(uri.clone()).to_string()).unwrap();
Expand All @@ -283,10 +290,11 @@ fn try_parse_range(
})
}

async fn is_dir(path_to_file: &Path) -> bool {
async fn is_dir(path_to_file: &Path) -> Option<bool> {
tokio::fs::metadata(path_to_file)
.await
.map_or(false, |meta_data| meta_data.is_dir())
.ok()
.map(|meta_data| meta_data.is_dir())
}

fn append_slash_on_path(uri: Uri) -> Uri {
Expand Down

0 comments on commit 18109da

Please sign in to comment.