aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven-Hendrik Haase <svenstaro@gmail.com>2024-01-13 04:21:15 +0000
committerSven-Hendrik Haase <svenstaro@gmail.com>2024-01-13 04:21:15 +0000
commit1923d2bdc31cd34b8cd807ed1593e39188225a87 (patch)
tree3dbbbdb027cfde4cdb1d7d31846a211d07644a4c
parentRefer to Helm chart by @wrenix (fixes #1215) (diff)
downloadminiserve-1923d2bdc31cd34b8cd807ed1593e39188225a87.tar.gz
miniserve-1923d2bdc31cd34b8cd807ed1593e39188225a87.zip
Use tokio::fs instead of std::fs to enable async file operations (fixes #445)
-rw-r--r--CHANGELOG.md1
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml1
-rw-r--r--src/file_op.rs17
-rw-r--r--tests/upload_files.rs4
5 files changed, 14 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fb6d682..0e25460 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased] - ReleaseDate
- Properly handle read-only errors on Windows [#1310](https://github.com/svenstaro/miniserve/pull/1310) (thanks @ViRb3)
+- Use `tokio::fs` instead of `std::fs` to enable async file operations [#445](https://github.com/svenstaro/miniserve/issues/445)
## [0.25.0] - 2024-01-07
- Add `--pretty-urls` [#1193](https://github.com/svenstaro/miniserve/pull/1193) (thanks @nlopes)
diff --git a/Cargo.lock b/Cargo.lock
index 50466c6..8e7371a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1769,6 +1769,7 @@ dependencies = [
"strum",
"tar",
"thiserror",
+ "tokio",
"url",
"zip",
]
diff --git a/Cargo.toml b/Cargo.toml
index dae4e6c..b5e65e3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -57,6 +57,7 @@ socket2 = "0.5"
strum = { version = "0.25", features = ["derive"] }
tar = "0.4"
thiserror = "1"
+tokio = { version = "1.35.1", features = ["fs"] }
zip = { version = "0.6.5", default-features = false }
[features]
diff --git a/src/file_op.rs b/src/file_op.rs
index 6537182..760b23e 100644
--- a/src/file_op.rs
+++ b/src/file_op.rs
@@ -1,14 +1,14 @@
//! Handlers for file upload and removal
use std::io::ErrorKind;
-use std::{
- io::Write,
- path::{Component, Path, PathBuf},
-};
+use std::path::{Component, Path, PathBuf};
use actix_web::{http::header, web, HttpRequest, HttpResponse};
+use futures::TryFutureExt;
use futures::TryStreamExt;
use serde::Deserialize;
+use tokio::fs::File;
+use tokio::io::AsyncWriteExt;
use crate::{
config::MiniserveConfig, errors::ContextualError, file_utils::contains_symlink,
@@ -28,7 +28,7 @@ async fn save_file(
return Err(ContextualError::DuplicateFileError);
}
- let file = match std::fs::File::create(&file_path) {
+ let file = match File::create(&file_path).await {
Err(err) if err.kind() == ErrorKind::PermissionDenied => Err(
ContextualError::InsufficientPermissionsError(file_path.display().to_string()),
),
@@ -43,7 +43,8 @@ async fn save_file(
.map_err(|x| ContextualError::MultipartError(x.to_string()))
.try_fold((file, 0u64), |(mut file, written_len), bytes| async move {
file.write_all(bytes.as_ref())
- .map_err(|e| ContextualError::IoError("Failed to write to file".to_string(), e))?;
+ .map_err(|e| ContextualError::IoError("Failed to write to file".to_string(), e))
+ .await?;
Ok((file, written_len + bytes.len() as u64))
})
.await?;
@@ -62,7 +63,7 @@ async fn handle_multipart(
) -> Result<u64, ContextualError> {
let field_name = field.name().to_string();
- match std::fs::metadata(&path) {
+ match tokio::fs::metadata(&path).await {
Err(_) => Err(ContextualError::InsufficientPermissionsError(
path.display().to_string(),
)),
@@ -132,7 +133,7 @@ async fn handle_multipart(
}
}
- return match std::fs::create_dir_all(&absolute_path) {
+ return match tokio::fs::create_dir_all(&absolute_path).await {
Err(err) if err.kind() == ErrorKind::PermissionDenied => Err(
ContextualError::InsufficientPermissionsError(path.display().to_string()),
),
diff --git a/tests/upload_files.rs b/tests/upload_files.rs
index 8cb3e8e..77a9dc3 100644
--- a/tests/upload_files.rs
+++ b/tests/upload_files.rs
@@ -122,8 +122,8 @@ fn uploading_files_is_restricted(#[case] server: TestServer) -> Result<(), Error
#[case(server(&["-u", "./-someDir"]), vec!["./-someDir"])]
#[case(server(&["-u", Path::new("someDir/some_sub_dir").to_str().unwrap()]),
vec!["someDir/some_sub_dir"])]
-#[case(server(&["-u", Path::new("someDir/some_sub_dir").to_str().unwrap(),
- "-u", Path::new("someDir/some_other_dir").to_str().unwrap()]),
+#[case(server(&["-u", Path::new("someDir/some_sub_dir").to_str().unwrap(),
+ "-u", Path::new("someDir/some_other_dir").to_str().unwrap()]),
vec!["someDir/some_sub_dir", "someDir/some_other_dir"])]
fn uploading_files_to_allowed_dir_works(
#[case] server: TestServer,