{"id":33003019,"url":"https://github.com/embeddedmz/ftpclient-cpp","last_synced_at":"2026-01-14T23:04:15.554Z","repository":{"id":37914892,"uuid":"79035880","full_name":"embeddedmz/ftpclient-cpp","owner":"embeddedmz","description":"C++ client for making FTP requests","archived":false,"fork":false,"pushed_at":"2023-02-07T16:09:20.000Z","size":374,"stargazers_count":231,"open_issues_count":12,"forks_count":71,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-11-18T08:08:52.148Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/embeddedmz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-15T13:57:38.000Z","updated_at":"2025-11-11T14:24:05.000Z","dependencies_parsed_at":"2023-01-23T07:30:33.019Z","dependency_job_id":null,"html_url":"https://github.com/embeddedmz/ftpclient-cpp","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/embeddedmz/ftpclient-cpp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/embeddedmz%2Fftpclient-cpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/embeddedmz%2Fftpclient-cpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/embeddedmz%2Fftpclient-cpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/embeddedmz%2Fftpclient-cpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/embeddedmz","download_url":"https://codeload.github.com/embeddedmz/ftpclient-cpp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/embeddedmz%2Fftpclient-cpp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28437920,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T22:37:52.437Z","status":"ssl_error","status_checked_at":"2026-01-14T22:37:31.496Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-11-13T14:00:38.907Z","updated_at":"2026-01-14T23:04:15.510Z","avatar_url":"https://github.com/embeddedmz.png","language":"C++","readme":"﻿# FTP client for C++\n[![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT) ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/embeddedmz/ftpclient-cpp/CMake%20Build%20Matrix) ![img](https://img.shields.io/badge/platform-linux%20%7C%20osx%20%7C%20win-red) ![GitHub all releases](https://img.shields.io/github/downloads/embeddedmz/ftpclient-cpp/total)\n\n## About\nThis is a simple FTP client for C++. It wraps libcurl for FTP requests and meant to be a portable\nand easy-to-use API to perform FTP related operations.\n\nCompilation has been tested with:\n- GCC 4.8.5 (Centos 7)\n- GCC 5.4.0/7.4.0/9.2.1 (GNU/Linux Ubuntu 16.04/18.04/20.04 LTS)\n- Microsoft Visual Studio 2015/2017/2019 (Windows 10)\n\nUnderlying libraries:\n- [libcurl](http://curl.haxx.se/libcurl/)\n\nWindows Users : vcpkg (Microsoft C++ Library Manager) can be used to easily install libcurl, Google Test (GTest) for the unit tests program and generate the Visual Studio solution with CMake. With vcpkg, no need to manually copy the DLL in the output directory, vcpkg handles all that ! Look at \"Building under Windows via Visual Studio\" section, for instructions.\n\n## Usage\nCreate an object and provide to its constructor a callable object (for log printing) having this signature :\n\n```cpp\nvoid(const std::string\u0026)\n```\n\nLater, you can enable log printing by using the flag CFTPClient::SettingsFlag::ENABLE_LOG when initializing a session.\n\nMake sure that Libcurl is compiled with SSH (https://github.com/embeddedmz/ftpclient-cpp/issues/12).\n\n```cpp\n#include \"FTPClient.h\"\n\nCFTPClient FTPClient([](const std::string\u0026 strLogMsg){ std::cout \u003c\u003c strLogMsg \u003c\u003c std::endl; });\n```\n\nBefore performing one or more requests, a session must be initialized with server parameters (don't prefix the address with an FTP protocol scheme e.g. ftp://).\n\n```cpp\n// Classic FTP client\nFTPClient.InitSession(\"127.0.0.1\", 21, \"username\", \"password\");\n\n// For SFTP : \nSFTPClient.InitSession(\"127.0.0.1\", 22, \"username\", \"password\", CFTPClient::FTP_PROTOCOL::SFTP);\n\n/* You might need to set insecure to true to turn off peer/host verification - this is the case if you don't use a CA file */\nSFTPClient.SetInsecure(true);\n```\n\nWith SFTP protocol, all API commands will work except DownloadWildcard.\n\nYou can also set parameters such as the time out (in seconds + enable/disable signal handling), the HTTP proxy server etc... before sending your request.\n\nTo enable FTP Active Mode, use this setter (I didn't test it but it should work fine, create an issue if it doesn't work) :\n\n```cpp\nFTPClient.SetActive(true);\n```\n\nTo create and remove a remote empty directory :\n\n```cpp\n/* creates a directory \"bookmarks\" under ftp://127.0.0.1:21/documents/ */\nFTPClient.CreateDir(\"/document/bookmarks\");\n\n/* removes the \"empty\" directory \"bookmarks\" created above\n * the directory must be empty, otherwise the method will fail */\nFTPClient.RemoveDir(\"/document/bookmarks\");\n```\n\nTo download a file :\n\n```cpp\n/* download ftp://127.0.0.1:21/info.txt to \"C:\\downloaded_info.txt\" */\nFTPClient.DownloadFile(\"C:\\\\downloaded_info.txt\", \"info.txt\");\n```\n\nTo download a whole directory with the wildcard '*' :\n\n```cpp\n/* download all the elements of ftp://127.0.0.1:21/pictures/ to WildcardTest/ */\nFTPClient.DownloadWildcard(\"/home/amine/WildcardTest\", \"pictures/*\");\n```\n\nTo upload and remove a file :\n\n```cpp\n/* upload C:\\test_upload.txt to  ftp://127.0.0.1:21/upload/documents/test_upload.txt */\n/* if /upload/documents/ doesn't exist, you can set the third parameter bCreateDir to true\nto create missing directories */\nFTPClient.UploadFile(\"C:\\\\test_upload.txt\", \"/upload/documents/test_upload.txt\");\n\n/* remove the above uploaded file */\nFTPClient.RemoveFile(\"/upload/documents/test_upload.txt\");\n```\n\nYou also have a method to append data to a remote file (Issue #34).\n\nTo list a remote directory:\n\n```cpp\nstd::string strList;\n\n/* list root directory\n * a third parameter can be set to false to request a detailed list */\n\nFTPClient.List(\"/\", strList);\n```\n\nTo request a remote file's size and mtime:\n\n```cpp\n/* create a helper object to receive file's info */\nCFTPClient::FileInfo ResFileInfo = { 0, 0.0 };\n\n/* requests ftp://127.0.0.1:21/info.txt file size and mtime */\nFTPClient.Info(\"info.txt\", ResFileInfo));\n\n/* if the operation succeeds, true will be returned. */\n\ncout \u003c\u003c ResFileInfo.dFileSize \u003c\u003c endl; // file size of \"/info.txt\"\ncout \u003c\u003c ResFileInfo.tFileMTime \u003c\u003c endl; // file mtime (epoch) of \"/info.txt\"\n```\n\nAlways check that the methods above return true, otherwise, that means that  the request wasn't properly\nexecuted.\n\nFinally cleanup can be done automatically if the object goes out of scope. If the log printing is enabled,\na warning message will be printed. Or you can cleanup manually by calling CleanupSession() :\n\n```cpp\nFTPClient.CleanupSession();\n```\n\nAfter cleaning the session, if you want to reuse the object, you need to re-initialize it with the\nproper method.\n\n## Callback to a Progress Function\n\nA pointer to a callback progress meter function or a callable object (lambda, functor etc...), which should match the prototype shown below, can be passed.\n\n```cpp\nint ProgCallback(void* ptr, double dTotalToDownload, double dNowDownloaded, double dTotalToUpload, double dNowUploaded);\n```\n\nThis function gets called by libcurl instead of its internal equivalent with a frequent interval. While data is being transferred it will be called very frequently, and during slow periods like when nothing is being transferred it can slow down to about one call per second.\n\nReturning a non-zero value from this callback will cause libcurl to abort the transfer.\n\nThe unit tests \"TestDownloadFile\" and \"TestUploadAndRemoveFile\" demonstrate how to use a progress function to display a progress bar on console when downloading or uploading a file.\n\n## Thread Safety\n\nDo not share CFTPClient objects across threads as this would mean accessing libcurl handles from multiple threads at the same time which is not allowed.\n\nThe method SetNoSignal can be used to skip all signal handling. This is important in multi-threaded applications as DNS resolution timeouts use signals. The signal handlers quite readily get executed on other threads.\n\n## HTTP Proxy Tunneling Support\n\nAn HTTP Proxy can be set to use for the upcoming request.\nTo specify a port number, append :[port] to the end of the host name. If not specified, `libcurl` will default to using port 1080 for proxies. The proxy string may be prefixed with `http://` or `https://`. If no HTTP(S) scheme is specified, the address provided to `libcurl` will be prefixed with `http://` to specify an HTTP proxy. A proxy host string can embed user + password.\nThe operation will be tunneled through the proxy as curl option `CURLOPT_HTTPPROXYTUNNEL` is enabled by default.\nA numerical IPv6 address must be written within [brackets].\n\n```cpp\nFTPClient.SetProxy(\"https://37.187.100.23:3128\");\n\n/* the following request will be tunneled through the proxy */\nstd::string strList;\n\nFTPClient.List(\"/\", strList);\n```\n\nif you need to specify a user and password\n\n```cpp\nFTPClient.SetProxyUserPwd(\"user:password\");\n```\n\n## Installation\n\nYou will need CMake to generate a makefile for the static library or to build the tests/code coverage program.\n\nAlso make sure you have libcurl and Google Test installed.\n\nYou can follow this script https://gist.github.com/fideloper/f72997d2e2c9fbe66459 to install libcurl.\n\nThis tutorial will help you installing properly Google Test on Ubuntu: https://www.eriksmistad.no/getting-started-with-google-test-on-ubuntu/\n\nThe CMake script located in the tree will produce Makefiles for the creation of the static library and for the unit tests program.\n\nTo create a debug static library and a test binary, change directory to the one containing the first CMakeLists.txt and :\n\n```Shell\nmkdir build\ncd build\ncmake .. -DCMAKE_BUILD_TYPE:STRING=Debug\nmake\n```\n\nTo create a release static library, just change \"Debug\" by \"Release\".\n\nThe library will be found under \"build/[Debug|Release]/lib/libftpclient.a\" whereas the test program will be located in \"build/[Debug|Release]/bin/test_ftpclient\"\n\nTo directly run the unit test binary, you must indicate the path of the INI conf file (see the section below)\n```Shell\n./[Debug|Release]/bin/test_ftpclient /path_to_your_ini_file/conf.ini\n```\n\n### Building under Windows via Visual Studio\n\n1. New Procedure (with vcpkg) :\n\nInstall [vcpkg](https://github.com/microsoft/vcpkg) then install libcurl (use 'x86-windows' for the 32-bit version) and Google Test (GTest) :\n```Shell\n.\\vcpkg install curl curl[openssl] curl[ssh] gtest --triplet=x64-windows\n```\n\nIf you have a french Visual Studio version, don't forget to install the english language pack (vcpkg will tell you this anyway).\n\nDownload and install the latest version of CMake : https://cmake.org/download/ (e.g. Windows win64-x64 Installer)\n\nOpen CMake (cmake-gui)\n\nIn \"Where is the source code\", put the ftpclient-cpp path (e.g. C:/Users/Amine/Documents/Work/PROJECTS/GitHub/ftpclient-cpp), where the main CMakeLists.txt file exist.\n\nIn \"Where to build binaries\", paste the directory where you want to build the project (e.g. C:/Users/Amine/Documents/Work/PROJECTS/GitHub/ftpclient_build)\n\nClick on \"Configure\".\n\nSelect your Visual Studio version (if it isn't already set).\nIn \"Optional platform for generator\", you can leave it empty (x64 by default) or choose another value.\n\nClick on the radio button \"Specify toolchain file for cross-compiling, then hit the \"Next\" button.\n\nIn \"Specify the toolchain file\", browse to vcpkg toolchain file (vcpkg/scripts/buildsystems/vcpkg.cmake) and select it.\n\nPress \"Finish\", wait until CMake configures the project then hit \"Generate\" to create the Visual Studio solution (library and unit test binary).\n\n2. Old Procedure (without vcpkg) :\n\nFirst of all, build libcurl using this fork of build-libcurl-windows : https://github.com/ribtoks/build-libcurl-windows\n\nIn fact, this fork will allow you to build libcurl under Visual Studio 2017.\n\n```Shell\ngit clone https://github.com/ribtoks/build-libcurl-windows.git\n```\n\nThen just build libcurl using :\n\n```Shell\nbuild.bat\n```\n\nThis batch script will automatically download the latest libcurl source code and build it using the most recent Visual Studio compiler\nthat it will find on your computer. For a particular version, you can modify the batch script...\n\nUnder YOUR_DIRECTORY\\build-libcurl-windows\\third-party\\libcurl, you will find the curl include directory and a lib directory containing different type of libraries : dynamic and static x86 and x64 libraries compiled in Debug and Release mode (8 libraries). Later, we will be using the libraries located in lib\\dll-debug-x64 and lib\\dll-release-x64 as an example.\n\nConcerning Google Test, the library will be downloaded and built automatically from its github repository. Someone with enough free time can do the same for libcurl and submit a pull request...\n\nDownload and install the latest version of CMake : https://cmake.org/download/ (e.g. Windows win64-x64 Installer)\n\nOpen CMake (cmake-gui)\n\nIn \"Where is the source code\", put the ftpclient-cpp path (e.g. C:/Users/Amine/Documents/Work/PROJECTS/GitHub/ftpclient-cpp), where the main CMakeLists.txt file exist.\n\nIn \"Where to build binaries\", paste the directory where you want to build the project (e.g. C:/Users/Amine/Documents/Work/PROJECTS/GitHub/ftpclient_build)\n\nClick on \"Configure\". After some time, an error message will be shown, that's normal as CMake is unable to find libcurl.\n\nMake sure \"Advanced\" checkbox is checked, in the list, locate the variables prefixed with \"CURL_\" and update them with the path of libcurl include directory and libraries, for example :\n\nCURL_INCLUDE_DIR C:\\LIBS\\build-libcurl-windows\\third-party\\libcurl\\include\nCURL_LIBRARY_DEBUG C:\\LIBS\\build-libcurl-windows\\third-party\\libcurl\\lib\\dll-debug-x64\\libcurl_debug.lib\nCURL_LIBRARY_RELEASE C:\\LIBS\\build-libcurl-windows\\third-party\\libcurl\\lib\\dll-release-x64\\libcurl.lib\n\nClick on \"Configure\" again ! You should not have errors this time. You can ignore the warning related to the test configuration file.\n\nThen click on \"Generate\", you can choose a Visual Studio version if it is not done before (e.g. Visual Studio 15 2017 Win64, I think it should be the same version used to build libcurl...)\n\nFinally, click on \"Open Project\" to open the solution in Visual Studio.\n\nIn Visual Studio, you can change the build type (Debug -\u003e Release). Build the solution (press F7). It must succeed without any errors. You can close Visual Studio.\n\nThe library will be found under C:\\Users\\Amine\\Documents\\Work\\PROJECTS\\GitHub\\ftpclient_build\\lib\\Release]\\ftpclient.lib\n\nAfter building a program using \"ftpclient.lib\", do not forget to copy libcurl DLL in the directory where the program binary is located.\n\nFor example, in the build directory (e.g. C:\\Users\\Amine\\Documents\\Work\\PROJECTS\\GitHub\\ftpclient_build), under \"bin\", directory, you may find \"Debug\", \"Release\" or both according to the build type used during the build in Visual Studio, and in it, the test program \"test_ftpclient.exe\". Before executing it, make sure to copy the libcurl DLL in the same directory (e.g. copy C:\\LIBS\\build-libcurl-windows\\third-party\\libcurl\\lib\\dll-release-x64\\libcurl.dll and the PDB file too if you want, do not change the name of the DLL !) The type of the library MUST correspond to the type of the .lib file fed to CMake-gui !\n\nIf you want to run the test program, in the command line, launch test_ftpclient.exe with the path of you test configuration file (INI) :\n\n```Shell\nC:\\Users\\Amine\\Documents\\Work\\PROJECTS\\GitHub\\ftpclient_build\\bin\\[Debug | Release]\\test_ftpclient.exe PATH_TO_YOUR_TEST_CONF_FILE\\conf.ini\n```\n\n## Run Unit Tests\n\nFirst of all, the CMake option SKIP_TESTS_BUILD must be set to \"OFF\" (via CMake-GUI then pressing on the \"Configure\" button or if you are using a command line via the argument -DSKIP_TESTS_BUILD=OFF).\n\n[simpleini](https://github.com/brofield/simpleini) is used to gather unit tests parameters from\nan INI configuration file. You need to fill that file with FTP and/or SFTP parameters.\nYou can also disable some tests (HTTP proxy for instance) and indicate\nparameters only for the enabled tests. A template of the INI file already exists under TestFTP/\n\nExample : (Run only FTP tests)\n\n```ini\n[tests]\n; FTP tests are enabled\nftp=yes\n; SFTP tests (not implemented) are disabled\nsftp=no\n; HTTP Proxy tests are enabled\nhttp-proxy=yes\n\n[ftp]\nhost=127.0.0.1\nport=21\nusername=foo\npassword=bar\n; remote elements below must exist\nremote_file=info.txt\n; for the download/info tests\nremote_upload_folder=/upload/documents\n; for upload/create dir tests\nremote_download_folder=pictures/\n; for the test TestWildcardedURL to download an entire remote directory\n; with the files and directories\n```\n\nYou can also generate an XML file of test results by adding --getst_output argument when calling the test program\n\n```Shell\n./[Debug|Release]/bin/test_ftpclient /path_to_your_ini_file/conf.ini --gtest_output=\"xml:./TestFTP.xml\"\n```\n\nAn alternative way to compile and run unit tests :\n\n```Shell\nmkdir build\ncd build\ncmake .. -DCMAKE_BUILD_TYPE=Debug -DTEST_INI_FILE=\"full_or_relative_path_to_your_test_conf.ini\"\nmake\nmake test\n```\n\nYou may use a tool like https://github.com/adarmalik/gtest2html to convert your XML test result in an HTML file.\n\n## Memory Leak Check\n\nVisual Leak Detector has been used to check memory leaks with the Windows build (Visual Sutdio 2015)\nYou can download it here: https://vld.codeplex.com/\n\nTo perform a leak check with the Linux build, you can do so :\n\n```Shell\nvalgrind --leak-check=full ./Debug/bin/test_ftpclient /path_to_ini_file/conf.ini\n```\n\n## Code Coverage\n\nThe code coverage build doesn't use the static library but compiles and uses directly the \nFTPClient-C++ API in the test program.\n\n```Shell\nmkdir build\ncd build\ncmake .. -DCMAKE_BUILD_TYPE=Coverage -DCOVERAGE_INI_FILE:STRING=\"full_path_to_your_test_conf.ini\"\nmake\nmake coverage_ftpclient\n```\n\nIf everything is OK, the results will be found under ./TestFTP/coverage/index.html\n\nMake sure you feed CMake with a full path to your test conf INI file, otherwise, the coverage test\nwill be useless.\n\nUnder Visual Studio, you can simply use OpenCppCoverage (https://opencppcoverage.codeplex.com/)\n\n## Contribute\nAll contributions are highly appreciated. This includes updating documentation, writing code and unit tests\nto increase code coverage and enhance tools.\n\nTry to preserve the existing coding style (Hungarian notation, indentation etc...).\n\n## Issues\n\n### Compiling with the macro DEBUG_CURL\n\nIf you compile the test program with the preprocessor macro DEBUG_CURL, to enable curl debug informations,\nthe static library used must also be compiled with that macro. Don't forget to mention a path where to store\nlog files in the INI file if you want to use that feature in the unit test program (curl_logs_folder under [local])\n\n### File names format when compiling with Visual Studio (Windows users)\n\nIt is assumed that the FTP servers you intend to connect with support UTF-8. You must feed the FTP client API with paths/file names encoded in UTF-8 and NOT in ANSI (Windows-1252 on Western/U.S. systems but it can represent certain other Windows code pages on other systems, ANSI is just an extension for ASCII).\n\nFor example, take look at the unit test \"TestDownloadFile\", the static helper method CFTPClient::AnsiToUtf8 can help you in converting ANSI encoded strings to UTF8.\n\nIf you restrict yourself to ASCII characters in your ANSI string, you don't need to convert your ANSI strings to UTF-8.\n\n### Using ftpclient-cpp inside a DLL on Windows\n\nAccording to this libcurl documentation [page](https://curl.se/libcurl/c/curl_global_init.html) I quote :\n\"If you are initializing libcurl from a Windows DLL you should not initialize it from DllMain or a static initializer because Windows holds the loader lock during that time and it could cause a deadlock.\"\n\nSo, please avoid to use this library in a DLL or if it's not possible you will have just to made the global libcurl initialization/cleaup stuff yourself (look at CurlHandle class and just call the curl_global_init() once before the beginning of the logic of your program in the main() function and curl_global_cleanup at the end of it and don't forget to remove the instance of that class in the CFTPClient class to fix this issue).\n","funding_links":[],"categories":["Networking"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fembeddedmz%2Fftpclient-cpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fembeddedmz%2Fftpclient-cpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fembeddedmz%2Fftpclient-cpp/lists"}