{"id":21659530,"url":"https://github.com/veeso/suppaftp","last_synced_at":"2026-01-07T19:17:43.662Z","repository":{"id":38616514,"uuid":"398528294","full_name":"veeso/suppaftp","owner":"veeso","description":"a super FTP/FTPS client library for Rust with support for both passive and active mode","archived":false,"fork":false,"pushed_at":"2024-05-22T15:11:58.000Z","size":1149,"stargazers_count":101,"open_issues_count":6,"forks_count":26,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-05-22T16:33:05.969Z","etag":null,"topics":["async","async-ftp","asynchronous","ftp","ftp-client","ftps","rust","rust-crate","rust-ftp","rust-lang","rust-library"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/veeso.png","metadata":{"funding":{"ko_fi":"veeso"},"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE-APACHE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-21T10:24:04.000Z","updated_at":"2024-05-22T16:33:16.886Z","dependencies_parsed_at":"2024-01-28T16:26:33.197Z","dependency_job_id":"972734bc-1585-4b6b-bec5-db1297b2f1dd","html_url":"https://github.com/veeso/suppaftp","commit_stats":{"total_commits":226,"total_committers":24,"mean_commits":9.416666666666666,"dds":0.5132743362831859,"last_synced_commit":"b864fc1249990f44bd8c8fdbc953a24d96bf5e3e"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veeso%2Fsuppaftp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veeso%2Fsuppaftp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veeso%2Fsuppaftp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veeso%2Fsuppaftp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/veeso","download_url":"https://codeload.github.com/veeso/suppaftp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247182042,"owners_count":20897379,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","async-ftp","asynchronous","ftp","ftp-client","ftps","rust","rust-crate","rust-ftp","rust-lang","rust-library"],"created_at":"2024-11-25T09:31:10.883Z","updated_at":"2026-01-07T19:17:43.656Z","avatar_url":"https://github.com/veeso.png","language":"Rust","funding_links":["https://ko-fi.com/veeso","https://www.paypal.me/chrisintin"],"categories":["Rust"],"sub_categories":[],"readme":"# SuppaFTP\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"/assets/images/suppaftp.svg\" alt=\"logo\" width=\"256\" height=\"256\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e~ A super FTP/FTPS client library for Rust ~\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://docs.rs/suppaftp\" target=\"_blank\"\u003eDocumentation\u003c/a\u003e\n  ·\n  \u003ca href=\"https://crates.io/crates/suppaftp\" target=\"_blank\"\u003eCrates.io\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eDeveloped by \u003ca href=\"https://veeso.me/\"\u003eveeso\u003c/a\u003e\u003c/p\u003e\n\u003cp align=\"center\"\u003eCurrent version: 7.0.7 (05/11/2025)\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\n    \u003e\u003cimg\n      src=\"https://img.shields.io/crates/l/suppaftp.svg\"\n      alt=\"License-Apache-2.0/MIT\"\n  /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/veeso/suppaftp/stargazers\"\n    \u003e\u003cimg\n      src=\"https://img.shields.io/github/stars/veeso/suppaftp?style=flat\"\n      alt=\"Repo stars\"\n  /\u003e\u003c/a\u003e\n  \u003ca href=\"https://crates.io/crates/suppaftp\"\n    \u003e\u003cimg\n      src=\"https://img.shields.io/crates/d/suppaftp.svg\"\n      alt=\"Downloads counter\"\n  /\u003e\u003c/a\u003e\n  \u003ca href=\"https://crates.io/crates/suppaftp\"\n    \u003e\u003cimg\n      src=\"https://img.shields.io/crates/v/suppaftp.svg\"\n      alt=\"Latest version\"\n  /\u003e\u003c/a\u003e\n  \u003ca href=\"https://ko-fi.com/veeso\"\u003e\n    \u003cimg\n      src=\"https://img.shields.io/badge/donate-ko--fi-red\"\n      alt=\"Ko-fi\"\n  /\u003e\u003c/a\u003e\n  \u003ca href=\"https://conventionalcommits.org\"\u003e\n    \u003cimg\n      src=\"https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits\u0026logoColor=white\"\n      alt=\"conventional-commits\"\n  /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/veeso/suppaftp/actions\"\n    \u003e\u003cimg\n      src=\"https://github.com/veeso/suppaftp/actions/workflows/test.yml/badge.svg\"\n      alt=\"Lib-CI\"\n  /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/veeso/suppaftp/actions\"\n    \u003e\u003cimg\n      src=\"https://github.com/veeso/suppaftp/workflows/cli-bin/badge.svg\"\n      alt=\"Cli-bin-ci\"\n  /\u003e\u003c/a\u003e\n  \u003ca href=\"https://coveralls.io/github/veeso/suppaftp\"\n    \u003e\u003cimg\n      src=\"https://coveralls.io/repos/github/veeso/suppaftp/badge.svg\"\n      alt=\"Coveralls\"\n  /\u003e\u003c/a\u003e\n  \u003ca href=\"https://docs.rs/suppaftp\"\n    \u003e\u003cimg\n      src=\"https://docs.rs/suppaftp/badge.svg\"\n      alt=\"Docs\"\n  /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n- [SuppaFTP](#suppaftp)\n  - [Introduction 👋](#introduction-)\n    - [Main differences between SuppaFTP and rust-ftp 🤔](#main-differences-between-suppaftp-and-rust-ftp-)\n  - [Get started 🏁](#get-started-)\n    - [Features](#features)\n      - [SSL/TLS Support](#ssltls-support)\n      - [Async support](#async-support)\n      - [Deprecated methods](#deprecated-methods)\n      - [Logging](#logging)\n    - [Examples 📚](#examples-)\n      - [Ftp with TLS (native-tls)](#ftp-with-tls-native-tls)\n      - [Ftp with TLS (rustls)](#ftp-with-tls-rustls)\n      - [Going Async](#going-async)\n  - [Built-in CLI client 🖥️](#built-in-cli-client-️)\n  - [Support the developer ☕](#support-the-developer-)\n  - [Changelog ⌛](#changelog-)\n  - [License 📜](#license-)\n    - [Contribution 🤝](#contribution-)\n\n---\n\n## Introduction 👋\n\nSuppaFTP is the main FTP/FTPS client library for Rust, with both support for sync/async programming and for all the FTP protocol features. It is a fork of the original ftp library \"[rust-ftp](https://github.com/mattnenterprise/rust-ftp)\", but since the original library is currently unmaintained, I decided to keep working on this library by myself. Currently, I consider myself as the only maintainer of this project, indeed I've already added some features to the library and improved it with better error handling and test units.\n\n### Main differences between SuppaFTP and rust-ftp 🤔\n\n- Replaced OpenSSL with **native-tls** or **rustls** as you prefer 🔒\n- Added methods to work with streams (e.g. `put_with_stream`) ⬇️\n- suppaftp supports **Active mode**\n- Added `get_welcome_msg` method 👋\n- Supports for both **sync/async** rust 🕙\n- Supports for more commands 🌟\n  - ABOR\n  - APPE\n  - REST\n  - EPSV\n  - EPRT\n- Some extra features, such as the **LIST** command output parser\n- Implementation of [RFC 2428](https://www.rfc-editor.org/rfc/rfc2428.html)\n- Implementationb of [RFC 2389](https://www.rfc-editor.org/rfc/rfc2389)\n- Removed deprecated statements ⚰️\n- Better error handling 🐛\n- Added test units keeping an eye on code coverage 👀\n\n---\n\n## Get started 🏁\n\nTo get started, first add **suppaftp** to your dependencies:\n\n```toml\nsuppaftp = \"^7\"\n```\n\n### Features\n\nThese are all the possible features, by family\n\n- **sync FTP**:\n  - `native-tls`: enable FTPS support using [native-tls](https://crates.io/crates/native-tls) as backend for TLS\n  - `native-tls-vendored`: enable vendored FTPS support using [native-tls](https://crates.io/crates/native-tls)\n  - `rustls`: enable FTPS support using [rustls](https://crates.io/crates/rustls) as backend for TLS\n- **Async FTP**:\n  - **Async-std**:\n    - `async-std`: enable async client using [async-std](https://crates.io/crates/async-std) as async backend\n    - `async-std-async-native-tls`: enable FTPS support using [async-native-tls](https://crates.io/crates/async-native-tls)\n    - `async-std-async-native-tls-vendored`: enable vendored FTPS support using [async-native-tls](https://crates.io/crates/async-native-tls)\n    - `async-std-async-rustls`: enable FTPS support using [async-rustls](https://crates.io/crates/async-rustls)\n  - **Tokio**:\n    - `tokio`: enable async client using [tokio](https://crates.io/crates/tokio) as async backend\n    - `tokio-async-native-tls`: enable FTPS support using [async-native-tls](https://crates.io/crates/async-native-tls)\n    - `tokio-async-native-tls-vendored`: enable vendored FTPS support using [async-native-tls](https://crates.io/crates/async-native-tls)\n    - `tokio-async-rustls`: enable FTPS support using [async-rustls](https://crates.io/crates/async-rustls)\n- **Misc**:\n  - `deprecated`: enable deprecated FTP/FTPS methods\n  - `no-log`: disable logging\n\nIn more details:\n\n#### SSL/TLS Support\n\nIf you want to enable **support for FTPS**, you must enable the `native-tls` or `rustls` feature in your cargo dependencies, based on the TLS provider you prefer.\n\n```toml\nsuppaftp = { version = \"^7\", features = [\"native-tls\"] }\n# or\nsuppaftp = { version = \"^7\", features = [\"rustls\"] }\n```\n\n\u003e [!NOTE]\n\u003e 💡 If you don't know what to choose, `native-tls` should be preferred for compatibility reasons.  \n\u003e ❗ If you want to link libssl statically, enable feature `native-tls-vendored`\n\n#### Async support\n\nIf you want to enable **async** support, you must enable either `async-std` feature, to use [async-std](https://crates.io/crates/async-std) or `tokio` feature, to use [tokio](https://crates.io/crates/tokio) as backend, in your cargo dependencies.\n\n```toml\nsuppaftp = { version = \"^7\", features = [\"tokio\"] }\n```\n\n\u003e [!CAUTION]\n\u003e ⚠️ If you want to enable both **native-tls** and **async-std** you must use the **async-std-async-native-tls** feature ⚠️  \n\u003e ⚠️ If you want to enable both **native-tls** and **tokio** you must use the **tokio-async-native-tls** feature ⚠️\n\u003e ⚠️ If you want to enable both **rustls** and **async** you must use the **async-rustls** feature ⚠️  \n\u003e ❗ If you want to link libssl statically with `async-std`, enable feature `async-std-async-native-tls-vendored`\n\u003e ❗ If you want to link libssl statically with `tokio`, enable feature `tokio-async-native-tls-vendored`\n\n#### Deprecated methods\n\nIf you want to enable deprecated methods of FTPS, please enable the `deprecated` feature in your cargo dependencies.\n\nThis feature enables these methods:\n\n- `connect_secure_implicit()`: used to connect via implicit FTPS\n\n#### Logging\n\nBy default, the library will log if there is any `log` crate consumer on the user implementation.\nLogging can be if preferred, disabled via the `no-log` feature.\n\n### Examples 📚\n\n```rust\nuse std::str;\nuse std::io::Cursor;\nuse suppaftp::FtpStream;\n\nfn main() {\n    // Create a connection to an FTP server and authenticate to it.\n    let mut ftp_stream = FtpStream::connect(\"127.0.0.1:21\").unwrap();\n    let _ = ftp_stream.login(\"username\", \"password\").unwrap();\n\n    // Get the current directory that the client will be reading from and writing to.\n    println!(\"Current directory: {}\", ftp_stream.pwd().unwrap());\n\n    // Change into a new directory, relative to the one we are currently in.\n    let _ = ftp_stream.cwd(\"test_data\").unwrap();\n\n    // Retrieve (GET) a file from the FTP server in the current working directory.\n    let data = ftp_stream.retr_as_buffer(\"ftpext-charter.txt\").unwrap();\n    println!(\"Read file with contents\\n{}\\n\", str::from_utf8(\u0026data.into_inner()).unwrap());\n\n    // Store (PUT) a file from the client to the current working directory of the server.\n    let mut reader = Cursor::new(\"Hello from the Rust \\\"ftp\\\" crate!\".as_bytes());\n    let _ = ftp_stream.put_file(\"greeting.txt\", \u0026mut reader);\n    println!(\"Successfully wrote greeting.txt\");\n\n    // Terminate the connection to the server.\n    let _ = ftp_stream.quit();\n}\n```\n\n#### Ftp with TLS (native-tls)\n\n```rust\nuse suppaftp::{NativeTlsFtpStream, NativeTlsConnector};\nuse suppaftp::native_tls::{TlsConnector, TlsStream};\n\nfn main() {\n    let ftp_stream = NativeTlsFtpStream::connect(\"test.rebex.net:21\").unwrap();\n    // Switch to the secure mode\n    let mut ftp_stream = ftp_stream.into_secure(NativeTlsConnector::from(TlsConnector::new().unwrap()), \"test.rebex.net\").unwrap();\n    ftp_stream.login(\"demo\", \"password\").unwrap();\n    // Do other secret stuff\n    assert!(ftp_stream.quit().is_ok());\n}\n```\n\n#### Ftp with TLS (rustls)\n\nYou can also find and run this example in the `suppaftp/examples/` directory (`cargo run --example rustls --features rustls`).\n\n```rust\nuse std::sync::Arc;\nuse suppaftp::{RustlsFtpStream, RustlsConnector};\nuse suppaftp::rustls;\nuse suppaftp::rustls::ClientConfig;\n\nfn main() {\n    let root_store = rustls::RootCertStore::from_iter(\n        webpki_roots::TLS_SERVER_ROOTS\n            .iter()\n            .cloned(),\n    );\n\n    let config = ClientConfig::builder()\n        .with_root_certificates(root_store)\n        .with_no_client_auth();\n\n    // Create a connection to an FTP server and authenticate to it.\n    let mut ftp_stream = RustlsFtpStream::connect(\"test.rebex.net:21\")\n        .unwrap()\n        .into_secure(RustlsConnector::from(Arc::new(config)), \"test.rebex.net\")\n        .unwrap();\n\n    // Terminate the connection to the server.\n    let _ = ftp_stream.quit();\n}\n```\n\n#### Going Async\n\n```rust\nuse suppaftp::{AsyncNativeTlsFtpStream, AsyncNativeTlsConnector};\nuse suppaftp::async_native_tls::{TlsConnector, TlsStream};\nlet ftp_stream = AsyncNativeTlsFtpStream::connect(\"test.rebex.net:21\").await.unwrap();\n// Switch to the secure mode\nlet mut ftp_stream = ftp_stream.into_secure(AsyncNativeTlsConnector::from(TlsConnector::new()), \"test.rebex.net\").await.unwrap();\nftp_stream.login(\"demo\", \"password\").await.unwrap();\n// Do other secret stuff\nassert!(ftp_stream.quit().await.is_ok());\n```\n\n## Built-in CLI client 🖥️\n\nSuppaFTP comes also with a built-in command-line FTP client. This CLI application provides all the commands to interact with a remote FTP server and supports FTPS too. You can also use it as a reference to implement your project. You can find it in the `cli/` directory.\n\nYou can simply install as any other rust application via **Cargo**:\n\n```sh\ncargo install suppaftp-cli\nsuppaftp --version\n```\n\n---\n\n## Support the developer ☕\n\nIf you like **SuppaFTP**, please consider a little donation 🥳\n\n[![ko-fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge\u0026logo=ko-fi\u0026logoColor=white)](https://ko-fi.com/veeso)\n[![PayPal](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge\u0026logo=paypal\u0026logoColor=white)](https://www.paypal.me/chrisintin)\n\n---\n\n## Changelog ⌛\n\n[View Changelog here](CHANGELOG.md)\n\n---\n\n## License 📜\n\nLicensed under either of\n\n- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or \u003chttp://www.apache.org/licenses/LICENSE-2.0\u003e)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or \u003chttp://opensource.org/licenses/MIT\u003e)\n\nat your option.\n\n---\n\n### Contribution 🤝\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual licensed as above, without any additional terms or\nconditions.\n\nIf you want to contribute to this project, please read the [Contributing guide](CONTRIBUTING.md) first 🙂.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveeso%2Fsuppaftp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fveeso%2Fsuppaftp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveeso%2Fsuppaftp/lists"}