Browse Source

V0.6.2
1、解决了CurlFtp每次操作都需要输入密码的问题

Apple 3 months ago
parent
commit
d96ed33a4b
2 changed files with 248 additions and 219 deletions
  1. 243 219
      common/CurlFtp/CurlFtp.cpp
  2. 5 0
      common/CurlFtp/CurlFtp.h

+ 243 - 219
common/CurlFtp/CurlFtp.cpp

@@ -416,6 +416,7 @@ CurlFtp::CurlFtp()
 CurlFtp::~CurlFtp()
 {
     /* 清理curl */
+    curl_easy_cleanup(m_curl);
     curl_global_cleanup();
     hasInstace = false;
 }
@@ -484,17 +485,18 @@ bool CurlFtp::getFileList(std::string dir, std::vector<std::string>& fileList)
     /* 检查dir,添加前缀“/” */
     auto dirTmp = checkDirPath(dir);
 
-    CURL *curl = nullptr;
-    curl = curl_easy_init();
-    if(curl == nullptr)
-    {
-        SPDLOG_ERROR("curl init failed !");
-        return false;
-    }
+    // CURL *curl = nullptr;
+    // curl = curl_easy_init();
+    // if(curl == nullptr)
+    // {
+    //     SPDLOG_ERROR("curl init failed !");
+    //     return false;
+    // }
+    resetCurl(m_curl);
 
     std::vector<CF_FileInfo> listInfo;
     /* 获取文件信息 */
-    listAll(curl, dirTmp, listInfo);
+    listAll(m_curl, dirTmp, listInfo);
     for(const CF_FileInfo& fi : listInfo)
     {
         // SPDLOG_INFO("type = {}, size = {}, name = {}", (int)fi.type, fi.size, fi.name);
@@ -504,7 +506,7 @@ bool CurlFtp::getFileList(std::string dir, std::vector<std::string>& fileList)
         }
     }
 
-    curl_easy_cleanup(curl);
+    // curl_easy_cleanup(curl);
     
     return true;
 }
@@ -520,17 +522,18 @@ bool CurlFtp::getDirList(std::string dir, std::vector<std::string>& dirList)
     /* 检查dir,添加前缀“/” */
     auto dirTmp = checkDirPath(dir);
 
-    CURL *curl = nullptr;
-    curl = curl_easy_init();
-    if(curl == nullptr)
-    {
-        SPDLOG_ERROR("curl init failed !");
-        return false;
-    }
+    // CURL *curl = nullptr;
+    // curl = curl_easy_init();
+    // if(curl == nullptr)
+    // {
+    //     SPDLOG_ERROR("curl init failed !");
+    //     return false;
+    // }
+    resetCurl(m_curl);
 
     std::vector<CF_FileInfo> listInfo;
     /* 获取文件信息 */
-    listAll(curl, dirTmp, listInfo);
+    listAll(m_curl, dirTmp, listInfo);
     for(const CF_FileInfo& fi : listInfo)
     {
         // SPDLOG_INFO("type = {}, size = {}, name = {}", (int)fi.type, fi.size, fi.name);
@@ -540,7 +543,7 @@ bool CurlFtp::getDirList(std::string dir, std::vector<std::string>& dirList)
         }
     }
 
-    curl_easy_cleanup(curl);
+    // curl_easy_cleanup(curl);
 
     return true;
 }
