7个稳定版本
6.0.1 | 2024年5月24日 |
---|---|
6.0.0 | 2024年5月20日 |
5.4.0 | 2024年5月18日 |
5.2.0 | 2023年9月7日 |
4.5.0 | 2022年10月8日 |
462 在 异步
每月446次下载
255KB
5K SLoC
SuppaFTP
~ 一个超级FTP/FTPS客户端库,适用于Rust ~
由veeso 和 Matt McCoy 开发
当前版本:6.0.1 (24/05/2024)
介绍 👋
SuppaFTP是Rust的主要FTP/FTPS客户端库,支持同步/异步编程以及所有FTP协议功能。它是原始ftp库 "rust-ftp" 的分支,但由于原始库目前未维护,我决定自己继续维护这个库。目前,我自认为是这个项目的唯一维护者,确实我已经添加了一些功能并改进了库,包括更好的错误处理和测试单元。
SuppaFTP与rust-ftp之间的主要区别 🤔
- 根据您的要求用 native-tls 或 rustls 替换OpenSSL 🔒
- 添加了与流一起工作的方法(例如
put_with_stream
) ⬇️ - suppaftp支持 主动模式
- 添加了
get_welcome_msg
方法 👋 - 支持同步/异步Rust 🕙
- 支持更多命令 🌟
- ABOR
- APPE
- REST
- EPSV
- EPRT
- 一些额外功能,例如 LIST 命令输出解析器
- RFC 2428 的实现
- RFC 2389 的实现
- 移除了过时的语句 ⚰️
- 更好的错误处理 🐛
- 添加了测试单元,以监控代码覆盖率 👀
入门 🏁
要开始使用,首先将 suppaftp 添加到您的依赖项中
suppaftp = "^6"
功能
SSL/TLS支持
如果您想启用 FTPS 支持,您必须根据您偏好的 TLS 提供者,在 cargo 依赖项中启用 native-tls
或 rustls
功能。
suppaftp = { version = "^6", features = ["native-tls"] }
# or
suppaftp = { version = "^6", features = ["rustls"] }
💡 如果您不知道选择什么,出于兼容性原因,应该首选
native-tls
。❗ 如果您想静态链接 libssl,请启用功能native-tls-vendored
异步支持
如果您想启用 异步 支持,您必须在 cargo 依赖项中启用 async
功能。
suppaftp = { version = "^6", features = ["async"] }
⚠️ 如果您想同时启用 native-tls 和 异步,您必须使用 async-native-tls 功能 ⚠️ ⚠️ 如果您想同时启用 rustls 和 异步,您必须使用 async-rustls 功能 ⚠️ ❗ 如果您想静态链接 libssl,请启用功能
async-native-tls-vendored
已弃用方法
如果您想启用 FTPS 的过时方法,请启用 cargo 依赖项中的 deprecated
功能。
此功能启用以下方法
connect_secure_implicit()
:用于通过隐式 FTPS 连接
日志记录
默认情况下,如果用户实现中有任何 log
crate 消费者,库将记录日志。如果需要,可以通过 no-log
功能禁用日志记录。
示例 📚
use std::str;
use std::io::Cursor;
use suppaftp::FtpStream;
fn main() {
// Create a connection to an FTP server and authenticate to it.
let mut ftp_stream = FtpStream::connect("127.0.0.1:21").unwrap();
let _ = ftp_stream.login("username", "password").unwrap();
// Get the current directory that the client will be reading from and writing to.
println!("Current directory: {}", ftp_stream.pwd().unwrap());
// Change into a new directory, relative to the one we are currently in.
let _ = ftp_stream.cwd("test_data").unwrap();
// Retrieve (GET) a file from the FTP server in the current working directory.
let data = ftp_stream.retr_as_buffer("ftpext-charter.txt").unwrap();
println!("Read file with contents\n{}\n", str::from_utf8(&data.into_inner()).unwrap());
// Store (PUT) a file from the client to the current working directory of the server.
let mut reader = Cursor::new("Hello from the Rust \"ftp\" crate!".as_bytes());
let _ = ftp_stream.put_file("greeting.txt", &mut reader);
println!("Successfully wrote greeting.txt");
// Terminate the connection to the server.
let _ = ftp_stream.quit();
}
使用TLS的FTP (native-tls)
use suppaftp::{NativeTlsFtpStream, NativeTlsConnector};
use suppaftp::native_tls::{TlsConnector, TlsStream};
fn main() {
let ftp_stream = NativeTlsFtpStream::connect("test.rebex.net:21").unwrap();
// Switch to the secure mode
let mut ftp_stream = ftp_stream.into_secure(NativeTlsConnector::from(TlsConnector::new().unwrap()), "test.rebex.net").unwrap();
ftp_stream.login("demo", "password").unwrap();
// Do other secret stuff
assert!(ftp_stream.quit().is_ok());
}
使用TLS的FTP (rustls)
use std::str;
use std::io::Cursor;
use std::sync::Arc;
use suppaftp::{RustlsFtpStream, RustlsConnector};
use suppaftp::rustls::ClientConfig;
fn main() {
let mut root_store = rustls::RootCertStore::empty();
root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
}));
let config = ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store)
.with_no_client_auth();
// Create a connection to an FTP server and authenticate to it.
let config = Arc::new(rustls_config());
let mut ftp_stream = RustlsFtpStream::connect("test.rebex.net:21")
.unwrap()
.into_secure(RustlsConnector::from(Arc::clone(&config)), "test.rebex.net")
.unwrap();
// Terminate the connection to the server.
let _ = ftp_stream.quit();
}
异步编程
use suppaftp::{AsyncNativeTlsFtpStream, AsyncNativeTlsConnector};
use suppaftp::async_native_tls::{TlsConnector, TlsStream};
let ftp_stream = AsyncNativeTlsFtpStream::connect("test.rebex.net:21").await.unwrap();
// Switch to the secure mode
let mut ftp_stream = ftp_stream.into_secure(AsyncNativeTlsConnector::from(TlsConnector::new()), "test.rebex.net").await.unwrap();
ftp_stream.login("demo", "password").await.unwrap();
// Do other secret stuff
assert!(ftp_stream.quit().await.is_ok());
内置CLI客户端 🖥️
SuppaFTP 还附带了一个内置的命令行 FTP 客户端。此 CLI 应用程序提供了与远程 FTP 服务器交互的所有命令,并支持 FTPS。您还可以将其用作实现您项目的参考。您可以在 cli/
目录中找到它。
您可以通过 Cargo 简单地安装它,就像安装任何其他 Rust 应用程序一样
cargo install suppaftp-cli
suppaftp --version
支持开发者 ☕
如果您喜欢 SuppaFTP,请考虑进行一点捐赠 🥳
变更日志 ⌛
查看变更日志 这里
许可证 📜
许可证为以下之一
- Apache License, Version 2.0, (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献 🤝
除非您明确说明,否则您提交给包含在作品中的任何贡献,根据 Apache-2.0 许可证的定义,应按上述方式双许可,不附加任何额外的条款或条件。
如果您想为此项目做出贡献,请首先阅读 贡献指南。
依赖关系
~4–18MB
~204K SLoC