關於Libcurl雙向認證請求Https
之前通過libcurl開發只是做http請求,這次公司專案需要請求https,所以就研究了一下,其實用libcurl做http請求是非常簡單的,所有底層實現都被封裝到了libcurl裡面(預設編譯的libcurl是沒有附加SSL的,也就是說預設的libcurl是不帶https功能的,因此需要自己重新編譯,這裡是一個libcurl支援https,可以直接用),具體關於https的實現如下:
int CHttpClient::sendRequest(std::string strRequestType,
std::string strUrl,
std::string &strReport,
std::string &strRetHeader,
std::vector<std::string> vecHeader,
std::string strParam/* ="" */,
std::string strCookie/* ="" */,
std::string strCaPath/* ="" */,
int nTimeOut/* =0 */)
{
CURL * curl;
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
if ( strRequestType.compare("post")==0 || strRequestType.compare("POST") == 0 )
{
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(strParam.c_str()));//post內容長度
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strParam.c_str());
}
else
{
curl_easy_setopt(curl, CURLOPT_POST, 0);//get請求
}
//設定http頭
curl_slist * headers = NULL;
for ( int i=0; i<vecHeader.size(); i++ )
{
if (!vecHeader.at(i).empty())
{
headers = curl_slist_append(headers, vecHeader.at(i).c_str());
}
}
if (headers != NULL)
{
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
}
curl_easy_setopt(curl,CURLOPT_SSLVERSION,1);
//判斷是否有證書
if(strCaPath.empty())
{
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_SSL_VERIFYHOST, true);
curl_easy_setopt(curl,CURLOPT_CAINFO,"C:/ssl/cacert.pem");
curl_easy_setopt(curl,CURLOPT_SSLCERT,"C:/ssl/client.pem");
curl_easy_setopt(curl,CURLOPT_SSLCERTPASSWD,"11111111");
curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl,CURLOPT_SSLKEY,"C:/ssl/clientkey.pem");
curl_easy_setopt(curl,CURLOPT_SSLKEYPASSWD,"11111111");
curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,"PEM");
}
//Web伺服器一般會重定向連結,比如訪問http:/xxx/x1.do自動轉到http:/xxx/x2.do
//所以一定要設定CURLOPT_FOLLOWLOCATION為1,否則重定向後的資料不會返回。
//curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,1);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);//可以看到除錯資訊
curl_easy_setopt(curl,CURLOPT_HEADERFUNCTION,_CURL_::write_data);
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &strRetHeader);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _CURL_::write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &strReport);
if ( nTimeOut > 0 )
{
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, nTimeOut);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);
}
if (!strCookie.empty())
{
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, strCookie.c_str());
}
CURLcode code = curl_easy_perform(curl);
if(code != CURLE_OK)
{
printf("curl_wasy_perform error = %s",curl_easy_strerror(code));}
if ( headers != NULL )
{
curl_slist_free_all(headers);
}
curl_easy_cleanup(curl);
return code;
}