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