本文主要是介绍通过https发请求时出现“curle_out_of_memory”错误,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在使用libcurl封装的HTTPClient,使用https(443端口)发请求时,遇到返回CURLE_OUT_OF_MEMORY,经过验证发现原因如下:
1、在初始化curl时,有且仅有一次,使用接口:CURLcode ret_code = curl_global_init(CURL_GLOBAL_SSL);
2、在程序退出时,有且仅有一次,使用接口:curl_global_cleanup();
3、经过查询curl的源码,在CURLcode global_init(long flags, bool memoryfuncs)中会调用Openssl的初始化:Curl_ssl_init(),在curl_global_cleanup(void)中会调用 Curl_ssl_cleanup();因此只要libcurl没有被cleanup,那么Openssl也不会被清理;
4、curle_out_of_memory实际的含义是:与服务端握手时,没有通过,我发现这个错误是由于调用ssl_library_init()初始化openssl库失败造成的。或者说,在使用openssl时发现openssl库被其他也依赖openssl的应用清理掉了(ssl_context_destroy),就算curl中没有清理,使得curl再一次请求时,又没有机会再一次Init,所以Iopenssl握手不成功,请求无法发出,返回错误。
5、最后验证确实如此,其他的应用逻辑在执行完毕时,将自己依赖的openssl清理掉:
......
ERR_free_strings();
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
6、在一个项目中,如果各个SDK依赖OpenSSL的动态库,那么一定会出现这种情况,一个模块Close后很可能清理掉OpenSSL对其他模块有影响,因此我们会想到,各自依赖OpenSSL的静态库,这样各个模块按理相互独立,无论是初始化还是销毁,都不会干扰,但是在一些平台如安卓,各个模块都使用OpenSSL的静态库,实际不是这样。比如SDK1依赖静态库a,SDK2依赖静态库a,SDK3依赖静态库a,静态库a改变只是针对SDK1而改,那么SDK2和SDK3无需更新a,只需SDK1重新编译即可,但是安卓平台,需要各个全部重新编译。这是我遇到的问题,我也不太明白为何这样?
7、针对这样的问题,我们只能判断使用全局变量控制和判断;
static int SSL_library_init = 0;
if(SSL_library_init >0) return ;
SSL_library_init =1;
这篇关于通过https发请求时出现“curle_out_of_memory”错误的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!