libcurl 筆記

來自https://curl.haxx.se/libcurl/c/libcurl-tutorial.html

初始化

參數指定要初始化的模塊

curl_global_init(CURL_GLOBAL_ALL);
CURL_GLOBAL_WIN32
CURL_GLOBAL_SSL

當不再使用libcurl時調用:

curl_global_cleanup();

查詢libcurl支持的特性

curl_version_info()

libcurl提供兩種接口

  1. easy interface - 函數以curl_easy爲前綴,同步、阻塞調用
    (let you do single transfers with a synchronous and blocking function call)
  2. multi interface - allows multiple simultaneous transfers in a single thread

Easy libcurl

首先獲得一個句柄,該句柄不能被多個線程共享

easyhandle = curl_easy_init();

設置選項,用於接下來的傳輸
設置的選項將一直保持,直到下一次修改
curl_easy_setopt()

重置選項
curl_easy_reset()
複製句柄,連同其選項
curl_easy_duphandle()

常用的選項比如URL

curl_easy_setopt(handle, CURLOPT_URL, "http://domain.com/");

假設想要接收上面指定的鏈接處收到的數據,默認輸出到stdout
可以設置自己的回調函數處理該數據

回調函數:
size_t write_data(void* buffer, size_t size, size_t nmemb, void* userp);

設置回調函數

curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);

設置回調函數第四個參數接收的自定義數據
可以將文件句柄傳入第四個參數,比如FILE*

curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct);

執行任務
該函數連接到遠程地址,傳輸數據,當接收到文件時,之前設置的回調函數會被調用

success = curl_easy_perform(easyhandle);

對於某些協議,比如FTP,下載一個文件需要登錄、設置傳輸模式、改變當前目錄然後傳輸文件數據等一系列步驟,libcurl會自動處理這些步驟,開發人員只需要提供這個需要下載的文件的URL。

多線程

libcurl是線程安全的 多線程專題https://curl.haxx.se/libcurl/c/threadsafe.html

調試

傳輸可能會因爲某些原因失敗
調試用選項
CURLOPT_VERBOSE
CURLOPT_HEADER
CURLOPT_DEBUGFUNCTION

如果瞭解某些傳輸協議,學習協議的RFC文檔,用利於更好地理解和使用libcurl


密碼

許多協議需要提供用戶名密碼才能上傳或下載。

libcurl提供了幾種方法來指定用戶名密碼

在URL中指定用戶名和密碼
protocol://user:[email protected]/path/
如果在用戶名密碼中包含奇怪的字符(URL只能包含ASCII字符),需要使用URL編碼:%XX,XX爲十六進制數字

使用選項設置用戶名密碼

curl_easy_setopt(easyhandle, CURLOPT_USERPWD, "myname:thesecret");

設置代理(proxy)的用戶名密碼

curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "myname:thesecret");

在Unix下用戶名密碼可以保存在某個配置文件中$HOME/.netrc
可以設置選項是libcurl使用配置文件中的用戶名和密碼

curl_easy_setopt(easyhandle, CURLOPT_NETRC, 1L);

配置文件.netrc中的內容例如:

machine myhost.mydomain.com
login userlogin
password secretword

設置SSL私鑰密碼

curl_easy_setopt(easyhandle, CURLOPT_KEYPASSWD, "keypassword");

HTTP 認證 Authentication

上文展示瞭如何設置用戶名和密碼
當使用HTTP協議時,有很多不同的方法提交認證,可以自由控制libcurl使用哪一種。
默認的認證方法是“Basic”:明文發送用戶名密碼,使用base64編碼,這是不安全的。

目前libcurl可以使用以下方法:Basic Digest NTLM Negotiate(SPNEGO)
可以設置選項告訴libcurl使用哪一種

curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);

代理的認證方法
CURLOPT_PROXYAUTH

可以使用邏輯或運算符指定多個認證方法,libcurl將自動選擇最安全的一種

curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST | CURLAUTH_BASIC);

也可以使用CURLAUTH_ANY

HTTP POST請求

使用libcurl發送如同<form>表單中的POST請求,方法如下:

char* data = "name=daniel&project=curl";
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(easyhandle, CURLOPT_URL, "http://posthere.com/");
curl_easy_perform(easyhandle);  // 執行POST請求

POST請求中使用二進制數據
需要指定二進制數據的長度,因爲libcurl無法使用strlen()獲得二進制數據的長度。

// header
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type:text/xml");
// 二進制數據
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, binaryptr);
// 二進制數據的長度
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDSIZE, 23L);
// 設置自定義header
curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
// 執行POST請求
curl_easy_perform(easyhandle);
// 釋放內存
curl_slist_free_all(headers);

Muti-part formpost
用於POST請求中包含非常大的二進制數據時,二進制數據可以分多個部分添加。
用法見文首原文鏈接。

因爲easyhandle會記住上次設置的選項。所以如果要回到GET請求模式,需要手動切換回來。

curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, 1L);

僅僅設置CURLOPT_POSTFIELDS爲空字符串或NULL並不會退出POST模式,這樣僅僅是不包含任何數據的POST請求。

顯示傳輸進度

libcurl有一個內置的顯示進度的功能,如果開啓,將在終端窗口顯示一個進度條。
設置選項開啓:CURLOPT_NOPROGRESS 設爲0爲開啓,默認值爲1

對於大多數應用程序來說,內置的進度條功能沒什麼用。
使用回調函數 CURLOPT_PROGRESSFUNCTION
回調函數的格式爲:

int progress_callback(
    void* clientp,   // 使用CURLOPT_PROGRESSDATA設置的自定義數據
    double dltotal,
    double dlnow,
    double ultotal,
    double ulnow);

libcurl 和 C++

使用C++需要注意的一點是:回調函數不能使用類的非靜態函數

待續…

擴展閱讀 http://www.cnblogs.com/suiyingjie/archive/2012/11/12/2766332.html

發佈了34 篇原創文章 · 獲贊 21 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章