@@ -549,6 +552,7 @@ bool CurlFtp::getDirList(std::string dir, std::vector<std::string>& dirList)
 /* 判断文件夹是否存在 */
 bool CurlFtp::isDirExist(const std::string& dir)
 {
+    SPDLOG_DEBUG("Check dir: {}", dir);
     if(m_ftpUrl.empty())
     {
         SPDLOG_ERROR("ftpUrl is empty");
@@ -557,43 +561,37 @@ bool CurlFtp::isDirExist(const std::string& dir)
     /* 检查传入的文件夹 */
     auto dirTmp = checkDirPath(dir);
 
-    CURL* curl = nullptr;
-    curl = curl_easy_init();
-    if(curl == nullptr)
-    {
-        SPDLOG_ERROR("curl init failed !");
-        return false;
-    }
+    // CURL* curl = nullptr;
+    resetCurl(m_curl);
     std::string ftpUrl = m_ftpUrl + dirTmp;
-    curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str());
-    curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
-    curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_URL, ftpUrl.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_USERNAME, m_username.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PASSWORD, m_password.c_str());
     /* 获取文件夹是否存在,不需要接收文件 */
-    curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
-
-    // 禁用被动模式(如果需要)
-    curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_NOBODY, 1L);
 
+    /* 设置SFTP */
+    setSftp(m_curl);
+    /* 启用调试信息 */
     if(m_enableCurlDebug)
     {
-        /* 启用调试信息 */
-        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+        curl_easy_setopt(m_curl, CURLOPT_VERBOSE, 1L);
     }
 
     /* 启用持久连接 */
-    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
-
-    CURLcode res = curl_easy_perform(curl);
+    // curl_easy_setopt(m_curl, CURLOPT_TCP_KEEPALIVE, 1L);
+    /* 这里只需要执行一次 */
+    CURLcode res = curl_easy_perform(m_curl);
     bool result = true;
     if(res != CURLE_OK)
     {
         // SPDLOG_ERROR("Failed to get file list, error code: {} ,{}", (int)res, curl_easy_strerror(res));
         result = false;
     }
-    // bool ret = performCurl(curl);
+    // bool ret = performCurl(m_curl);
     // if(!ret)
     // {
-    //     SPDLOG_ERROR("Failed to create FTP Dir");
+    //     // SPDLOG_ERROR("Failed to create FTP Dir");
     // }
 
     return result;
@@ -623,49 +621,61 @@ bool CurlFtp::createDirectory(const std::string& ftpDir)
     /* 检查传入的文件夹格式 */
     auto dirTmp = checkDirPath(ftpDir);
 
-    CURL *curl = curl_easy_init();
-    if(curl == nullptr)
+    // CURL *curl = curl_easy_init();
+    // if(curl == nullptr)
+    // {
+    //     SPDLOG_ERROR("Create FTP DIR, curl init failed !");
+    //     return false;
+    // }
+    if(m_curl == nullptr)
     {
-        SPDLOG_ERROR("Create FTP DIR, curl init failed !");
-        return false;
+        m_curl = curl_easy_init();
+        if(m_curl == nullptr)
+        {
+            SPDLOG_ERROR("curl init failed !");
+            return false;
+        }
+    }else {
+        curl_easy_reset(m_curl);
     }
 
-    curl_easy_setopt(curl, CURLOPT_URL, m_ftpUrl.c_str());
-    curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
-    curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_URL, m_ftpUrl.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_USERNAME, m_username.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PASSWORD, m_password.c_str());
     /* 创建FTP头信息 */
     struct curl_slist *headerlist = NULL;
     std::string mkdir = "MKD " + dirTmp;
     headerlist = curl_slist_append(headerlist, mkdir.c_str());
     /* 设置FTP命令行选项 */
-    curl_easy_setopt(curl, CURLOPT_QUOTE, headerlist);
+    curl_easy_setopt(m_curl, CURLOPT_QUOTE, headerlist);
     /* 不包含实体 */
-    curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_NOBODY, 1L);
     /* 启用跟随重定向 */
-    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_FOLLOWLOCATION, 1L);
     /* 设置超时时间 */
-    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
-    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L);
+    curl_easy_setopt(m_curl, CURLOPT_TIMEOUT, 30L);
+    curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT, 30L);
 
-    // 禁用被动模式(如果需要)
-    // curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 1L);
+    /* 设置SFTP */
+    setSftp(m_curl);
 
     if(m_enableCurlDebug)
     {
         /* 启用调试信息 */
-        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+        curl_easy_setopt(m_curl, CURLOPT_VERBOSE, 1L);
     }
     // 启用持久连接
