immortalwrt/package/lean/dclient/src/dcurl.cpp
2018-09-21 21:30:39 +08:00

325 lines
7.9 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "dcurl.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <fstream>
using namespace std;
DCurl::DCurl()
{
// 获取用户临时文件夹
GetTmpDir(m_tmpDir);
// 设置cookie临时保存文件
m_cookieFile = m_tmpDir + "dcurl.tmp";
//初始化Url
m_strUrl = "";
// 初始化超时
m_connTimeout = 3L;
m_timeout = 30L;
// 初始化POST字符串
m_strPost = "";
// 初始化CA证书路径
m_pCaPath = "";
// 初始化文件指针
m_pFile = NULL;
// 初始化输出变量
m_strResponse = "";
m_sType = W_NONE;
m_rType = GET;
}
DCurl::~DCurl()
{
}
size_t DCurl::_handleWrite(void *buffer, size_t size, size_t nmemb, void *pfn)
{
DCurl *pDCurl = dynamic_cast<DCurl *>((DCurl *)pfn);
if (pDCurl)
{
return pDCurl->onWrite(buffer, size, nmemb);
}
return 0;
}
void DCurl::setOption()
{
if(NULL == m_pCurl) return;
// 远程URL支持 http, https, ftp
curl_easy_setopt(m_pCurl, CURLOPT_URL, m_strUrl.c_str());
// 设置User-Agent
std::string useragent = ("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1");
curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, useragent.c_str());
// 设置重定向的最大次数
curl_easy_setopt(m_pCurl, CURLOPT_MAXREDIRS, 5);
// 设置301、302跳转跟随location
curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);
// 设置写入回调函数
curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, _handleWrite);
curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, this);
// 备注:调试的时候打开
//curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1);
//curl_easy_setopt(m_pCurl, CURLOPT_PROXY, "127.0.0.1:8888");
// 超时设置
curl_easy_setopt(m_pCurl, CURLOPT_CONNECTTIMEOUT, m_connTimeout);
curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, m_timeout);
// 当多个线程都使用超时处理的时候同时主线程中有sleep或是wait等操作。
// 如果不设置这个选项libcurl将会发信号打断这个wait从而导致程序退出。
curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
// Cookie设置
if(!m_cookieFile.empty()) // 没有设定文件名就不使用Cookie
{
curl_easy_setopt(m_pCurl, CURLOPT_COOKIEFILE, m_cookieFile.c_str()); // 读取本地存储的cookie
curl_easy_setopt(m_pCurl, CURLOPT_COOKIEJAR, m_cookieFile.c_str()); // 在cleanup之后保存cookie到文件
}
// 设置POST数据
if(m_rType == POST)
{
curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L);
curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, m_strPost.c_str());
}
// HTTPS相关设置
if(!m_pCaPath.empty())
{
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L);
}
else
{
//缺省情况就是PEM所以无需设置另外支持DER
//curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(m_pCurl, CURLOPT_CAINFO, m_pCaPath.c_str());
}
}
size_t DCurl::_run()
{
CURLcode res;
m_pCurl = curl_easy_init();
if(NULL == m_pCurl)
return CURLE_FAILED_INIT;
setOption();
res = curl_easy_perform(m_pCurl);
curl_easy_cleanup(m_pCurl);
return res;
}
size_t DCurl::onWrite(void *buffer, size_t size, size_t nmemb )
{
size_t return_size = 0;
if(m_sType == W_NONE) return 0;
if(m_sType == W_FILE || m_sType == W_ALL)
{
if(m_pFile)
{
return_size = fwrite(buffer, size, nmemb, m_pFile);
}
else
return_size = -1;
//std::cout << (char*) buffer << std::endl;
}
if(m_sType == W_VAR || m_sType == W_ALL)
{
m_strResponse.append((char *)buffer, size * nmemb);
}
else
m_strResponse.append((char *)buffer, size * nmemb);
return return_size;
}
bool DCurl::_openFile()
{
// 创建文件
m_pFile = fopen(m_fileName.c_str(), "wb");
if (m_pFile == NULL)
return false;
return true;
}
bool DCurl::_closeFile()
{
if(m_pFile)
{
fclose(m_pFile);
m_pFile = NULL;
}
return true;
}
int DCurl::httpDownload(const string & strUrl, const string & fileName, const RequestType rType)
{
SaveType pre_sType = m_sType;
string preFileName = m_fileName;
string preStrUrl = m_strUrl;
RequestType pre_rType = m_rType;
m_rType = rType;
m_sType = W_FILE; // 设置输出类型
if(!strUrl.empty()) m_strUrl = strUrl;
if(!fileName.empty()) m_fileName = fileName;
if(!_openFile()) { m_sType = pre_sType; return -1; }
_run();
_closeFile();
m_sType = pre_sType;
m_fileName = preFileName;
m_strUrl = preStrUrl;
m_rType = pre_rType;
return 1;
}
int DCurl::httpRequest(const string & strUrl, const RequestType rType, bool toVar)
{
SaveType pre_sType = m_sType;
RequestType pre_rType = m_rType;
string preStrUrl = m_strUrl;
m_rType = rType;
if(!strUrl.empty())
m_strUrl = strUrl;
else
if(m_strUrl.empty()) return 0;
m_strResponse.clear();
if(toVar)
m_sType = W_VAR;
else
m_sType = W_NONE;
_run();
m_sType = pre_sType;
m_rType = pre_rType;
m_strUrl = preStrUrl;
return true;
}
string DCurl::httpSuperRequest(const string & strUrl, const RequestType rType,
const SaveType sType, const string & fileName)
{
SaveType pre_sType = m_sType, tmpType = sType;
string preFileName = m_fileName;
RequestType pre_rType = m_rType;
string preStrUrl = m_strUrl;
m_rType = rType;
m_strResponse.clear();
bool f_ext = !fileName.empty();
if(m_strUrl.empty())
{
// 如果本身没有设置地址,并且没有传参,直接返回
if(strUrl.empty()) return 0;
else m_strUrl = strUrl;
}
// 处理参数为空或者是成员函数m_fileName为空的情况
if((sType == W_FILE || sType == W_ALL) && !f_ext)
{
// 如果sType是W_FILE和W_ALL中的一种而且没有传参也没有预先设置m_fileName执行W_NONE
if(m_fileName.empty()) tmpType = (sType == W_FILE) ? W_NONE : W_VAR;
}
else
if(f_ext) m_fileName = fileName;
// 处理打开文件
if((tmpType == W_FILE || tmpType == W_ALL) && !_openFile())
{
if(tmpType == W_ALL) tmpType = W_VAR;
else tmpType = W_NONE;
}
if(sType == W_VAR)
tmpType = W_VAR;
m_sType = tmpType;
_run();
if(m_pFile) _closeFile();
m_sType = pre_sType;
m_rType = pre_rType;
m_fileName = preFileName;
m_strUrl = preStrUrl;
if(tmpType == W_VAR || tmpType == W_ALL) return m_strResponse;
else return "";
}
void DCurl::getResponse(string & strResponse)
{
strResponse = m_strResponse;
m_strResponse.clear();
}
void DCurl::setUrl(const string & strUrl)
{
m_strUrl = strUrl;
}
void DCurl::setRequestType(RequestType rType)
{
m_rType = rType;
}
void DCurl::setFileName(const string & fileName)
{
m_fileName = fileName;
}
void DCurl::setCaPath(const string & pCaPath)
{
m_pCaPath = pCaPath;
}
void DCurl::setTimeout(const long connTimeout, const long timeout)
{
m_connTimeout = connTimeout;
m_timeout = timeout;
}
void DCurl::setPostData(const string & postData)
{
m_strPost = postData;
}
bool DCurl::cleanCookie()
{
using std::ofstream;
using std::ios_base;
ofstream fout(m_cookieFile, ios_base::out | ios_base::trunc);
if(!fout.is_open()) return false;
fout.close();
return true;
}