dani-garcia / rust_async_ftp Goto Github PK
View Code? Open in Web Editor NEWFork of https://crates.io/crates/ftp with tokio async support
License: Apache License 2.0
Fork of https://crates.io/crates/ftp with tokio async support
License: Apache License 2.0
Not an issue as such, but I couldn't find any contact information on your Github profile-- is this crate/repo still being maintained?
FtpStream::retr is very useful, because it allows parsing streaming data from the server and, at the same time, it automatically handles FTP response statuses.
However, there is a major issue related to the error type of the inner function: if you need to perform non-trivial parsing of the remote data, you will end up with a richer set of errors, making FtpStream::retr
unusable because FtpError
cannot encapsulate all the possible errors anymore.
I propose to change the return type from Result<T, FtpError>
to Result<T, E> where E: From<FtpError>
. If you like the idea, I will be glad to send you a PR.
I'm trying to use a loop to read data from a file, PUT
it to a FTP server and update a progress bar.
tokio::fs::File
already implements the R trait trait in put
:
pub async fn put<R: AsyncRead + Unpin>(&mut self, filename: &str, r: &mut R) -> Result<()>
So one can just write something like:
let mut file = tokio::fs::File::open(&filename).await.unwrap();
let mut ftp_stream = FtpStream::connect(server_address);
ftp_stream.put(filename, &mut file).await.unwrap();
Qs:
loop
to buffer-read from the file and async PUT it to the ftp stream?r
in the put
signature need to be mutable? I'm kind of confused, since we just read from the file. I see here, r
is just copied.The current implementation of FtpStream::list_command
uses a custom line splitting implementation, which causes unix newlines to be ignored.
Example:
use async_ftp::FtpStream;
use std::convert::TryFrom;
use tokio_rustls::rustls::{ClientConfig, RootCertStore, ServerName};
#[tokio::main]
async fn main() {
let ftp_stream = FtpStream::connect("lettir.orangewebsite.com:21")
.await
.unwrap();
let mut root_store = RootCertStore::empty();
// root_store.add_pem_file(...);
let conf = ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store)
.with_no_client_auth();
let domain = ServerName::try_from("lettir.orangewebsite.com").expect("invalid DNS name");
// Switch to the secure mode
let mut ftp_stream = ftp_stream.into_secure(conf, domain).await.unwrap();
ftp_stream.login("anonymous", "anonymous").await.unwrap();
// Do other secret stuff
// Switch back to the insecure mode (if required)
let mut ftp_stream = ftp_stream.into_insecure().await.unwrap();
// Do all public stuff
let _ = ftp_stream.quit().await;
}
gives:
error[E0308]: arguments to this function are incorrect
--> src/main.rs:20:37
|
20 | let mut ftp_stream = ftp_stream.into_secure(conf, domain).await.unwrap();
| ^^^^^^^^^^^ ---- ------ expected enum `rustls::client::client_conn::ServerName`, found enum `tokio_rustls::rustls::ServerName`
| |
| expected struct `rustls::client::client_conn::ClientConfig`, found struct `ClientConfig`
|
= note: perhaps two different versions of crate `rustls` are being used?
= note: perhaps two different versions of crate `rustls` are being used?
note: associated function defined here
--> /home/mgh/.cargo/registry/src/github.com-1ecc6299db9ec823/async_ftp-6.0.0/src/ftp.rs:87:18
|
87 | pub async fn into_secure(mut self, config: ClientConfig, domain: ServerName) -> Result<FtpStream> {
| ^^^^^^^^^^^
While FtpStream::retr()
tries to read a status after reading from the stream, it looks like FtpStream::get()
doesn't do this. When we wrote some code that calls get()
and completes successfully, then call FtpStream::quit()
, it errored out because it read an unexpected error code off the stream:
thread 'main' panicked at 'downloader encountered a critical error: FTP InvalidResponse: Expected code [221], got response: 226 Transfer complete
', downloader/src/bin/downloader.rs:78:10
Maybe it should wrap the BufReader
in another type that Deref
s to the BufReader
but tries to read out the status code on Drop
?
Line 298 in FtpStream in the get function is :
self.read_response(status::ABOUT_TO_SEND).await?;
but should be
self.read_response_in(&[status::ABOUT_TO_SEND, status::ALREADY_OPEN]).await?;
(same as in the FtpStream::retr
function)
Can this be fixed in the next release?
The documentation in the crate root explains that you need to enable the openssl
feature to enable support for FTPS, but Cargo.toml
only features a dependency on tokio-rustls.
Feature request to add a timeout function to api
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.