-    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
+    // curl_easy_setopt(m_curl, CURLOPT_TCP_KEEPALIVE, 1L);
 
+    SPDLOG_DEBUG("Create dir: {}", dirTmp);
     // CURLcode res = curl_easy_perform(curl);
-    bool ret = performCurl(curl);
+    bool ret = performCurl(m_curl);
     if(!ret)
     {
         SPDLOG_ERROR("Failed to create FTP Dir");
     }
 
-    curl_easy_cleanup(curl);
+    // curl_easy_cleanup(curl);
     curl_slist_free_all(headerlist);
     return ret;
 }
@@ -743,68 +753,53 @@ bool CurlFtp::downloadFile(const std::string& remoteFile, const std::string& loc
         return false;
     }
 
-    CURL* curl = nullptr;
-    curl = curl_easy_init();
-    if(curl == nullptr)
-    {
-        SPDLOG_ERROR("curl init failed !");
-        return false;
-    }
+    // CURL* curl = nullptr;
+    // curl = curl_easy_init();
+    // if(curl == nullptr)
+    // {
+    //     SPDLOG_ERROR("curl init failed !");
+    //     return false;
+    // }
+    resetCurl(m_curl);
     /* 打开文件 */
     std::ofstream ofs;
     ofs.open(localFile, std::ios::out | std::ios::binary | std::ios::trunc);
 
     /* 设置FTP地址 */
-    curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str());
-    curl_easy_setopt(curl, CURLOPT_PORT, m_port);
+    curl_easy_setopt(m_curl, CURLOPT_URL, ftpUrl.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PORT, m_port);
     /* 设置用户名和密码 */
-    // curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
-    // curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
-    curl_easy_setopt(curl, CURLOPT_USERPWD, (m_username + ":" + m_password).c_str());
+    curl_easy_setopt(m_curl, CURLOPT_USERNAME, m_username.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PASSWORD, m_password.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_USERPWD, (m_username + ":" + m_password).c_str());
     /* 启用跟随重定向 */
-    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_FOLLOWLOCATION, 1L);
     /* 设置回调函数 */
-    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFileCallBack);
-    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ofs);
+    curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeFileCallBack);
+    curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &ofs);
     /* 设置超时时间 */
     // curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
-    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
+    curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT, timeout);
     /* 设置进度回调函数 */
-    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
-    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, nullptr);
+    curl_easy_setopt(m_curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
+    curl_easy_setopt(m_curl, CURLOPT_XFERINFODATA, nullptr);
     /* 启用下载进度回调函数 */
-    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
-    /* 判断是否是SFTP */
-    if(m_isSftp)
-    {
-        /* 判断是否需要设置CA证书 */
-        if(m_isIgnoreSSLCert)
-        {
-            /* 忽略证书验证 */
-            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
-            /* 忽略主机名验证 */
-            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
-        } else
-        {
-            /* 设置CA证书 */
-            curl_easy_setopt(curl, CURLOPT_CAINFO, m_caCertFile.c_str());
-        }
-    }
-    // 禁用被动模式(如果需要)
-    curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_NOPROGRESS, 0L);
+    /* 设置SFTP */
+    setSftp(m_curl);
+
     if(m_enableCurlDebug)
     {
         /* 启用调试信息 */
-        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+        curl_easy_setopt(m_curl, CURLOPT_VERBOSE, 1L);
     }
     /* 启用持久连接 */
-    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_TCP_KEEPALIVE, 1L);
     /* 发送请求 */
