Skip to content

Commit

Permalink
refactor: add missing async
Browse files Browse the repository at this point in the history
Signed-off-by: simonsan <[email protected]>
  • Loading branch information
simonsan committed Jan 24, 2024
1 parent 5c94f80 commit 4a1e73e
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 42 deletions.
46 changes: 32 additions & 14 deletions src/handlers/file_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,33 @@ use axum::{
response::IntoResponse,
};
use axum_extra::{headers::Range, TypedHeader};
use axum_range::{KnownSize, Ranged};

use crate::{
acl::AccessType,
auth::AuthFromRequest,
error::{ErrorKind, Result},
handlers::{
access_check::check_auth_and_acl,
file_exchange::{check_name, get_file, get_save_file, save_body},
file_exchange::{check_name, get_save_file, save_body},
},
storage::STORAGE,
};

/// has_config
/// Interface: HEAD {path}/config
pub(crate) async fn has_config(
AxumPath((path, tpe)): AxumPath<(Option<String>, String)>,
AxumPath(path): AxumPath<Option<String>>,
auth: AuthFromRequest,
) -> Result<impl IntoResponse> {
let tpe = "config";
tracing::debug!("[has_config] path: {path:?}, tpe: {tpe}");
let path_str = path.unwrap_or_default();
let path = std::path::Path::new(&path_str);
check_auth_and_acl(auth.user, &tpe, path, AccessType::Read)?;
check_auth_and_acl(auth.user, tpe, path, AccessType::Read)?;

let storage = STORAGE.get().unwrap();
let file = storage.filename(path, &tpe, None);
let file = storage.filename(path, tpe, None);
if file.exists() {
Ok(())
} else {
Expand All @@ -40,24 +42,41 @@ pub(crate) async fn has_config(
/// get_config
/// Interface: GET {path}/config
pub(crate) async fn get_config(
path: AxumPath<(Option<String>, String, Option<String>)>,
AxumPath(path): AxumPath<Option<String>>,
auth: AuthFromRequest,
range: Option<TypedHeader<Range>>,
) -> Result<impl IntoResponse> {
get_file(path, auth, range).await
let tpe = "config";
tracing::debug!("[get_config] path: {path:?}, tpe: {tpe}");

check_name(tpe, None)?;
let path_str = path.unwrap_or_default();
let path = Path::new(&path_str);

check_auth_and_acl(auth.user, tpe, path, AccessType::Read)?;

let storage = STORAGE.get().unwrap();
let file = storage.open_file(path, tpe, None).await?;

let body = KnownSize::file(file)
.await
.map_err(|err| ErrorKind::GettingFileMetadataFailed(format!("{err:?}")))?;
let range = range.map(|TypedHeader(range)| range);
Ok(Ranged::new(range, body).into_response())
}

/// add_config
/// Interface: POST {path}/config
pub(crate) async fn add_config(
AxumPath((path, tpe)): AxumPath<(Option<String>, String)>,
AxumPath(path): AxumPath<Option<String>>,
auth: AuthFromRequest,
request: Request,
) -> Result<impl IntoResponse> {
let tpe = "config";
tracing::debug!("[add_config] path: {path:?}, tpe: {tpe}");
let path = path.unwrap_or_default();
let path = PathBuf::from(&path);
let file = get_save_file(auth.user, path, &tpe, None).await?;
let file = get_save_file(auth.user, path, tpe, None).await?;

let stream = request.into_body().into_data_stream();
save_body(file, stream).await?;
Expand All @@ -68,19 +87,18 @@ pub(crate) async fn add_config(
/// Interface: DELETE {path}/config
/// FIXME: The original restic spec does not define delete_config --> but rustic did ??
pub(crate) async fn delete_config(
AxumPath((path, tpe)): AxumPath<(Option<String>, String)>,
AxumPath(path): AxumPath<Option<String>>,
auth: AuthFromRequest,
) -> Result<impl IntoResponse> {
let tpe = "config";
tracing::debug!("[delete_config] path: {path:?}, tpe: {tpe}");
check_name(&tpe, None)?;
check_name(tpe, None)?;
let path_str = path.unwrap_or_default();
let path = Path::new(&path_str);
check_auth_and_acl(auth.user, &tpe, path, AccessType::Append)?;
check_auth_and_acl(auth.user, tpe, path, AccessType::Append)?;

let storage = STORAGE.get().unwrap();
if storage.remove_file(path, &tpe, None).is_err() {
return Err(ErrorKind::RemovingFileFailed(path_str));
}
storage.remove_file(path, tpe, None).await?;
Ok(())
}

Expand Down
8 changes: 4 additions & 4 deletions src/handlers/file_exchange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ use crate::{
/// Background info: https://github.com/tokio-rs/axum/blob/main/examples/stream-to-file/src/main.rs
/// Future on ranges: https://www.rfc-editor.org/rfc/rfc9110.html#name-partial-put
pub(crate) async fn add_file(
AxumPath((path, tpe, name)): AxumPath<(Option<String>, String, String)>,
AxumPath((path, tpe, name)): AxumPath<(Option<String>, String, Option<String>)>,
auth: AuthFromRequest,
request: Request,
) -> Result<impl IntoResponse> {
tracing::debug!("[get_file] path: {path:?}, tpe: {tpe}, name: {name}");
tracing::debug!("[get_file] path: {path:?}, tpe: {tpe}, name: {name:?}");
let path_str = path.unwrap_or_default();

//credential & access check executed in get_save_file()
let path = std::path::PathBuf::from(&path_str);
let file = get_save_file(auth.user, path, &tpe, Some(name)).await?;
let file = get_save_file(auth.user, path, &tpe, name).await?;

let stream = request.into_body().into_data_stream();
save_body(file, stream).await?;
Expand All @@ -62,7 +62,7 @@ pub(crate) async fn delete_file(

let storage = STORAGE.get().unwrap();

storage.remove_file(path, &tpe, Some(&name))?;
storage.remove_file(path, &tpe, Some(&name)).await?;

Ok(())
}
Expand Down
18 changes: 11 additions & 7 deletions src/handlers/path_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,23 @@ pub(crate) enum ArchivePathKind {
Snapshots,
}

pub(crate) struct ArchivePath {
pub(crate) path_type: ArchivePathKind,
pub(crate) struct PathParams {
// pub(crate) path_type: ArchivePathKind,
pub(crate) path: Option<String>,
pub(crate) tpe: String,
pub(crate) path: String,
pub(crate) name: String,
pub(crate) name: Option<String>,
}

impl Display for ArchivePath {
impl Display for PathParams {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"[ArchivePath] path_type = {:?}, path: {}, tpe: {}, name: {:?}",
self.path_type, self.path, self.tpe, self.name,
// "[ArchivePath] path_type = {:?}, path: {}, tpe: {}, name: {:?}",
"[ArchivePath] path_type = path: {:?}, tpe: {:?}, name: {:?}",
// self.path_type, self.path, self.tpe, self.name,
self.path,
self.tpe,
self.name,
)
}
}
4 changes: 2 additions & 2 deletions src/handlers/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub(crate) async fn create_repository(
match params.create {
true => {
for tpe_i in TYPES.iter() {
storage.create_dir(path, Some(tpe_i))?
storage.create_dir(path, Some(tpe_i)).await?
}

Ok((
Expand Down Expand Up @@ -67,7 +67,7 @@ pub(crate) async fn delete_repository(
check_auth_and_acl(auth.user, "", path, AccessType::Modify)?;

let storage = STORAGE.get().unwrap();
storage.remove_repository(path)?;
storage.remove_repository(path).await?;

Ok(())
}
Expand Down
34 changes: 19 additions & 15 deletions src/storage.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::{
fs,
path::{Path, PathBuf},
sync::{Arc, OnceLock},
};

use tokio::fs::File;
use tokio::fs::{create_dir_all, remove_dir_all, remove_file, File};
use walkdir::WalkDir;

use crate::{
Expand All @@ -26,7 +25,7 @@ pub(crate) fn init_storage(storage: impl Storage) -> Result<()> {
#[async_trait::async_trait]
//#[enum_dispatch(StorageEnum)]
pub trait Storage: Send + Sync + 'static {
fn create_dir(&self, path: &Path, tpe: Option<&str>) -> Result<()>;
async fn create_dir(&self, path: &Path, tpe: Option<&str>) -> Result<()>;
fn read_dir(
&self,
path: &Path,
Expand All @@ -40,8 +39,8 @@ pub trait Storage: Send + Sync + 'static {
tpe: &str,
name: Option<&str>,
) -> Result<WriteOrDeleteFile>;
fn remove_file(&self, path: &Path, tpe: &str, name: Option<&str>) -> Result<()>;
fn remove_repository(&self, path: &Path) -> Result<()>;
async fn remove_file(&self, path: &Path, tpe: &str, name: Option<&str>) -> Result<()>;
async fn remove_repository(&self, path: &Path) -> Result<()>;
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -71,11 +70,12 @@ impl LocalStorage {
}
#[async_trait::async_trait]
impl Storage for LocalStorage {
fn create_dir(&self, path: &Path, tpe: Option<&str>) -> Result<()> {
async fn create_dir(&self, path: &Path, tpe: Option<&str>) -> Result<()> {
match tpe {
Some(tpe) if tpe == "data" => {
for i in 0..256 {
fs::create_dir_all(self.path.join(path).join(tpe).join(format!("{:02x}", i)))
create_dir_all(self.path.join(path).join(tpe).join(format!("{:02x}", i)))
.await
.map_err(|err| {
ErrorKind::CreatingDirectoryFailed(format!(
"Could not create directory: {err}"
Expand All @@ -84,15 +84,18 @@ impl Storage for LocalStorage {
}
Ok(())
}
Some(tpe) => fs::create_dir_all(self.path.join(path).join(tpe)).map_err(|err| {
ErrorKind::CreatingDirectoryFailed(format!("Could not create directory: {err}"))
}),
None => fs::create_dir_all(self.path.join(path)).map_err(|err| {
Some(tpe) => create_dir_all(self.path.join(path).join(tpe))
.await
.map_err(|err| {
ErrorKind::CreatingDirectoryFailed(format!("Could not create directory: {err}"))
}),
None => create_dir_all(self.path.join(path)).await.map_err(|err| {
ErrorKind::CreatingDirectoryFailed(format!("Could not create directory: {err}"))
}),
}
}

// FIXME: Make async?
fn read_dir(
&self,
path: &Path,
Expand Down Expand Up @@ -137,18 +140,19 @@ impl Storage for LocalStorage {
WriteOrDeleteFile::new(file_path).await
}

fn remove_file(&self, path: &Path, tpe: &str, name: Option<&str>) -> Result<()> {
async fn remove_file(&self, path: &Path, tpe: &str, name: Option<&str>) -> Result<()> {
let file_path = self.filename(path, tpe, name);
fs::remove_file(file_path)
remove_file(file_path)
.await
.map_err(|err| ErrorKind::RemovingFileFailed(format!("Could not remove file: {err}")))
}

fn remove_repository(&self, path: &Path) -> Result<()> {
async fn remove_repository(&self, path: &Path) -> Result<()> {
tracing::debug!(
"Deleting repository: {}",
self.path.join(path).to_string_lossy()
);
fs::remove_dir_all(self.path.join(path)).map_err(|err| {
remove_dir_all(self.path.join(path)).await.map_err(|err| {
ErrorKind::RemovingRepositoryFailed(format!("Could not remove repository: {err}"))
})
}
Expand Down

0 comments on commit 4a1e73e

Please sign in to comment.