libcurl移植并支持ssl
libcurl移植并支持ssl
设备需要使用https与后台进行交互,使用libcurl非常方便进行http操作,但如果要支持https需要用到openssl,下面记录一下让libcurl支持ssl的过程
编译openssl
- 下载openssl,版本openssl-1.0.1u.tar.gz
解压openssl-1.0.1u.tar.gz - 配置openssl编译选项
./config --prefix=/opt/openssl-lib no-shared no-zlib no-asm no-sse2no-compno-dso -DOPENSSL_THREADS -pthread -D_REENTRANT -D_THREAD_SAFE -D_THREADSAFE
配置选项含义:安装目录/opt/openssl-lib,静态编译的形式,采用线程安全(如果要编译OpenSSL的动态库,可以把no-shared改成on-static)
config执行完成后,在当前目录下生成Makefile,修改Makefile更换交叉编译工具:
CC=arm-hisiv400-linux-gcc
AR=arm-hisiv400-linux-ar $(ARFLAGS) r
RANLIB= arm-hisiv400-linux-ranlib - 编译openssl
make
make install
编译完成后,在/opt/openssl-lib目录下会有如下文件:
至此,openssl编译完成。
编译libcurl
- 下载libcurl(我使用的版本是curl-7.61.1)
去官网下载,下载后解压,进入解压后目录 - 配置编译选项
./configure --prefix=/opt/curl-7.61.1/ --build=i686-linux --host=arm-linux CC=arm-hisiv400-linux-gcc CFLAGS=’-Os’ --enable-debug --enable-optimize --enable-static --disable-dict --disable-ares --disable-threaded-resolver --disable-rtsp --disable-ftp --disable-ldap --disable-ldaps --disable-proxy --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-ipv6 --without-zlib --enable-http -enable-crypto-auth --without-gnutls --without-nss --without-ca-bundle --with-random=/dev/urandom -with-ssl=/opt/openssl-lib
注意:-with-ssl=/opt/openssl-lib,这里要使用openssl编译后的安装目录 - 编译libcurl
make
编译完成后,进入lib/.libs目录下找到libcurl.a,编译后的libcurl.a比较大,用strip压缩一下
arm-hisiv400-linux-strip --strip-unneeded libcurl.a
至此,libcurl静态库编译完成。
测试libcurl https请求
将libcurl.a,libssl.a,libcurl.a,libcrypto.a单独拷贝出来放入lib文件夹,libcurl头文件拷贝出来放入include文件夹,编译如下测试代码验证能否返回https请求
#include "curl.h"
#include "cJSON.h"
#include "public.h"
// 淘宝查询电话号码归属地(可用)
#define POST_URL "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=%s"
typedef size_t (*PARSE_FUN)(void *, size_t, size_t, void *);
size_t process_data(void *data, size_t size, size_t num, void *args)
{
DEBUG("%s", data);
return size * num;
}
int curl_ssl_test(char *data, char *url, PARSE_FUN func, void *args)
{
int ret = -1;
CURLcode code;
code = curl_global_init(CURL_GLOBAL_ALL);
if (CURLE_OK != code)
{
ERROR("curl_global_init error");
return -1;
}
CURL *handle = curl_easy_init();
if (NULL == handle)
{
ERROR("curl_easy_init error");
curl_global_cleanup();
return -1;
}
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json;charset:utf-8");
headers = curl_slist_append(headers, "Expect:");
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, func);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, args);
// use get
curl_easy_setopt(handle, CURLOPT_POST, 0L);
// ssl
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0);
// curl debug
curl_easy_setopt(handle, CURLOPT_VERBOSE, 1);
code = curl_easy_perform(handle);
if (code != CURLE_OK)
{
ERROR("http perform fail(%d:%s)", code, curl_easy_strerror(code));
ret = -1;
}
else
{
ret = 0;
}
curl_easy_cleanup(handle);
curl_slist_free_all(headers); /* free the list again */
curl_global_cleanup();
return ret;
}
char *curl_ssl_json()
{
char *json = NULL;
cJSON *root = xz_cJSON_CreateObject();
if (NULL == root)
{
return NULL;
}
cJSON_AddStringToObject(root, "version", "2.0.1-20191119");
cJSON_AddStringToObject(root, "sn", "5021903003757");
cJSON_AddNumberToObject(root, "cmdId", 10000);
json = xz_cJSON_PrintUnformatted(root);
xz_cJSON_Delete(root);
return json;
}
int main()
{
int ret = -1;
char url[256] = {0};
// 随便乱填一个手机号码测试
snprintf(url, sizeof(url) - 1, POST_URL, "18141124114");
ret = curl_ssl_test(NULL, url, process_data, NULL);
return ret;
}
返回结果: