veeso / suppaftp

a super FTP/FTPS client library for Rust with support for both passive and active mode
Apache License 2.0
121 stars 31 forks source link

[BUG] - Async TLS example fails to compile #48

Closed my4ng closed 1 year ago

my4ng commented 1 year ago

Description

The async example in README fails to compile, specifically the line:

let mut ftp_stream = ftp_stream.into_secure(AsyncNativeTlsConnector::from(TlsConnector::new()), "test.rebex.net").await.unwrap();

Error message:

error[E0271]: type mismatch resolving `<AsyncNativeTlsConnector as AsyncTlsConnector>::Stream == AsyncNoTlsStream`
   --> test/src/main.rs:8:49
    |
8   | ...am.into_secure(AsyncNativeTlsConnector::from(TlsConnector::new()), "...
    |       ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `AsyncNoTlsStream`, found `AsyncNativeTlsStream`
    |       |
    |       required by a bound introduced by this call
    |
note: required by a bound in `ImplAsyncFtpStream::<T>::into_secure`
   --> /home/michaelyang/.cargo/registry/src/index.crates.io-6f17d22bba15001f/suppaftp-5.1.2/src/async_ftp/mod.rs:122:47
    |
122 | ... AsyncTlsConnector<Stream = T> + 'static,
    |                       ^^^^^^^^^^ required by this bound in `ImplAsyncFtpStream::<T>::into_secure`

Investigation

I did some digging around in the source file, and it appears that the problem stems from the fact that ImplAsyncFtpStream::into_secure requires the bound on T for the parameter tls_connector:

tls_connector: impl AsyncTlsConnector<Stream = T> + 'static

which suggests that the stream before and after switching to secure mode must be the same, and hence why AsyncFtpStream with T = AsyncNoTlsStream failed to be promoted to a secure ftp stream with T = AsyncNativeTlsStream.

On the other hand, the into_secure documentation provides the correct example:

let mut ctx = TlsConnector::new();
let mut ftp_stream = ImplAsyncFtpStream::connect("127.0.0.1:21").await.unwrap();
let mut ftp_stream = ftp_stream.into_secure(ctx, "localhost").await.unwrap();

Where the original ftp_stream has an indeterminate generic type T that is subsequently inferred in the following line.

Hence, which of the two (either promotion from insecure stream or direct construction from ImplAsyncFtpStream) examples is the desired behaviour?

Environment

veeso commented 1 year ago

That code compiles in unit tests, so it must be correct. Probably your stream is not of the type AsyncNativeTlsFtpStream, but probably is a AsyncFtpStream.