Files
geomative/GeomativeStudio/cpp/Tools/FileTransfer_crul.cpp
T
coco df489d5640 a
2026-07-03 16:05:30 +08:00

493 lines
13 KiB
C++

// DownloadFile.cpp: implementation of the CFileTransfer_crul class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FileTransfer_crul.h"
#include "Constant.h"
#include "CtrlProtocolDef.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern SYSTEMTIME g_sysCurTime;
extern int g_iUILanguage;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
/////////////////////////////z/////////////////////////////////////////
DOUBLE CFileTransfer_crul::m_RecvFileSize = 0;
int CFileTransfer_crul::m_nWriteFileSize = 0;
CFileTransfer_crul::CFileTransfer_crul()
{
//curl_global_init(CURL_GLOBAL_ALL);
m_pCrEasyHandl = NULL;
m_pCrPuteasyHandl = NULL;
//m_nWriteFileSize = 0;
m_strSavePath = _T("");
m_strSaveName = _T("");
m_strUrl = _T("");
m_lTotalRecvFileSize = 0;
m_lCurRecvSize = 0;
// m_pDownLoadFile = NULL;
m_nTimeOut = 120;
m_bIsNeedProgress = false;
m_bIsNeedErrInfo = false;
m_bIsGobalInitial = false;
m_pLog = NULL;
m_bIsHttpsFlag = false;
m_bIsSSLCertify = false;
InitalLogInfo();
}
CFileTransfer_crul::~CFileTransfer_crul()
{
// curl_easy_cleanup(m_pCrEasyHandl);
curl_global_cleanup();
m_bIsGobalInitial = false;
if (m_pLog)
{
fclose(m_pLog);
m_pLog = NULL;
}
}
void CFileTransfer_crul::InitalLogInfo()
{
if (NULL == m_pLog)
{
m_pLog = fopen("LOG\\filetrans_crul_log.txt","ab+");
if (NULL == m_pLog)
{
if (LANG_ZHCN == g_iUILanguage)
AfxMessageBox(_T("打开 filetrans_crul_log.txt 失败!!"));
else
MessageBoxEx(NULL, _T("Open filetrans_crul_log.txt failed!!!"), STRING_MESSAGEBOXEX_TITLE, MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
}
}
}
bool CFileTransfer_crul::Inital()
{
if (m_bIsGobalInitial)
{
return true;
}
CURLcode res;
res = curl_global_init(CURL_GLOBAL_WIN32);
CString strTmp = _T("");
if (CURLE_OK != res)
{
strTmp.Format(_T("[%d] global Inital crul failed! error_code = %d"),__LINE__, res);
PrintLog(strTmp);
return false;
}
if (LIBCURL_VERSION_NUM < 0x072000)
{
strTmp.Format(_T("[%d] libcrul version is low!!!, version_num = %d"), __LINE__, LIBCURL_VERSION_NUM);
PrintLog(strTmp);
return false;
}
m_bIsGobalInitial = true;
return true;
}
void CFileTransfer_crul::UnInital()
{
curl_global_cleanup();
}
void CFileTransfer_crul::SetOption(EnOptFlag enFlag, CString strInfo, bool bFlag)
{
switch (enFlag)
{
case OPT_URL_ADDRESS:
m_strUrl = strInfo;
break;
case OPT_DOWNLOAD_PATH:
m_strSavePath = strInfo;
break;
case OPT_DOWNLOAD_NAME:
m_strSaveName = strInfo;
break;
case OPT_TIMEOUT:
m_nTimeOut = atoi(strInfo.GetBuffer(0));
break;
case OPT_NEED_PROGRESS:
m_bIsNeedProgress = bFlag;
break;
case OPT_NEED_ERRORINFO:
m_bIsNeedErrInfo = bFlag;
break;
case OPT_HTTPS_ACCESS:
m_bIsHttpsFlag = bFlag;
break;
case OPT_SSL_CERTIFY:
m_bIsSSLCertify = bFlag;
break;
default:
CString strTmp = _T("");
strTmp.Format(_T("[%d] Unknow Opt_Flag, value = %d"), __LINE__, enFlag);
PrintLog(strTmp);
break;
}
return ;
}
bool CFileTransfer_crul::DownloadFile()
{
CString strTmp = _T("");
if (m_strUrl.IsEmpty() || m_strSaveName.IsEmpty() || m_strSavePath.IsEmpty())
{
strTmp.Format(_T("[%d] Url or SaveFileInfo is not set!!!"),__LINE__);
PrintLog(strTmp);
return false;
}
if (m_bIsHttpsFlag && m_bIsSSLCertify)
{
if (LANG_ZHCN == g_iUILanguage)
AfxMessageBox(_T("不支持协议https的ssl认证。"));
else
MessageBoxEx(NULL, _T("Ssl certify of protocol https is not supported."), STRING_MESSAGEBOXEX_TITLE, MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
return false;
}
if (!GetUrlResConValild())
{
if (LANG_ZHCN == g_iUILanguage)
AfxMessageBox(_T("下载文件失败!!"));
else
MessageBoxEx(NULL, _T("DownLoad file failed!!!"), STRING_MESSAGEBOXEX_TITLE, MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
return false;
}
FILE *pFile = NULL;
CString strDownLoadFile = m_strSavePath + m_strSaveName;
pFile = fopen(strDownLoadFile.GetBuffer(0), "wb+");
if (NULL == pFile)
{
strTmp.Format(_T("[%d] open file failed, errorno = %d, file_path = %s"), __LINE__, GetLastError(), strDownLoadFile.GetBuffer(0));
//AfxMessageBox(strTmp.GetBuffer(0));
PrintLog(strTmp);
return false;
}
m_pCrEasyHandl = curl_easy_init();
if (NULL == m_pCrEasyHandl)
{
strTmp.Format(_T("[%d] curl_easy_init failed!!!"), __LINE__);
PrintLog(strTmp);
return false;
}
STWriteInfo stWriteInfo;
stWriteInfo.pFile = pFile;
stWriteInfo.pFileTrans = (void *)this;
char chErrorInfo[CURL_ERROR_SIZE];
memset(chErrorInfo, 0, sizeof(chErrorInfo));
long nOnOff = (true == m_bIsNeedProgress) ? 0 : 1;
// struct curl_slist *headers=NULL;
// headers = curl_slist_append(headers, "Pragma:no-cache");
// headers = curl_slist_append(headers, "Cache-Control:max-age=0");
// headers = curl_slist_append(headers, "Cache-Control: no-cache");
// headers = curl_slist_append(headers, "Cache-Control: max-age=0");
// headers = curl_slist_append(headers, "Cache-Control: no-store");
CURLcode resSetOpt;
//设置可选项
// resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_HTTPHEADER, headers);
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_URL, m_strUrl.GetBuffer(0));
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_TIMEOUT, m_nTimeOut);
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_WRITEDATA, &stWriteInfo);
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_WRITEFUNCTION, &WriteToFile);
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_NOPROGRESS, nOnOff);
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_ERRORBUFFER, chErrorInfo);//设置错误信息
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_VERBOSE, 1);
if (m_bIsNeedProgress)
{
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_XFERINFOFUNCTION, xferinfo);
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_XFERINFODATA, this);
}
//取消SSL验证
if (m_bIsHttpsFlag && !m_bIsSSLCertify)
{
resSetOpt = curl_easy_setopt(m_pCrEasyHandl, CURLOPT_SSL_VERIFYPEER, 0L);
}
strTmp.Empty();
strTmp.Format(_T("[%d] url = %s, timeout = %d, show_progress = %d"), __LINE__,
m_strUrl.GetBuffer(0), m_nTimeOut, m_bIsNeedProgress);
PrintLog(strTmp);
//show progress
m_nWriteFileSize = 0;
CURLcode resCode = curl_easy_perform(m_pCrEasyHandl);
// curl_slist_free_all(headers);
if (CURLE_OK != resCode)
{
strTmp.Empty();
if (LANG_ZHCN == g_iUILanguage)
{
strTmp.Format(_T("下载文件失败,请检查网络环境."));
AfxMessageBox(strTmp.GetBuffer(0));
}
else
{
strTmp.Format(_T("Download failed, please check the network environment."));
MessageBoxEx(NULL, strTmp, STRING_MESSAGEBOXEX_TITLE, MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
}
strTmp.Empty();
strTmp.Format(_T("[%d]Download failed, excute easy_perform failed!!!, return_code = %d, error_msg = %s"), __LINE__, resCode, chErrorInfo);
PrintLog(strTmp);
}
// else
// {
// if (0 == m_nWriteFileSize)
// {
// // AfxMessageBox(_T("download file failed!"));
// strTmp.Empty();
// strTmp.Format(_T("[%d] excute easy_perform ok,but Dst_File_Length is 0!"),__LINE__);
// PrintLog(strTmp);
// resCode = CURLE_REMOTE_FILE_NOT_FOUND;;
//
//
// }
// }
fclose(pFile);
pFile = NULL;
curl_easy_cleanup(m_pCrEasyHandl);
return (CURLE_OK == resCode) ? true : false;
}
size_t CFileTransfer_crul::WriteToFile(void *ptr, size_t size, size_t nmemb, void *userp)
{
STWriteInfo* pWriteInfo = (STWriteInfo*)userp;
size_t szRes = fwrite(ptr, size, nmemb, pWriteInfo->pFile);
m_nWriteFileSize += szRes;
if (szRes == size * nmemb)
{
return szRes;
}
else
{
CString strTmp = _T("");
CFileTransfer_crul* pFileTrans = (CFileTransfer_crul*)pWriteInfo->pFileTrans;
if (0 == szRes)
{
strTmp.Format(_T("[%d] write File failed!, FileName = %s, errorno = %d"),__LINE__,
pFileTrans->m_strSaveName.GetBuffer(0), GetLastError());
}
else
{
strTmp.Format(_T("[%d] writed bytes is not equal to received bytes! FileName = %s, Writed_number = %d, Received_number = %d"),
__LINE__, pFileTrans->m_strSaveName.GetBuffer(0), szRes, size * nmemb);
}
pFileTrans->PrintLog(strTmp);
return szRes;
}
}
DOUBLE CFileTransfer_crul::GetFileSize()
{
CURL *curl;
CURLcode res;
DOUBLE FileSize=0;
curl = curl_easy_init();
if(curl)
{
// struct curl_slist *headers=NULL;
// headers = curl_slist_append(headers, "Cache-Control: no-cache");
// headers = curl_slist_append(headers, "Cache-Control: max-age=0");
// headers = curl_slist_append(headers, "Cache-Control: no-store");
// curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, m_strUrl);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 120);
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
res = curl_easy_perform(curl);
// curl_slist_free_all(headers);
if(res != CURLE_OK)
return FALSE;
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &FileSize);
if(res != CURLE_OK)
return FALSE;
curl_easy_cleanup(curl);
}
return FileSize;
}
bool CFileTransfer_crul::GetUrlResConValild()
{
CURL *curl;
CURLcode res;
DOUBLE FileSize=0;
curl = curl_easy_init();
CString strLog = _T("");
int iTest = 1;
if(curl)
{
char chErrInfo[CURL_ERROR_SIZE];
memset(chErrInfo, 0, sizeof(chErrInfo));
// struct curl_slist *headers=NULL;
// headers = curl_slist_append(headers, "Cache-Control: no-cache");
// headers = curl_slist_append(headers, "Cache-Control: max-age=0");
// headers = curl_slist_append(headers, "Cache-Control: no-store");
// curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, m_strUrl);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &iTest);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteFuncForUrlTest);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, chErrInfo);//设置错误信息
//为了防止偶尔报无法解析网站的问题,在这里只使用IPV4进行DNS的解析
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
//temp 临时版本,添加重试功能,次数为3
int iTimes = 3;
while(iTimes > 0)
{
res = curl_easy_perform(curl);
if (res == CURLE_OK)
break;
iTimes--;
}
if(res != CURLE_OK)
{
//此时如果错误原因是Failed writing body,代表回调函数返回值和回调函数传入的大小不一致,则会引起中断,并报错
//如果没有设置回调函数,则会用默认的回调函数代替,默认的回调函数是将数据写入到标准的输入出里去
strLog.Format(_T("[%d]GetUrlResContent::excute curl_perform 3 times failed!,errmsg = %s,url = %s"),__LINE__ ,chErrInfo,m_strUrl);
PrintLog(strLog);
curl_easy_cleanup(curl);
return false;
}
long retCode = 0;
res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE , &retCode);
//如果返回200,则说明正确的找到了网址
if ((CURLE_OK == res) && (200 == retCode))
{
curl_easy_cleanup(curl);
return true;
}
strLog.Format(_T("[%d]GetUrlResConValild::get_crul_info failed, resCode = %d, ResponseCode = %d, ErrorMSg = %s, url = %s"),
__LINE__, res, retCode, chErrInfo, m_strUrl);
PrintLog(strLog);
curl_easy_cleanup(curl);
return false;
}
strLog.Format(_T("[%d]GetUrlResConValild:: crul inital failed!!!"),__LINE__);
PrintLog(strLog);
return false;
}
VOID CFileTransfer_crul::SetRecvSize(size_t f_size)
{
m_RecvFileSize += f_size;
}
// BOOL CFileTransfer_crul::GetFileList(char *f_buff)
// {
// CURL *curl;
// CURLcode res;
// DOUBLE FileSize;
//
// curl = curl_easy_init();
//
// if(curl)
// {
// curl_easy_setopt(curl, CURLOPT_URL, m_strUrl);
// curl_easy_setopt(curl, CURLOPT_TIMEOUT, 120);
// curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)f_buff);
// curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteToBuff);
//
// res = curl_easy_perform(curl);
//
// if(res != CURLE_OK)
// return FALSE;
//
// curl_easy_cleanup(curl);
//
// }
//}
size_t CFileTransfer_crul::WriteToBuff(void *ptr, size_t size, size_t nmemb, void *userp)
{
memcpy((char *)userp, ptr, (size * nmemb));
return size * nmemb;
}
int CFileTransfer_crul::xferinfo(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
CFileTransfer_crul* pFileTrans = (CFileTransfer_crul*)p;
pFileTrans->m_lTotalRecvFileSize = dltotal;
pFileTrans->m_lCurRecvSize = dlnow;
return 0;
}
void CFileTransfer_crul::PrintLog(CString strLog)
{
if (NULL == m_pLog)
{
MessageBox(NULL, "can't write fileTransfer_crul_log, log File point is NULL", "LOG_ERROR", MB_OK);
return;
}
CString strOutPut = _T("");
strOutPut.Format(_T("%04d-%02d-%02d %02d:%02d:%02d.%03d %s \r\n"),g_sysCurTime.wYear, g_sysCurTime.wMonth, g_sysCurTime.wDay,
g_sysCurTime.wHour, g_sysCurTime.wMinute, g_sysCurTime.wSecond, g_sysCurTime.wMilliseconds, strLog.GetBuffer(0));
fwrite(strOutPut.GetBuffer(0), 1, strOutPut.GetLength(), m_pLog);
fflush(m_pLog);
}
size_t CFileTransfer_crul::WriteFuncForUrlTest(void *ptr, size_t size, size_t nmemb, void *userp)
{
return size * nmemb;
}