1. 程式人生 > >關於Libcurl雙向認證請求Https

關於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;
}