text: #include "client.h"
  #include <curl/curl.h>
  #include <string>
  #include <cstring>
  #include <iostream>
  using namespace std;
  CHttpClient::CHttpClient(void) : 
  m_bDebug(false)
  {
  }
  CHttpClient::~CHttpClient(void)
  {
  
  }
  
  static const std::string UrlEncode(const std::string& s)
  {
          std::string ret;
          unsigned char *ptr = (unsigned char *)s.c_str();
          ret.reserve(s.length());
  
          for(int i=0;i<s.length();++i)
          {
                  if((int(ptr[i])==42) || (int(ptr[i])==45) || (int(ptr[i])==46) || (int(ptr[i])==47) || (int(ptr[i])==58) ||(int(ptr[i])==95))
                          ret += ptr[i];
                  else if((int(ptr[i])>=48) && (int(ptr[i])<=57))
                          ret += ptr[i];
                  else if((int(ptr[i])>=65) && (int(ptr[i])<=90))
                          ret += ptr[i];
                  else if((int(ptr[i])>=97) && (int(ptr[i])<=122))
                          ret += ptr[i];
                  else if(int(ptr[i])==32)
                          ret += '+';
                  else
                  {
                          char buf[5];
                          memset(buf,0,5);
                          snprintf(buf,5,"%%%X",ptr[i]);
                          ret.append(buf);
                  }
          }
          return ret;
  }
  
  
  static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)
  {
  	if(itype == CURLINFO_TEXT)
  	{
  		//printf("[TEXT]%s\n", pData);
  	}
  	else if(itype == CURLINFO_HEADER_IN)
  	{
  		printf("[HEADER_IN]%s\n", pData);
  	}
  	else if(itype == CURLINFO_HEADER_OUT)
  	{
  		printf("[HEADER_OUT]%s\n", pData);
  	}
  	else if(itype == CURLINFO_DATA_IN)
  	{
  		printf("[DATA_IN]%s\n", pData);
  	}
  	else if(itype == CURLINFO_DATA_OUT)
  	{
  		printf("[DATA_OUT]%s\n", pData);
  	}
  	return 0;
  }
  
  static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid)
  {
  	std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid);
  	if( NULL == str || NULL == buffer )
  	{
  		return -1;
  	}
  
      char* pData = (char*)buffer;
      str->append(pData, size * nmemb);
  	return nmemb;
  }
  
  int CHttpClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse)
  {
  	strResponse.clear();
  	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, UrlEncode(strUrl).c_str());
  	curl_easy_setopt(curl, CURLOPT_POST, 1);
  	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, 3);
  	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
  	res = curl_easy_perform(curl);
  	curl_easy_cleanup(curl);
  	return res;
  }
  
  int CHttpClient::Get(const std::string & strUrl, std::string & strResponse)
  {
  	strResponse.clear();
  	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, UrlEncode(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, 3);
  	//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
  	res = curl_easy_perform(curl);
  	curl_easy_cleanup(curl);
  	return res;
  }
  
  int CHttpClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath)
  {
  	strResponse.clear();
  	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, UrlEncode(strUrl).c_str());
  	curl_easy_setopt(curl, CURLOPT_POST, 1);
  	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)
  	{
  		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, 3);
  	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
  	res = curl_easy_perform(curl);
  	curl_easy_cleanup(curl);
  	return res;
  }
  
  int CHttpClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath)
  {
  	strResponse.clear();
  	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, UrlEncode(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)
  	{
  		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, 3);
  	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
  	res = curl_easy_perform(curl);
  	curl_easy_cleanup(curl);
  	return res;
  }
  
  ///////////////////////////////////////////////////////////////////////////////////////////////
  void CHttpClient::SetDebug(bool bDebug)
  {
  	m_bDebug = bDebug;
  }
  
  