curl_easy_setopt-curl庫的關鍵函式之一

double2li發表於2015-06-17

函式原型:
#include <curl/curl.h>
CURLcodecurl_easy_setopt(CURL *handle, CURLoption option, parameter);

說明:
此函式用來告訴 libcurl 執行什麼樣的動作。該函式有 3 個引數(該函式的可設定選項非常之多):
第 1 個引數 handle 是由 curl_easy_init() 返回的控制程式碼;第 2 個引數是可以設定的選項(CURLoption);第 3 個引數是與第 2 個選項相關聯的引數,這個引數可以是 long 型,也可以是一個函式指標(function pointer),還可以是一個物件的指標 (object pointer),或者是一個 curl_off_t 型別,這些引數型別必須由選項值(CURLoption)來確定。

具體選項說明(分大類和小類,本說明為個人理解以及對說明手冊的翻譯,根據應用不斷更新說明內容,分類順序不按照說明手冊):

網路選項(NETWORK OPTIONS):

1. CURLOPT_URL
這個選項後面接實際要處理的 URL ,這個 URL 是一個以 ` ` 結尾的字串或引數指標(關於這個引數的簡單示例見:http://www.groad.net/bbs/read.php?tid-1641.html)。如果 URL 引數不寫上協議頭(如 “http://” 或者 “ftp:// 等等 ),那麼函式會自己進行猜解所給的主機上用的是哪一種服務協議。假如你給的這個地址是一個不被 支援的協議,那麼在其後執行 curl_easy_perform() 函式或 curl_multi_perform() 函式時, libcurl 將返回錯誤(CURLE_UNSUPPORTED_PROTOCOL)。這個選項是唯一一個必須在 curl_easy_perform() 呼叫之前就要設定的選項。

2. CURLOPT_POSTFIELDSIZE
該選項要求第 3 個引數 parameter 是一個 void * 指標,它指向一個向 HTTP 伺服器 POST 出去的一段資料,這段資料要根據伺服器的具體要求填寫。該選項用法參考示例:http://www.groad.net/bbs/read.php?tid-3909.html

3. CURLOPT_WRITEFUNCTION
使用該選項時,要求第 3 個引數中的回撥函式必須是下面的函式原型:

size_t function( char *ptr, size_t size, size_t nmemb, void *userdata);

在啟動會話時,一旦檢測到有需要接收的資料時,回撥函式被呼叫。ptr 所指向的資料大小由 size 和 nmemb 的乘積獲得。函式最後需要返回接收資料的大小。如果不使用該函式,那麼接收到的資料會直接列印到終端;使用該函式,那麼接收到的資料儲存在 ptr 所執向的區域,可以利用此來儲存接收下來的資料。

4. CURLOPT_USERAGENT
該選項要求傳遞一個以 ` ` 結尾的字串指標,這個字串用來在向伺服器請求時傳送 HTTP 頭部中的 User-Agent 資訊,有些伺服器是需要檢測這個資訊的,如果沒有設定 User-Agent,那麼伺服器拒絕請求。設定後,可以騙過伺服器對此的檢查。

5.  CURLOPT_WRITEDATA

使用該選項時,第 3 個引數作為使用者資料的指標而傳遞到使用  CURLOPT_WRITEFUNCTION 選項時指定的回撥函式中(第 4 個引數)。如果不想用回撥函式而儲存資料,那麼可以使用 CURLOPT_WRITEDATA 選項,使用該選項時,函式的第 3 個引數必須是個 FILE 指標,函式會將接收到的資料自動的寫到這個 FILE 指標所指向的檔案流中。

6. CURLOPT_VERBOSE
在使用該選項且第 3 個引數為 1 時,curl 庫會顯示詳細的操作資訊。這對程式的除錯具有極大的幫助。

7. CURLOPT_NOBODY
使用該選項時,若第 3 個引數設為 1,這樣在輸出中就不會包含主體內容部分。這僅是對在傳輸的所有內容中,含有“頭部”和“主題內容”兩部分的協議而言。如 HTTP(S) 伺服器,在這種情況下將會使 libcurl 庫僅發出一個頭部請求。

8. CURLOPT_HEADER
使用該選項時,第 3 個引數設定為 1,那麼會通知 curl 庫在輸出時要同時包含 “頭部“ 和 “主題內容” 兩個部分。該選項僅是對那些同時包含了”頭部“和”主題內容“這兩部分的協議而言(如 HTTP)。

9. CURLOPT_HEADERFUNCTION
該選項與上面第 3 個選項 CURLOPT_WRITEFUNCTION 類似,只要它一接收到頭部資訊時,它就會執行回撥函式。需要注意的是,回撥函式裡處理的頭部包含了所有收到的響應的頭部資訊,而不只是最後一次的響應。如果需要處理其中的一個頭部,那麼自己需要在所收集的頭部資訊中進行區分。

10. CURLOPT_WRITEHEADER 和  CURLOPT_HEADERDATA
這兩個選項是同一種意思。它們和第 5 條中的 CURLOPT_WRITEDATA 選項功能一樣,表示在接收到頭部資訊並呼叫回撥函式時,給回撥函式傳遞第 4 個引數。

11. CURLOPT_INFILESIZE
當向伺服器上傳檔案時,該選項用來告訴 curl 庫期望上傳的檔案的大小。使用該選項時,應該給函式第 3 個引數的應該是個 long 型變數。如果用的是 SCP 傳輸,那麼該選項強制使用 CURLOPT_INFILESIZE_LARGE 。

12. CURLOPT_INFILESIZE_LARGE
該選項和 CURLOPT_INFILESIZE 功能一樣,但是它要求函式的第 3 個引數必須是個 curl_off_t 型別。curl_off_t 為 int64_t 型別,而 int64_t 定義在 stdint.h 中:

if __WORDSIZE == 64 

typedef long int                int64_t;

# else 

__extension__ 

typedef long long int           int64_t; 

由上面定義知,一般的,如果是 32 位平臺,它就是 long long 型,表示 64 位的;如果是 64 位平臺,它就是 long 型,也為 64 位。總之,就是個 64 位的。

13. CURLOPT_QUOTE 和 CURLOPT_POSTQUOTE
這兩個選項的功能類似,它們的共同點都是給 FTP 或 SFTP 傳遞命令。這些命令應該放在 struct slist 連結串列中儲存,使用時需要用 curl_slist_append() 函式將這些命令打包起來,然後一起傳送出去。
它們的不同點是:CURLOPT_QUOTE 選項要求命令要在 FTP 傳輸請求之前就要傳送到庫,而 CURLOPT_POSTQUOTE 則可以在 FTP 傳輸請求傳送完後傳送。比如像下面的執行順序是無法達到目的的:

1 . … …

2 curl_easy_perform(curl);

3 curl_easy_setopt(curl, CURLOPT_QUOTE, headerlist);

4 curl_easy_perform(curl);

5 … …

上面假設第 1 條 curl_easy_perform(curl); 語句已經傳送了 FTP 傳輸請求,然後再用 CURLOPT_QUOTE 傳送命令是錯誤的,這裡應該使用 CURLOPT_POSTQUOTE 選項。使用 CURLOPT_QUOTE 選項需要先用 curl_easy_perform() 函式將其傳送,然後再用一次 curl_easy_perform() 傳送 FTP 傳輸請求。也就是說需要執行兩次  curl_easy_perform() 函式。而用  CURLOPT_POSTQUOTE 選項則不需要這樣,它只要將選項設定好後,然後只執行一次 curl_easy_perform() 函式即可。

14. CURLOPT_READFUNCTION 和 CURLOPT_READDATA
這兩個選項和上面的  CURLOPT_WRITEFUNCTION 和 CURLOPT_WRITEDATA 類似。在 CURLOPT_READFUNCTION 的回撥函式裡,第 1 個引數 ptr 指標用來接收從第 4 個引數傳遞過來的資料(這個引數往往是個檔案流指標),而這個引數是使用 CURLOPT_READDATA 選項時傳遞過來的。

15. CURLOPT_UPLOAD
在使用該選項時,第 3 個引數設定為 1,表示要準備上傳檔案。這個引數往往會配合 CURLOPT_READDATA,CURLOPT_INFILESIZE_LARGE,以及 CURLOPT_INFILESIZE 這幾個選項一起用。如果是使用 HTTP 協議,那麼使用 PUT 的方法進行上傳,除非另有指定。

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

CURLOPT_HEADER:設為1,則在返回的內容裡包含http header;

CURLOPT_FOLLOWLOCATION:設為0,則不會自動301,302跳轉;

*CURLOPT_INFILESIZE: 當你上傳一個檔案到遠端站點,這個選項告訴PHP你上傳檔案的大小。
*CURLOPT_VERBOSE: 如果你想CURL報告每一件意外的事情,設定這個選項為一個非零值。
*CURLOPT_HEADER: 如果你想把一個頭包含在輸出中,設定這個選項為一個非零值。
*CURLOPT_NOPROGRESS: 如果你不會PHP為CURL傳輸顯示一個程式條,設定這個選項為一個非零值。

 

注意:PHP自動設定這個選項為非零值,你應該僅僅為了除錯的目的來改變這個選項。

*CURLOPT_NOBODY: 如果你不想在輸出中包含body部分,設定這個選項為一個非零值。
*CURLOPT_FAILONERROR: 如果你想讓PHP在發生錯誤(HTTP程式碼返回大於等於300)時,不顯示,設定這個選項為一人非零值。預設行為是返回一個正常頁,忽略程式碼。
*CURLOPT_UPLOAD: 如果你想讓PHP為上傳做準備,設定這個選項為一個非零值。
*CURLOPT_POST: 如果你想PHP去做一個正規的HTTP POST,設定這個選項為一個非零值。這個POST是普通的 application/x-www-from-urlencoded 型別,多數被HTML表單使用。
*CURLOPT_FTPLISTONLY: 設定這個選項為非零值,PHP將列出FTP的目錄名列表。
*CURLOPT_FTPAPPEND: 設定這個選項為一個非零值,PHP將應用遠端檔案代替覆蓋它。
*CURLOPT_NETRC: 設定這個選項為一個非零值,PHP將在你的 ~./netrc 檔案中查詢你要建立連線的遠端站點的使用者名稱及密碼。
*CURLOPT_FOLLOWLOCATION: 設定這個選項為一個非零值(象 “Location: “)的頭,伺服器會把它當做HTTP頭的一部分傳送(注意這是遞迴的,PHP將傳送形如 “Location: “的頭)。
*CURLOPT_PUT: 設定這個選項為一個非零值去用HTTP上傳一個檔案。要上傳這個檔案必須設定CURLOPT_INFILE和CURLOPT_INFILESIZE選項.
*CURLOPT_MUTE: 設定這個選項為一個非零值,PHP對於CURL函式將完全沉默。
*CURLOPT_TIMEOUT: 設定一個長整形數,作為最大延續多少秒。
*CURLOPT_LOW_SPEED_LIMIT: 設定一個長整形數,控制傳送多少位元組。
*CURLOPT_LOW_SPEED_TIME: 設定一個長整形數,控制多少秒傳送CURLOPT_LOW_SPEED_LIMIT規定的位元組數。
*CURLOPT_RESUME_FROM: 傳遞一個包含位元組偏移地址的長整形引數,(你想轉移到的開始表單)。
*CURLOPT_SSLVERSION: 傳遞一個包含SSL版本的長引數。預設PHP將被它自己努力的確定,在更多的安全中你必須手工設定。
*CURLOPT_TIMECONDITION: 傳遞一個長引數,指定怎麼處理CURLOPT_TIMEVALUE引數。你可以設定這個引數為TIMECOND_IFMODSINCE 或 TIMECOND_ISUNMODSINCE。這僅用於HTTP。
*CURLOPT_TIMEVALUE: 傳遞一個從1970-1-1開始到現在的秒數。這個時間將被CURLOPT_TIMEVALUE選項作為指定值使用,或被預設TIMECOND_IFMODSINCE使用。

下列選項的值將被作為字串:

*CURLOPT_URL: 這是你想用PHP取回的URL地址。你也可以在用curl_init()函式初始化時設定這個選項。
*CURLOPT_USERPWD: 傳遞一個形如[username]:[password]風格的字串,作用PHP去連線。
*CURLOPT_PROXYUSERPWD: 傳遞一個形如[username]:[password] 格式的字串去連線HTTP代理。
*CURLOPT_RANGE: 傳遞一個你想指定的範圍。它應該是”X-Y”格式,X或Y是被除外的。HTTP傳送同樣支援幾個間隔,用逗句來分隔(X-Y,N-M)。
*CURLOPT_POSTFIELDS: 傳遞一個作為HTTP “POST”操作的所有資料的字串。
*CURLOPT_REFERER: 在HTTP請求中包含一個”referer”頭的字串。
*CURLOPT_USERAGENT: 在HTTP請求中包含一個”user-agent”頭的字串。
*CURLOPT_FTPPORT: 傳遞一個包含被ftp “POST”指令使用的IP地址。這個POST指令告訴遠端伺服器去連線我們指定的IP地址。這個字串可以是一個IP地址,一個主機名,一個網路介面名(在UNIX下),或是‘-’(使用系統預設IP地址)。
*CURLOPT_COOKIE: 傳遞一個包含HTTP cookie的頭連線。
*CURLOPT_SSLCERT: 傳遞一個包含PEM格式證照的字串。
*CURLOPT_SSLCERTPASSWD: 傳遞一個包含使用CURLOPT_SSLCERT證照必需的密碼。
*CURLOPT_COOKIEFILE: 傳遞一個包含cookie資料的檔案的名字的字串。這個cookie檔案可以是Netscape格式,或是堆存在檔案中的HTTP風格的頭。
*CURLOPT_CUSTOMREQUEST: 當進行HTTP請求時,傳遞一個字元被GET或HEAD使用。為進行DELETE或其它操作是有益的,更Pass a string to be used instead of GET or HEAD when doing an HTTP request. This is useful for doing or another, more obscure, HTTP request.

注意: 在確認你的伺服器支援命令先不要去這樣做。

下列的選項要求一個檔案描述(通過使用fopen()函式獲得):

*CURLOPT_FILE: 這個檔案將是你放置傳送的輸出檔案,預設是STDOUT.
*CURLOPT_INFILE: 這個檔案是你傳送過來的輸入檔案。
*CURLOPT_WRITEHEADER: 這個檔案寫有你輸出的頭部分。
*CURLOPT_STDERR: 這個檔案寫有錯誤而不是stderr。

 

 

 

幾種選項測試函式:

#include <stdio.h>

#include <stdlib.h> 

#include <string.h> 

#include <curl/curl.h> 

#include <curl/easy.h>     

static size_t save_header(void *ptr, size_t size, size_t nmemb, void *data) 

{          

fwrite(ptr, size, nmemb, data);         

return (size * nmemb);

}   

 

int main(void) 

{         

char url[] = “http://www.sina.com.cn/”;         

CURL *curl;         CURLcode res;             

FILE *fp;         

if (!(fp = fopen(“htmheader.html”, “w”))) 

{                 

printf (“fopen error
“);                

return -1;         

}          

curl_global_init(CURL_GLOBAL_ALL);           

curl = curl_easy_init();        

if (curl) 

{                

curl_easy_setopt(curl, CURLOPT_URL, url);                

curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);               

curl_easy_setopt(curl, CURLOPT_HEADER, 0L);           

curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, save_header);   

curl_easy_setopt(curl, CURLOPT_WRITEHEADER, fp);               

curl_easy_perform(curl);        

}       

curl_easy_cleanup(curl);  

curl_global_cleanup();          

fclose (fp);        

return 0;


相關文章