-    CURLcode res = curl_easy_perform(curl);
-    if(res != CURLE_OK)
+    bool ret = performCurl(m_curl);
+    if(!ret)
     {
-        SPDLOG_ERROR("Failed to get file list, error code: {} ,{}", (int)res, curl_easy_strerror(res));
-        SPDLOG_ERROR("Url = {}", ftpUrl);
+        SPDLOG_ERROR("Failed to get file list, Url = {}", ftpUrl);
         /* 清理下载失败的文件 */
         ofs.close();
         std::remove(localFile.c_str());
@@ -812,7 +807,7 @@ bool CurlFtp::downloadFile(const std::string& remoteFile, const std::string& loc
     }
     /* 关闭文件,清理curl */
     ofs.close();
-    curl_easy_cleanup(curl);
+    // curl_easy_cleanup(curl);
 
     /* 打印一个换行符 */
     // printf("\n");
@@ -834,76 +829,59 @@ bool CurlFtp::downloadToArray(const std::string& remoteFile, std::vector<char>&
     std::string remoteFileTmp = checkFilePath(remoteFile);
     std::string ftpUrl = m_ftpUrl + remoteFileTmp;
 
-    CURL* curl = nullptr;
-    curl = curl_easy_init();
-    if(curl == nullptr)
-    {
-        SPDLOG_ERROR("curl init failed !");
-        return false;
-    }
+    // CURL* curl = nullptr;
+    // curl = curl_easy_init();
+    // if(curl == nullptr)
+    // {
+    //     SPDLOG_ERROR("curl init failed !");
+    //     return false;
+    // }
+    resetCurl(m_curl);
 
     /* 设置FTP地址 */
-    curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str());
-    curl_easy_setopt(curl, CURLOPT_PORT, m_port);
+    curl_easy_setopt(m_curl, CURLOPT_URL, ftpUrl.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PORT, m_port);
     /* 设置用户名和密码 */
-    // curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
-    // curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
-    curl_easy_setopt(curl, CURLOPT_USERPWD, (m_username + ":" + m_password).c_str());
+    curl_easy_setopt(m_curl, CURLOPT_USERNAME, m_username.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PASSWORD, m_password.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_USERPWD, (m_username + ":" + m_password).c_str());
     /* 启用跟随重定向 */
-    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_FOLLOWLOCATION, 1L);
     /* 设置回调函数 */
-    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeDataCallBack);
-    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &arrayInfo);
+    curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeDataCallBack);
+    curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &arrayInfo);
     /* 设置超时时间 */
     // curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
-    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
+    curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT, timeout);
     /* 设置进度回调函数 */
-    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
-    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, nullptr);
+    curl_easy_setopt(m_curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
+    curl_easy_setopt(m_curl, CURLOPT_XFERINFODATA, nullptr);
     /* 启用下载进度回调函数 */
-    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
-    /* 判断是否是SFTP */
-    if(m_isSftp)
-    {
-        /* 判断是否需要设置CA证书 */
-        if(m_isIgnoreSSLCert)
-        {
-            /* 忽略证书验证 */
-            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
-            /* 忽略主机名验证 */
-            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
-        } else
-        {
-            /* 设置CA证书 */
-            curl_easy_setopt(curl, CURLOPT_CAINFO, m_caCertFile.c_str());
-        }
-    }
-    // 禁用被动模式(如果需要)
-    curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_NOPROGRESS, 0L);
+    /* 设置SFTP */
+    setSftp(m_curl);
+
     if(m_enableCurlDebug)
     {
         /* 启用调试信息 */
-        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+        curl_easy_setopt(m_curl, CURLOPT_VERBOSE, 1L);
     }
     /* 启用持久连接 */
-    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_TCP_KEEPALIVE, 1L);
     /* 发送请求 */
-    CURLcode res = curl_easy_perform(curl);
-    if(res != CURLE_OK)
+    bool ret = performCurl(m_curl);
+    if(!ret)
     {
-        SPDLOG_ERROR("Failed to get file list, error code: {} ,{}", (int)res, curl_easy_strerror(res));
-        SPDLOG_ERROR("Url = {}", ftpUrl);
-        /* 清理下载失败的文件 */
-        return false;
+        SPDLOG_ERROR("Failed to get file list, Url = {}", ftpUrl);
     }
     /* 清理curl */
