一、使用 ftp crate
由于我使用的 ftp server 使用了 TLSv1.2 的加密算法,所以必须使用 ftp crate 中的 secure features。故而我们需要为编译做一些准备工作,否则会编译失败。
1、准备工作
在 ftp crate 的 build.rs 中可以发现其依赖 openssl 的版本是 1.0.1 / 1.0.2 / 1.1.0 这三个版本中的任意一个。
match env::var("DEP_OPENSSL_VERSION") {
Ok(ref v) if v == "101" => {
println!("cargo:rustc-cfg=ossl101");
println!("cargo:rustc-cfg=ossl10x");
}
Ok(ref v) if v == "102" => {
println!("cargo:rustc-cfg=ossl102");
println!("cargo:rustc-cfg=ossl10x");
}
Ok(ref v) if v == "110" => {
println!("cargo:rustc-cfg=ossl110");
}
_ => panic!("Unable to detect OpenSSL version"),
}
所以我们需要先编译好这三个版本中的一个,我编译的是 1.1.0l :
- 从 openssl 网站的
source/old选择下载openssl-1.1.0l代码;并将压缩包解压; - 下载安装
perl,我用的是 5.32 版本;安装完执行perl -v查看版本,确定安装成功; - 下载
nasm,我用的是nasm-2.16.01-win64;将其解压,并把两个 exe 文件拷贝到代码解压目录; - 然后运行
perl configure VC-WIN64A --prefix=D:\OpenSSL\x64,这样配置最终会安装到D:\tools\OpenSSL目录下; - 再执行
nmake,等待执行编译结束; - 最后用管理员权限运行 cmd,并在代码目录下执行
nmake install;这一步就会将编译产物拷贝到D:\tools\OpenSSL目录下。 - 再添加几个环境变量:
OPENSSL_DIR=D:\tools\OpenSSL
OPENSSL_INCLUDE_DIR=D:\tools\OpenSSL\include
OPENSSL_LIB_DIR=D:\tools\OpenSSL\lib
2、代码编译
首先添加 ftp crate 依赖,需要使用 secure features:
[dependencies]
ftp = { version = "3.0.1", features = ["secure"] }
示例代码:
use ftp::FtpStream;
use ftp::openssl::ssl::{ SslContext, SslMethod };
fn main() {
let ftp_stream = FtpStream::connect("127.0.0.1:21").unwrap();
let ctx = SslContext::builder(SslMethod::tls()).unwrap().build();
let mut ftp_stream = ftp_stream.into_secure(ctx).unwrap();
ftp_stream.login("username", "password").unwrap();
println!("{}", ftp_stream.pwd().unwrap()); //列出当前目录
let _ = ftp_stream.quit();
}
编译执行:
D:\Codes\rust\study>cargo run
Compiling study v0.1.0 (D:\Codes\rust\study)
Finished dev [unoptimized + debuginfo] target(s) in 0.56s
warning: the following packages contain code that will be rejected by a future version of Rust: winapi v0.2.8
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 12`
Running `target\debug\study.exe`
/ #刚登陆在根目录
D:\Codes\rust\study>
追加 Note: ftp crate 不支持 openssl 1.1.0 以上的版本,且依赖 winapi crate 版本较低,将被丢弃。所以建议使用 suppaftp crate 而不是 ftp crate。
二、使用 suppaftp crate
这个没啥好说的,直接上代码:
[dependencies]
suppaftp = "^4.7.0"
如果使用了 SSL/TLS 加密了,则需要启用 native-tls 或者 rustls ,例如 native-tls :
[dependencies]
suppaftp = { version = "^4.7.0", features = ["native-tls"] }
代码示例:
use suppaftp::FtpStream;
use suppaftp::native_tls::TlsConnector;
fn main() {
let ftp = FtpStream::connect("127.0.0.1:21").expect("connect error");
let mut ftp = ftp.into_secure(TlsConnector::new().expect("Tls connetor new error").into(), "127.0.0.1").expect("into secure error");
ftp.login("username", "password").expect("login error");
ftp.set_mode(suppaftp::types::Mode::ExtendedPassive);
ftp.cwd("/wlb").expect("cwd error");
println!("{}", ftp.pwd().expect("pwd error"));
let list_dir = ftp.nlst(Some("/wlb")).expect("nlst error");
println!("{:#?}", list_dir);
ftp.quit().unwrap();
}
有一个需要注意的点,连接时有三种模式:
pub enum Mode {
Active,
ExtendedPassive,
Passive,
}
登录上去默认是 Passive 模式,在这个模式下无法使用 nlst() 等方法。需要将其设置为 ExtendedPassive 模式。即
ftp.set_mode(suppaftp::types::Mode::ExtendedPassive);
以上代码执行结果如下:
PS D:\Codes\rust\suppaftp> cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.06s
Running `target\debug\suppaftp.exe`
/wlb
[
"/wlb/aaaa",
"/wlb/bbbbbbbb",
"/wlb/cccccccccc",
"/wlb/2023-02-22-18-16-34_2.7z",
"/wlb/2023-02-23-10-22-45_2.7z",
]
Hello, world!
PS D:\Codes\rust\suppaftp>
其他信息可以在 docs.rs 上查看 FtpStream in suppaftp - Rust (docs.rs)
本文介绍了如何在Rust项目中使用ftpcrate库连接使用TLSv1.2加密的FTP服务器,包括编译openssl的不同版本和配置环境变量。由于ftpcrate不支持openssl1.1.0以上版本,作者推荐使用suppaftpcrate替代,并提供了启用native-tls加密的示例代码。
766

被折叠的 条评论
为什么被折叠?



