curl是一个开源的网络协议库,主要针对http(是否提供其他应用层协议,我没有深究,故用一个宽松的语句描述我对其的认识)
curl的文档风格很赞。 读者可以猛击链接阅读其sample的主页。另外几个在我印象中,文档风格很清晰的库是extjs、opencv、boost、tbb。
遇到一个比较特俗的需求,有一个项目,http协议的接口不明(接口提供方没人维护,或者说,外包给其他公司做的,后面没人管了),仅仅有一个网页(我需要的几个接口混杂在web的HTML和js代码中)
好吧,上fiddle抓包。
某一接口的抓包结果如下,为了隐去信息,抓包结果有进行修改和调整:
POST http://192.168.0.6:8080/cgi-bin/upload.cgi HTTP/1.1
Host: 192.168.0.6:8080
Connection: keep-alive
Content-Length: 3932475
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://192.168.0.6:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryMI3QTHGZw9Rwg6G5
Referer: http://192.168.0.6:8080/api/upload_result.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
------WebKitFormBoundaryMI3QTHGZw9Rwg6G5
Content-Disposition: form-data; name="filename"; filename="helloworld.cpp"
Content-Type: application/octet-stream
blablabla...file data octet-stream....
------WebKitFormBoundaryMI3QTHGZw9Rwg6G5--
我Google了一下关键词:form post file curl,可能是我理解不对,这个关键词搜的结果不是我需要的。
鉴于http本质就是用tcp做传输层的特定格式字符串,故我转而对抓包的raw数据进行分析。
经过比较多次的比较和测试,最后得出如上的http请求的curl代码如下
int flashfw(const string &url, string &responese)
{
int retVal = 0 ;
CURL *curl;
CURLM *multi_handle;
int still_running;
struct curl_httppost *formpost=NULL;
struct curl_httppost *lastptr=NULL;
struct curl_slist *headerlist=NULL;
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "filename",
CURLFORM_FILE, "mypicture.jpg",
CURLFORM_CONTENTTYPE, "application/octet-stream",
CURLFORM_END);
curl = curl_easy_init();
multi_handle = curl_multi_init();
if(curl && multi_handle) {
struct curl_slist *chunk = NULL;
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36");
chunk = curl_slist_append(chunk, "Connection: keep-alive");
chunk = curl_slist_append(chunk, "DNT: 1");
chunk = curl_slist_append(chunk, "Accept-Encoding: gzip, deflate");
chunk = curl_slist_append(chunk, "Accept-Language: zh-CN,zh;q=0.8");
curl_easy_setopt(curl, CURLOPT_POST, 1);
/* set our custom set of headers */
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
int res = curl_easy_perform(curl);
/* get http response status */
long http_code = 0;
curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
retVal = http_code ;
/* always cleanup */
curl_easy_cleanup(curl);
/* then cleanup the formpost chain */
curl_formfree(formpost);
/* free slist */
curl_slist_free_all (headerlist);
}
return retVal ;
}