-    curl_easy_cleanup(curl);
+    // curl_easy_cleanup(curl);
 
     /* 打印一个换行符 */
     // printf("\n");
     printf("\n");
 
-    return true;
+    return ret;
 }
 
 /**
@@ -966,63 +944,65 @@ bool CurlFtp::uploadFile(const std::string& localFile, const std::string& remote
     ifs.seekg(0, std::ios::beg);
     SPDLOG_DEBUG("File size: {}", (long)fileSize);
 
-    CURL* curl = nullptr;
-    curl = curl_easy_init();
-    if(curl == nullptr)
+    // CURL* curl = nullptr;
+    // curl = curl_easy_init();
+    // if(curl == nullptr)
+    // {
+    //     SPDLOG_ERROR("curl init failed !");
+    //     ifs.close();
+    //     return false;
+    // }
+    if(!resetCurl(m_curl))
     {
-        SPDLOG_ERROR("curl init failed !");
         ifs.close();
         return false;
     }
     /* 设置FTP地址 */
-    curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str());
-    curl_easy_setopt(curl, CURLOPT_PORT, m_port);
+    curl_easy_setopt(m_curl, CURLOPT_URL, ftpUrl.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PORT, m_port);
     /* 设置用户名和密码 */
-    curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
-    curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_USERNAME, m_username.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PASSWORD, m_password.c_str());
     /* 启用跟随重定向 */
-    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_FOLLOWLOCATION, 1L);
     /* 启用上传 */
-    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_UPLOAD, 1L);
     /* 设置回调函数 */
-    curl_easy_setopt(curl, CURLOPT_READFUNCTION, readFileCallBack);
-    curl_easy_setopt(curl, CURLOPT_READDATA, &ifs);
+    curl_easy_setopt(m_curl, CURLOPT_READFUNCTION, readFileCallBack);
+    curl_easy_setopt(m_curl, CURLOPT_READDATA, &ifs);
     /* 设置上传文件的大小 */
-    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fileSize);
+    curl_easy_setopt(m_curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fileSize);
     /* 设置超时时间 */
     // curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
-    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
+    curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT, timeout);
     /* 设置进度回调函数 */
-    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
-    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, nullptr);
+    curl_easy_setopt(m_curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
+    curl_easy_setopt(m_curl, CURLOPT_XFERINFODATA, nullptr);
     /* 启用下载进度回调函数 */
-    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+    curl_easy_setopt(m_curl, CURLOPT_NOPROGRESS, 0L);
 
-    // 禁用被动模式(如果需要)
-    curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 1L);
+    /* 设置SFTP */
+    setSftp(m_curl);
+    /* 启用调试信息 */
     if(m_enableCurlDebug)
     {
-        /* 启用调试信息 */
-        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+        curl_easy_setopt(m_curl, CURLOPT_VERBOSE, 1L);
     }
     /* 启用持久连接 */
-    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_TCP_KEEPALIVE, 1L);
     /* 发送请求 */
-    CURLcode res = curl_easy_perform(curl);
-    bool result = true;
-    if(res != CURLE_OK)
+    bool ret = performCurl(m_curl);
+    if(!ret)
     {
-        SPDLOG_ERROR("Upload file failed, error code: {} ,{}", (int)res, curl_easy_strerror(res));
-        SPDLOG_ERROR("Url = {}", ftpUrl);
-        result = false;
+        SPDLOG_ERROR("Upload file failed, Url = {}", ftpUrl);
     }
     /* 关闭文件,清理curl */
     ifs.close();
-    curl_easy_cleanup(curl);
+    // curl_easy_cleanup(curl);
     /* 打印一个换行符 */
     printf("\n");
 
-    return result;
+    return ret;
 }
 
 
