#include "pch.h" #include "CurlClient.h" #include "CharEncoding.h" CCurlClient::CCurlClient(void) { m_bDebug = FALSE; m_headers = NULL; } CCurlClient::~CCurlClient(void) { // 释放curl的全局对象; curl_global_cleanup(); } INT CCurlClient::Initialize() { // 初始化全局调用模式; CURLcode res = ::curl_global_init( CURL_GLOBAL_ALL ); if( CURLE_OK != res ) { fprintf( stderr, "curl_global_init failed: %d \n", res ); return -1; } return 0; } static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *) { if(itype == CURLINFO_TEXT) { //TRACE("[TEXT]%s\n", pData); LOG4C((LOG_WARN, "[TEXT]%s\n", pData)); } else if(itype == CURLINFO_HEADER_IN) { //TRACE("[HEADER_IN]%s\n", pData); LOG4C((LOG_WARN, "[HEADER_IN]%s\n", pData)); } else if(itype == CURLINFO_HEADER_OUT) { //TRACE("[HEADER_OUT]%s\n", pData); LOG4C((LOG_WARN, "[HEADER_OUT]%s\n", pData)); } else if(itype == CURLINFO_DATA_IN) { //TRACE("[DATA_IN]%s\n", pData); LOG4C((LOG_WARN, "[DATA_IN]%s\n", pData)); } else if(itype == CURLINFO_DATA_OUT) { //TRACE("[DATA_OUT]%s\n", pData); LOG4C((LOG_WARN, "[DATA_OUT]%s\n", pData)); } return 0; } size_t CCurlClient::OnWriteData(const void *ptr, size_t size, size_t nmemb, std::string *stream) { if( NULL == stream || NULL == ptr ) return -1; stream->append((char*)ptr, size * nmemb); return nmemb; } int CCurlClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse, long time_out /*= 3*/) { CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl) { return CURLE_FAILED_INIT; } if(m_bDebug) {// 是否开启调试日志输出; curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); } // 设置URL地址; curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); // 设置POST方式; curl_easy_setopt(curl, CURLOPT_POST, 1); // 设置POST参数; curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str()); // 设置回调函数-读取; curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); // 设置回调函数-写入; curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); // 设置回调函数-写入的缓存区; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); // 设置(多线程下,只是尽量减少)无签名; curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // 设置连接超时值(单位毫秒); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30000); // 设置操作超时值(单位毫秒); curl_easy_setopt(curl, CURLOPT_TIMEOUT, time_out); // 设置头; curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headers); // 执行POST提交; res = curl_easy_perform(curl); // 释放资源; curl_easy_cleanup(curl); //curl_global_cleanup(); ClearHeaders(); /* free the header list */ return res; } int CCurlClient::Post(IN LPCTSTR lpUrl, IN LPCTSTR lpPost, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, long time_out /*= 3*/) { if ( lpUrl == NULL || lpPost == NULL ) return CURLE_FAILED_INIT; string strUrl; string strPost; string strResponse; #ifdef UNICODE CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl); CharEncoding::UNICODE2ASCII((LPWCH)lpPost, strPost); int res = Post(strUrl, strPost, strResponse) ; if ( CURLE_OK == res ) { CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen); return CURLE_OK; } return res; #else strUrl = lpUrl; strPost = lpPost; int res = Post(strUrl, strPost, strResponse, time_out) ; if ( CURLE_OK == res ) { sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str()); return CURLE_OK; } return res; #endif } int CCurlClient::Post(IN CString& strUrl, IN CString& strPost, OUT CString& strResponse, long time_out /*= 3*/) { if ( strUrl.IsEmpty() || strPost.IsEmpty() ) return CURLE_FAILED_INIT; string url; string post; string response; #ifdef UNICODE CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url); CharEncoding::UNICODE2ASCII((LPWCH)strPost.GetString(), post); int res = Post(url, post, response) ; if ( CURLE_OK == res ) { WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str()); if ( pResult ) { strResponse = pResult; delete []pResult; pResult = NULL; return CURLE_OK; } } return res; #else url = strUrl.GetString(); post = strPost.GetString(); int res = Post(url, post, response, time_out) ; if ( CURLE_OK == res ) { strResponse = response.c_str(); return CURLE_OK; } return res; #endif } int CCurlClient::Get(const std::string & strUrl, std::string & strResponse, long time_out /*= 3*/) { CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl) { return CURLE_FAILED_INIT; } if(m_bDebug) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); } // 设置URL地址; curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); // 设置回调函数-读取; curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); // 设置回调函数-写入; curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); // 设置回调函数-写入的缓存区; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); /** * 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。 * 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。 */ // 设置(多线程下,只是尽量减少)无签名; curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // 设置连接超时值; curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT,5000); // 设置超时值; curl_easy_setopt(curl,CURLOPT_TIMEOUT, time_out); // 设置头; curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headers); res = curl_easy_perform(curl); curl_easy_cleanup(curl); //curl_global_cleanup(); ClearHeaders(); /* free the header list */ return res; } int CCurlClient::Get(IN LPCTSTR lpUrl, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, long time_out /*= 3*/) { if ( lpUrl == NULL ) return CURLE_FAILED_INIT; string strUrl; string strResponse; #ifdef UNICODE CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl); int res = Get(strUrl, strResponse) ; if ( CURLE_OK == res ) { CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen); return CURLE_OK; } return res; #else strUrl = lpUrl; int res = Get(strUrl, strResponse, time_out) ; if ( CURLE_OK == res ) { sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str()); return CURLE_OK; } return res; #endif } int CCurlClient::Get(IN CString& strUrl, OUT CString& strResponse, long time_out /*= 3*/) { if ( strUrl.IsEmpty() ) return CURLE_FAILED_INIT; string url; string post; string response; #ifdef UNICODE CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url); int res = Get(url, response) ; if ( CURLE_OK == res ) { WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str()); if ( pResult ) { strResponse = pResult; delete []pResult; pResult = NULL; return CURLE_OK; } } return res; #else url = strUrl.GetString(); int res = Get(url, response, time_out) ; if ( CURLE_OK == res ) { strResponse = response.c_str(); return CURLE_OK; } return res; #endif } int CCurlClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath, long time_out /*= 3*/) { CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl) { return CURLE_FAILED_INIT; } if(m_bDebug) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); } // 设置URL地址; curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); // 设置POST提交方式; curl_easy_setopt(curl, CURLOPT_POST, 1); // 设置POST参数; curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str()); // 设置回调函数-读取; curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); // 设置回调函数-写入; curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); // 设置回调函数-写入的缓存区; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); // 设置; curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); if(NULL == pCaPath || pCaPath[0] == '\0') { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); } else { //缺省情况就是PEM,所以无需设置,另外支持DER //curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM"); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true); curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath); } // 设置连接超时值; curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT,5000); // 设置超时值; curl_easy_setopt(curl,CURLOPT_TIMEOUT, time_out); // 设置头; curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headers); // 执行POST提交; res = curl_easy_perform(curl); // 释放资源; curl_easy_cleanup(curl); //curl_global_cleanup(); ClearHeaders(); /* free the header list */ return res; } int CCurlClient::Posts(IN LPCTSTR lpUrl, IN LPCTSTR lpPost, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, IN LPCTSTR lpCaPath /* = NULL */, long time_out /*= 3*/) { if ( lpUrl == NULL || lpPost == NULL ) return CURLE_FAILED_INIT; string strUrl; string strPost; string strCapath; string strResponse; #ifdef UNICODE CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl); CharEncoding::UNICODE2ASCII((LPWCH)lpPost, strPost); CharEncoding::UNICODE2ASCII((LPWCH)lpCaPath, strCapath); int res = Posts(strUrl, strPost, strResponse, strCapath.c_str()) ; if ( CURLE_OK == res ) { CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen); return CURLE_OK; } return res; #else strUrl = lpUrl; strPost = lpPost; strCapath = lpCaPath; int res = Posts(strUrl, strPost, strResponse, strCapath.c_str(), time_out ) ; if ( CURLE_OK == res ) { sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str()); return CURLE_OK; } return res; #endif } int CCurlClient::Posts(IN CString& strUrl, IN CString& strPost, OUT CString& strResponse, IN const CString& strCaPath /* = _T("") */, long time_out /*= 3*/) { if ( strUrl.IsEmpty() || strPost.IsEmpty() ) return CURLE_FAILED_INIT; string url; string post; string capth; string response; #ifdef UNICODE CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url); CharEncoding::UNICODE2ASCII((LPWCH)strPost.GetString(), post); CharEncoding::UNICODE2ASCII((LPWCH)strCaPath.GetString(), capth); int res = Posts(url, post, response, capth.c_str()) ; if ( CURLE_OK == res ) { WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str()); if ( pResult ) { strResponse = pResult; delete []pResult; pResult = NULL; return CURLE_OK; } } return res; #else url = strUrl.GetString(); post = strPost.GetString(); capth = strCaPath.GetString(); int res = Posts(url, post, response, capth.c_str(), time_out) ; if ( CURLE_OK == res ) { strResponse = response.c_str(); return CURLE_OK; } return res; #endif } int CCurlClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath, long time_out /*= 3*/) { CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl) { return CURLE_FAILED_INIT; } if(m_bDebug) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); } curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); if(NULL == pCaPath || pCaPath[0] == '\0') { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); } else { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true); curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath); } curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5000); curl_easy_setopt(curl, CURLOPT_TIMEOUT, time_out); // 设置头; curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headers); res = curl_easy_perform(curl); curl_easy_cleanup(curl); //curl_global_cleanup(); ClearHeaders(); /* free the header list */ return res; } int CCurlClient::Gets(IN LPCTSTR lpUrl, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, IN LPCTSTR lpCaPath /* = NULL */, long time_out /*= 3*/) { if ( lpUrl == NULL ) return CURLE_FAILED_INIT; string strUrl; string strCapath; string strResponse; #ifdef UNICODE CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl); CharEncoding::UNICODE2ASCII((LPWCH)lpCaPath, strCapath); int res = Gets(strUrl, strResponse, strCapath.c_str()) ; if ( CURLE_OK == res ) { CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen); return CURLE_OK; } return res; #else strUrl = lpUrl; strCapath = lpCaPath; int res = Gets(strUrl, strResponse, strCapath.c_str(), time_out) ; if ( CURLE_OK == res ) { sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str()); return CURLE_OK; } return res; #endif } int CCurlClient::Gets(IN CString& strUrl, OUT CString& strResponse, IN const CString& strCaPath /* = _T("") */, long time_out /*= 3*/) { if ( strUrl.IsEmpty() ) return CURLE_FAILED_INIT; string url; string post; string capth; string response; #ifdef UNICODE CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url); CharEncoding::UNICODE2ASCII((LPWCH)strCaPath.GetString(), capth); int res = Gets(url, response, capth.c_str()) ; if ( CURLE_OK == res ) { WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str()); if ( pResult ) { strResponse = pResult; delete []pResult; pResult = NULL; return CURLE_OK; } } return res; #else url = strUrl.GetString(); capth = strCaPath.GetString(); int res = Gets(url, response, capth.c_str(), time_out) ; if ( CURLE_OK == res ) { strResponse = response.c_str(); return CURLE_OK; } return res; #endif } void CCurlClient::SetDebug(bool bDebug) { m_bDebug = bDebug; } void CCurlClient::SetHeaders(const std::string headers) { m_headers = curl_slist_append(m_headers, headers.c_str()); }