#include "lhfileremote.h" #include #include #include #include #include "curl.h" #include "Common/External/Core/WNetUtility/wnetutility.h" long* g_pPos = NULL; qint64 g_llTotal =0; qint64 g_llTotalWrite=0; //2016.12.8 url 解码 #define IsHexNum(c) ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) QString UrlDecode(const QString& url) { return QUrl::toPercentEncoding(url); } QString UrlEncodeEx(const QString& strToEncode) { return QUrl::fromPercentEncoding(strToEncode.toUtf8()); } CLHFileRemote::CLHFileRemote(void) { m_btCurlPASV = 0; } CLHFileRemote::~CLHFileRemote(void) { } bool CLHFileRemote::LoginServer(const QString& lpszPath, const QString& lpszUser, const QString& lpszPwd) { QString strPath(lpszPath); strPath.replace("\\\\", ";;"); QStringList ayRet = strPath.split("\\"); if( !ayRet.isEmpty() ) { strPath = ayRet.at(0); } strPath.replace(";;", "\\\\"); bool bNetWork = (strPath.indexOf("\\\\")==0); if( bNetWork && lpszUser.size() > 0 ) { // 网络路径 if(QFile::exists(lpszPath)) { return true; } bool bRet = false; #ifdef Q_OS_WIN bRet = WNetUtility::WNetTryConnect(lpszPwd, lpszUser, lpszPwd); #endif return bRet ? true : false; } else { // 本机路径 if( QFile::exists(lpszPath) ) { return false; } return true; } } //UTF8 TO GBK //QString CLHFileRemote::UTF8ToGBK(QString str) //{ // int len=MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)str, -1, NULL,0); // WCHAR * wszGBK = new WCHAR[len+1]; // memset(wszGBK, 0, len * 2 + 2); // MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)str, -1, wszGBK, len); // len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); // char *szGBK=new char[len + 1]; // memset(szGBK, 0, len + 1); // WideCharToMultiByte (CP_ACP, 0, wszGBK, -1, szGBK, len, NULL,NULL); // QString strResult = szGBK; // delete[] szGBK; // delete[] wszGBK; // return strResult; //} //GBK TO UTF8 //QString CLHFileRemote::GBKToUTF8(QString& str) //{ // int len=MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)str, -1, NULL,0); // WCHAR * wszUtf8 = new WCHAR[len*2]; // memset(wszUtf8, 0, len * 4); // MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)str, -1, wszUtf8, len); // len = WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, NULL, 0, NULL, NULL); // char *szUtf8=new char[len *2]; // memset(szUtf8, 0, len *2); // WideCharToMultiByte (CP_UTF8, 0, wszUtf8, -1, szUtf8, len, NULL,NULL); // QString strResult = szUtf8; // delete[] szUtf8; // delete[] wszUtf8; // return strResult; //} size_t write_data_post( void *buffer, size_t size, size_t nmemb, void *user_p ) { Q_UNUSED(size); SUsreDate* ud = (SUsreDate*)user_p; if(ud) { CLHFileRemote* pObject = (CLHFileRemote*)ud->pOwner; ud->buffer = (char*)buffer; ud->buffersize = nmemb; return pObject->curl_ReceivePost(ud); } return 0; } static size_t throw_away(void *ptr, size_t size,size_t nmemb,void *data) { (void)ptr; (void)data; return (size_t)(size * nmemb); } size_t read_data( void *buffer, size_t size, size_t nmemb, void *user_p ) { return fread(buffer, size, nmemb, (FILE *)user_p); } size_t write_data( void *buffer, size_t size, size_t nmemb, void *user_p ) { SUpDownData* pData = (SUpDownData*)user_p; if( pData) { if( pData->llTotal>0) *(pData->nProgress) = ( (pData->llBaseSize + pData->llCurrent)*100)/pData->llTotal; size_t nSize=size*nmemb; if( pData->pFile) { nSize = fwrite(buffer, size, nmemb, (FILE *)pData->pFile); } else { if( pData->pBuffer) memcpy(pData->pBuffer+pData->llCurrent,buffer,nSize); } pData->llCurrent += size*nmemb; return nSize; } return 0; } size_t CLHFileRemote::curl_ReceivePost(SUsreDate* ud) { if( ud ) { char* pBuffer = new char[ud->buffersize+1]; memset(pBuffer,0, ud->buffersize+1 ); memcpy(pBuffer,ud->buffer,ud->buffersize); QString strReceive(pBuffer); QString strGBK = strReceive;// utf8->gbk? delete[] pBuffer; pBuffer =NULL; pBuffer = new char [strGBK.length()+1]; memset(pBuffer,0, strGBK.length()+1 ); sprintf(pBuffer,"%s",strGBK.toStdString().c_str()); if( strGBK.length() >100) m_strErrorPostContent = strGBK.left(100); else m_strErrorPostContent = strGBK; int size = ud->buffersize; delete ud; ud = NULL; return size; } return 0; } bool CLHFileRemote::curl_Post(const QString& strUrl,const QString& strContent) { SUsreDate* ud = new SUsreDate; ud->pOwner = this; ud->strContent = strContent; ud->btRequestType = 0; m_strErrorPostContent = ""; CURL *curl_easy_handle = curl_easy_init(); if (NULL == curl_easy_handle) { m_strError = "CURL初始化失败"; return false; } // 将路径转换为url编码格式 QString strPath = strUrl; strPath = UrlDecode(strPath); strPath = UrlEncodeEx(strPath); //strContent = strContent;// gbk->utf8 int nLen = strContent.length()+1; char* szContent = new char[nLen]; memset(szContent,0,nLen); sprintf(szContent,"%s",strContent.toStdString().c_str()); //设置URL curl_easy_setopt(curl_easy_handle, CURLOPT_URL, strPath.toStdString().c_str()); // 设置http发送的内容类型为JSON curl_slist *plist = curl_slist_append(NULL,"Content-Type:application/x-www-form-urlencoded;charset=utf-8"); //text/html; //Content-Type:application/json; curl_easy_setopt(curl_easy_handle, CURLOPT_HTTPHEADER, plist); // 设置http发送的内容 curl_easy_setopt(curl_easy_handle, CURLOPT_POSTFIELDS,szContent); //设置返回数据 curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEFUNCTION,write_data_post); //对返回的数据进行操作的函数地址 curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEDATA,ud); //这是write_data的第四个参数值 //设置其他 curl_easy_setopt(curl_easy_handle, CURLOPT_TIMEOUT, 15); curl_easy_setopt(curl_easy_handle, CURLOPT_TCP_KEEPALIVE, 1); // 执行创建操作 CURLcode res = curl_easy_perform(curl_easy_handle); if (res != CURLE_OK) { if( res != CURLE_WRITE_ERROR) { m_strError = QString("CURL执行失败(%1),%2").arg(res).arg(curl_easy_strerror(res)); } curl_easy_cleanup(curl_easy_handle); return false; } curl_easy_cleanup(curl_easy_handle); return true; } bool CLHFileRemote::curl_IsFileExist(const QString& strRemoteFile) { CURL *curl; CURLcode res; long filetime = -1; double filesize = 0.0; curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, strRemoteFile.toStdString().c_str()); curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, throw_away); curl_easy_setopt(curl, CURLOPT_HEADER, 0L); res = curl_easy_perform(curl); if(CURLE_OK == res) { res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime); if((CURLE_OK == res) && (filetime >= 0)) { //time_t file_time = (time_t)filetime; return true; } res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize); if((CURLE_OK == res) && (filesize>0.0)) { return true; } } else { fprintf(stderr, "curl told us %d\n", res); } curl_easy_cleanup(curl); } return false; } /** * @brief FTP上传时,root用户貌似不行 2024-01-06 * @param szLocalFile * @param szRemoteFile * @param szUser * @param szPwd * @return */ bool CLHFileRemote::curl_Upload(const char* szLocalFile, const char* szRemoteFile,const char* szUser,const char* szPwd) { // 获取curl句柄 CURL *curl_easy_handle = curl_easy_init(); if (NULL == curl_easy_handle) { m_strError = "CURL初始化失败"; return false; } // 打开本地文件 FILE *fp = NULL; fp = fopen(szLocalFile, "ab+"); if (NULL == fp) { curl_easy_cleanup(curl_easy_handle); m_strError = QString("上载失败,打开本地文件失败:%1").arg(szLocalFile); return false; } // 获取文件大小 fseek(fp, 0, SEEK_END); long file_size = ftell(fp); rewind(fp); // 将路径转换为url编码格式,ftp模式是不需要的(2024.01.06) QString strPath(szRemoteFile); strPath = UrlDecode(strPath); if(strlen(szUser)>0) { curl_easy_setopt(curl_easy_handle, CURLOPT_USERNAME, szUser); curl_easy_setopt(curl_easy_handle, CURLOPT_PASSWORD, szPwd); } if( strPath.left(4).compare("http", Qt::CaseInsensitive) == 0 ) { curl_easy_setopt(curl_easy_handle, CURLOPT_POST, 1L); curl_easy_setopt(curl_easy_handle, CURLOPT_URL, strPath.toLocal8Bit().data()); curl_easy_setopt(curl_easy_handle, CURLOPT_READFUNCTION, &read_data); curl_easy_setopt(curl_easy_handle, CURLOPT_READDATA, fp); curl_easy_setopt(curl_easy_handle, CURLOPT_FAILONERROR, 1); } else { curl_easy_setopt(curl_easy_handle, CURLOPT_UPLOAD, 1); curl_easy_setopt(curl_easy_handle, CURLOPT_URL, szRemoteFile); curl_easy_setopt(curl_easy_handle, CURLOPT_READFUNCTION, &read_data); curl_easy_setopt(curl_easy_handle, CURLOPT_READDATA, fp); curl_easy_setopt(curl_easy_handle, CURLOPT_INFILESIZE, file_size); curl_easy_setopt(curl_easy_handle, CURLOPT_FAILONERROR, 1); } // 执行上传操作 CURLcode res = curl_easy_perform(curl_easy_handle); // ftp协议返回码 long retcode = 0; curl_easy_getinfo(curl_easy_handle, CURLINFO_RESPONSE_CODE, &retcode); // 释放资源 fclose(fp); curl_easy_cleanup(curl_easy_handle); if (res != CURLE_OK) { m_strError = QString("上载失败,返回码:%1,%2").arg(retcode).arg(res); return false; } return true; } qint64 CLHFileRemote::curl_GetFileLength(const char* szRemoteFile,const char* szUser,const char* szPwd) { // 将路径转换为url编码格式 QString strPath(szRemoteFile); //2017.9.30 //strPath = strPath;// gbk->utf8 strPath = UrlEncodeEx(strPath); if( strPath.left(4).compare("http", Qt::CaseInsensitive) != 0 && strPath.left(3).compare("ftp", Qt::CaseInsensitive) !=0 ) { //qint64 nReadTotal = 0; strPath.replace("/","\\"); LoginServer(strPath.toStdString().c_str(),szUser,szPwd); QFile fStatus(strPath); if( !fStatus.open(QIODevice::ReadOnly)) { return -1; } return fStatus.size(); } // 获取curl句柄 CURL *curl_easy_handle = curl_easy_init(); if (NULL == curl_easy_handle) { m_strError = "CURL初始化失败"; return -1; } if( strPath.left(5).compare("https", Qt::CaseInsensitive) == 0) { //curl_easy_setopt(curl_easy_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); curl_easy_setopt(curl_easy_handle, CURLOPT_SSL_VERIFYPEER, FALSE); // 跳过证书检查 curl_easy_setopt(curl_easy_handle, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在 } // 设置curl_easy_handle属性 if(strlen(szUser)>0) { curl_easy_setopt(curl_easy_handle, CURLOPT_USERNAME, szUser); curl_easy_setopt(curl_easy_handle, CURLOPT_PASSWORD, szPwd); } curl_easy_setopt(curl_easy_handle, CURLOPT_URL, strPath.toStdString().c_str()); curl_easy_setopt(curl_easy_handle, CURLOPT_NOBODY, 1L); curl_easy_setopt(curl_easy_handle, CURLOPT_FILETIME, 1L); curl_easy_setopt(curl_easy_handle, CURLOPT_HEADERFUNCTION, throw_away); curl_easy_setopt(curl_easy_handle, CURLOPT_HEADER, 0L); double filesize = 0.0; if (curl_easy_perform(curl_easy_handle) == CURLE_OK) { curl_easy_getinfo(curl_easy_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize); } else { curl_easy_cleanup(curl_easy_handle); return -1; } curl_easy_cleanup(curl_easy_handle); return filesize; } qint64 CLHFileRemote::curl_Read(char* pBuffer,const char* szRemoteFile,const char* szUser,const char* szPwd,LONGLONG llStart,LONGLONG llSize,long& nProgress) { if( pBuffer == NULL) return -1; // 将路径转换为url编码格式 QString strPath(szRemoteFile); //2017.9.30 //strPath = strPath;// gbk->utf8 strPath = UrlEncodeEx(strPath); if( strPath.left(4).compare("http", Qt::CaseInsensitive) != 0 && strPath.left(3).compare("ftp", Qt::CaseInsensitive) !=0 ) { qint64 nReadTotal = 0; strPath.replace("/","\\"); LoginServer(strPath.toStdString().c_str(),szUser,szPwd); try { QFile fRemote(strPath); if( fRemote.open(QIODevice::ReadOnly) == false ) { m_strError = QString("打开文件失败(%1),%2").arg(GetLastError(), strPath); return false; } qint64 nSize = fRemote.size(); if( llStart>=0 && llSize>0 ) { nSize = llSize; } fRemote.seek(llStart); int nBufferSize = 76800; while( nSize>0 ) { if( nBufferSize > nSize ) nBufferSize = nSize; int nRead = fRemote.read(pBuffer+nReadTotal,nBufferSize); if( nRead <= 0 ) { break; } nSize -= nRead; nReadTotal += nRead; nProgress = (nReadTotal*100)/llSize; } fRemote.close(); } catch (...) { } return nReadTotal; } // 获取curl句柄 CURL *curl_easy_handle = curl_easy_init(); if (NULL == curl_easy_handle) { m_strError = "CURL初始化失败"; return -1; } if( strPath.left(5).compare("https", Qt::CaseInsensitive) == 0) { //curl_easy_setopt(curl_easy_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); curl_easy_setopt(curl_easy_handle, CURLOPT_SSL_VERIFYPEER, FALSE); // 跳过证书检查 curl_easy_setopt(curl_easy_handle, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在 } // 设置curl_easy_handle属性 if(strlen(szUser)>0) { curl_easy_setopt(curl_easy_handle, CURLOPT_USERNAME, szUser); curl_easy_setopt(curl_easy_handle, CURLOPT_PASSWORD, szPwd); } SUpDownData* pData = new SUpDownData; if( pData == NULL) { m_strError = QString("内存不足"); return -1; } pData->pBuffer=pBuffer; pData->llCurrent = 0; pData->llTotal =llSize; pData->pFile = NULL; pData->nProgress = &nProgress; pData->llBaseSize = 0; curl_easy_setopt(curl_easy_handle, CURLOPT_URL, strPath.toStdString().c_str()); curl_easy_setopt(curl_easy_handle, CURLOPT_WRITEFUNCTION, &write_data); curl_easy_setopt(curl_easy_handle, CURLOPT_WRITEDATA, pData); curl_easy_setopt(curl_easy_handle, CURLOPT_TIMEOUT,3600);//下载超过60分钟则超时 curl_easy_setopt(curl_easy_handle, CURLOPT_FAILONERROR, 1); if( llStart >= 0 && llSize > 0 ) { //char szRange[128]{0}; // XXX:linux下好像要使用%lld来替换%I64d //sprintf( szRange, "%I64d-%I64d", llStart, llStart + llSize - 1); QString strRange(QString("%1-%2").arg(llStart).arg(llStart + llSize - 1)); curl_easy_setopt(curl_easy_handle, CURLOPT_RANGE, strRange.toStdString().c_str()); } if( m_btCurlPASV == 1 ) curl_easy_setopt(curl_easy_handle, CURLOPT_FTP_USE_EPSV,0); //EPSV设置为0,就代表启用PASV else curl_easy_setopt(curl_easy_handle, CURLOPT_FTP_USE_EPSV,1); // 执行上传操作 CURLcode res = curl_easy_perform(curl_easy_handle); if( res != CURLE_OK) { if( m_btCurlPASV == 1 ) curl_easy_setopt(curl_easy_handle, CURLOPT_FTP_USE_EPSV,1); else curl_easy_setopt(curl_easy_handle, CURLOPT_FTP_USE_EPSV,0); //EPSV设置为0,就代表启用PASV res = curl_easy_perform(curl_easy_handle); if( res == CURLE_OK) { if(m_btCurlPASV ==1) m_btCurlPASV = 0; else m_btCurlPASV = 1; } } long retcode = 0; CURLcode code = curl_easy_getinfo(curl_easy_handle, CURLINFO_RESPONSE_CODE, &retcode); if (res != CURLE_OK) { m_strError = QString("源文件下载失败,返回码:%1(%2),%3").arg(res).arg(retcode).arg(curl_easy_strerror(res)); return -1; } // 释放资源 curl_easy_cleanup(curl_easy_handle); int nReturn = pData->llCurrent; if( pData) { delete pData; pData = NULL; } if(CURLE_OK == res && retcode>=200 && retcode<300) { } else { m_strError = QString("源文件可能不存在,返回码:%1(%2),%3").arg(code).arg(retcode).arg(curl_easy_strerror(res) ); return -1; } return nReturn; } bool CLHFileRemote::curl_Download(const char* szLocalFile, const char* szRemoteFile,const char* szUser,const char* szPwd,qint64 llStart,qint64 llSize,bool bAppendFile,qint64 nTotal,qint64 nBaseSize,long& nProgress) { // 打开本地文件 QFile fp(szLocalFile); if( bAppendFile ) { fp.open(QIODevice::Append); } else { QFile::remove(szLocalFile); fp.open(QIODevice::WriteOnly); } if (!fp.isOpen()) { qInfo() << fp.errorString(); m_strError = QString("打开本地文件失败:%1").arg(szLocalFile); return false; } // 获取文件大小 //fseek(fp, 0, SEEK_END); //qint64 file_size = (qint64)ftell(fp); //rewind(fp); // 将路径转换为url编码格式 QString strPath(szRemoteFile); //2017.9.30 //strPath = strPath;// gbk->utf8 strPath = UrlEncodeEx(strPath); if( strPath.left(4).compare("http", Qt::CaseInsensitive) != 0 && strPath.left(3).compare("ftp", Qt::CaseInsensitive) !=0 ) { strPath.replace("/","\\"); LoginServer(strPath.toStdString().c_str(),szUser,szPwd); try { QFile fRemote(strPath); if( fRemote.open(QIODevice::ReadOnly) == false ) { fp.close(); QFile::remove(szLocalFile); m_strError = QString("打开文件失败(%1),%2").arg(GetLastError()).arg(strPath); return false; } qint64 nSize = fRemote.size(); if( llStart>=0 && llSize>0 ) { nSize = llSize; } fRemote.seek(llStart); int nBufferSize = 76800; char* pBuffer = new char[nBufferSize]{0}; if(pBuffer == NULL) { fp.close(); QFile::remove(szLocalFile); m_strError = QString("内存不足"); return false; } qint64 nReadTotal = 0; memset(pBuffer,0,nBufferSize); while( nSize>0 ) { if( nSize < nBufferSize ) nBufferSize = nSize; int nRead = fRemote.read(pBuffer,nBufferSize); if( nRead <= 0 ) { break; } fp.write(pBuffer, nRead); nSize -= nRead; nReadTotal += nRead; if( nTotal > 0) nProgress = (( nBaseSize + nReadTotal)*100)/nTotal; } fRemote.close(); fp.close(); delete []pBuffer; pBuffer = nullptr; } catch (...) { } return true; } // 获取curl句柄 CURL *curl_easy_handle = curl_easy_init(); if (NULL == curl_easy_handle) { fp.close(); QFile::remove(szLocalFile); m_strError = "CURL初始化失败"; return false; } if( strPath.left(5).compare("https", Qt::CaseInsensitive) == 0) { //curl_easy_setopt(curl_easy_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); curl_easy_setopt(curl_easy_handle, CURLOPT_SSL_VERIFYPEER, FALSE); // 跳过证书检查 curl_easy_setopt(curl_easy_handle, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在 } // 设置curl_easy_handle属性 if(strlen(szUser)>0) { curl_easy_setopt(curl_easy_handle, CURLOPT_USERNAME, szUser); curl_easy_setopt(curl_easy_handle, CURLOPT_PASSWORD, szPwd); } fp.close(); FILE* ffp = fopen(szLocalFile, "ab+"); if (NULL == ffp) { return false; } SUpDownData* pData = new SUpDownData; if( pData == NULL) { fclose(ffp); QFile::remove(szLocalFile); m_strError = QString("内存不足"); return false; } pData->pBuffer=NULL; pData->llCurrent = 0; pData->llTotal =nTotal; pData->pFile = ffp; pData->nProgress = &nProgress; pData->llBaseSize = nBaseSize; curl_easy_setopt(curl_easy_handle, CURLOPT_URL, strPath.toStdString().c_str()); curl_easy_setopt(curl_easy_handle, CURLOPT_WRITEFUNCTION, &write_data); curl_easy_setopt(curl_easy_handle, CURLOPT_WRITEDATA, pData); curl_easy_setopt(curl_easy_handle, CURLOPT_TIMEOUT,3600);//下载超过60分钟则超时 curl_easy_setopt(curl_easy_handle, CURLOPT_FAILONERROR, 1); if( llStart>=0 && llSize>0 ) { //char szRange[128] ={}; //sprintf( szRange, "%I64d-%I64d", llStart,llStart+llSize-1); QString strRange(QString("%1-%2").arg(llStart).arg(llStart+llSize-1)); curl_easy_setopt(curl_easy_handle, CURLOPT_RANGE, strRange.toStdString().c_str()); } if( m_btCurlPASV == 1 ) curl_easy_setopt(curl_easy_handle, CURLOPT_FTP_USE_EPSV,0); //EPSV设置为0,就代表启用PASV else curl_easy_setopt(curl_easy_handle, CURLOPT_FTP_USE_EPSV,1); // 执行上传操作 CURLcode res = curl_easy_perform(curl_easy_handle); if( res != CURLE_OK) { if( m_btCurlPASV == 1 ) curl_easy_setopt(curl_easy_handle, CURLOPT_FTP_USE_EPSV,1); else curl_easy_setopt(curl_easy_handle, CURLOPT_FTP_USE_EPSV,0); //EPSV设置为0,就代表启用PASV res = curl_easy_perform(curl_easy_handle); if( res == CURLE_OK) { if(m_btCurlPASV ==1) m_btCurlPASV = 0; else m_btCurlPASV = 1; } } long retcode = 0; CURLcode code = curl_easy_getinfo(curl_easy_handle, CURLINFO_RESPONSE_CODE, &retcode); if (res != CURLE_OK) { fclose(ffp); QFile::remove(szLocalFile); m_strError = QString("源文件下载失败,返回码:%1(%2),%3").arg(res).arg(retcode).arg(curl_easy_strerror(res)); return false; } // 释放资源 fclose(ffp); curl_easy_cleanup(curl_easy_handle); if( pData) { delete pData; pData = NULL; } if(CURLE_OK == res && retcode>=200 && retcode<300) { fclose(ffp);// } else { fclose(ffp); QFile::remove(szLocalFile); m_strError = QString("源文件可能不存在,返回码:%1(%2),%3").arg(code).arg(retcode).arg(curl_easy_strerror(res) ); return false; } return true; }