123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756 |
- #include "lhfileremote.h"
- #include <QStringList>
- #include <QFile>
- #include <QUrl>
- #include <QDebug>
- #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;
- }
|