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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章