@@ -1073,62 +1053,63 @@ bool CurlFtp::uploadData(char* srcData, size_t size, const std::string& remoteFi
     std::string ftpUrl = m_ftpUrl + remoteFileTmp;
     SPDLOG_DEBUG("Data size: {}", arrayInfo.size);
 
-    CURL* curl = nullptr;
-    curl = curl_easy_init();
-    if(curl == nullptr)
+    // CURL* curl = nullptr;
+    // curl = curl_easy_init();
+    // if(curl == nullptr)
+    // {
+    //     SPDLOG_ERROR("curl init failed !");
+    //     return false;
+    // }
+    if(!resetCurl(m_curl))
     {
-        SPDLOG_ERROR("curl init failed !");
         return false;
     }
     /* 设置FTP地址 */
-    curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str());
-    curl_easy_setopt(curl, CURLOPT_PORT, m_port);
+    curl_easy_setopt(m_curl, CURLOPT_URL, ftpUrl.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PORT, m_port);
     /* 设置用户名和密码 */
     // curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
     // curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
-    curl_easy_setopt(curl, CURLOPT_USERPWD, (m_username + ":" + m_password).c_str());
+    curl_easy_setopt(m_curl, CURLOPT_USERPWD, (m_username + ":" + m_password).c_str());
     /* 启用跟随重定向 */
-    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_FOLLOWLOCATION, 1L);
     /* 启用上传 */
-    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_UPLOAD, 1L);
     /* 设置回调函数 */
-    curl_easy_setopt(curl, CURLOPT_READFUNCTION, readDataCallBack);
-    curl_easy_setopt(curl, CURLOPT_READDATA, &arrayInfo);
+    curl_easy_setopt(m_curl, CURLOPT_READFUNCTION, readDataCallBack);
+    curl_easy_setopt(m_curl, CURLOPT_READDATA, &arrayInfo);
     /* 设置上传文件的大小 */
-    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)arrayInfo.size);
+    curl_easy_setopt(m_curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)arrayInfo.size);
     /* 设置超时时间 */
     // curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
-    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
+    curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT, timeout);
     /* 设置进度回调函数 */
-    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
-    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, nullptr);
+    curl_easy_setopt(m_curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
+    curl_easy_setopt(m_curl, CURLOPT_XFERINFODATA, nullptr);
     /* 启用下载进度回调函数 */
-    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+    curl_easy_setopt(m_curl, CURLOPT_NOPROGRESS, 0L);
 
     // 禁用被动模式(如果需要)
-    curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_FTP_USE_EPSV, 1L);
     if(m_enableCurlDebug)
     {
         /* 启用调试信息 */
-        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+        curl_easy_setopt(m_curl, CURLOPT_VERBOSE, 1L);
     }
     /* 启用持久连接 */
-    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
+    curl_easy_setopt(m_curl, CURLOPT_TCP_KEEPALIVE, 1L);
     /* 发送请求 */
-    CURLcode res = curl_easy_perform(curl);
-    bool result = true;
-    if(res != CURLE_OK)
+    bool ret = performCurl(m_curl);
+    if(!ret)
     {
-        SPDLOG_ERROR("Upload file failed, error code: {} ,{}", (int)res, curl_easy_strerror(res));
-        SPDLOG_ERROR("Url = {}", ftpUrl);
-        result = false;
+        SPDLOG_ERROR("Upload file failed, Url = {}", ftpUrl);
     }
     /* 关闭文件,清理curl */
-    curl_easy_cleanup(curl);
+    // curl_easy_cleanup(curl);
     /* 打印一个换行符 */
     printf("\n");
 
-    return result;
+    return ret;
 }
 
 
@@ -1149,11 +1130,7 @@ bool CurlFtp::listAll(CURL* curl, std::string dir, std::vector<CF_FileInfo>& fil
         SPDLOG_ERROR("IP is empty");
         return false;
     }
