头文件:
#include <string>
#include <iostream>
#include <assert.h>
#include "curl/curl.h"
#include "downloadinterfaceImpl.h"
#pragma comment(lib,"libcurl.lib")
using namespace std;
#define SKIP_PEER_VERIFICATION 1
#pragma once
class CurlDown;
#define TOHEX(x) ((x)>9 ? (x)+55 : (x)+48)
//Curl 下载写文件回调函数
size_t CallBack_WriteFun(void* ptr, size_t size, size_t nmemb, void* stream);
//Curl 下载报文头回调函数
size_t CallBack_Header(char *ptr, size_t size, size_t nmemb, CurlDown* pCurlThis);
//Curl 下载进度 回调函数
size_t CallBack_Progress(void *ptr,double dTotalDown,double dNowDown,double dTotalUpLoad,double dNowUpLoaded);
//Curl 上传文件 回调函数
size_t CallBack_ReadFun(void* ptr, size_t size, size_t nmemb, FILE* userdata);
//Curl 上传文件 回调函数
size_t CallBack_UpHeader(char *ptr, size_t size, size_t nmemb, void* userdata);
//Curl 上传文件 回调函数
size_t CallBack_UpProgress(void *ptr,double dTotalDown,double dNowDown,double dTotalUpLoad,double dNowUpLoaded);
std::string string_To_UTF8(const std::string & str);
void URLEncode(const char* szIn, char** pOut);
//------下载类----------------
class CurlDown
{
private:
string mFileName; // 下载文件名称
bool isStop;
string m_strUrl; //URL
string m_strHeaderBuffer;
public:
~CurlDown();
CurlDown();
CurlDown(CurlDownParam* ptaskpro);
CurlDownParam m_DownLoadParam;
string m_strErrorMsg; //错误信息
string m_strFilePath; //本地存储地址
string m_strBuffer;
CURL* m_pCurl; //curl指针
FILE* m_fpFileHandle; //文件指针
public:
string GetLastErrorMsg(){return m_strErrorMsg;} //错误信息
bool InitCurl(); //初始化,下载之前必须调用此函数
bool UnInitCurl(); //释放,下载之后必须调用此函数
bool BeginDownLoad(); //开始下载
void SetDownLoadPath(); //设置下载路径
void SetDownLoadUrl(tagtaskinfo structDownload);
bool CheckFileFolder(const string& strPra);
unsigned long CheckTaskBreakPoint(); //检查任务断点信息
FILE* GetFileHandle();
std::string GetDestFileName(const string& strPra,bool bContainSuffix = false);//false 包含文件后缀
};
//上传类
class CurlUpload
{
public:
CurlUpload(CurlDownParam* ptaskpro);
~CurlUpload();
bool InitUploadCurl();
CURL* GetCURLHandle(){return m_pUploadCurl;}
string GetUploadFile(){return m_strUpFileName;}
void SetUploadFile();
string GetFileName(const string strFileName);
string GetUploadURL(){return m_strUploadURL;}
void SetUploadURL();
void UploadBegin();
void UnInitCurl();
public:
CurlDownParam m_sUploadParam;
string m_strErrorMsg;
string m_strHeader;
FILE* m_fpFile;
private:
CURL* m_pUploadCurl;
struct curl_httppost* m_pPost;
struct curl_httppost* m_pLast;
struct curl_slist* m_pHeaderList;
string m_strUploadURL;
string m_strUpFileName;
string m_strTargetFileName;
};
#include "TpCurl.h"
#include <stdio.h>
#include <io.h>
#include "downloadinterface.h"
#include "downloadinterfaceImpl.h"
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/convenience.hpp>
#include "LogTool.h"
#include <tchar.h>
#include <atlconv.h>
string g_strVer = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1";
#define FILE_FORMAT "File"
//全局变量动态Token
//curl下载类
//-----------------------------
CurlDown::~CurlDown()
{
m_pCurl = NULL;
if (m_fpFileHandle)
{
fclose(m_fpFileHandle);
m_fpFileHandle = NULL;
}
}
CurlDown::CurlDown()
{
m_strBuffer = "";
m_pCurl = NULL;
m_fpFileHandle = NULL;
}
CurlDown::CurlDown(CurlDownParam* pParam)
{
m_DownLoadParam.pThis = pParam->pThis;
m_DownLoadParam.pNotify = pParam->pNotify;
m_DownLoadParam.task = pParam->task;
m_strFilePath = "";
m_fpFileHandle = NULL;
}
void CurlDown::SetDownLoadUrl(tagtaskinfo structDownload)
{
if (ENDOWNLOAD_FROM_PLAT == structDownload.downloadfrom)
{
string strRsult = structDownload.input.strPatUrl+"/fUpload/fileDownloadServlet?";
char szTemp[16];
sprintf(szTemp, "%lu", (int)structDownload.input.ulStartIndex);
string strStartIndex = szTemp;
string strFileId = "&FILE_ID="+structDownload.input.strFileId;
string strFileName = "&FILE_NAME="+GetDestFileName(structDownload.input.strFileId);
string strEndIndex = "&END_INDEX="+strStartIndex; //断点索引值
string strUserId = "&USER_ID="+structDownload.input.strUserId;
string strConSumerId = "&CONSUMER_ID="+structDownload.input.strToken;
strRsult += strFileName+strEndIndex+strUserId+strConSumerId+strFileId;
m_strUrl = strRsult;
}
else if (ENDOWNLOAD_FROM_CTRL == structDownload.downloadfrom)
{
string strRsult = structDownload.input.strPatUrl;
string strFileId = structDownload.input.strFileId;
strRsult += "/" + strFileId;
m_strUrl = strRsult;
}
else if (ENDOWNLOAD_FROM_SERV == structDownload.downloadfrom)
{
//TODO::
TLOG_INFORMATION(_T("ENDOWNLOAD_FROM_SERV 暂未处理"));
}
}
void CurlDown::SetDownLoadPath()
{
m_strFilePath = m_DownLoadParam.task.input.strFilePath+"/"+m_DownLoadParam.task.input.strFileId;
m_DownLoadParam.task.filefullpath = m_strFilePath;
}
std::string CurlDown::GetDestFileName(const string& strPra,bool bContainSuffix)
{
string strUserName = strPra;
int nName = strPra.find_last_of("/");
int nNameEnd = strPra.find_last_of(".");
if (nName > 0 && nNameEnd > 0)
{
if (bContainSuffix)
return strPra.substr(nName+1,strPra.length()-nName);
return strPra.substr(nName+1,nNameEnd-nName-1);
}
TLOG_INFORMATION(_T("filename == NULL"));
return "";
}
bool CurlDown::CheckFileFolder(const string& strPra)
{
bool bCheckResult = false;
string strPath = strPra;
//获得文件保存全路径,不包含文件名
int nPos = strPath.find_last_of("/");
if (nPos > 0)
{
strPath = strPra.substr(0,nPos);
}
else
{
return bCheckResult;
}
namespace fs = boost::filesystem;
#ifdef WIN32
if (!fs::exists(strPath))
{
bool bflag = fs::create_directories(strPath);
if (!bflag)
{
TLOG_ERROR(_T("createdirectories %s failed"),strPath.c_str());
return bCheckResult;//创建失败
}
}
bCheckResult = true;
#endif
return bCheckResult;
}
unsigned long CurlDown::CheckTaskBreakPoint()
{
//若是断点下载,设置断点位置为本地文件size和传入size的最小值
if (0 != m_DownLoadParam.task.input.ulStartIndex)
{
if(_access(m_strFilePath.c_str(), 0)==0)
{
try
{
FILE* fp = fopen(m_strFilePath.c_str(),"r");
fseek(fp, 0, SEEK_END);
unsigned long ulBreakPoint = ftell(fp);
fclose(fp);
m_DownLoadParam.task.input.ulStartIndex = min(ulBreakPoint,m_DownLoadParam.task.input.ulStartIndex);
m_DownLoadParam.task.output.ulEndIndex = m_DownLoadParam.task.input.ulStartIndex;
}
catch (...)
{
TLOG_ERROR(_T("operate file %s failed"),m_strFilePath.c_str());
}
}
else
{
m_DownLoadParam.task.input.ulStartIndex = 0;
m_DownLoadParam.task.output.ulEndIndex = 0;
}
}
return m_DownLoadParam.task.input.ulStartIndex;
}
FILE* CurlDown::GetFileHandle()
{
try
{
if(_access(m_strFilePath.c_str(), 0)==0) //文件是否存在
{
unsigned long ulPos = CheckTaskBreakPoint();
m_fpFileHandle = fopen(m_strFilePath.c_str(),"rb+");
if (NULL == m_fpFileHandle)
{
m_DownLoadParam.task.output.strRetMsg = "open file failed";
return NULL;
}
if (0 != ulPos)//断点
{
fseek(m_fpFileHandle,ulPos,SEEK_SET);
}
//非断点
}
else //文件不存在
{
m_fpFileHandle = fopen(m_strFilePath.c_str(),"wb");
if (NULL == m_fpFileHandle)
{
m_DownLoadParam.task.output.strRetMsg = "create file failed";
return NULL;
}
}
}
catch (...)
{
TLOG_ERROR(_T("operate file %s failed"),m_strFilePath.c_str());
}
return m_fpFileHandle;
}
bool CurlDown::InitCurl()
{
bool bInitResult = true;
string url = m_strUrl;
string useragent = g_strVer;
curl_global_init(CURL_GLOBAL_ALL);
m_pCurl = curl_easy_init();
if(m_pCurl)
{
curl_easy_setopt(m_pCurl, CURLOPT_URL, url.c_str());
curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, useragent.c_str());
curl_easy_setopt(m_pCurl, CURLOPT_ENCODING, "gzip, deflate");
curl_easy_setopt(m_pCurl, CURLOPT_CONNECTTIMEOUT, 10);//设置连接超时
//int nTOut =curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数。
//if (nTOut <0)
//{
// bInitResult = false;
// m_strErrorMsg = "m_pCurl设置延时失败";
// return bInitResult;
//}
#ifdef SKIP_PEER_VERIFICATION
//跳过服务器SSL验证,不使用CA证书
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
#ifdef SKIP_HOSTNAME_VERFICATION
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
curl_easy_setopt(m_pCurl, CURLOPT_COOKIEFILE, "./cookie.txt");
curl_easy_setopt(m_pCurl, CURLOPT_COOKIEJAR, "./cookie.txt");
/* POST 数据 */
curl_easy_setopt(m_pCurl, CURLOPT_MAXREDIRS, 5);
curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, CallBack_WriteFun);
curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, this);
curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSFUNCTION, CallBack_Progress); //下载进度回调方法
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSDATA, this);
curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L);
curl_easy_setopt(m_pCurl, CURLOPT_HEADERFUNCTION, CallBack_Header);
curl_easy_setopt(m_pCurl, CURLOPT_HEADERDATA, this);
}
return bInitResult;
}
bool CurlDown::BeginDownLoad()
{
bool bDownResult = true;
//设置本地保存路径
SetDownLoadPath();
//检查任务断点信息
CheckTaskBreakPoint();
SetDownLoadUrl(m_DownLoadParam.task);
bDownResult = CheckFileFolder(m_strFilePath);
if (false == bDownResult)
{
m_DownLoadParam.task.output.strRetMsg = "failed to create local folder";
m_DownLoadParam.task.status = ENDOWNLOAD_FAILED;
m_DownLoadParam.pThis->ChangeTaskStatus(m_DownLoadParam.task.taskid,ENDOWNLOAD_FAILED);
m_DownLoadParam.pNotify->OnNotifyStatus(m_DownLoadParam.task);
return bDownResult;
}
if (!GetFileHandle())
{
m_DownLoadParam.task.output.strRetMsg = "faild to write file";
m_DownLoadParam.task.status = ENDOWNLOAD_FAILED;
m_DownLoadParam.pThis->ChangeTaskStatus(m_DownLoadParam.task.taskid,ENDOWNLOAD_FAILED);
m_DownLoadParam.pNotify->OnNotifyStatus(m_DownLoadParam.task);
return false;
}
bDownResult = InitCurl();//初始化Curl库
if (false == bDownResult)
{
if (m_fpFileHandle)
{
fclose(m_fpFileHandle);
m_fpFileHandle = NULL;
}
UnInitCurl();
m_DownLoadParam.task.output.strRetMsg = "faild to init curl";
m_DownLoadParam.task.status = ENDOWNLOAD_FAILED;
m_DownLoadParam.pThis->ChangeTaskStatus(m_DownLoadParam.task.taskid,ENDOWNLOAD_FAILED);
m_DownLoadParam.pNotify->OnNotifyStatus(m_DownLoadParam.task);
return bDownResult;
}
//设置任务状态为下载
m_DownLoadParam.task.status = ENDOWNLOAD_WORKING;
m_DownLoadParam.pThis->ChangeTaskStatus(m_DownLoadParam.task.taskid,ENDOWNLOAD_WORKING);
CURLcode curlCode;
TLOG_INFORMATION(_T("begin URL:%s"),m_strUrl.c_str());
curlCode = curl_easy_perform(m_pCurl);
if(CURLE_OK != curlCode)
{
if (m_fpFileHandle)
{
fseek(m_fpFileHandle, 0, SEEK_END);
unsigned long ulLength = ftell(m_fpFileHandle);
fclose(m_fpFileHandle);
if (0 >= ulLength)
{
remove(m_strFilePath.c_str());
}
}
// 下载回调函数已做过消息的处理,这里再次发送而且指定状态为失败导致上层模块处理混乱
m_DownLoadParam.task.output.strRetMsg = "failed to call curl_easy_perform function";
m_DownLoadParam.task.status = ENDOWNLOAD_FAILED;
m_DownLoadParam.pThis->ChangeTaskStatus(m_DownLoadParam.task.taskid,ENDOWNLOAD_FAILED);
m_DownLoadParam.pNotify->OnNotifyStatus(m_DownLoadParam.task);
bDownResult = false;
}
if (m_fpFileHandle)
{
fclose(m_fpFileHandle);
m_fpFileHandle = NULL;
}
//释放Curl
UnInitCurl();
return bDownResult;
}
bool CurlDown::UnInitCurl()
{
curl_easy_cleanup(m_pCurl);
curl_global_cleanup();
return true;
}
size_t CallBack_WriteFun(void* ptr, size_t size, size_t nmemb, void *stream)
{
assert(stream != NULL);
size_t len = size * nmemb;
CurlDown* pCurlDown = (CurlDown*)stream;
string strHeader = "";
strHeader.append((char*)ptr, len);
string strError = "resultMsg=login_Proxy_Token";
int nFindOut = strHeader.find(strError);
if (0 <= nFindOut)
{
pCurlDown->m_strErrorMsg = "resultMsg=login_Proxy_Token cannot use";
return -1;
}
long retcode = 0;
CURLcode cCode = curl_easy_getinfo(pCurlDown->m_pCurl, CURLINFO_RESPONSE_CODE , &retcode);
if (!pCurlDown->m_fpFileHandle)
{
TLOG_ERROR(_T("m_fpFileHandle == NULL"));
return -1;
}
size_t written = -1;
if ( (cCode == CURLE_OK) && retcode == 200 )
{
written = fwrite(ptr, size, nmemb, pCurlDown->m_fpFileHandle);
//保存文件下载断点
pCurlDown->m_DownLoadParam.task.output.ulEndIndex += written;
(pCurlDown->m_DownLoadParam).pThis->SetDownloadBreakPoint(pCurlDown->m_DownLoadParam.task.taskid,written);
}
return written;
}
#define Transfe_Size 16384 //每次传输的大小
bool IsSendStatus(unsigned long uTotalSize,unsigned long uDownSize)
{
if(uTotalSize == uDownSize)
return true;
int iPercentagePoint = 0;
if(uTotalSize <= 10 * 1024 * 1024) // 10M以内
{
iPercentagePoint = 10;
}else
{
iPercentagePoint = 100;
}
if((uTotalSize/iPercentagePoint) > uDownSize)
return false;
long lTemp = uDownSize%(uTotalSize/iPercentagePoint);
if((lTemp < Transfe_Size) && (lTemp - Transfe_Size < Transfe_Size))
return true;
else
return false;
}
size_t CallBack_Progress(void *ptr,double dTotalDown,double dNowDown,double dTotalUpLoad,double dNowUpLoaded)
{
CurlDown* pCurlDown = (CurlDown*)ptr;
CurlDownParam* pTaskProg = &(pCurlDown->m_DownLoadParam);
long retcode = 0;
CURLcode cCode = curl_easy_getinfo(pCurlDown->m_pCurl, CURLINFO_RESPONSE_CODE , &retcode);
if ( (cCode == CURLE_OK) && retcode == 200 )
{
bool bIsSendStatus = true;
//输入的文件size若是为0,则为异常任务或者绝对路径任务
if (0 == pTaskProg->task.input.ulFileSize)
{
pTaskProg->task.input.ulFileSize = (unsigned long)dTotalDown;
pTaskProg->task.output.ulFileSize = (unsigned long)dTotalDown;
}
//下载任务是否删除
if (true == (pTaskProg->pThis)->IsTaskDelete(pTaskProg->task.taskid))
{
pTaskProg->task.isdelete = true;
pTaskProg->task.status = ENDOWNLOAD_STOPED;
pTaskProg->task.output.strRetMsg = "任务删除";
(pTaskProg->pThis)->ChangeTaskStatus(pTaskProg->task.taskid,ENDOWNLOAD_STOPED);
}else if(ENDOWNLOAD_STOPED == (pTaskProg->pThis)->GetTaskStatus(pTaskProg->task.taskid))
{
pTaskProg->task.status = ENDOWNLOAD_STOPED;
pTaskProg->task.output.strRetMsg = "任务终止";
curl_easy_pause(pCurlDown->m_pCurl,CURLPAUSE_ALL);
(pTaskProg->pNotify)->OnNotifyStatus(pTaskProg->task);
return -1;
}else if (pTaskProg->task.output.ulEndIndex >= pTaskProg->task.input.ulFileSize)
{
// 关闭文件
if (pCurlDown->m_fpFileHandle)
{
fclose(pCurlDown->m_fpFileHandle);
pCurlDown->m_fpFileHandle = NULL;
}
pTaskProg->task.output.bIsFinished = true;
pTaskProg->task.status = ENDOWNLOAD_OVER;
if (ENDOWNLOAD_WORKING == (pTaskProg->pThis)->GetTaskStatus(pTaskProg->task.taskid))
{
(pTaskProg->pThis)->ChangeTaskStatus(pTaskProg->task.taskid,ENDOWNLOAD_OVER);
}
}
else
{
bIsSendStatus = IsSendStatus(pTaskProg->task.input.ulFileSize,pTaskProg->task.output.ulEndIndex + Transfe_Size);
}
if(bIsSendStatus)
{
(pTaskProg->pNotify)->OnNotifyStatus(pTaskProg->task);
}
pTaskProg = NULL;
}
else
{
//若需要更详细的报错信息此处需对retcode做switch处理
pTaskProg->task.output.strRetMsg = "HTTP/1.1 404 Not Found";
(pTaskProg->pThis)->ChangeTaskStatus(pTaskProg->task.taskid,ENDOWNLOAD_NOTBEGIN);
(pTaskProg->pNotify)->OnNotifyStatus(pTaskProg->task);
pTaskProg = NULL;
return -1;
}
return 0;
}
size_t CallBack_Header(char *ptr, size_t size, size_t nmemb, CurlDown* pCurlThis)
{
assert(pCurlThis != NULL);
size_t len = size * nmemb;
string *psHeader = &(pCurlThis->m_strBuffer);
psHeader->append(ptr, len);
return len;
}
//上传类
CurlUpload::CurlUpload(CurlDownParam* ptaskpro)
{
m_pUploadCurl = NULL;
m_pPost = NULL;
m_pLast = NULL;
m_strUploadURL = "";
m_fpFile = NULL;
m_strHeader = "";
m_sUploadParam.task = ptaskpro->task;
m_sUploadParam.pNotify = ptaskpro->pNotify;
m_sUploadParam.pThis = ptaskpro->pThis;
}
CurlUpload::~CurlUpload()
{
m_pUploadCurl = NULL;
m_pPost = NULL;
m_pLast = NULL;
m_strUploadURL = "";
m_strHeader = "";
if (m_fpFile)
{
fclose(m_fpFile);
}
m_fpFile = NULL;
}
bool CurlUpload::InitUploadCurl()
{
bool bInitResult = true;
string url = m_strUploadURL;
string useragent = g_strVer;
m_pHeaderList = NULL;
m_strTargetFileName = GetFileName(m_strUpFileName);
//char* pUrlName = NULL;
//URLEncode(m_strTargetFileName.c_str(), &pUrlName);
string strUTF8Name = string_To_UTF8(m_strTargetFileName);
curl_global_init(CURL_GLOBAL_ALL);
m_pUploadCurl = curl_easy_init();
if(m_pUploadCurl)
{
curl_easy_setopt(m_pUploadCurl,CURLOPT_URL,url.c_str());
curl_easy_setopt(m_pUploadCurl,CURLOPT_USERAGENT,useragent.c_str());
//m_pHeaderList = curl_slist_append(m_pHeaderList, "Content-Type: application/x-www-form-urlencoded;charset=UTF-8");
m_pHeaderList = curl_slist_append(m_pHeaderList, "Expect:");
curl_easy_setopt(m_pUploadCurl, CURLOPT_HTTPHEADER, m_pHeaderList);
curl_formadd(&m_pPost,&m_pLast,CURLFORM_COPYNAME,"upload",CURLFORM_FILE,m_strUpFileName.c_str(),
CURLFORM_FILENAME,strUTF8Name.c_str(),CURLFORM_END);
/* Fill in the submit field too, even if this is rarely needed */
curl_formadd(&m_pPost,&m_pLast,CURLFORM_COPYNAME,"submit",CURLFORM_COPYCONTENTS,"send",CURLFORM_END);
curl_easy_setopt(m_pUploadCurl, CURLOPT_HTTPPOST,m_pPost);
curl_easy_setopt(m_pUploadCurl, CURLOPT_HEADER, true);
curl_easy_setopt(m_pUploadCurl, CURLOPT_HEADERFUNCTION, CallBack_UpHeader);
curl_easy_setopt(m_pUploadCurl, CURLOPT_HEADERDATA, &m_strHeader);
curl_easy_setopt(m_pUploadCurl, CURLOPT_NOPROGRESS, false);
curl_easy_setopt(m_pUploadCurl, CURLOPT_PROGRESSFUNCTION, CallBack_UpProgress);
curl_easy_setopt(m_pUploadCurl, CURLOPT_PROGRESSDATA, this);
curl_easy_setopt(m_pUploadCurl, CURLOPT_CONNECTTIMEOUT, 10);//设置连接超时
}
return bInitResult;
}
string CurlUpload::GetFileName(const string strFileName)
{
string strUserName = strFileName;
int nName = strUserName.find_last_of("\\");
int nNameEnd = strUserName.find_last_of(".");
if (nName > 0 && nNameEnd > 0)
{
return strUserName.substr(nName+1,strUserName.length()-nName);
}
TLOG_INFORMATION(_T("strFileName == NULL"));
return "";
}
void CurlUpload::SetUploadURL()
{
m_strUploadURL = m_sUploadParam.task.input.strPatUrl + m_sUploadParam.task.input.strFilePath /*+ GetFileName(pUploadParam->task.input.strFileId)*/;
}
void CurlUpload::SetUploadFile()
{
m_strUpFileName = m_sUploadParam.task.input.strFileId;
}
void CurlUpload::UploadBegin()
{
CURLcode curlCode;
string strResult;
SetUploadURL();//设置URL
SetUploadFile();//设置上传文件名
InitUploadCurl();//初始化CURL
//更改任务为上传状态
m_sUploadParam.task.status = ENUPLOAD_WORKING;
m_sUploadParam.pThis->ChangeTaskStatus(m_sUploadParam.task.taskid,ENUPLOAD_WORKING);
USES_CONVERSION;
TLOG_INFORMATION(_T("begin URL:%s,filename:%s"),A2T(m_strUploadURL.c_str()),A2T(m_strUpFileName.c_str()));
curlCode = curl_easy_perform(m_pUploadCurl);
if(CURLE_OK != curlCode)
{
m_sUploadParam.task.output.strRetMsg = "failed to call curl_easy_perform function";
m_sUploadParam.task.status = ENUPLOAD_FAILED;
m_sUploadParam.pThis->ChangeTaskStatus(m_sUploadParam.task.taskid,ENUPLOAD_FAILED);
m_sUploadParam.pNotify->OnNotifyStatus(m_sUploadParam.task);
}
//释放Curl
//fclose(m_fpFile);
UnInitCurl();
}
void CurlUpload::UnInitCurl()
{
curl_formfree(m_pPost);
curl_easy_cleanup(m_pUploadCurl);
curl_global_cleanup();
}
size_t CallBack_ReadFun(void* ptr, size_t size, size_t nmemb, FILE* userdata)
{
return fread(ptr, size, nmemb, userdata);
}
//Curl 上传文件 回调函数
size_t CallBack_UpHeader(char *ptr, size_t size, size_t nmemb, void* userdata)
{
string* strMsg = (string*)userdata;
strMsg->append((const char*)ptr,size*nmemb);
return size*nmemb;
}
//Curl 上传文件 回调函数
size_t CallBack_UpProgress(void *ptr,double dTotalDown,double dNowDown,double dTotalUpLoad,double dNowUpLoaded)
{
CurlUpload* pUpload = (CurlUpload*)ptr;
CurlDownParam* pPara = &(pUpload->m_sUploadParam);
pPara->task.output.ulFileSize = (unsigned long)dTotalUpLoad;
pPara->task.output.ulEndIndex = (unsigned long)dNowUpLoaded;
pPara->task.status = ENUPLOAD_WORKING;
if (dTotalUpLoad <= 0)//任务异常
{
pPara->task.status = ENUPLOAD_STOPED;
pPara->task.output.strRetMsg = "上传异常dTotalUpLoad <= 0";
(pPara->pThis)->ChangeTaskStatus(pPara->task.taskid,ENUPLOAD_STOPED);
(pPara->pNotify)->OnNotifyStatus(pPara->task);
return -1;
}
if (dNowUpLoaded == dTotalUpLoad)//任务完成
{
pPara->task.status = ENUPLOAD_OVER;
pPara->task.output.strRetMsg = "上传完成";
pPara->task.output.bIsFinished = true;
if (ENUPLOAD_WORKING == (pPara->pThis)->GetTaskStatus(pPara->task.taskid))
{
(pPara->pThis)->ChangeTaskStatus(pPara->task.taskid,ENUPLOAD_OVER);
(pPara->pNotify)->OnNotifyStatus(pPara->task);
}
return 0;
}
if (pPara->task.isdelete) //上传任务是否删除
{
pPara->task.status = ENUPLOAD_STOPED;
pPara->task.output.strRetMsg = "任务删除";
(pPara->pThis)->ChangeTaskStatus(pPara->task.taskid,ENUPLOAD_STOPED);
(pPara->pNotify)->OnNotifyStatus(pPara->task);
return -1;
}
//任务是否终止
if(ENUPLOAD_STOPED == (pPara->pThis)->GetTaskStatus(pPara->task.taskid))
{
pPara->task.status = ENUPLOAD_STOPED;
pPara->task.output.strRetMsg = "任务终止";
(pPara->pThis)->ChangeTaskStatus(pPara->task.taskid,ENUPLOAD_STOPED);
curl_easy_pause(pUpload->GetCURLHandle(),CURLPAUSE_ALL);
(pPara->pNotify)->OnNotifyStatus(pPara->task);
return -1;
}
pPara->task.output.strRetMsg = "上传中";
(pPara->pNotify)->OnNotifyStatus(pPara->task);
pPara = NULL;
return 0;
}
std::string string_To_UTF8(const std::string & str)
{
int len=str.length();
int unicodeLen=MultiByteToWideChar(CP_ACP,0,str.c_str(),-1,NULL,0);
wchar_t * pUnicode;
pUnicode=new wchar_t[unicodeLen+1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
MultiByteToWideChar(CP_ACP,0,str.c_str(),-1,(LPWSTR)pUnicode,unicodeLen);
BYTE * pTargetData=NULL;
int targetLen=WideCharToMultiByte(CP_UTF8,0,(LPWSTR)pUnicode,-1,(char *)pTargetData,0,NULL,NULL);
pTargetData=new BYTE[targetLen+1];
memset(pTargetData,0,targetLen+1);
WideCharToMultiByte(CP_UTF8,0,(LPWSTR)pUnicode,-1,(char *)pTargetData,targetLen,NULL,NULL);
string retStr((char*)pTargetData);
delete pUnicode;
delete pTargetData;
return retStr;
}
void URLEncode(const char* szIn, char** pOut)
{
int nInLenth = strlen(szIn);
int nFlag = 0;
BYTE byte;
*pOut = new char[nInLenth*3];
char* szOut = *pOut;
for (int i=0; i<nInLenth; i++)
{
byte = szIn[i];
if (isalnum(byte))
{
szOut[nFlag++] = byte;
}
else
{
if (isspace(byte))
{
szOut[nFlag++] = '+';
}
else
{
szOut[nFlag++] = '%';
szOut[nFlag++] = TOHEX(byte>>4);
szOut[nFlag++] = TOHEX(byte%16);
}
}
}
szOut[nFlag] = '\0';
}