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异步

Download history 354/week @ 2024-05-17 155/week @ 2024-05-24 5/week @ 2024-05-31 2/week @ 2024-06-07 2/week @ 2024-06-14 2/week @ 2024-06-28 4/week @ 2024-07-05

每月446次下载

MIT/Apache

255KB
5K SLoC

SuppaFTP

logo

~ 一个超级FTP/FTPS客户端库,适用于Rust ~

文档 · Crates.io

veesoMatt McCoy 开发

当前版本:6.0.1 (24/05/2024)

License-Apache-2.0/MIT Repo stars Downloads counter Latest version Ko-fi conventional-commits

Lib-CI Cli-bin-ci Coveralls Docs



介绍 👋

SuppaFTP是Rust的主要FTP/FTPS客户端库,支持同步/异步编程以及所有FTP协议功能。它是原始ftp库 "rust-ftp" 的分支,但由于原始库目前未维护,我决定自己继续维护这个库。目前,我自认为是这个项目的唯一维护者,确实我已经添加了一些功能并改进了库,包括更好的错误处理和测试单元。

SuppaFTP与rust-ftp之间的主要区别 🤔

  • 根据您的要求用 native-tlsrustls 替换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-tlsrustls 功能。

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,请考虑进行一点捐赠 🥳

ko-fi PayPal


变更日志 ⌛

查看变更日志 这里


许可证 📜

许可证为以下之一

任选其一。


贡献 🤝

除非您明确说明,否则您提交给包含在作品中的任何贡献,根据 Apache-2.0 许可证的定义,应按上述方式双许可,不附加任何额外的条款或条件。

如果您想为此项目做出贡献,请首先阅读 贡献指南

依赖关系

~4–18MB
~204K SLoC