CURL使用
Curl恐怕是大多数项目喜欢依赖的一个轻巧、高效的http协议处理库。
下面是简单的例子:
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
{
int bytes = size*nmemb;
char *out= new char[bytes+1];
memcpy(out,buffer,bytes);
out[bytes] = 0;
printf("%s", out);
return bytes;
}
int main(int argc, char *argv)
{
CURLcode cc;
CHECKCC(curl_global_init(CURL_GLOBAL_SSL))
curl_slist *slist = NULL;
slist = curl_slist_append(slist, "Accept: text/xml");
slist = curl_slist_append(slist, "Depth: infinity");
slist = curl_slist_append(slist, "Connection: Keep-Alive");
slist = curl_slist_append(slist, "Content-Type: text/xml");
slist = curl_slist_append(slist, "Expect:");
CURL *pcurl = curl_easy_init();
CHECKCC(curl_easy_setopt(pcurl, CURLOPT_VERBOSE, 1))
CHECKCC(curl_easy_setopt(pcurl, CURLOPT_URL, "http://10.94.248.184/exchange/ut_cugal0/Calendar/portingcugal.eml"))
CHECKCC(curl_easy_setopt(pcurl, CURLOPT_CUSTOMREQUEST, "PROPPATCH"))
CHECKCC(curl_easy_setopt(pcurl, CURLOPT_HTTPHEADER, slist))
CHECKCC(curl_easy_setopt(pcurl, CURLOPT_POSTFIELDS, pszPostData))
CHECKCC(curl_easy_setopt(pcurl, CURLOPT_POSTFIELDSIZE, strlen(pszPostData)))
CHECKCC(curl_easy_setopt(pcurl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC))
CHECKCC(curl_easy_setopt(pcurl, CURLOPT_USERPWD, "aspen\\cucsvc:Bould3r"))
CHECKCC(curl_easy_setopt(pcurl, CURLOPT_WRITEFUNCTION, write_data))
CHECKCC(curl_easy_perform(pcurl))
}
和
size_t reponseWrite(void *buff,size_t size,size_t nmemb,void *stream){
strcat((char*)stream,(char*)buff);
return size * nmemb;
}
string request(string url,string data,bool isPost){
CURL *curl_obj;
string response_data = "";
char buff[BUFSIZE] = {0};
curl_obj = curl_easy_init();
curl_easy_setopt(curl_obj,CURLOPT_URL,url.c_str());
curl_easy_setopt(curl_obj,CURLOPT_HEADER,true);
curl_easy_setopt(curl_obj,CURLOPT_POST,isPost);
curl_easy_setopt(curl_obj,CURLOPT_TIMEOUT,30);
curl_easy_setopt(curl_obj,CURLOPT_POSTFIELDS,data.c_str());
curl_easy_setopt(curl_obj,CURLOPT_WRITEFUNCTION,&reponseWrite);
curl_easy_setopt(curl_obj,CURLOPT_WRITEDATA,buff);
CURLcode return_code = curl_easy_perform(curl_obj);
if(return_code == CURLE_OK){
response_data = string(buff);
}
curl_easy_cleanup(curl_obj);
return response_data;
}
很简单吧。
Expect100-continue 问题解决
在使用curl做POST的时候, 当要POST的数据大于1024字节的时候, curl并不会直接就发起POST请求, 而是会分为俩步,
- 发送一个请求, 包含一个Expect:100-continue, 询问Server使用愿意接受数据
- 接收到Server返回的100-continue应答以后, 才把数据POST给Server
这是libcurl的行为.
具体的RFC相关描述: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3
Host: kimnote.com Accept: */* Content-Length: 50 Content-Type: application/x-www-form-urlencoded Expect: 100-continue
要解决的办法也挺容易:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
C & c++ 语言的解决办法如下:
struct curl_slist * headers = 0; // Disable "Expect: 100-continue" headers = curl_slist_append(headers, "Expect:"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_slist_free_all(headers);
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTHTTPHEADER
参考:
http://kimnote.com/2014/03/libcurl%E7%9A%84expect100-continue-%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3-phpcc/