libcurl是一个跨平台的网络协议库,支持dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp等协议。这是一个优秀稳定的网络库,是c++进行http开发的首选。
curl官网地址:https://curl.haxx.se/libcurl/
openssl官网地址:https://www.openssl.org
如果只需要http接口访问,我们只需要移植curl即可,但实际上现在很多网页都是https方式,因此我们需要libcurl支持https协议。特别需要注意的一点是如果不打开ssl支持,去访问https接口将会访问失败,返回错误:CURLE_UNSUPPORTED_PROTOCOL, 1: unsupported protocol
移植的时候需要打开–with-ssl,下载libcurl解压源码,进入源码目录查看帮助:./configure -h
这里我们可以看到–with-ssl=PATH后面是openssl的路径。
好了,接下来我们开始移植工作。
移植这个库之前需要注意需要特别注意的一个坑,如果目标平台是32位系统需要指定平台,64位则略过。32位系统如果不指定,curl在使用过程很可能会出现ssl握手失败的可能:
curl: (35) error:1007C06B:elliptic curve routines:EC_POINT_set_affine_coordinates_GFp:point is not on curve
最终我使用的配置如下:
setarch linux32 ./config no-asm shared --prefix=/home/xxx/work/Hi3516/bulid_libs/openssl --cross-compile-prefix=arm-himix200-linux-
或者
setarch i386 ./config no-asm shared --prefix=/home/xxx/work/Hi3516/bulid_libs/openssl --cross-compile-prefix=arm-himix200-linux-
setarch i386:声明生成的是32位CPU,如果是64位CPU则去除该部分。
no-asm: 是在交叉编译过程中不使用汇编代码代码加速编译过程,原因是它的汇编代码是对arm格式不支持的。
shared :生成动态连接库。
–prefix :指定make install后生成目录的路径。
./configure --with-ssl=/home/xxx/work/Hi3516/mklibs/bulid_libs/openssl --prefix=/home/xxx/work/Hi3516/bulid_libs/curl --host=arm-himix200-linux CC=arm-himix200-linux-gcc CXX=arm-himix200-linux-g++
配置过程情理之中意料之外的出现了错误:
checking for HMAC_Update in -lcrypto… no
checking for HMAC_Init_ex in -lcrypto… no
checking for ssl_version in -laxtls… no
configure: WARNING: SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.
这个错误很奇怪,应该是找不到ssl目录下libcrypto库,当然前提是要于存在ssl和crypto库,但是在我指定的ssl库明显是有这个库的,经过查找答案,在配置前面加路径声明:
LDFLAGS=-L/home/xxx/work/Hi3516/mklibs/bulid_libs/openssl/lib
但是让人抓狂的是上个错误没了,却出现另外一个问题:
configure: error: OpenSSL libs and/or directories were not found where specified!
说到底还是没找到库文件,百思不得其解。困顿良久,通过仔细分析发现原因所在,因为我编译完openssl后把目录移动了,而curl编译的时候查找依赖是通过pkg-config下的.pc文件进行查找的,我移动了目录,但是pc文件却还指向我原来的目录,ok,把openssl整个目录搬回原来路劲,在进行配置,完美通过~!
可以看到支持配置打印:
SSL support: enabled (OpenSSL)
接下来就是make & make install
到此支持ssl的curl编译完成。把bin、lib拷贝到开发板进行测试。
curl -v https://www.baidu.com
很不幸的再次翻车:
很明显这是由于没有设置本地证书导致https访问失败,这里有2个办法,下载证书放到本地路径:https://curl.haxx.se/docs/sslcerts.html
或者跳过证书验证:
curl -v -k https://www.baidu.com
访问成功:
到此支持https的libcurl移植完成。下面我们进行简单的代码访问测试,
实现http/get接口
int Http::http_get_api(const string &url, string &response, const char *ca_path)
{
CURLcode res;
CURL* curl = curl_easy_init();
if (NULL == curl)
{
return CURLE_FAILED_INIT;
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
if (NULL == ca_path)
{
//设定为不验证证书和HOST
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
}
else
{
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);
curl_easy_setopt(curl, CURLOPT_CAINFO, ca_path);
}
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 4);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 4);//超时设置
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(res)
{
printf("http get response failed!");
}
return res;
}
简单的介绍下:
(1)调用curl_easy_init()函数得到 easy interface型指针
(2)调用curl_easy_setopt()设置传输参数
(4)调用curl_easy_perform()函数完成传输任务
(5)调用curl_easy_cleanup()释放内存
作者:费码程序猿
欢迎技术交流:QQ:255895056
转载请注明出处,如有不当欢迎指正