调用curl

头文件:

#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;
};


cpp文件

#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';
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值