Skip to content

Commit 49279f1

Browse files
Fix path problem for DirStream.
Fix create() function, it would now create corresponding directories if not exist.
1 parent bdf9e75 commit 49279f1

File tree

2 files changed

+54
-45
lines changed

2 files changed

+54
-45
lines changed

src/services/ftp/backend.rs

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use log::info;
1516
use std::collections::HashMap;
1617
use std::fmt::Debug;
1718
use std::fmt::Formatter;
@@ -26,10 +27,9 @@ use anyhow::anyhow;
2627
use async_trait::async_trait;
2728
use futures::io::copy;
2829
use futures::AsyncReadExt;
29-
use log::info;
3030
use suppaftp::async_native_tls::TlsConnector;
3131
use suppaftp::list::File;
32-
use suppaftp::types::FileType;
32+
use suppaftp::types::{FileType, Response};
3333
use suppaftp::FtpError;
3434
use suppaftp::FtpStream;
3535
use suppaftp::Status;
@@ -237,47 +237,52 @@ impl Accessor for Backend {
237237
}
238238

239239
async fn create(&self, args: &OpCreate) -> Result<()> {
240-
let path = args.path();
241-
242240
let mut ftp_stream = self.ftp_connect(Operation::Create).await?;
243241

244-
if args.mode() == ObjectMode::FILE {
245-
ftp_stream
246-
.put_file(&path, &mut "".as_bytes())
247-
.await
248-
.map_err(|e| {
249-
other(ObjectError::new(
250-
Operation::Create,
251-
path,
252-
anyhow!("put request: {e:?}"),
253-
))
254-
})?;
255-
256-
ftp_stream
257-
.quit()
258-
.await
259-
.map_err(|e| new_request_quit_err(e, Operation::Create, path))?;
260-
261-
return Ok(());
242+
let paths: Vec<&str> = args.path().split_inclusive('/').collect();
243+
244+
let mut curr_path = String::new();
245+
246+
for path in paths {
247+
curr_path.push_str(path);
248+
// try to create directory
249+
if curr_path.ends_with('/') {
250+
match ftp_stream.mkdir(&curr_path).await {
251+
// Do nothing if status is FileUnavailable or OK(()) is return.
252+
Err(FtpError::UnexpectedResponse(Response {
253+
status: Status::FileUnavailable,
254+
..
255+
}))
256+
| Ok(()) => (),
257+
Err(e) => {
258+
return Err(other(ObjectError::new(
259+
Operation::Create,
260+
args.path(),
261+
anyhow!("mkdir request: {e:?}"),
262+
)));
263+
}
264+
}
265+
} else {
266+
// else, create file
267+
ftp_stream
268+
.put_file(&curr_path, &mut "".as_bytes())
269+
.await
270+
.map_err(|e| {
271+
other(ObjectError::new(
272+
Operation::Create,
273+
path,
274+
anyhow!("put request: {e:?}"),
275+
))
276+
})?;
277+
}
262278
}
263279

264-
if args.mode() == ObjectMode::DIR {
265-
ftp_stream.mkdir(&path).await.map_err(|e| {
266-
other(ObjectError::new(
267-
Operation::Create,
268-
path,
269-
anyhow!("mkdir request: {e:?}"),
270-
))
271-
})?;
272-
273-
ftp_stream
274-
.quit()
275-
.await
276-
.map_err(|e| new_request_quit_err(e, Operation::Create, path))?;
277-
return Ok(());
278-
}
280+
ftp_stream
281+
.quit()
282+
.await
283+
.map_err(|e| new_request_quit_err(e, Operation::Create, args.path()))?;
279284

280-
unreachable!()
285+
return Ok(());
281286
}
282287

283288
async fn read(&self, args: &OpRead) -> Result<BytesReader> {
@@ -319,6 +324,8 @@ impl Accessor for Backend {
319324
}
320325

321326
async fn write(&self, args: &OpWrite, r: BytesReader) -> Result<u64> {
327+
// TODO: create before write
328+
322329
let path = args.path();
323330

324331
let mut ftp_stream = self.ftp_connect(Operation::Write).await?;

src/services/ftp/dir_stream.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,18 @@ impl futures::Stream for DirStream {
9090
Poll::Ready(Some(Err(parse_io_error(e, Operation::List, &self.path))))
9191
}
9292
Some(Ok(de)) => {
93+
let path = self.path.to_string() + de.name();
94+
9395
let d = if de.is_file() {
94-
DirEntry::new(self.backend.clone(), ObjectMode::FILE, de.name())
96+
DirEntry::new(self.backend.clone(), ObjectMode::FILE, &path)
9597
} else if de.is_directory() {
96-
let mut dir_path = de.name().to_string();
97-
if !dir_path.ends_with('/') {
98-
dir_path.push('/');
99-
}
100-
DirEntry::new(self.backend.clone(), ObjectMode::DIR, dir_path.as_str())
98+
DirEntry::new(
99+
self.backend.clone(),
100+
ObjectMode::DIR,
101+
&format!("{}/", &path),
102+
)
101103
} else {
102-
DirEntry::new(self.backend.clone(), ObjectMode::Unknown, de.name())
104+
DirEntry::new(self.backend.clone(), ObjectMode::Unknown, &path)
103105
};
104106

105107
debug!(

0 commit comments

Comments
 (0)