初始化
参数指定要初始化的模块
curl_global_init(CURL_GLOBAL_ALL);
CURL_GLOBAL_WIN32
CURL_GLOBAL_SSL
当不再使用libcurl时调用:
curl_global_cleanup();
查询libcurl支持的特性
curl_version_info()
libcurl
提供两种接口
easy interface
- 函数以curl_easy
为前缀,同步、阻塞调用
(let you do single transfers with a synchronous and blocking function call)
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:password@example.com/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