-    if(curl == nullptr)
-    {
-        SPDLOG_ERROR("curl is nullptr");
-        return false;
-    }
+
     bool result = false;
     std::string strSrc;
     /* 先设置FTP地址 */
@@ -1175,19 +1152,19 @@ bool CurlFtp::listAll(CURL* curl, std::string dir, std::vector<CF_FileInfo>& fil
     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
 
-    // 禁用被动模式(如果需要)
-    curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 1L);
+    // 禁用被动模式,设置为0是禁用(如果需要)
+    // curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 1L);
     if(m_enableCurlDebug)
     {
         /* 启用调试信息 */
         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
     }
     /* 发送请求 */
-    CURLcode res = curl_easy_perform(curl);
-    if(res != CURLE_OK)
+    // CURLcode res = curl_easy_perform(curl);
+    bool ret = performCurl(curl);
+    if(!ret)
     {
-        SPDLOG_ERROR("Failed to get file list, error code: {} ,{}", (int)res, curl_easy_strerror(res));
-        SPDLOG_ERROR("Url = {}", ftpUrl);
+        SPDLOG_ERROR("Failed to get file listUrl = {}", ftpUrl);
         return false;
     }
     /* 解析字符串 */
@@ -1284,16 +1261,63 @@ bool CurlFtp::performCurl(CURL* curl)
         if(res == CURLE_OK)
         {
             return true;
-        }else
+        } 
+        else if (res == CURLE_LOGIN_DENIED) 
+        {
+            SPDLOG_ERROR("Login failed, error code: {} ,{}", (int)res, curl_easy_strerror(res));
+            /* 设置用户名和密码 */
+            curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
+            curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
+        } 
+        else
         {
             SPDLOG_ERROR("Perform curl failed, error code: {} ,{}", (int)res, curl_easy_strerror(res));
-            SPDLOG_ERROR("Retry times: {}", 3 - retry);
-            retry--;
+            SPDLOG_ERROR("Retry times: {}", 4 - retry);
         }
+        retry--;
     }
 
     return false;
 }
 
+/* 重置curl设置 */
+bool CurlFtp::resetCurl(CURL* curl)
+{
+    if(m_curl == nullptr)
+    {
+        m_curl = curl_easy_init();
+        if(m_curl == nullptr)
+        {
+            SPDLOG_ERROR("curl init failed !");
+            return false;
+        }
+    }else {
+        curl_easy_reset(m_curl);
+    }
+    return true;
+}
+
+/* 设置sftp,如果是sftp就设置 */
+bool CurlFtp::setSftp(CURL* curl)
+{
+    /* 判断是否是SFTP */
+    if(m_isSftp)
+    {
+        /* 判断是否需要设置CA证书 */
+        if(m_isIgnoreSSLCert)
+        {
+            /* 忽略证书验证 */
+            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+            /* 忽略主机名验证 */
+            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+        } else
+        {
+            /* 设置CA证书 */
+            curl_easy_setopt(curl, CURLOPT_CAINFO, m_caCertFile.c_str());
+        }
+    }
+    return true;
+}
+
 
 

+ 5 - 0
common/CurlFtp/CurlFtp.h

@@ -78,11 +78,16 @@ private:
     bool checkLocalDir(const std::string& localDir);
     /* 执行curl,添加重试机制 */
     bool performCurl(CURL* curl);
+    /* 重置curl设置 */
+    inline bool resetCurl(CURL* curl);
+    /* 设置sftp,如果是sftp就设置 */
+    inline bool setSftp(CURL* curl);
 
 private:
     std::mutex m_mutexCurl;                 /* curl互斥锁 */
     std::string m_currentDir;               /* 当前目录 */
 
+    CURL* m_curl = nullptr;                 /* curl句柄 */
     std::string m_IP;                       /* IP */
     int m_port = 21;                        /* 端口 */
     std::string m_ftpUrl;                   /* ftpUrl */